]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
* lily/parser.yy (event_that_take_dir): allow postfix notation for ties.
[lilypond.git] / lily / parser.yy
index 520bb9000fdcb4deb285f599eec1b9d2f9a4166c..d124c5095dec8c3b7c4f708120b1bfc4a1c4e9f1 100644 (file)
@@ -5,20 +5,52 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c)  1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
            Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
 /*
   Two shift/reduce problems:
-    -
-    -
+    - empty music-list
+    - empty pre-events
+
+
+
+(bullshit.
+
+s/r:
+
+1.     foo = bar.
+
+       "bar" -> String -> Lyric -> Music
+
+       "bar" -> String
+
+
+2.  \repeat
+       \repeat .. \alternative
+
+
+    \repeat { \repeat .. \alternative }
+
+or
+
+    \repeat { \repeat } \alternative 
+
+)
+
+--hwn
+
  */
 
 /*
 
-the rules for who is protecting what are very shady. TODO: uniformise
-this.
+TODO:
+
+* The rules for who is protecting what are very shady. Uniformise
+  this.
+
+* There are too many lexical modes. 
 
 
 */
@@ -119,10 +151,7 @@ of the parse stack onto the heap. */
 
 
 %union {
-
-    Link_array<Music> *reqvec;
-
-    String *string; // needed by the lexer as temporary scratch area.
+       String * string;
     Music *music;
     Score *score;
     Music_output_def * outputdef;
@@ -157,9 +186,7 @@ yylex (YYSTYPE *s,  void * v)
 %token BREATHE
 %token CHORDMODIFIERS
 %token CHORDS
-%token CHAR_T
 %token CLEF
-%token CM_T
 %token CONSISTS
 %token DURATION
 %token SEQUENTIAL
@@ -173,14 +200,12 @@ yylex (YYSTYPE *s,  void * v)
 %token GRACE 
 %token HEADER
 %token HYPHEN
-%token IN_T
 %token INVALID
 %token KEY
 %token LYRICS
 %token MARK
 %token MULTI_MEASURE_REST
 %token MIDI
-%token MM_T
 %token PITCH
 %token DEFAULT
 %token NAME
@@ -191,7 +216,6 @@ yylex (YYSTYPE *s,  void * v)
 %token PARTIAL
 %token PROPERTY
 %token OVERRIDE SET REVERT 
-%token PT_T
 %token RELATIVE
 %token REMOVE
 %token REPEAT
@@ -213,6 +237,10 @@ yylex (YYSTYPE *s,  void * v)
 %token CONTEXT
 %token REST
 
+%token CHORD_OPEN
+%token CHORD_CLOSE
+
+
 /* escaped */
 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
@@ -258,10 +286,12 @@ yylex (YYSTYPE *s,  void * v)
 %type <i>      script_dir
 %type <scm>    identifier_init 
 
+%type <music> note_chord_element chord_body chord_body_element
+%type <scm>  chord_body_elements 
 %type <scm> steno_duration optional_notemode_duration multiplied_duration
 %type <scm>  verbose_duration
        
-%type <reqvec>  pre_events post_events
+%type <scm>  pre_events post_events
 %type <music> gen_text_def
 %type <scm>   steno_pitch pitch absolute_pitch
 %type <scm>   explicit_pitch steno_tonic_pitch
@@ -284,7 +314,6 @@ yylex (YYSTYPE *s,  void * v)
 %type <music> hyphen_req
 %type <music> string_event
 %type <scm>    string bare_number number_expression number_term number_factor 
-
 %type <score>  score_block score_body
 
 %type <scm>    translator_spec_block translator_spec_body
@@ -650,12 +679,13 @@ The representation of a  list is the
 
  to have  efficient append.
 */
-Music_list: /* empty */ {
+Music_list:
+       /* empty */ {
                $$ = scm_cons (SCM_EOL, SCM_EOL);
        }
        | Music_list Music {
                SCM s = $$;
-               SCM c = scm_cons ($2->self_scm (), SCM_EOL);
+               SCM c = scm_cons ($2->self_scm (), SCM_EOL);
                scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
                if (gh_pair_p (ly_cdr (s)))
                        gh_set_cdr_x (ly_cdr (s), c); /* append */
@@ -1121,19 +1151,67 @@ event_chord:
        pre_events {
                THIS->push_spot ();
        } /*cont */ simple_element post_events  {
-               Music_sequence *l = dynamic_cast<Music_sequence*> ($3);
-               
-               $1->concat (*$4);
-               for (int i=0; i < $1->size (); i++) {
-                 Music * m = $1->elem (i);
-                 l->append_music (m);
-               }
-               $$ = $3;
+               SCM elts = $3-> get_mus_property ("elements");
+
+               elts = gh_append3 (elts, scm_reverse_x ($1, SCM_EOL),
+                                  scm_reverse_x ($4, SCM_EOL));
 
-               delete $1;
-               delete $4;
+               $3-> set_mus_property ("elements", elts);
+               $$ = $3;
        }
        | command_element
+       | note_chord_element
+       ;
+
+
+note_chord_element:
+       chord_body optional_notemode_duration post_events
+       {
+               SCM dur = unsmob_duration ($2)->smobbed_copy();
+               SCM es = $1->get_mus_property ("elements");
+               SCM postevs = scm_reverse_x ($3, SCM_EOL);
+
+               for (SCM s = es; gh_pair_p (s); s = gh_cdr (s))
+                 unsmob_music (gh_car(s))->set_mus_property ("duration", dur);
+               es = gh_append2 (es, postevs);
+
+               $1-> set_mus_property ("elements", es);
+               $$ = $1;
+       }
+       ;
+
+chord_body:
+       CHORD_OPEN chord_body_elements CHORD_CLOSE
+       {
+               $$ = MY_MAKE_MUSIC("EventChord");
+               $$->set_mus_property ("elements",
+                       scm_reverse_x ($2, SCM_EOL));
+       }
+       ;
+
+chord_body_elements:
+       /* empty */             { $$ = SCM_EOL; }
+       | chord_body_elements chord_body_element {
+               $$ = gh_cons ($2->self_scm(), $1);
+               scm_gc_unprotect_object ($2->self_scm());
+       }
+       ;
+
+chord_body_element:
+       pitch exclamations questions post_events
+       {
+               Music * n = MY_MAKE_MUSIC("NoteEvent");
+               n->set_mus_property ("pitch", $1);
+               if ($3 % 2)
+                       n->set_mus_property ("cautionary", SCM_BOOL_T);
+               if ($2 % 2 || $3 % 2)
+                       n->set_mus_property ("force-accidental", SCM_BOOL_T);
+
+               SCM arts = scm_reverse_x ($4, SCM_EOL);
+               n->set_mus_property ("articulations", arts);
+
+               $$ = n;
+       }
        ;
 
 command_element:
@@ -1309,12 +1387,13 @@ verbose_command_req:
        ;
 
 post_events:
-       {
-               $$ = new Link_array<Music>;
+       /* empty */ {
+               $$ = SCM_EOL;
        }
        | post_events post_event {
                $2->set_spot (THIS->here_input ());
-               $$->push ($2);
+               $$ = gh_cons ($2->self_scm(), $$);
+               scm_gc_unprotect_object ($2->self_scm());
        }
        ;
 
@@ -1340,6 +1419,23 @@ event_that_take_dir:
        | verbose_event
        | close_event
        | open_event
+       | '['  {
+               Music * m = MY_MAKE_MUSIC ("NewBeamEvent");
+               m->set_spot (THIS->here_input());
+               m->set_mus_property ("span-direction" , gh_int2scm (START));
+               $$ = m;
+       }
+       | ']'  {
+               Music * m = MY_MAKE_MUSIC ("NewBeamEvent");
+               m->set_spot (THIS->here_input());
+               m->set_mus_property ("span-direction" , gh_int2scm (STOP));
+               $$ = m;
+       }
+       | '~' {
+               Music * m = MY_MAKE_MUSIC ("NewTieEvent");
+               m->set_spot (THIS->here_input());
+               $$ = m;
+       }
        | script_abbreviation {
                SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
                Music *a = MY_MAKE_MUSIC("ArticulationEvent");
@@ -1548,11 +1644,9 @@ gen_text_def:
                $$ = t;
        }
        | DIGIT {
-               String ds = to_string ($1);
-               Music * t = MY_MAKE_MUSIC("TextScriptEvent");
+               Music * t = MY_MAKE_MUSIC("FingerEvent");
                SCM finger = ly_symbol2scm ("finger");
-               t->set_mus_property ("text",  scm_makfrom0str (ds.to_str0 ()));
-               t->set_mus_property ("text-type" , finger);
+               t->set_mus_property ("digit",  gh_int2scm ($1));
                t->set_spot (THIS->here_input ());
                $$ = t;
        }
@@ -1589,11 +1683,12 @@ script_dir:
        ;
 
 pre_events:
-       {
-               $$ = new Link_array<Music>;
+       /* empty */ { 
+               $$ = SCM_EOL;
        }
        | pre_events open_event {
-               $$->push ($2);
+               $$ = gh_cons ($2->self_scm(), $$);
+               scm_gc_unprotect_object ($2->self_scm());
        }
        ;
 
@@ -1696,6 +1791,10 @@ tremolo_type:
        ;
 
 
+
+/*****************************************************************
+               BASS FIGURES
+*****************************************************************/
 bass_number:
        DIGIT
        | UNSIGNED 
@@ -1807,30 +1906,27 @@ simple_element:
                Input i = THIS->pop_spot (); 
                m->set_spot (i);
                for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = ly_cdr (s))
-                       {
-                               unsmob_music (ly_car (s))->set_mus_property ("duration", $2);
-                       }
+               {
+                       unsmob_music (ly_car (s))->set_mus_property ("duration", $2);
+               }
                $$ = m;
        }       
        | RESTNAME optional_notemode_duration           {
 
                Input i = THIS->pop_spot ();
-               SCM e = SCM_UNDEFINED;
+               Music * ev = 0;
                if (ly_scm2string ($1) =="s") {
                        /* Space */
-                       Music * skip = MY_MAKE_MUSIC("SkipEvent");
-                       skip->set_mus_property ("duration" ,$2);
-                       skip->set_spot (i);
-                       e = skip->self_scm ();
+                       ev = MY_MAKE_MUSIC("SkipEvent");
                  }
-                 else {
-                       Music * rest_req = MY_MAKE_MUSIC("RestEvent");
-                       rest_req->set_mus_property ("duration", $2);
-                       rest_req->set_spot (i);
-                       e = rest_req->self_scm ();
+               else {
+                       ev = MY_MAKE_MUSIC("RestEvent");
+               
                    }
+               ev->set_mus_property ("duration" ,$2);
+               ev->set_spot (i);
                Music * velt = MY_MAKE_MUSIC("EventChord");
-               velt-> set_mus_property ("elements", scm_list_n (e,SCM_UNDEFINED));
+               velt->set_mus_property ("elements", scm_list_n (ev->self_scm (),SCM_UNDEFINED));
                velt->set_spot (i);
 
                $$ = velt;
@@ -2005,20 +2101,11 @@ bare_number:
        | NUMBER_IDENTIFIER             {
                $$ = $1;
        }
-       | REAL CM_T     {
-               $$ = gh_double2scm (gh_scm2double ($1) CM );
-       }
-       | REAL PT_T     {
-               $$ = gh_double2scm (gh_scm2double ($1) PT);
-       }
-       | REAL IN_T     {
-               $$ = gh_double2scm (gh_scm2double ($1) INCH);
-       }
-       | REAL MM_T     {
-               $$ = gh_double2scm (gh_scm2double ($1) MM);
+       | REAL NUMBER_IDENTIFIER        {
+               $$ = gh_double2scm (gh_scm2double ($1) * gh_scm2double ($2));
        }
-       | REAL CHAR_T   {
-               $$ = gh_double2scm (gh_scm2double ($1) CHAR);
+       | UNSIGNED NUMBER_IDENTIFIER    {
+               $$ = gh_double2scm ($1 * gh_scm2double ($2));
        }
        ;