]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
''
[lilypond.git] / lily / parser.yy
index f5425dc2ef69462145804df25f8e29dd93472bf0..c1a0b28271f7eaa856f5121affd26c81e9d0be97 100644 (file)
@@ -47,7 +47,6 @@ this.
 #include "property-iterator.hh"
 #include "file-results.hh"
 #include "input.hh"
-#include "scope.hh"
 #include "relative-music.hh"
 #include "lyric-combine-music.hh"
 #include "transposed-music.hh"
@@ -112,11 +111,11 @@ set_music_properties (Music *p, SCM a)
 
 
 // needed for bison.simple's malloc () and free ()
+
 #include <malloc.h>
+#include <stdlib.h>
+
 
-#ifndef NDEBUG
-#define YYDEBUG 1
-#endif
 
 #define YYERROR_VERBOSE 1
 
@@ -130,6 +129,10 @@ set_music_properties (Music *p, SCM a)
 
 %}
 
+/* We use SCMs to do strings, because it saves us the trouble of
+deleting them.  Let's hope that a stack overflow doesnt trigger a move
+of the parse stack onto the heap. */
+
 
 %union {
 
@@ -138,16 +141,11 @@ set_music_properties (Music *p, SCM a)
     String *string; // needed by the lexer as temporary scratch area.
     Music *music;
     Score *score;
-    Scope *scope;
     Scheme_hash_table *scmhash;
     Music_output_def * outputdef;
 
     Request * request;
 
-    /* We use SCMs to do strings, because it saves us the trouble of
-deleting them.  Let's hope that a stack overflow doesnt trigger a move
-of the parse stack onto the heap. */
-
     SCM scm;
 
     Tempo_req *tempo;
@@ -195,6 +193,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %token DURATION
 %token EXTENDER
 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
+%token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
 %token GLISSANDO
 %token GRACE 
 %token HEADER
@@ -239,14 +238,19 @@ yylex (YYSTYPE *s,  void * v_l)
 %token TYPE
 %token UNSET
 %token CONTEXT
+%token REST
 
 /* escaped */
-%token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE E_TILDE
-%token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET 
+%token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
+%token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
+%token E_BACKSLASH
+%token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET
+%token FIGURE_SPACE
+
 
-%type <i>      exclamations questions dots
+%type <i>      exclamations questions dots optional_rest
 %type <i>      bass_number bass_mod
-%type <scm>    bass_figure figure_list figure_spec
+%type <scm>    br_bass_figure bass_figure figure_list figure_spec
 %token <i>     DIGIT
 %token <scm>   NOTENAME_PITCH
 %token <scm>   TONICNAME_PITCH
@@ -284,7 +288,7 @@ yylex (YYSTYPE *s,  void * v_l)
 %type <scm>    identifier_init 
 
 %type <scm> steno_duration optional_notemode_duration multiplied_duration
-%type <scm>  explicit_duration
+%type <scm>  verbose_duration
        
 %type <reqvec>  pre_requests post_requests
 %type <request> gen_text_def
@@ -355,9 +359,9 @@ toplevel_expression:
        }
        | output_def {
                if (dynamic_cast<Paper_def*> ($1))
-                       THIS->lexer_p_->set_identifier ("$defaultpaper", $1->self_scm ());
+                       THIS->lexer_p_->set_identifier (gh_str02scm ("$defaultpaper"), $1->self_scm ());
                else if (dynamic_cast<Midi_def*> ($1))
-                       THIS->lexer_p_->set_identifier ("$defaultmidi", $1->self_scm ());
+                       THIS->lexer_p_->set_identifier (gh_str02scm ("$defaultmidi"), $1->self_scm ());
        }
        | embedded_scm {
                // junk value
@@ -398,9 +402,7 @@ notenames_body:
 lilypond_header_body:
        {
                $$ = new Scheme_hash_table;
-               
-               Scope *sc = new Scope ($$);
-               THIS->lexer_p_-> scope_l_arr_.push (sc);
+               THIS->lexer_p_-> scope_l_arr_.push ($$);
        }
        | lilypond_header_body assignment  { 
 
@@ -410,7 +412,7 @@ lilypond_header_body:
 lilypond_header:
        HEADER '{' lilypond_header_body '}'     {
                $$ = $3;
-               delete THIS->lexer_p_-> scope_l_arr_.pop ();
+               THIS->lexer_p_->scope_l_arr_.pop ();
        }
        ;
 
@@ -434,7 +436,7 @@ assignment:
                        ip.warning (_ ("Identifier should have  alphabetic characters only"));
                }
 
-               THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4);
+               THIS->lexer_p_->set_identifier ($1, $4);
 
 /*
  TODO: devise standard for protection in parser.
@@ -468,7 +470,7 @@ identifier_init:
                $$ = $1->self_scm ();
                scm_gc_unprotect_object ($$);
        }
-       | explicit_duration {
+       | verbose_duration {
                $$ = $1;
        }
        | number_expression {
@@ -568,6 +570,13 @@ score_body:
                SCM m = $1->self_scm ();
                scm_gc_unprotect_object (m);
                $$->music_ = m;
+
+               /*
+                       guh.
+               */
+               SCM check_func = scm_c_eval_string ("check-start-chords");
+               gh_call1 (check_func, m);
+               
        }
        | SCORE_IDENTIFIER {
                $$ = new Score (*unsmob_score ($1));
@@ -608,7 +617,7 @@ music_output_def_body:
                p = new Midi_def;
 
         $$ = p;
-        THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
+        THIS->lexer_p_->scope_l_arr_.push (p->variable_tab_);
        }
        | PAPER '{'     {
                Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
@@ -617,20 +626,20 @@ music_output_def_body:
                        p = dynamic_cast<Paper_def*> (id->clone ());
                else
                        p = new Paper_def;
-               THIS-> lexer_p_-> scope_l_arr_.push (p->scope_p_);
+               THIS-> lexer_p_-> scope_l_arr_.push (p->variable_tab_);
                $$ = p;
        }
        | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER         {
                Music_output_def *p = unsmob_music_output_def ($3);
                p = p->clone ();
-               THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
+               THIS->lexer_p_->scope_l_arr_.push (p->variable_tab_);
                $$ = p;
        }
        | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER  {
                Music_output_def *p = unsmob_music_output_def ($3);
                p = p->clone ();
 
-               THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
+               THIS->lexer_p_->scope_l_arr_.push (p->variable_tab_);
                $$ = p;
        }
        | music_output_def_body assignment  {
@@ -739,10 +748,12 @@ Sequential_music:
        SEQUENTIAL '{' Music_list '}'           {
                $$ = new Sequential_music (SCM_EOL);
                $$->set_mus_property ("elements", ly_car ($3));
+               $$->set_spot(THIS->here_input());
        }
        | '{' Music_list '}'            {
                $$ = new Sequential_music (SCM_EOL);
                $$->set_mus_property ("elements", ly_car ($2));
+               $$->set_spot(THIS->here_input());
        }
        ;
 
@@ -750,11 +761,13 @@ Simultaneous_music:
        SIMULTANEOUS '{' Music_list '}'{
                $$ = new Simultaneous_music (SCM_EOL);
                $$->set_mus_property ("elements", ly_car ($3));
+               $$->set_spot(THIS->here_input());
 
        }
        | '<' Music_list '>'    {
                $$ = new Simultaneous_music (SCM_EOL);
                $$->set_mus_property ("elements", ly_car ($2));
+               $$->set_spot(THIS->here_input());
        }
        ;
 
@@ -783,6 +796,8 @@ Simple_music:
        }
        | MUSIC_IDENTIFIER {
                $$ = unsmob_music ($1)->clone ();
+
+               $$->set_spot (THIS->here_input());
        }
        | property_def
        | translator_change
@@ -1033,7 +1048,7 @@ property_def:
                Music *t = new Music (SCM_EOL);
                t->set_mus_property ("iterator-ctor",
                        Push_property_iterator::constructor_cxx_function);
-               t->set_mus_property ("symbols", scm_string_to_symbol ($4));
+               t->set_mus_property ("symbol", scm_string_to_symbol ($4));
                t->set_mus_property ("pop-first", SCM_BOOL_T);
                t->set_mus_property ("grob-property", $6);
                t->set_mus_property ("grob-value", $8);
@@ -1049,7 +1064,7 @@ property_def:
                Music *t = new Music (SCM_EOL);
                t->set_mus_property ("iterator-ctor",
                        Push_property_iterator::constructor_cxx_function);
-               t->set_mus_property ("symbols", scm_string_to_symbol ($4));
+               t->set_mus_property ("symbol", scm_string_to_symbol ($4));
                t->set_mus_property ("grob-property", $6);
                t->set_mus_property ("grob-value", $8);
                Context_specced_music *csm = new Context_specced_music (SCM_EOL);
@@ -1065,7 +1080,7 @@ property_def:
                Music *t = new Music (SCM_EOL);
                t->set_mus_property ("iterator-ctor",
                        Pop_property_iterator::constructor_cxx_function);
-               t->set_mus_property ("symbols", scm_string_to_symbol ($4));
+               t->set_mus_property ("symbol", scm_string_to_symbol ($4));
                t->set_mus_property ("grob-property", $6);
 
                Context_specced_music *csm = new Context_specced_music (SCM_EOL);
@@ -1091,15 +1106,16 @@ request_chord:
                THIS->push_spot ();
        } /*cont */ simple_element post_requests        {
                Music_sequence *l = dynamic_cast<Music_sequence*> ($3);
-               if (l) {
-                       for (int i=0; i < $1->size (); i++)
-                               l->append_music ($1->elem (i));
-                       for (int i=0; i < $4->size (); i++)
-                               l->append_music ($4->elem (i));
-                       }
-               else
-                       programming_error ("Need Sequence to add music to");
+               
+               $1->concat (*$4);
+               for (int i=0; i < $1->size (); i++) {
+                 Music * m = $1->elem (i);
+                 l->append_music (m);
+               }
                $$ = $3;
+
+               delete $1;
+               delete $4;
        }
        | command_element
        ;
@@ -1111,6 +1127,16 @@ command_element:
                $$-> set_spot (THIS->here_input ());
                $1-> set_spot (THIS->here_input ());
        }
+       | E_BACKSLASH {
+               $$ = new Music (gh_list (gh_cons (ly_symbol2scm ("name"), ly_symbol2scm ("separator")), SCM_UNDEFINED));
+               $$->set_spot (THIS->here_input ());
+       }
+       | '|'      {
+
+               extern Music * get_barcheck();
+               $$ = get_barcheck ();
+               $$->set_spot (THIS->here_input ());
+       }
        | BAR STRING                    {
                Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
 
@@ -1158,11 +1184,11 @@ command_element:
        | TIME_T fraction  {
                Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2);
 
-  int l = gh_scm2int (ly_car ($2));
-  int o = gh_scm2int (ly_cdr ($2));
-  
-  Moment one_beat = Moment (1)/Moment (o);
-  Moment len = Moment (l) * one_beat;
+               int l = gh_scm2int (ly_car ($2));
+               int o = gh_scm2int (ly_cdr ($2));
+
+               Moment one_beat = Moment (1)/Moment (o);
+               Moment len = Moment (l) * one_beat;
 
 
                Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ());
@@ -1205,9 +1231,6 @@ shorthand_command_req:
        | hyphen_req {
                $$ = $1;
        }
-       | '|'                           {
-               $$ = new Barcheck_req;
-       }
        | '~'   {
                $$ = new Tie_req;
        }
@@ -1216,6 +1239,9 @@ shorthand_command_req:
                b->set_span_dir (START);
                b->set_mus_property ("span-type", ly_str02scm ("beam"));
                $$ =b;
+
+
+               THIS->last_beam_start_ = b->self_scm ();
        }
        | ']'           {
                Span_req*b= new Span_req;
@@ -1223,6 +1249,19 @@ shorthand_command_req:
                b->set_mus_property ("span-type", ly_str02scm ("beam"));
                $$ = b;
        }
+       | E_LEFTSQUARE {
+               Span_req *b = new Span_req;
+               b->set_span_dir (START);
+               b->set_mus_property ("span-type", ly_str02scm ("ligature-bracket"));
+               $$ = b;
+               THIS->last_ligature_start_ = b->self_scm ();
+       }
+       | E_RIGHTSQUARE {
+               Span_req *b = new Span_req;
+               b->set_span_dir (STOP);
+               b->set_mus_property ("span-type", ly_str02scm ("ligature-bracket"));
+               $$ = b;
+       }
        | BREATHE {
                $$ = new Breathing_sign_req;
        }
@@ -1250,8 +1289,6 @@ verbose_command_req:
 
        }
        | PENALTY SCM_T         {
-
-               
                Break_req * b = new Break_req;
                SCM s = $2;
                if (!gh_number_p (s))
@@ -1333,7 +1370,8 @@ verbose_request:
                        TODO: junkme, use text-type == dynamic
                */
                Text_script_req *d = new Text_script_req;
-               d->set_mus_property ("text-type" , ly_symbol2scm ("dynamic"));
+               SCM dyn = ly_symbol2scm ("dynamic");
+               d->set_mus_property ("text-type" , dyn);
                d->set_mus_property ("text", $2);
                d->set_spot (THIS->here_input ());
                $$ = d;
@@ -1449,7 +1487,7 @@ explicit_pitch:
        }
        ;
 
-explicit_duration:
+verbose_duration:
        DURATION embedded_scm   {
                $$ = $2;
                if (!unsmob_duration ($2))
@@ -1481,7 +1519,8 @@ close_request:
                $$ = $1;
                dynamic_cast<Span_req*> ($$)->set_span_dir ( START);
        }
-       
+       ;
 close_request_parens:
        '('     {
                Span_req* s= new Span_req;
@@ -1548,9 +1587,9 @@ gen_text_def:
        | DIGIT {
                String ds = to_str ($1);
                Text_script_req* t = new Text_script_req;
-
+               SCM finger = ly_symbol2scm ("finger");
                t->set_mus_property ("text",  ly_str02scm (ds.ch_C ()));
-               t->set_mus_property ("text-type" , ly_symbol2scm ("finger"));
+               t->set_mus_property ("text-type" , finger);
                t->set_spot (THIS->here_input ());
                $$ = t;
        }
@@ -1577,7 +1616,6 @@ script_abbreviation:
        }
        ;
 
-
 script_dir:
        '_'     { $$ = DOWN; }
        | '^'   { $$ = UP; }
@@ -1603,20 +1641,27 @@ duration_length:
        multiplied_duration {
                $$ = $1;
        }
-       | explicit_duration {
+       | verbose_duration {
                $$ = $1;
        }       
        ;
 
 optional_notemode_duration:
        {
-               $$ = THIS->default_duration_.smobbed_copy ();
+               Duration dd = THIS->default_duration_;
+               $$ = dd.smobbed_copy ();
+
+               THIS->beam_check ($$);
        }
        | multiplied_duration   {
                $$ = $1;
+               THIS->default_duration_ = *unsmob_duration ($$);
+
+               THIS->beam_check ($$);
        }
-       | explicit_duration {
+       | verbose_duration {
                $$ = $1;
+               THIS->default_duration_ = *unsmob_duration ($$);
        }       
        ;
 
@@ -1629,15 +1674,11 @@ steno_duration:
                        l =  intlog2 ($1);
 
                $$ = Duration (l, $2).smobbed_copy ();
-
-               THIS->set_last_duration (unsmob_duration ($$));
        }
        | DURATION_IDENTIFIER dots      {
                Duration *d =unsmob_duration ($1);
                Duration k (d->duration_log (),d->dot_count () + $2);
                $$ = k.smobbed_copy ();
-
-               THIS->set_last_duration (unsmob_duration ($$));
        }
        ;
 
@@ -1699,31 +1740,51 @@ bass_mod:
        ;
 
 bass_figure:
-       bass_number  {
-               Pitch p ;
-               p .notename_i_ = $1 - 1;
-               p.normalise();
-               
-               Note_req * nr = new Note_req;
-               $$ = nr->self_scm ();
-               nr->set_mus_property ("pitch", p.smobbed_copy ());
+       FIGURE_SPACE {
+               Bass_figure_req *bfr = new Bass_figure_req;
+               $$ = bfr->self_scm();
+               scm_gc_unprotect_object ($$);
+       }
+       | bass_number  {
+               Bass_figure_req *bfr = new Bass_figure_req;
+               $$ = bfr->self_scm();
+
+               bfr->set_mus_property ("figure", gh_int2scm ($1));
+
                scm_gc_unprotect_object ($$);
        }
        | bass_figure bass_mod {
-               if ($2) { 
-                       SCM sp = unsmob_music ($1)->get_mus_property ("pitch");
-                       unsmob_pitch (sp)->alteration_i_ += $2;
+               Music *m = unsmob_music ($1);
+               if ($2) {
+                       SCM salter =m->get_mus_property ("alteration");
+                       int alter = gh_number_p( salter) ? gh_scm2int (salter) : 0;
+                       m->set_mus_property ("alteration",
+                               gh_int2scm (alter + $2));
                } else {
-                       unsmob_music ($1)->set_mus_property ("force-accidental", SCM_BOOL_T);
+                       m->set_mus_property ("alteration", gh_int2scm (0));
                }
        }
        ;
 
+br_bass_figure:
+       '[' bass_figure {
+               $$ = $2;
+               unsmob_music ($$)->set_mus_property ("bracket-start", SCM_BOOL_T);
+       }
+       | bass_figure   {
+               $$ = $1;
+       }
+       | br_bass_figure ']' {
+               $$ = $1;
+               unsmob_music ($1)->set_mus_property ("bracket-stop", SCM_BOOL_T);
+       }
+       ;
+
 figure_list:
        /**/            {
                $$ = SCM_EOL;
        }
-       | figure_list bass_figure {
+       | figure_list br_bass_figure {
                $$ = gh_cons ($2, $1); 
        }
        ;
@@ -1737,18 +1798,29 @@ figure_spec:
        }
        ;
 
+
+optional_rest:
+       /**/   { $$ = 0; }
+       | REST { $$ = 1; }
+       ;
+
 simple_element:
-       pitch exclamations questions optional_notemode_duration {
+       pitch exclamations questions optional_notemode_duration optional_rest {
 
                Input i = THIS->pop_spot ();
                if (!THIS->lexer_p_->note_state_b ())
                        THIS->parser_error (_ ("Have to be in Note mode for notes"));
 
-               Note_req *n = new Note_req;
+               Music *n = 0;
+               if ($5)
+                       n =  new Rest_req ;
+               else
+                       n =  new Note_req;
                
                n->set_mus_property ("pitch", $1);
                n->set_mus_property ("duration", $4);
 
+
                if ($3 % 2)
                        n->set_mus_property ("cautionary", SCM_BOOL_T);
                if ($2 % 2 || $3 % 2)
@@ -1756,7 +1828,7 @@ simple_element:
 
                Simultaneous_music*v = new Request_chord (SCM_EOL);
                v->set_mus_property ("elements", scm_list_n (n->self_scm (), SCM_UNDEFINED));
-               
+
                v->set_spot (i);
                n->set_spot (i);
                $$ = v;
@@ -2052,9 +2124,9 @@ questions:
 %%
 
 void
-My_lily_parser::set_yydebug (bool b)
+My_lily_parser::set_yydebug (bool )
 {
-#ifdef YYDEBUG
+#if 0
        yydebug = b;
 #endif
 }
@@ -2070,3 +2142,24 @@ My_lily_parser::do_yyparse ()
 }
 
 
+/*
+Should make this optional?    It will also complain when you do
+
+       [s4]
+
+which is entirely legitimate.
+
+Or we can scrap it. Barchecks should detect wrong durations, and
+skipTypesetting speeds it up a lot.
+*/
+void
+My_lily_parser::beam_check (SCM dur)
+{
+  Duration *d = unsmob_duration (dur);
+  if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
+    {
+      Music * m = unsmob_music (last_beam_start_);
+      m->origin ()->warning (_("Suspect duration found following this beam"));
+    }
+  last_beam_start_ = SCM_EOL;
+}