]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-0.0.9
authorfred <fred>
Mon, 11 Nov 1996 23:22:07 +0000 (23:22 +0000)
committerfred <fred>
Mon, 11 Nov 1996 23:22:07 +0000 (23:22 +0000)
src/identifier.cc [new file with mode: 0644]
src/lexer.l [new file with mode: 0644]
src/parser.y [new file with mode: 0644]

diff --git a/src/identifier.cc b/src/identifier.cc
new file mode 100644 (file)
index 0000000..024fe06
--- /dev/null
@@ -0,0 +1,26 @@
+#include <assert.h>
+#include "identifier.hh"
+#include "staff.hh"
+#include "lexer.hh"
+
+
+Identifier::Identifier(String n)
+    :name  (n)
+{
+    data = 0;
+}
+
+
+Identifier::~Identifier()
+{    
+}
+
+Staff_id::~Staff_id()
+{
+    delete staff();
+}
+
+Voice_id::~Voice_id()
+{
+    delete voice();
+}
diff --git a/src/lexer.l b/src/lexer.l
new file mode 100644 (file)
index 0000000..1e3443e
--- /dev/null
@@ -0,0 +1,229 @@
+%{ // -*-Fundamental-*-
+
+#include <fstream.h>
+#include <stdio.h>
+#include "glob.hh"
+#include "string.hh"
+
+#include "lexer.hh"
+#include "keyword.hh"
+#include "vray.hh"
+#include "parser.hh"
+#include "debug.hh"
+
+sstack<istream *> include_stack;
+static int last_print;
+const int DOTPRINT=50; // every 50 lines dots
+%}
+
+%option c++
+%option noyywrap
+%option nodefault
+%option yylineno
+%option debug
+%x notes
+%x incl
+%x quote
+
+
+NOTECOMMAND    \\{WORD}
+OPTSIGN                !?
+NOTENAMEI       A|B|C|D|E|F|G|As|Bes|Ces|Des|Es|Fes|Ges|Ais|Bis|Cis|Dis|Eis|Fis|Gis
+NOTENAMEII     a|b|c|d|e|f|g|as|bes|ces|des|es|fes|ges|ais|bis|cis|dis|eis|fis|gis
+NOTENAMEIII      Ases|Beses|Ceses|Deses|Eses|Feses|Geses|Aisis|Bisis|Cisis|Disis|Eisis|Fisis|Gisis
+NOTENAMEIIII      ases|beses|ceses|deses|eses|feses|geses|aisis|bisis|cisis|disis|eisis|fisis|gisis
+RESTNAME        r|s
+NOTENAME        {NOTENAMEI}|{NOTENAMEII}|{NOTENAMEIII}|{NOTENAMEIIII}
+PITCH          ['`]*{OPTSIGN}{NOTENAME}
+DURNAME                1|2|4|8|16|32
+DURATION       {DURNAME}\.*
+FULLNOTE       {PITCH}{DURATION}?
+WORD           [a-zA-Z][a-zA-Z0-9_]+
+REAL           [0-9]+(\.[0-9]*)?
+
+%%
+
+\$             {
+       BEGIN(notes); return '$';
+}
+
+<notes>{NOTECOMMAND}   {
+       String c = YYText() +1;
+       int l = lookup_keyword(c);
+       if (l == -1) {
+               String e("unknown NOTECOMMAND: \\");
+               e += c;
+               yyerror(e);
+       }
+       return l;
+}
+
+<notes>{RESTNAME}      {
+       const char *s = YYText();
+       yylval.string = new String (s); 
+       mtor << "rest:"<< yylval.string;
+       return RESTNAME;
+}
+<notes>{PITCH} {
+       const char *s = YYText();
+       yylval.string = new String (s);
+       mtor << "pitch:"<< *yylval.string;
+       return PITCH;
+}
+<notes>{DURATION}      {
+       yylval.string = new String (YYText());
+       return DURATION;
+}
+<notes>\|              {
+}
+<notes>[:space:]+              {
+}
+<notes>[ \t\n]+                {
+}
+<notes>%.*             {
+
+}
+<notes>\$      {
+       BEGIN(INITIAL); return '$';
+}
+<notes>[\[){]  { /* parens () are NO mistake */
+       yylval.c = YYText()[0];
+       return OPEN_REQUEST_PARENS;
+}
+<notes>[\]()}] { /* parens () are NO mistake */
+       yylval.c = YYText()[0];
+       return CLOSE_REQUEST_PARENS;
+}
+
+<notes>.       {
+       String s("lexer error: illegal character found: " + String(YYText()));
+       yyerror(s);
+}
+
+\"             {
+       BEGIN(quote);
+}
+<quote>[^\"]*  {
+       yylval.string = new String (YYText());
+}
+<quote>\"      {
+       BEGIN(INITIAL);
+       return STRING;
+}
+
+<<EOF>> {
+       if(!close_input())
+               yyterminate();
+}
+{WORD}         {
+       int l = lookup_keyword(YYText());
+       if (l != -1)
+               return l;
+       Identifier * id = lookup_identifier(YYText());
+       if (id) {               
+               yylval.id = id;
+               return IDENTIFIER;
+       }
+       String *sp = new String( YYText());
+       mtor << "new id: " << *sp;
+       yylval.string=sp;
+       return NEWIDENTIFIER;
+}
+
+{REAL}         {
+       Real r;
+       int cnv=sscanf (YYText(), "%lf", &r);
+       assert(cnv == 1);
+       mtor  << "token (REAL)" << r;
+       yylval.real = r;
+       return REAL;
+}
+
+[\{\}\[\]\(\)] {
+
+       mtor << "parens\n";
+       return YYText()[0];
+}
+[:=]           {
+       char c = YYText()[0];
+       mtor << "misc char" <<c<<"\n";
+       return c;
+}
+[ \t\n]+       {
+       
+}
+
+%.*            {
+       //ignore
+}
+.              {
+       error("lexer error: illegal character '"+String(YYText()[0])+
+         "' encountered");
+       return YYText()[0];
+}
+
+%%
+
+yyFlexLexer *lexer=0;
+
+// set the  new input to s, remember old file.
+void
+new_input(String s)
+{    
+    istream *newin ;
+    
+    if (s=="")
+       newin = &cin;
+    else
+       newin = new ifstream( s ); //
+    
+   if ( ! *newin)
+      error("cant open "  + s);
+   cout << "["<<s<<flush;
+   
+   include_stack.push(newin);
+
+   if (!lexer) {
+       lexer = new yyFlexLexer;
+       lexer->set_debug( !monitor.silence("Lexer"));
+   }           
+   
+   lexer->switch_streams(newin);
+}
+
+
+// pop the inputstack.
+bool
+close_input()
+{
+
+  istream *closing= include_stack.pop();
+  if (closing != &cin)
+      delete closing;
+  
+  cout << "]" << flush;
+  
+  if (include_stack.empty()) {
+       return false ;
+  } else 
+      lexer->switch_streams(include_stack.top());  
+  return true;  
+}
+
+int
+yylex() {
+       return lexer->yylex();
+}
+
+void
+yyerror(const char *s)
+{
+  *mlog << "error in line " << lexer->lineno() <<  ": " << s << '\n';
+  exit(1);
+}
+
+void
+kill_lexer()
+{
+       delete lexer;
+}
diff --git a/src/parser.y b/src/parser.y
new file mode 100644 (file)
index 0000000..691d306
--- /dev/null
@@ -0,0 +1,292 @@
+%{ // -*-Fundamental-*-
+#include <iostream.h>
+
+#include "lexer.hh"
+#include "paper.hh"
+#include "staff.hh"
+#include "score.hh"
+#include "main.hh"
+#include "keyword.hh"
+#include "scommands.hh"
+#include "debug.hh"
+#include "parseconstruct.hh"
+#include "dimen.hh"
+#include "identifier.hh"
+
+#ifndef NDEBUG
+#define YYDEBUG 1
+#endif
+
+svec<Request*> pre_reqs, post_reqs;
+%}
+
+
+%union {    
+    Real real;
+    Command *command;
+    Identifier *id;    
+    Score_commands *scommands;
+    Voice *voice;    
+    Voice_element *el; 
+    Staff *staff;    
+    String *string;
+    Score *score;
+    const char *consstr;
+    Paperdef *paper;
+    Request* request;
+    int i;
+    char c;
+}
+
+%token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT
+%token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS
+%token MELODICSTAFF GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
+
+%token <id>  IDENTIFIER
+%token <string> NEWIDENTIFIER 
+%token <string> PITCH DURATION RESTNAME
+%token <real> REAL
+%token <string> STRING
+%token <i> OPEN_REQUEST_PARENS CLOSE_REQUEST_PARENS
+
+
+%type <consstr> unit
+
+%type <id> declaration 
+%type <paper> paper_block paper_body
+%type <real> dim
+%type <voice> voice_block voice_body voice_elts voice_elts_dollar
+%type <el> voice_elt
+%type <command> score_command
+%type <score> score_block score_body
+%type <staff> staff_block  rhythmstaff_block rhythmstaff_body
+%type <staff> melodicstaff_block melodicstaff_body staffdecl
+%type <i> int
+%type <scommands> score_commands_block score_commands_body
+%type <request> post_request pre_request
+
+
+%%
+
+mudela:        /* empty */
+       | mudela score_block { 
+               add_score($2);
+       }
+       | mudela add_declaration {      }
+       ;
+
+add_declaration: declaration   {
+               add_identifier($1);
+       }
+       ;
+
+declaration:
+       NEWIDENTIFIER '=' staff_block  {
+               $$ = new Staff_id(*$1, $3);
+               delete $1; // this sux
+       }
+       | NEWIDENTIFIER '=' voice_block {
+               $$ = new Voice_id(*$1, $3);
+               delete $1;
+       }
+       ;
+
+
+score_block: SCORE '{' score_body '}'  { $$ = $3; }
+       ;
+
+score_body:            { $$ = new Score; } 
+       | score_body staff_block        { $$->add($2); }
+       | score_body score_commands_block       { $$->set($2); }
+       | score_body paper_block                { $$->set($2);  }
+       ;
+score_commands_block:
+       COMMANDS '{' score_commands_body '}' { $$ =$3;}
+       ;
+
+score_commands_body:                   { $$ = new Score_commands; }
+       | score_commands_body score_command             {
+               $$->parser_add($2);
+       }
+       ;
+
+paper_block:
+       PAPER '{' paper_body '}'        { $$ = $3; }
+       ;
+
+paper_body:
+       /* empty */                     { $$ = new Paperdef; }
+       | paper_body WIDTH dim          { $$->linewidth = $3;}
+       | paper_body OUTPUT STRING      { $$->outfile = *$3;
+               delete $3;
+       }
+       | paper_body UNITSPACE dim      { $$->whole_width = $3; }
+       | paper_body GEOMETRIC REAL     { $$->geometric_ = $3; }
+       ;
+
+dim:
+       REAL unit       { $$ = convert_dimen($1,$2); }
+       ;
+
+
+unit:  CM              { $$ = "cm"; }
+       |IN             { $$ = "in"; }
+       |MM             { $$ = "mm"; }
+       |PT             { $$ = "pt"; }
+       ;
+       
+/*
+       staff
+*/
+staff_block:
+       staffdecl
+       | rhythmstaff_block
+       | melodicstaff_block
+       ;
+
+staffdecl: STAFF '{' IDENTIFIER '}' { $$ = $3->staff()->clone(); }
+       ;
+
+rhythmstaff_block:
+       RHYTHMSTAFF '{' rhythmstaff_body '}'    { $$ = $3; }
+       ;
+
+rhythmstaff_body:
+       /* empty */                     { $$ = get_new_rhythmstaff(); }
+       | rhythmstaff_body voice_block  { $$->add_voice($2); }  
+       ;
+
+melodicstaff_block:
+       MELODICSTAFF '{' melodicstaff_body '}'  { $$ = $3; }
+       ;
+
+melodicstaff_body:
+       /* empty */                     { $$ = get_new_melodicstaff(); }
+       | melodicstaff_body voice_block         { $$->add_voice($2); }  
+       ;
+
+/*
+       voice
+*/
+voice_block:
+       VOICE '{' voice_body '}'        { $$ = $3; }
+       ;
+
+
+voice_body:
+       IDENTIFIER              { $$ = new Voice(*$1->voice()); }
+       | voice_elts_dollar     { $$ = $1; }
+       | voice_body START_T REAL { $$->start = $3; }
+       ;
+
+
+       
+
+voice_elts_dollar:
+       '$' voice_elts '$'  { $$ = $2; }
+       ;
+
+voice_elts:
+       /* empty */             {
+            $$ = new Voice;
+        }
+        | voice_elts pre_requests voice_elt post_requests {
+               add_requests($3, pre_reqs);
+               add_requests($3, post_reqs);
+               $$->add($3);
+        }
+
+       | voice_elts voice_command { }
+       ;
+
+post_requests:
+       {
+               assert(post_reqs.empty());
+       }
+       | post_requests post_request {
+               post_reqs.add($2);
+       }
+       ;
+
+post_request:
+       CLOSE_REQUEST_PARENS            { $$ = get_request($1); }
+       ;
+
+pre_requests:   
+       | pre_requests pre_request {
+               pre_reqs.add($2);
+       }
+       ;
+
+pre_request: 
+       OPEN_REQUEST_PARENS             { $$ = get_request($1); }
+       ;
+/*
+*/
+voice_command:
+       DURATIONCOMMAND DURATION        {
+               set_default_duration(*$2);
+               delete $2;
+       }
+       | OCTAVECOMMAND PITCH   {
+               set_default_pitch(*$2);
+               delete $2;
+       }
+       ;
+
+voice_elt:
+       PITCH  DURATION                         {
+               $$ = get_note_element(*$1, *$2);
+               delete $1;
+               delete $2;
+       }
+       |  RESTNAME DURATION            {
+               $$ = get_rest_element(*$1, *$2);
+               delete $1;
+               delete $2;
+       }
+       | PITCH                         { $$ = get_note_element(*$1, "");
+               delete $1;
+       }
+       |  RESTNAME             { $$ = get_rest_element(*$1, "");
+               delete $1;
+       }
+       ;
+
+score_command:
+       SKIP int ':' REAL               {
+               $$ = get_skip_command($2, $4);
+       }
+       | METER  int int                {
+               $$ = get_meterchange_command($2, $3);
+       }
+/*     | PARTIALMEASURE REAL           {
+               $$ = get_partial_command($2);
+       }*/
+       ;
+       
+
+int:
+       REAL                    {
+               $$ = int($1);
+               if (ABS($1-Real(int($$))) > 1e-8)
+                       yyerror("expecting integer number");
+               
+       }
+       ;
+
+%%
+
+void
+parse_file(String s)
+{
+   *mlog << "Parsing ... ";
+#ifdef YYDEBUG
+   yydebug = !monitor.silence("Parser");
+#endif
+   new_input(s);
+   yyparse();
+   delete_identifiers();
+   kill_lexer();
+   *mlog << "\n";
+}