]> git.donarmstrong.com Git - lilypond.git/blobdiff - src/parser.y
release: 0.0.34
[lilypond.git] / src / parser.y
index 8d6ac75f0c2cdbe32816f3b0896e6fbc0cda5db0..d065f19cae89b1209754f347b42bceaef4c91dba 100644 (file)
@@ -4,25 +4,28 @@
 #include "lookup.hh"
 #include "misc.hh"
 #include "lexer.hh"
-#include "paper.hh"
+#include "paperdef.hh"
+#include "mididef.hh"
 #include "inputscore.hh"
 #include "main.hh"
 #include "keyword.hh"
-#include "inputcommand.hh"
 #include "debug.hh"
 #include "parseconstruct.hh"
 #include "dimen.hh"
 #include "identifier.hh"
+#include "commandrequest.hh"
+#include "musicalrequest.hh"
 
 #ifndef NDEBUG
 #define YYDEBUG 1
 #endif
 
 Array<Request*> pre_reqs, post_reqs;
-sstack<String> define_spots;
+Array<const char *> define_spots;
 Paperdef*default_paper();
 char const* defined_ch_c_l;
 char const* req_defined_ch_c_l;
+int fatal_error_i = 0;
 
 %}
 
@@ -30,13 +33,13 @@ char const* req_defined_ch_c_l;
 %union {
     Request * request;
     Real real;
-    Input_command *command;
     Identifier *id;    
-    Voice *voice;    
+   Voice *voice;    
     Voice_element *el; 
     String *string;
     const char *consstr;
     Paperdef *paper;
+    Midi_def* midi;
     Input_music *music;
     Music_general_chord *chord;
     Music_voice *mvoice; 
@@ -46,9 +49,8 @@ char const* req_defined_ch_c_l;
        Moment *moment;
 
     Array<String> * strvec;
-    Array<Input_command*> *commandvec;
     Array<int> *intvec;
-
+    Array<Melodic_req*> *melreqvec;
     Input_staff *staff;    
     Input_score *score;
     Symtables * symtables;
@@ -63,12 +65,13 @@ char const* req_defined_ch_c_l;
 }
 
 %token VOICE STAFF SCORE TITLE  BAR  OUTPUT MULTIVOICE
-%token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND
+%token CM_T IN_T PT_T MM_T PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND
 %token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND
 %token KEY CLEF  TABLE  VOICES STEM
 %token PARTIAL MUSIC GROUPING CADENZA
 %token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET
-%token MARK GOTO
+%token  GOTO
+%token MIDI TEMPO
 
 %token <id>  IDENTIFIER
 %token <string> PITCHMOD DURATION RESTNAME
@@ -77,25 +80,24 @@ char const* req_defined_ch_c_l;
 %token <string> STRING
 
 %token <i> DOTS INT
-%type <consstr> unit
-%type <intvec> pitch_list 
-%type <c> open_request_parens close_request_parens
+%type <real> unit
+%type <melreqvec> pitch_list 
+%type <c> open_request_parens close_request_parens close_plet_parens
 %type <id> declaration
 %type <string> declarable_identifier
 %type <paper> paper_block paper_body
+%type <midi> midi_block midi_body
 %type <real> dim real
 %type <ii>  default_duration explicit_duration notemode_duration mudela_duration
 %type <ii> notename
 %type <moment> duration_length
-%type <el> voice_elt full_element lyrics_elt
-%type <command> score_command staff_command position_command
+%type <el> voice_elt full_element lyrics_elt command_elt
+
 %type <score> score_block score_body
 %type <staff> staff_block staff_init staff_body
 %type <i> int
-%type <intvec> int_list intastint_list
-%type <commandvec> score_commands_block score_commands_body
-%type <commandvec> staff_commands_block staff_commands_body
-%type <request> post_request pre_request 
+%type <intvec> intastint_list
+%type <request> post_request pre_request command_req
 %type <string> pitchmod
 %type <music> music 
 %type <chord> music_chord music_chord_body
@@ -144,7 +146,7 @@ declarable_identifier:
 declaration:
        declarable_identifier '=' staff_block  {
                $$ = new Staff_id(*$1, $3);
-               delete $1; // this sux
+               delete $1; 
        }
        | declarable_identifier '=' music_voice {
                $$ = new M_voice_id(*$1, $3);
@@ -171,7 +173,7 @@ declaration:
                delete $1;
        }
        | declarable_identifier error '}' {
-               warning( "parse error", lexer->here_ch_c_l() );
+
        }
        ;
 
@@ -194,13 +196,13 @@ notename_tab_body:                                {
 /*
        SCORE
 */
-score_block: SCORE 
-               { define_spots.push(lexer->spot()); }
-       '{' score_body '}'      {
+score_block:
+       SCORE { define_spots.push(lexer->here_ch_c_l()); }
+       /*cont*/ '{' score_body '}'     {
                $$ = $4;
-               $$->define_spot_str_ = define_spots.pop();
-               if (!$$->paper_)
-                       $$->paper_ = default_paper();
+               $$->defined_ch_c_l_ = define_spots.pop();
+               if (!$$->paper_p_ && ! $$->midi_p_)
+                       $$->paper_p_ = default_paper();
 
                /* handle error levels. */
                $$->errorlevel_i_ = lexer->errorlevel_i_;
@@ -212,68 +214,16 @@ score_body:               {
                $$ = new Input_score; 
        }
        | score_body staff_block        { $$->add($2); }
-       | score_body score_commands_block       {
-               $$->add(*$2);
-               delete $2;
+       | score_body COMMANDS '{' music_voice_body '}'          {
+               $$->set($4);
        }
        | score_body paper_block                { $$->set($2);  }
-       ;
-/*
-       COMMANDS
-*/
-score_commands_block:
-       COMMANDS '{' score_commands_body '}' { $$ =$3;}
-       | COMMANDS '{' error '}' {
-               warning( "parse error", lexer->here_ch_c_l() );
-       }
-       ;
-
-score_commands_body:                   { $$ = new Array<Input_command*>; }
-       | score_commands_body score_command             {
-               $$->push($2);
-       }
-       | score_commands_body position_command          {
-               $$->push($2);
-       }
-       ;
-
-staff_commands_block: COMMANDS '{' staff_commands_body '}'     {       
-               $$ = $3; }
-       ;
-
-staff_commands_body:
-       /* empty */                     { $$ = new Array<Input_command*>; }
-       | staff_commands_body staff_command     {
-               $$->push($2);
-       }
-       | staff_commands_body position_command  {
-               $$->push($2);
-       }
-       ;
-
-staff_command:
-       KEY pitch_list  {/*UGH*/
-               $$ = get_key_interpret_command(*$2);
-               delete $2;
-       }
-       | CLEF STRING                   {
-               $$ = get_clef_interpret_command(*$2);
-               delete $2;
-       }
-       ;
+       | score_body midi_block         { $$->set($2);  }
+       | score_body error {
 
-position_command:
-       SKIP int ':' duration_length            {
-               $$ = get_skip_command($2, *$4);
-               delete $4;
-       }
-       | GOTO STRING   {
-               $$ = get_goto_command(*$2);
-               delete $2;
        }
        ;
 
-
 intastint_list:
        /* */   { $$ =new Array<int>; }
        | intastint_list int '*' int    {
@@ -281,28 +231,6 @@ intastint_list:
        }
        ;
 
-score_command:
-       BAR STRING                      {
-               $$ = get_bar_command(*$2);
-               delete $2;
-       }
-       | METER  int '*' int            {
-               $$ = get_meterchange_command($2, $4);
-       }
-       | PARTIAL duration_length               {
-               $$ = get_partial_command(*$2);
-               delete $2;
-       }
-       | GROUPING intastint_list               {
-               $$ = get_grouping_command(*$2);
-               delete $2;
-       }
-       | CADENZA int   {
-               $$ = get_cadenza_toggle($2);
-       }
-       ;
-
-
 
 /*
        PAPER
@@ -325,7 +253,31 @@ paper_body:
        | paper_body UNITSPACE dim      { $$->whole_width = $3; }
        | paper_body GEOMETRIC REAL     { $$->geometric_ = $3; }
        | paper_body error {
-               warning( "parse error", lexer->here_ch_c_l() );
+
+       }
+       ;
+
+/*
+       MIDI
+*/
+midi_block:
+       MIDI
+
+       '{' midi_body '}'       { $$ = $3; }
+       ;
+
+midi_body: { 
+               $$ = new Midi_def; 
+       }
+       | midi_body OUTPUT STRING       { 
+               $$->outfile_str_ = *$3; 
+               delete $3; 
+       }
+       | midi_body TEMPO mudela_duration ':' int {
+               $$->set_tempo( wholes( $3[0], $3[1] ), $5 );
+       }
+       | midi_body error {
+
        }
        ;
 
@@ -333,10 +285,10 @@ paper_body:
        STAFFs
 */
 staff_block:
-       STAFF   { define_spots.push(lexer->spot()); }
+       STAFF   { define_spots.push(lexer->here_ch_c_l()); }
 /*cont*/       '{' staff_body '}'      {
                $$ = $4; 
-               $$->define_spot_str_ = define_spots.pop();
+               $$-> defined_ch_c_l_ = define_spots.pop();
        }
        ;
 
@@ -352,16 +304,14 @@ staff_init:
 
 staff_body:
        staff_init
+       | staff_body COMMANDS '{' music_voice_body '}'  {
+               $$->set_score_wide($4);
+       }
        | staff_body music      {
                $2->set_default_group( "staff_music" + String($$->music_.size()));
                $$->add($2);
        }
-       | staff_body staff_commands_block {
-               $$->add(*$2);
-               delete $2;
-       }
        | staff_body error {
-               warning( "parse error", lexer->here_ch_c_l() );
        }
        ;
 
@@ -392,7 +342,6 @@ music_voice_body:
                $$->add($2);
        }
        | music_voice_body error {
-               warning( "parse error", lexer->here_ch_c_l() );
        }
        ;
 
@@ -410,18 +359,16 @@ music_chord_body:
                $$->concatenate($2->mchord(true));
        }
        | music_chord_body music {
-               $$ -> add($2);
+               $$->add($2);
        }
        | music_chord_body full_element {
                $$ ->add_elt($2);
        }
        | music_chord_body error {
-               warning( "parse error", lexer->here_ch_c_l() );
        }
        ;
 
 
-
 /*
        VOICE ELEMENTS
 */
@@ -430,61 +377,116 @@ full_element:    pre_requests voice_elt post_requests {
                add_requests($2, post_reqs);
                $$ = $2;
        }
-       | MARK STRING   {
-               $$ = get_mark_element(*$2);
+       | pre_requests lyrics_elt post_requests {
+               add_requests($2, pre_reqs);
+               add_requests($2, post_reqs);
+               $$ = $2;
+        }
+       | command_elt
+       ;
+
+command_elt:
+/* empty */    {
+               $$ = new Voice_element;
+               $$-> defined_ch_c_l_ = lexer->here_ch_c_l();
+       }
+/* cont: */
+       command_req     {
+               $2-> defined_ch_c_l_ = $$->defined_ch_c_l_;
+               $$->add($2);
+
+       }
+       ;
+
+command_req:
+        '|'                            { 
+               $$ = new Barcheck_req;
+       }
+       | BAR STRING                    {
+               $$ = new Bar_req(*$2);
                delete $2;
        }
-       | COMMAND '{' staff_command '}' { $$=get_command_element($3); }
-       | COMMAND '{' score_command '}' { $$=get_command_element($3); }
-       | '|'                           { $$ = get_barcheck_element(); }
+       | METER '{' int '*' int '}'     {
+               Meter_change_req *m = new Meter_change_req;
+               m->set($3,$5);
+               $$ = m;
+       }
+       | SKIP '{' duration_length '}' {
+               Skip_req * skip_p = new Skip_req;
+               skip_p->duration_ = *$3;
+               delete $3;
+               $$ = skip_p;
+       }
+       | CADENZA '{' int '}'   {
+               $$ = new Cadenza_req($3);
+       }
+       | PARTIAL '{' duration_length '}'       {
+               $$ = new Partial_measure_req(*$3);
+               delete $3;
+       }
        | STEM '{' int '}'              {
-               $$ = get_stemdir_element($3);
+               $$ = get_stemdir_req($3);
+       }
+       | CLEF STRING {
+               $$ = new Clef_change_req(*$2);
+               delete $2;
+       }
+       | KEY '{' pitch_list '}'        {       
+               Key_change_req *key_p= new Key_change_req;
+               key_p->melodic_p_arr_ = *$3;
+               $$ = key_p;
+               delete $3;
+       }
+       | GROUPING '{' intastint_list '}' {
+               $$ = get_grouping_req(*$3); delete $3;
        }
-       | lyrics_elt
-/*
-+      | pre_requests voice_elt post_requests error '|' { 
-+              warning( "parse error", lexer->here_ch_c_l() );
-+      }
-+ */
        ;
-               
+
 post_requests:
        {
                assert(post_reqs.empty());
        }
        | post_requests post_request {
+               $2->defined_ch_c_l_ = lexer->here_ch_c_l();
                post_reqs.push($2);
        }
+       | post_requests close_plet_parens INT '/' INT { 
+               post_reqs.push( get_request($2) ); 
+               req_defined_ch_c_l = lexer->here_ch_c_l();
+               post_reqs.push( get_plet_request( $2, $3, $5 ) ); 
+       }
        ;
 
 post_request:
        close_request_parens    { 
                $$ = get_request($1); 
-               req_defined_ch_c_l = lexer->here_ch_c_l();
        }
        | script_req
        | textscript_req
        ;
 
+close_plet_parens:
+       ']' {
+               req_defined_ch_c_l = lexer->here_ch_c_l();
+               $$ = ']';
+       }
+       ;
+
 close_request_parens:
        '('     { 
                $$='(';
-               req_defined_ch_c_l = lexer->here_ch_c_l();
        }
        | ']'   { 
                $$ = ']';
-               req_defined_ch_c_l = lexer->here_ch_c_l();
        }
        ;
   
 open_request_parens:
        ')'     { 
                $$=')';
-               req_defined_ch_c_l = lexer->here_ch_c_l();
        }
        | '['   {
                $$='[';
-               req_defined_ch_c_l = lexer->here_ch_c_l();
        }
        ;
 
@@ -505,14 +507,16 @@ textscript_req:
 
 mudela_text:
        STRING                  { 
+               defined_ch_c_l = lexer->here_ch_c_l();
                $$ = get_text(*$1); 
                delete $1;
-               defined_ch_c_l = lexer->here_ch_c_l();
        }
        ;
 
 script_req:
-       script_dir mudela_script        { $$ = get_script_req($1, $2); }
+       script_dir mudela_script        { 
+               $$ = get_script_req($1, $2);
+       }
        ;
 
 mudela_script:
@@ -530,6 +534,10 @@ mudela_script:
                    warning( "too many staccato dots", lexer->here_ch_c_l() );
                $$ = get_scriptdef('.');
        }
+       | error {
+               $$ = get_scriptdef('.');
+               yyerrok;
+       }
        ;
 
 script_dir:
@@ -541,13 +549,14 @@ script_dir:
 pre_requests:
        | pre_requests pre_request {
                pre_reqs.push($2);
+               $2->defined_ch_c_l_ = lexer->here_ch_c_l();
        }
        ;
 
 pre_request: 
        open_request_parens     { 
-               $$ = get_request($1); 
                defined_ch_c_l = lexer->here_ch_c_l();
+               $$ = get_request($1); 
        }
        ;
 
@@ -566,7 +575,7 @@ voice_command:
                set_default_octave(*$3);
                delete $3;
        }
-       | TEXTSTYLE STRING      {
+       | TEXTSTYLE STRING      {
                set_text_style(*$2);
                delete $2;
        }
@@ -622,12 +631,12 @@ default_duration:
        ;
 
 pitchmod:              { 
-               $$ = new String; 
                defined_ch_c_l = lexer->here_ch_c_l();
+               $$ = new String; 
        }
        | PITCHMOD      { 
-               $$ = $1;
                defined_ch_c_l = lexer->here_ch_c_l();
+               $$ = $1;
        }
        ;
 
@@ -654,13 +663,15 @@ lyrics_elt:
 
 /*
        UTILITIES
-*/
+ */
 pitch_list:                    {
-               $$ = new Array<int>;
+               $$ = new Array<Melodic_req*>;
        }
        | pitch_list NOTENAME   {
-               $$->push($2[0]);
-               $$->push($2[1]);                
+               Melodic_req *m_p = new Melodic_req;
+               m_p->notename_i_ = $2[0];
+               m_p->accidental_i_ = $2[1];
+               $$->push(m_p);
        }
        ;
 
@@ -685,24 +696,16 @@ real:
        ;
        
 
-int_list:              {
-               $$ = new Array<int>;
-       }
-       | int_list int          {
-               $$->push($2);
-       }
-       ;
-
 
 dim:
-       real unit       { $$ = convert_dimen($1,$2); }
+       real unit       { $$ = $1*$2; }
        ;
 
 
-unit:  CM              { $$ = "cm"; }
-       |IN             { $$ = "in"; }
-       |MM             { $$ = "mm"; }
-       |PT             { $$ = "pt"; }
+unit:  CM_T            { $$ = 1 CM; }
+       |IN_T           { $$ = 1 INCH; }
+       |MM_T           { $$ = 1 MM; }
+       |PT_T           { $$ = 1 PT; }
        ;
        
 /*
@@ -770,6 +773,15 @@ dinterval: dim     dim             {
 
 %%
 
+void
+yyerror(const char *s)
+{
+       lexer->LexerError(s);
+
+       if ( fatal_error_i )
+               exit( fatal_error_i );
+}
+
 void
 parse_file(String init, String s)
 {
@@ -777,16 +789,16 @@ parse_file(String init, String s)
    lexer = new My_flex_lexer;
 
 #ifdef YYDEBUG
-   yydebug = !monitor.silence("InitParser") && check_debug;
-   lexer->set_debug( !monitor.silence("InitLexer") && check_debug);
+   yydebug = !monitor->silence("InitParser") && check_debug;
+   lexer->set_debug( !monitor->silence("InitLexer") && check_debug);
 #endif
 
    lexer->new_input(init);
    yyparse();
 
 #ifdef YYDEBUG
-   yydebug = !monitor.silence("Parser") && check_debug;
-   lexer->set_debug( !monitor.silence("Lexer") && check_debug);
+   yydebug = !monitor->silence("Parser") && check_debug;
+   lexer->set_debug( !monitor->silence("Lexer") && check_debug);
 #endif
 
    lexer->new_input(s);
@@ -794,7 +806,8 @@ parse_file(String init, String s)
    delete lexer;
    lexer = 0;
 
-   assert(define_spots.empty());
+   if(!define_spots.empty())
+       warning("Braces don't match.",0);
 }
 
 Paperdef*