]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.y
release: 0.1.10
[lilypond.git] / lily / parser.y
index 4f074fb2dc0b7f03a32d708b8fe9cd825ec927fd..288d1407f1219f2c62ef0de670f282bf4111f31f 100644 (file)
@@ -1,7 +1,7 @@
 %{ // -*-Fundamental-*-
 
 /*
-  parser.y -- lily parser
+  parser.y -- YACC parser for mudela
 
   source file of the GNU LilyPond music typesetter
 
@@ -12,7 +12,7 @@
 #include <iostream.h>
 
 // mmm
-#define MUDELA_VERSION "0.1.0"
+#define MUDELA_VERSION "0.1.1"
 
 #include "script-def.hh"
 #include "symtable.hh"
@@ -34,6 +34,8 @@
 #include "input-translator.hh"
 #include "score.hh"
 #include "music-list.hh"
+#include "header.hh"
+#include "duration-convert.hh"
 
 #ifndef NDEBUG
 #define YYDEBUG 1
@@ -62,6 +64,7 @@
     Music *music;
     Music_list *musiclist;
     Score *score;
+    Header *header;
     Interval *interval;
     Lookup*lookup;
     Melodic_req * melreq;
@@ -77,6 +80,7 @@
     Symtable * symtable;
     Symtables * symtables;
     Text_def * textdef;
+    Tempo_req *tempo;
     char c;
     const char *consstr;
     int i;
@@ -100,7 +104,6 @@ yylex(YYSTYPE *s,  void * v_l)
 %pure_parser
 
 /* tokens which are not keywords */
-%token CONCAT
 
 %token ALIAS
 %token BAR
@@ -111,17 +114,16 @@ yylex(YYSTYPE *s,  void * v_l)
 %token CONSISTS
 %token ACCEPTS
 %token CM_T
-%token DURATIONCOMMAND
+%token DURATION
 %token ABSDYNAMIC
 %token END
-%token GEOMETRIC
 %token GROUPING
 %token GROUP
 %token REQUESTTRANSLATOR
 %token HSHIFT
+%token HEADER
 %token IN_T
 %token ID
-%token INIT_END
 %token LYRIC
 %token KEY
 %token MELODIC
@@ -130,9 +132,8 @@ yylex(YYSTYPE *s,  void * v_l)
 %token METER
 %token MM_T
 %token MULTI
-%token NOTE
 %token NOTENAMES
-%token OCTAVECOMMAND
+%token OCTAVE
 %token OUTPUT
 %token PAPER
 %token PARTIAL
@@ -152,8 +153,6 @@ yylex(YYSTYPE *s,  void * v_l)
 %token TEXID
 %token TEXTSTYLE
 %token TITLE
-%token UNITSPACE
-%token WIDTH
 %token VERSION
 
 /* escaped */
@@ -162,13 +161,14 @@ yylex(YYSTYPE *s,  void * v_l)
 %type <i>      dots
 %token <i>     INT
 %token <melreq>        NOTENAME_ID
+%token <id>    DURATION_IDENTIFIER
 %token <id>    IDENTIFIER
 %token <id>    MELODIC_REQUEST_IDENTIFIER 
 %token <id>    MUSIC_IDENTIFIER
 %token <id>    VOICE_IDENTIFIER
 %token <id>    POST_REQUEST_IDENTIFIER
 %token <id>    SCRIPT_IDENTIFIER
-%token <id>    STAFF_IDENTIFIER
+%token <id>    COMMAND_IDENTIFIER
 %token <id>    REAL_IDENTIFIER
 %token <id>    INPUT_TRANS_IDENTIFIER
 %token <id>    INT_IDENTIFIER
@@ -178,19 +178,22 @@ yylex(YYSTYPE *s,  void * v_l)
 %token <id>    REQUEST_IDENTIFIER
 %token <real>  REAL 
 %token <string>        DURATION RESTNAME
-%token <string>        STRING
+%token <string>        STRING 
+%token <string> FIELDNAME RECORDLINE
 %token <i>     POST_QUOTES 
 %token <i>     PRE_QUOTES
 
 
+%type <header>         mudela_header mudela_header_body
 %type <box>    box
 %type <c>      open_request_parens close_request_parens
 %type <c>      open_plet_parens close_plet_parens
 %type <music>  simple_element music_elt full_element lyrics_elt command_elt
 %type <i>      int
 %type <i>      script_dir
-%type <id>     declaration
-%type <duration>       explicit_duration notemode_duration
+%type <id>     identifier_init
+%type <duration> explicit_steno_duration notemode_duration 
+%type <duration> entered_notemode_duration explicit_duration
 %type <interval>       dinterval
 %type <intvec> intastint_list
 %type <lookup> symtables symtables_body
@@ -206,23 +209,28 @@ yylex(YYSTYPE *s,  void * v_l)
 %type <paper>  paper_block paper_body
 %type <real>   dim real
 %type <real>   unit
-%type <request>        post_request pre_request command_req verbose_command_req abbrev_command_req
+%type <request>        post_request pre_request command_req verbose_command_req 
+%type <request> abbrev_command_req
 %type <request>        script_req  dynamic_req 
 %type <score>  score_block score_body
 %type <script> script_definition script_body mudela_script gen_script_def
 %type <textdef> text_def
-%type <string> declarable_identifier
 %type <string> script_abbreviation
-%type <id>     old_identifier
 %type <symbol> symboldef
 %type <symtable>       symtable symtable_body
 %type <itrans> input_translator_spec input_translator_spec_body
+%type <tempo>  tempo_request
+%type <string> header_record
 
 %left PRIORITY
 
 %%
 
 mudela:        /* empty */
+       | mudela mudela_header {
+               delete THIS->default_header_p_ ;
+               THIS->default_header_p_ = $2;
+       }
        | mudela score_block {
                add_score($2);          
        }
@@ -234,7 +242,7 @@ mudela:     /* empty */
 
 check_version:
        VERSION STRING ';'              {
-               if (*$2 != MUDELA_VERSION) {
+               if ( String( *$2 ) != MUDELA_VERSION) {
                        if (THIS->ignore_version_b_) {
                                THIS->here_input().error("Incorrect mudela version");
                        } else {
@@ -259,84 +267,100 @@ notenames_body:
                delete $2;
        }
        ;
-/*
-       DECLARATIONS
-*/
-add_declaration: declaration   {
-               THIS->lexer_p_->add_identifier($1);
-               $1->init_b_ = THIS->init_parse_b_;
-               $1->set_spot(THIS->pop_spot());
+
+mudela_header_body:
+               {
+               $$ = new Header;
+       }
+       | mudela_header_body FIELDNAME header_record {
+               (*$$)[*$2] = *$3;
+               delete $2;
+               delete $3;
        }
        ;
 
-declarable_identifier:
-       STRING {
-               THIS->remember_spot();
-           $$ = $1;
+mudela_header:
+       HEADER  {
+               THIS->lexer_p_->push_header_state();
        }
-       | old_identifier { 
-               THIS->remember_spot();
-               $$ = new String($1->name_str_); 
-               THIS->here_input().warning("redeclaration of `" + *$$ + "'");
+       
+       '{' mudela_header_body '}'      {
+               $$ = $4;
+               THIS->lexer_p_->pop_state();
        }
        ;
 
 
-old_identifier:
-       IDENTIFIER
-       |       INPUT_TRANS_IDENTIFIER
-       |       MELODIC_REQUEST_IDENTIFIER 
-       |       POST_REQUEST_IDENTIFIER
-       |       SCRIPT_IDENTIFIER
-       |       REAL_IDENTIFIER
-       |       SCORE_IDENTIFIER
-       |       REQUEST_IDENTIFIER
+header_record:
+               {
+               $$ = new String;
+       }
+       | header_record RECORDLINE      {
+               *$$ += *$2;
+               delete $2;
+       }
        ;
 
-declaration:
-       declarable_identifier '=' score_block {
-               $$ = new Score_id(*$1, $3, SCORE_IDENTIFIER);
-               delete $1;
+/*
+       DECLARATIONS
+*/
+
+add_declaration:
+       STRING {
+               THIS->remember_spot();
        }
-       | declarable_identifier '=' paper_block {
-               $$ = new Paper_def_id(*$1, $3, PAPER_IDENTIFIER);
-               delete $1;
+       /* cont */ '=' identifier_init {
+           THIS->lexer_p_->set_identifier(*$1, $4);
+           $4->init_b_ = THIS->init_parse_b_;
+           $4->set_spot(THIS->pop_spot());
        }
-       | declarable_identifier '=' midi_block {
-               $$ = new Midi_def_id(*$1, $3, MIDI_IDENTIFIER);
-               delete $1;
+       ;
+identifier_init:
+       score_block {
+               $$ = new Score_id($1, SCORE_IDENTIFIER);
+               
        }
-       | declarable_identifier '=' script_definition {
-               $$ = new Script_id(*$1, $3, SCRIPT_IDENTIFIER);
-               delete $1;
+       | paper_block {
+               $$ = new Paper_def_id($1, PAPER_IDENTIFIER);
+               
        }
-       | declarable_identifier '=' Music  {
-               $$ = new Music_id(*$1, $3, MUSIC_IDENTIFIER);
-               delete $1;
+       | midi_block {
+               $$ = new Midi_def_id($1, MIDI_IDENTIFIER);
+               
        }
-       | declarable_identifier '=' symtables {
-               $$ = new Lookup_id(*$1, $3, IDENTIFIER);
-               delete $1;
+       | script_definition {
+               $$ = new Script_id($1, SCRIPT_IDENTIFIER);
+               
        }
-       | declarable_identifier '=' real        {
-               $$ = new Real_id(*$1, new Real($3), REAL_IDENTIFIER);
-               delete $1;
+       | Music  {
+               $$ = new Music_id($1, MUSIC_IDENTIFIER);
+               
        }
-       | declarable_identifier '=' int {
-               $$ = new Int_id(*$1, new int($3), INT_IDENTIFIER);
-               delete $1;
+       | symtables {
+               $$ = new Lookup_id($1, IDENTIFIER);
+               
        }
-       | declarable_identifier '=' post_request {
-               $$ = new Request_id(*$1, $3, POST_REQUEST_IDENTIFIER);
-               delete $1;
+       | real  {
+               $$ = new Real_id(new Real($1), REAL_IDENTIFIER);
+               
        }
-       | declarable_identifier '=' melodic_request {
-               $$ = new Request_id(*$1, $3, MELODIC_REQUEST_IDENTIFIER);
-               delete $1;
+       | int   {
+               $$ = new Int_id(new int($1), INT_IDENTIFIER);
+               
        }
-       | declarable_identifier '=' input_translator_spec {
-               $$ = new Input_translator_id ( *$1, $3, INPUT_TRANS_IDENTIFIER);
-               delete $1;
+       | post_request {
+               $$ = new Request_id($1, POST_REQUEST_IDENTIFIER);
+               
+       }
+       | melodic_request {
+               $$ = new Request_id($1, MELODIC_REQUEST_IDENTIFIER);
+               
+       }
+       | input_translator_spec {
+               $$ = new Input_translator_id ( $1, INPUT_TRANS_IDENTIFIER);
+       }
+       | explicit_duration {
+               $$ = new Duration_id( $1, DURATION_IDENTIFIER);
        }
        ;
 
@@ -349,7 +373,7 @@ input_translator_spec:
 
 input_translator_spec_body:
        INPUT_TRANS_IDENTIFIER  {
-               $$ = $1->input_translator(true);
+               $$ = $1->input_translator();
                $$-> set_spot( THIS->here_input() );
        }
        | STRING STRING { 
@@ -381,7 +405,9 @@ input_translator_spec_body:
        SCORE
 */
 score_block:
-       SCORE { THIS->remember_spot(); }
+       SCORE { THIS->remember_spot();
+               THIS->error_level_i_ =0;
+       }
        /*cont*/ '{' score_body '}'     {
                $$ = $4;
                $$->set_spot(THIS->pop_spot());
@@ -391,6 +417,8 @@ score_block:
                /* handle error levels. */
                $$->errorlevel_i_ = THIS->error_level_i_;
                THIS->error_level_i_ = 0;
+               if (!$$->header_p_ && THIS->default_header_p_)
+                       $$->header_p_ = new Header(*THIS->default_header_p_);
        }
        ;
 
@@ -398,7 +426,10 @@ score_body:                {
                $$ = new Score; 
        }
        | SCORE_IDENTIFIER {
-               $$ = $1->score(true);
+               $$ = $1->score();
+       }
+       | score_body mudela_header      {
+               $$->header_p_ = $2;
        }
        | score_body Music      {
                $$->music_p_ = $2;
@@ -434,6 +465,9 @@ paper_body:
        /* empty */                     {
                $$ = THIS->default_paper(); // paper / video / engrave
        }
+       | PAPER_IDENTIFIER      {
+               $$ = $1->paperdef();
+       }
        | paper_body OUTPUT STRING ';'  { $$->outfile_str_ = *$3;
                delete $3;
        }
@@ -441,7 +475,7 @@ paper_body:
        | paper_body STRING '=' dim ';'         { 
                $$->set_var(*$2, $4);
        }
-       | paper_body STRING '=' REAL ';' {
+       | paper_body STRING '=' real ';' {
                $$->set_var(*$2, $4);
        }
        | paper_body input_translator_spec      {
@@ -461,15 +495,16 @@ midi_block:
        '{' midi_body '}'       { $$ = $3; }
        ;
 
-midi_body: /* empty */                 {
-               $$ = THIS->default_midi(); // midi / audio / perform
+midi_body: /* empty */                 {
+               $$ = THIS->default_midi();
        }
        | midi_body OUTPUT STRING ';'   { 
                $$->outfile_str_ = *$3; 
                delete $3; 
        }
-       | midi_body TEMPO notemode_duration ':' int ';' {
-               $$->set_tempo( $3->length(), $5 );
+       | midi_body tempo_request ';' {
+               $$->set_tempo( $2->dur_.length(), $2->metronome_i_ );
+               delete $2;
        }
        | midi_body input_translator_spec       {
                $$->set( $2 );
@@ -479,6 +514,15 @@ midi_body: /* empty */                     {
        }
        ;
 
+tempo_request:
+       TEMPO entered_notemode_duration '=' int         {
+               $$ = new Tempo_req;
+               $$->dur_ = *$2;
+               delete $2;
+               $$-> metronome_i_ = $4;
+       }
+       ;
+
 /*
        MUSIC
 */
@@ -510,7 +554,7 @@ Music:
        | Voice         { $$ = $1; }
        | Chord                 { $$ = $1; }
        | transposed_music      { $$ = $1; }
-       | MUSIC_IDENTIFIER      { $$ = $1->music(true); }
+       | MUSIC_IDENTIFIER      { $$ = $1->music(); }
        | MELODIC 
                { THIS->lexer_p_->push_note_state(); } 
        Music
@@ -562,33 +606,23 @@ full_element:
                THIS->add_requests((Chord*)$2);//ugh
                $$ = $2;
        }
+       | command_elt
        | voice_command ';'     { $$ = 0; }
        ;       
 
 simple_element:
        music_elt 
        | lyrics_elt
-       | command_elt
        ;
 
 command_elt:
-/* empty */    {
-               $$ = new Voice_element;
-               $$-> set_spot( THIS->here_input());
-       }
-/* cont: */
        command_req {
-               $2-> set_spot( THIS->here_input());
-               ((Chord*)$$) ->add($2);//ugh
+               $$ = new Request_chord;
+               $$-> set_spot( THIS->here_input());
+               $1-> set_spot( THIS->here_input());
+               ((Chord*)$$) ->add($1);//ugh
 
        }
-       | GROUP STRING ';' { // ugh ugh ugh
-               Change_reg *chr_p = new Change_reg;
-               $$ = chr_p;
-               chr_p-> type_str_ = "Voice_group_engravers"; //ugh
-               chr_p-> id_str_ = *$2;
-               delete $2;
-       }
        ;
 
 command_req:
@@ -600,6 +634,9 @@ abbrev_command_req:
         '|'                            { 
                $$ = new Barcheck_req;
        }
+       | COMMAND_IDENTIFIER    {
+               $$ = $1->request();
+       }
        ;
 
 verbose_command_req:
@@ -620,13 +657,15 @@ verbose_command_req:
        }
        | SKIP duration_length {
                Skip_req * skip_p = new Skip_req;
-               skip_p->duration_ = Duration(1,0);
                skip_p->duration_.set_plet($2->numerator().as_long(), 
                        $2->denominator().as_long());
                
                delete $2;
                $$ = skip_p;
        }
+       | tempo_request {
+               $$ = $1;
+       }
        | CADENZA int   {
                $$ = new Cadenza_req($2);
        }
@@ -653,7 +692,6 @@ verbose_command_req:
        | GROUPING intastint_list {
                $$ = get_grouping_req(*$2); delete $2;
        }
-       
        ;
 
 post_requests:
@@ -669,7 +707,7 @@ post_requests:
 
 post_request:
        POST_REQUEST_IDENTIFIER {
-               $$ = (Request*)$1->request(true);
+               $$ = (Request*)$1->request();
        }
        |close_request_parens   { 
                $$ = THIS->get_parens_request($1); 
@@ -718,6 +756,14 @@ melodic_request:
        }
        ;
 
+explicit_duration:
+       DURATION '{' int int '}'        {
+               $$ = new Duration;
+               $$-> durlog_i_ = $3;
+               $$-> dots_i_ = $4;
+       }
+       ;
+
 dynamic_req:
        ABSDYNAMIC '{' int '}'  {
                Absolute_dynamic_req *ad_p = new Absolute_dynamic_req;
@@ -735,7 +781,8 @@ dynamic_req:
 close_plet_parens:
        ']' INT '/' INT {
                $$ = ']';
-               THIS->default_duration_.set_plet($2,$4);
+               THIS->plet_.type_i_ = $4;
+               THIS->plet_.iso_i_ = $2;
        }
        ;
 
@@ -763,7 +810,8 @@ close_request_parens:
 open_plet_parens:
        '[' INT '/' INT {
                $$ = '[';
-               THIS->default_duration_.set_plet($2,$4);
+               THIS->plet_.type_i_ = $4;
+               THIS->plet_.iso_i_ = $2;
        }
        ;
 
@@ -837,10 +885,10 @@ script_abbreviation:
        ;
        
 mudela_script:
-       SCRIPT_IDENTIFIER               { $$ = $1->script(true); }
+       SCRIPT_IDENTIFIER               { $$ = $1->script(); }
        | script_definition             { $$ = $1; }
        | script_abbreviation           { 
-               $$ = THIS->lexer_p_->lookup_identifier(*$1)->script(true);
+               $$ = THIS->lexer_p_->lookup_identifier(*$1)->script();
                delete $1;
        }
        ;
@@ -868,15 +916,15 @@ voice_command:
        PLET     INT '/' INT {
                THIS->default_duration_.set_plet($2,$4);
        }
-       | DURATIONCOMMAND STRING {
+       | DURATION STRING {
                THIS->set_duration_mode(*$2);
                delete $2;
        }
-       | DURATIONCOMMAND notemode_duration {
+       | DURATION entered_notemode_duration {
                THIS->set_default_duration($2);
                delete $2;
        }
-       | OCTAVECOMMAND { 
+       | OCTAVE { 
                /*
                        This is weird, but default_octave_i_
                        is used in steno_note_req too
@@ -900,7 +948,7 @@ duration_length:
        {
                $$ = new Moment(0,1);
        }
-       | duration_length explicit_duration             {       
+       | duration_length explicit_steno_duration               {       
                *$$ += $2->length();
        }
        ;
@@ -910,37 +958,47 @@ dots:
        | dots '.'      { $$ ++; }
        ;
 
-notemode_duration:
+entered_notemode_duration:
        /* */           { 
                $$ = new Duration(THIS->default_duration_);
        }
        | dots          {
-               $$ = new Duration(THIS->default_duration_);
+               $$ = new Duration(THIS->default_duration_);             
                $$->dots_i_  = $1;
        }
-       | explicit_duration     {
+       | explicit_steno_duration       {
                THIS->set_last_duration($1);
                $$ = $1;
        }
        ;
 
-explicit_duration:
+notemode_duration:
+       entered_notemode_duration {
+               $$ = $1;
+               $$->plet_.type_i_ *= THIS->plet_.type_i_;
+               $$->plet_.iso_i_ *= THIS->plet_.iso_i_;
+       }
+       ;
+
+explicit_steno_duration:
        int             {
                $$ = new Duration;
                if ( !Duration::duration_type_b($1) )
                        THIS->parser_error("Not a duration");
                else {
-                       $$->type_i_ = $1;
-                       $$->set_plet(THIS->default_duration_);
+                       $$->durlog_i_ = Duration_convert::i2_type($1);
                     }
        }
-       | explicit_duration '.'         {
+       | DURATION_IDENTIFIER   {
+               $$ = $1->duration();
+       }
+       | explicit_steno_duration '.'   {
                $$->dots_i_ ++;
        }
-       | explicit_duration '*' int  {
+       | explicit_steno_duration '*' int  {
                $$->plet_.iso_i_ *= $3; 
        }
-       | explicit_duration '/' int {
+       | explicit_steno_duration '/' int {
                $$->plet_.type_i_ *= $3; 
        }
        ;
@@ -961,6 +1019,7 @@ music_elt:
 
 lyrics_elt:
        text_def notemode_duration                      {
+       /* this sux! text-def should be feature of lyric-engraver. */
                if (!THIS->lexer_p_->lyric_state_b())
                        THIS->parser_error("Have to be in Lyric mode for lyrics");
                $$ = THIS->get_word_element($1, $2);
@@ -983,7 +1042,9 @@ int:
                $$ = $1;
        }
        | INT_IDENTIFIER        {
-               $$ = * $1->intid(0);
+               int *i_p = $1->intid();
+               $$ = *i_p;
+               delete i_p;
        }
        ;
 
@@ -993,7 +1054,9 @@ real:
                $$ = $1;
        }
        | REAL_IDENTIFIER               {
-               $$ = * $1->real(0);             
+               Real *r_p = $1->real();
+               $$ = * r_p;
+               delete r_p;
        }
        ;
        
@@ -1022,7 +1085,7 @@ symtables_body:
                $$ = new Lookup;
        }
        | IDENTIFIER            {
-               $$ = $1->lookup(true);
+               $$ = $1->lookup();
        }
        | symtables_body TEXID STRING           {
                $$->texsetting = *$3;
@@ -1092,13 +1155,13 @@ Paper_def*
 My_lily_parser::default_paper()
 {
        Identifier *id = lexer_p_->lookup_identifier( "default_paper" );
-       return id ? id->paperdef(true) : new Paper_def ;
+       return id ? id->paperdef() : new Paper_def ;
 }
 
 Midi_def*
 My_lily_parser::default_midi()
 {
        Identifier *id = lexer_p_->lookup_identifier( "default_midi" );
-       return id ? id->mididef(true) : new Midi_def ;
+       return id ? id->mididef() : new Midi_def ;
 }