]> git.donarmstrong.com Git - lilypond.git/blob - lily/parser.yy
bf19d07cc17bf0e401537976f9b56a81dc56f726
[lilypond.git] / lily / parser.yy
1 %{ // -*-Fundamental-*-
2
3 /*
4   parser.yy -- Bison/C++ parser for lilypond
5
6   source file of the GNU LilyPond music typesetter
7
8   (c)  1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9            Jan Nieuwenhuizen <janneke@gnu.org>
10 */
11
12 /*
13   Two shift/reduce problems:
14     -
15     -
16  */
17
18 #include <ctype.h>
19 #include <iostream.h>
20
21 #include "translator-def.hh"
22 #include "lily-guile.hh"
23 #include "change-iterator.hh"
24 #include "misc.hh"
25 #include "my-lily-lexer.hh"
26 #include "paper-def.hh"
27 #include "midi-def.hh"
28 #include "main.hh"
29 #include "file-path.hh"
30 #include "debug.hh"
31 #include "dimensions.hh"
32 #include "command-request.hh"
33 #include "musical-request.hh"
34 #include "my-lily-parser.hh"
35 #include "context-specced-music.hh"
36 #include "score.hh"
37 #include "music-list.hh"
38 #include "output-property-music-iterator.hh"
39 #include "property-iterator.hh"
40 #include "file-results.hh"
41 #include "input.hh"
42 #include "scope.hh"
43 #include "relative-music.hh"
44 #include "lyric-combine-music.hh"
45 #include "transposed-music.hh"
46 #include "time-scaled-music.hh"
47 #include "repeated-music.hh"
48 #include "lilypond-input-version.hh"
49 #include "grace-music.hh"
50 #include "part-combine-music.hh"
51 #include "scm-hash.hh"
52 #include "auto-change-iterator.hh"
53 #include "un-relativable-music.hh"
54 #include "chord.hh"
55
56
57
58 bool
59 regular_identifier_b (SCM id)
60 {
61   String str = ly_scm2string (id);
62   char const *s = str.ch_C() ;
63
64   bool v = true;
65   while (*s && v)
66    {
67         v = v && isalpha (*s);
68         s++;
69    }
70   return v;
71 }
72
73
74 bool
75 is_duration_b (int t)
76 {
77   return t && t == 1 << intlog2 (t);
78 }
79
80
81 void
82 set_music_properties (Music *p, SCM a)
83 {
84   for (SCM k = a; gh_pair_p (k); k = gh_cdr (k))
85         {
86         p->set_mus_property (gh_caar (k), gh_cdar (k));
87         }
88 }
89
90
91 // mmm JUNKME ?
92 Lilypond_version oldest_version ("1.3.59");
93
94 void
95 print_lilypond_versions (ostream &os)
96 {
97   os << _f ("Oldest supported input version: %s", oldest_version.str ()) 
98     << endl;
99 }
100
101
102 // needed for bison.simple's malloc () and free ()
103 #include <malloc.h>
104
105 #ifndef NDEBUG
106 #define YYDEBUG 1
107 #endif
108
109 #define YYERROR_VERBOSE 1
110
111 #define YYPARSE_PARAM my_lily_parser_l
112 #define YYLEX_PARAM my_lily_parser_l
113 #define THIS\
114         ((My_lily_parser *) my_lily_parser_l)
115
116 #define yyerror THIS->parser_error
117 #define ARRAY_SIZE(a,s)   if (a.size () != s) THIS->parser_error (_f ("Expecting %d arguments", s))
118
119 %}
120
121
122 %union {
123
124     Link_array<Request> *reqvec;
125
126     String *string; // needed by the lexer as temporary scratch area.
127     Music *music;
128     Score *score;
129     Scope *scope;
130     Scheme_hash_table *scmhash;
131     Music_output_def * outputdef;
132
133     Request * request;
134
135     /* We use SCMs to do strings, because it saves us the trouble of
136 deleting them.  Let's hope that a stack overflow doesnt trigger a move
137 of the parse stack onto the heap. */
138
139     SCM scm;
140
141     Tempo_req *tempo;
142     int i;
143 }
144 %{
145
146 int
147 yylex (YYSTYPE *s,  void * v_l)
148 {
149         My_lily_parser   *pars_l = (My_lily_parser*) v_l;
150         My_lily_lexer * lex_l = pars_l->lexer_p_;
151
152         lex_l->lexval_l = (void*) s;
153         return lex_l->yylex ();
154 }
155
156
157 %}
158
159 %pure_parser
160
161 /* tokens which are not keywords */
162 %token AUTOCHANGE
163 %token ALIAS
164 %token APPLY
165 %token ARPEGGIO
166 %token DYNAMICSCRIPT
167 %token ACCEPTS
168 %token ALTERNATIVE
169 %token BAR
170 %token BREATHE
171 %token CHORDMODIFIERS
172 %token CHORDS
173 %token CHAR_T
174 %token CLEF
175 %token CM_T
176 %token CONSISTS
177 %token DURATION
178 %token SEQUENTIAL
179 %token ELEMENTDESCRIPTIONS
180 %token SIMULTANEOUS
181 %token CONSISTSEND
182 %token DENIES
183 %token DURATION
184 %token EXTENDER
185 %token FONT
186 %token GLISSANDO
187 %token GRACE
188 %token HEADER
189 %token HYPHEN
190 %token IN_T
191 %token INVALID
192 %token KEY
193 %token LYRICS
194 %token MARK
195 %token MULTI_MEASURE_REST
196 %token MIDI
197 %token MM_T
198 %token PITCH
199 %token DEFAULT
200 %token NAME
201 %token PITCHNAMES
202 %token NOTES
203 %token PAPER
204 %token PARTIAL
205 %token PENALTY
206 %token PROPERTY
207 %token OVERRIDE SET REVERT 
208 %token PT_T
209 %token RELATIVE
210 %token REMOVE
211 %token REPEAT
212 %token ADDLYRICS
213 %token PARTCOMBINE
214 %token SCM_T
215 %token SCORE
216 %token SCRIPT
217 %token SKIP
218 %token SPANREQUEST
219 %token STYLESHEET
220 %token COMMANDSPANREQUEST
221 %token TEMPO
222 %token OUTPUTPROPERTY
223 %token TIME_T
224 %token TIMES
225 %token TRANSLATOR
226 %token TRANSPOSE
227 %token TYPE
228 %token UNSET
229 %token CONTEXT
230
231 /* escaped */
232 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
233 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET 
234
235 %type <i>       exclamations questions dots
236 %token <i>      DIGIT
237 %token <scm>    NOTENAME_PITCH
238 %token <scm>    TONICNAME_PITCH
239 %token <scm>    CHORDMODIFIER_PITCH
240 %token <scm>    DURATION_IDENTIFIER
241 %token <id>     IDENTIFIER
242
243
244 %token <scm>    SCORE_IDENTIFIER
245 %token <scm>    MUSIC_OUTPUT_DEF_IDENTIFIER
246
247 %token <scm>    NUMBER_IDENTIFIER
248 %token <scm>    REQUEST_IDENTIFIER
249 %token <scm>    MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
250 %token <scm>    STRING_IDENTIFIER SCM_IDENTIFIER 
251 %token <scm>    RESTNAME
252 %token <scm>    STRING   
253 %token <scm>    SCM_T
254 %token <i>      UNSIGNED
255 %token <scm>   REAL
256
257 %type <outputdef> output_def
258 %type <scmhash>         lilypond_header lilypond_header_body
259 %type <request> open_request_parens close_request_parens open_request close_request
260 %type <request> request_with_dir request_that_take_dir verbose_request
261 %type <i>       sub_quotes sup_quotes
262 %type <music>   simple_element  request_chord command_element Simple_music  Composite_music 
263 %type <music>   Alternative_music Repeated_music
264 %type <i>       tremolo_type
265 %type <i>       bare_int  bare_unsigned
266 %type <i>       script_dir
267
268 %type <scm>     identifier_init 
269
270 %type <scm> steno_duration optional_notemode_duration multiplied_duration
271 %type <scm>  explicit_duration
272         
273 %type <reqvec>  pre_requests post_requests
274 %type <request> gen_text_def
275 %type <scm>   steno_pitch pitch absolute_pitch
276 %type <scm>   explicit_pitch steno_tonic_pitch
277
278 %type <scm>     chord_additions chord_subtractions chord_notes chord_step
279 %type <music>   chord
280 %type <scm>     chord_note chord_inversion chord_bass
281 %type <scm>     duration_length
282
283 %type <scm>  embedded_scm scalar
284 %type <music>   Music Sequential_music Simultaneous_music Music_sequence
285 %type <music>   relative_music re_rhythmed_music part_combined_music
286 %type <music>   property_def translator_change
287 %type <scm> Music_list
288 %type <outputdef>  music_output_def_body
289 %type <request> shorthand_command_req
290 %type <request> post_request 
291 %type <music> command_req verbose_command_req
292 %type <request> extender_req
293 %type <request> hyphen_req
294 %type <scm>     string bare_number number_expression
295
296 %type <score>   score_block score_body
297
298 %type <scm>     translator_spec_block translator_spec_body
299 %type <tempo>   tempo_request
300 %type <scm> notenames_body notenames_block chordmodifiers_block
301 %type <scm>     script_abbreviation
302
303
304 /*
305   left association: must reduce
306   a - b - c = (a - b) - c
307  */
308 %left '-' '+'
309 %left '*' '/'
310 %left UNARY_MINUS
311
312
313
314 /*
315   multiplied_duration precedence
316   `* 3 / c' and `* 1 / 2' should be equal, try shift rather than
317    forced reduce, and take higher precedence than plain `*' and `/'
318
319   -- ugr, but it doesn't really work? input/no-notation/parse5.ly
320      it seems that:
321
322        %left *forces* reduce
323        %right *forces* shift
324
325      but we need (the default): *try* shift, and we can't override
326      above %left '*' '/' with `%prec default setting'?
327
328  */
329 %right MUL1 MUL2 INVERSION
330
331 %%
332
333 lilypond:       /* empty */
334         | lilypond toplevel_expression {}
335         | lilypond assignment  { }
336         | lilypond error {
337                 THIS->error_level_i_  = 1;
338                 //THIS->parser_error (_ ("ly invalid"));
339         }
340         | lilypond INVALID      {
341                 THIS->error_level_i_  = 1;
342                 //THIS->parser_error (_ ("ly invalid"));
343         }
344         ;
345
346 toplevel_expression:
347         notenames_block                 {
348                 THIS->lexer_p_->pitchname_tab_ =  $1;
349         }
350         | chordmodifiers_block                  {
351                 THIS->lexer_p_->chordmodifier_tab_  = $1;
352         }
353         | lilypond_header {
354                 if (global_header_p)
355                         scm_unprotect_object (global_header_p->self_scm ());
356                 global_header_p = $1;
357         }
358         | score_block {
359                 score_global_array.push ($1);
360                 
361         }
362         | output_def {
363                 if (dynamic_cast<Paper_def*> ($1))
364                         THIS->lexer_p_->set_identifier ("$defaultpaper", $1->self_scm ());
365                 else if (dynamic_cast<Midi_def*> ($1))
366                         THIS->lexer_p_->set_identifier ("$defaultmidi", $1->self_scm ());
367         }
368         | embedded_scm {
369                 // junk value
370         }       
371         ;
372
373 embedded_scm:
374         SCM_T
375         | SCM_IDENTIFIER 
376         ;
377
378
379 chordmodifiers_block:
380         CHORDMODIFIERS notenames_body   {  $$ = $2; }
381         ;
382
383
384 notenames_block:
385         PITCHNAMES notenames_body   {  $$ = $2; }
386         ;
387
388
389
390 notenames_body:
391         embedded_scm    {
392           int i = scm_ilength ($1);
393
394           SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
395           for (SCM s = $1; gh_pair_p (s); s = gh_cdr (s)) {
396                 SCM pt = gh_cdar (s);
397                 if (!unsmob_pitch (pt))
398                         THIS->parser_error ("Need pitch object.");
399                 else
400                         scm_hashq_set_x (tab, gh_caar (s), pt);
401           }
402
403           $$ = tab;
404         }
405         ;
406
407 lilypond_header_body:
408         {
409                 $$ = new Scheme_hash_table;
410                 
411                 Scope *sc = new Scope ($$);
412                 THIS->lexer_p_-> scope_l_arr_.push (sc);
413         }
414         | lilypond_header_body assignment  { 
415
416         }
417         ;
418
419 lilypond_header:
420         HEADER '{' lilypond_header_body '}'     {
421                 $$ = $3;
422                 delete THIS->lexer_p_-> scope_l_arr_.pop ();
423         }
424         ;
425
426
427 /*
428         DECLARATIONS
429 */
430 assignment:
431         STRING {
432                 THIS->remember_spot ();
433         }
434         /* cont */ '=' identifier_init  {
435                 if (! regular_identifier_b ($1))
436                         THIS->parser_error (_ ("Identifier should have  alphabetic characters only"));
437
438                 THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4);
439
440 /*
441  TODO: devise standard for protection in parser.
442
443   The parser stack lives on the C-stack, which means that
444 all objects can be unprotected as soon as they're here.
445
446 */
447         /*
448                 Should find generic way of associating input with objects.
449         */
450                 THIS->pop_spot ();
451         }
452         ;
453
454
455
456 identifier_init:
457         score_block {
458                 $$ = $1->self_scm ();
459                 scm_unprotect_object ($$);
460         }
461         | output_def {
462                 $$ = $1->self_scm ();
463                 scm_unprotect_object ($$);
464         }
465         | translator_spec_block {
466                 $$ = $1;
467         }
468         | Music  {
469                 $$ = $1->self_scm ();
470                 scm_unprotect_object ($$);
471         }
472         | post_request {
473                 $$ = $1->self_scm ();
474                 scm_unprotect_object ($$);
475         }
476         | explicit_duration {
477                 $$ = $1;
478         }
479         | number_expression {
480                 $$ = $1;
481         }
482         | string {
483                 $$ = $1;
484         }
485         | embedded_scm  {
486                 $$ = $1;
487         }
488         ;
489
490 translator_spec_block:
491         TRANSLATOR '{' translator_spec_body '}'
492                 {
493                 $$ = $3;
494         }
495         ;
496
497 translator_spec_body:
498         TRANSLATOR_IDENTIFIER   {
499                 $$ = unsmob_translator_def ($1)->clone_scm ();
500                 unsmob_translator_def ($$)-> set_spot (THIS->here_input ());
501         }
502         | TYPE STRING   {
503                 $$ = Translator_def::make_scm ();
504                 Translator_def*td =  unsmob_translator_def ($$);
505                 td->translator_group_type_ = $2;
506                 td->set_spot (THIS->here_input ());
507         }
508         | translator_spec_body STRING '=' embedded_scm                  {
509                 unsmob_translator_def ($$)->add_property_assign ($2, $4);
510         }
511         | translator_spec_body STRING OVERRIDE embedded_scm '=' embedded_scm {
512                 unsmob_translator_def ($$)
513                         ->add_push_property (scm_string_to_symbol ($2), $4, $6);
514         }
515         | translator_spec_body STRING REVERT embedded_scm  {
516           unsmob_translator_def ($$)->add_pop_property (
517                 scm_string_to_symbol ($2), $4);
518         }
519         | translator_spec_body NAME STRING  {
520                 unsmob_translator_def ($$)->type_name_ = $3;
521         }
522         | translator_spec_body CONSISTS STRING  {
523                 unsmob_translator_def ($$)->add_element ($3);
524         }
525         | translator_spec_body ALIAS STRING  {
526                 Translator_def*td = unsmob_translator_def ($$);
527                 td->type_aliases_ = gh_cons ($3, td->type_aliases_);
528         }
529         | translator_spec_body ELEMENTDESCRIPTIONS embedded_scm {
530                 for (SCM p = $3; gh_pair_p (p); p = gh_cdr (p))
531                         unsmob_translator_def ($$)
532                         ->add_property_assign (scm_symbol_to_string (gh_caar (p)), gh_cdar (p));
533
534         }
535         | translator_spec_body CONSISTSEND STRING  {
536                 unsmob_translator_def ($$)->add_last_element ( $3);
537         }
538         | translator_spec_body ACCEPTS STRING  {
539                 unsmob_translator_def ($$)->set_acceptor ($3,true);
540         }
541         | translator_spec_body DENIES STRING  {
542                 unsmob_translator_def ($$)->set_acceptor ($3,false);
543         }
544         | translator_spec_body REMOVE STRING  {
545                 unsmob_translator_def ($$)->remove_element ($3);
546         }
547         ;
548
549 /*
550         SCORE
551 */
552 score_block:
553         SCORE { 
554                 THIS->remember_spot ();
555         }
556         /*cont*/ '{' score_body '}'     {
557                 THIS->pop_spot ();
558                 $$ = $4;
559                 if (!$$->def_p_arr_.size ())
560                 {
561                   Music_output_def *id =
562                         unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
563                   $$->add_output (id ? id->clone () :  new Paper_def );
564                 }
565         }
566         ;
567
568 score_body:
569         Music   {
570                 $$ = new Score;
571         
572                 $$->set_spot (THIS->here_input ());
573                 SCM m = $1->self_scm ();
574                 scm_unprotect_object (m);
575                 $$->music_ = m;
576         }
577         | SCORE_IDENTIFIER {
578                 $$ = new Score (*unsmob_score ($1));
579                 $$->set_spot (THIS->here_input ());
580         }
581         | score_body lilypond_header    {
582                 scm_unprotect_object ($2->self_scm ()); 
583                 $$->header_p_ = $2;
584         }
585         | score_body output_def {
586                 $$->add_output ($2);
587         }
588         | score_body error {
589
590         }
591         ;
592
593
594 /*
595         MIDI
596 */
597 output_def:
598         music_output_def_body '}' {
599                 $$ = $1;
600                 THIS-> lexer_p_-> scope_l_arr_.pop ();
601         }
602         ;
603
604 music_output_def_body:
605         MIDI '{'    {
606            Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultmidi"));
607
608                 
609          Midi_def* p =0;
610         if (id)
611                 p = dynamic_cast<Midi_def*> (id->clone ());
612         else
613                 p = new Midi_def;
614
615          $$ = p;
616          THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
617         }
618         | PAPER '{'     {
619                 Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
620                   Paper_def *p = 0;
621                 if (id)
622                         p = dynamic_cast<Paper_def*> (id->clone ());
623                 else
624                         p = new Paper_def;
625                 THIS-> lexer_p_-> scope_l_arr_.push (p->scope_p_);
626                 $$ = p;
627         }
628         | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER         {
629                 Music_output_def *p = unsmob_music_output_def ($3);
630                 p = p->clone ();
631                 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
632                 $$ = p;
633         }
634         | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER  {
635                 Music_output_def *p = unsmob_music_output_def ($3);
636                 p = p->clone ();
637
638                 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
639                 $$ = p;
640         }
641         | music_output_def_body assignment  {
642
643         }
644         | music_output_def_body translator_spec_block   {
645                 $$->assign_translator ($2);
646         }
647         | music_output_def_body STYLESHEET embedded_scm {
648                 dynamic_cast<Paper_def*> ($$)-> style_sheet_ = $3;
649         }
650         | music_output_def_body tempo_request  {
651                 /*
652                         junk this ? there already is tempo stuff in
653                         music.
654                 */
655                 int m = gh_scm2int ( $2->get_mus_property ("metronome-count"));
656                 Duration *d = unsmob_duration ($2->get_mus_property ("duration"));
657                 dynamic_cast<Midi_def*> ($$)->set_tempo (d->length_mom (), m);
658         }
659         | music_output_def_body error {
660
661         }
662         ;
663
664 tempo_request:
665         TEMPO steno_duration '=' bare_unsigned  {
666                 $$ = new Tempo_req;
667                 $$->set_mus_property ("duration", $2);
668                 $$->set_mus_property ("metronome-count", gh_int2scm ( $4));
669         }
670         ;
671
672 Music_list: /* empty */ {
673                 $$ = gh_cons (SCM_EOL, SCM_EOL);
674         }
675         | Music_list Music {
676                 SCM s = $$;
677                 SCM c = gh_cons ($2->self_scm (), SCM_EOL);
678                 scm_unprotect_object ($2->self_scm ()); /* UGH */
679                 if (gh_pair_p (gh_cdr (s)))
680                         gh_set_cdr_x (gh_cdr (s), c); /* append */
681                 else
682                         gh_set_car_x (s, c); /* set first cons */
683                 gh_set_cdr_x (s, c) ;  /* remember last cell */ 
684         }
685         | Music_list error {
686         }
687         ;
688
689
690 Music:
691         Simple_music
692         | Composite_music
693         ;
694
695 Alternative_music:
696         /* empty */ {
697                 $$ = 0;
698         }
699         | ALTERNATIVE Music_sequence {
700                 $$ = $2;
701                 $2->set_spot (THIS->here_input ());
702         }
703         ;
704
705
706
707
708 Repeated_music:
709         REPEAT string bare_unsigned Music Alternative_music
710         {
711                 Music_sequence* alts = dynamic_cast <Music_sequence*> ($5);
712                 if (alts && $3 < alts->length_i ())
713                         $5->origin ()->warning (_ ("More alternatives than repeats.  Junking excess alternatives."));
714                 Music *beg = $4;
715                 int times = $3;
716
717                 Repeated_music * r = new Repeated_music (SCM_EOL);
718
719                 if (beg)
720                         {
721                         r-> set_mus_property ("body", beg->self_scm ());
722                         scm_unprotect_object (beg->self_scm ());
723                         }
724                 r->set_mus_property ("repeat-count", gh_int2scm (times >? 1));
725
726                 if (alts)
727                         {
728                         alts->truncate (times);
729                         r-> set_mus_property ("alternatives", alts->self_scm ());
730                         scm_unprotect_object (alts->self_scm ());  
731                         }
732                 SCM func = scm_eval2 (ly_symbol2scm ("repeat-name-to-ctor"), SCM_EOL);
733                 SCM result = gh_call1 (func, $2);
734
735                 set_music_properties (r, result);
736
737                 r->set_spot (*$4->origin ());
738                 $$ = r;
739         }
740         ;
741
742 Music_sequence: '{' Music_list '}'      {
743                 $$ = new Music_sequence (SCM_EOL);
744                 $$->set_mus_property ("elements", gh_car ($2));
745         }
746         ;
747
748 Sequential_music:
749         SEQUENTIAL '{' Music_list '}'           {
750                 $$ = new Sequential_music (SCM_EOL);
751                 $$->set_mus_property ("elements", gh_car ($3));
752         }
753         | '{' Music_list '}'            {
754                 $$ = new Sequential_music (SCM_EOL);
755                 $$->set_mus_property ("elements", gh_car ($2));
756         }
757         ;
758
759 Simultaneous_music:
760         SIMULTANEOUS '{' Music_list '}'{
761                 $$ = new Simultaneous_music (SCM_EOL);
762                 $$->set_mus_property ("elements", gh_car ($3));
763
764         }
765         | '<' Music_list '>'    {
766                 $$ = new Simultaneous_music (SCM_EOL);
767                 $$->set_mus_property ("elements", gh_car ($2));
768         }
769         ;
770
771 Simple_music:
772         request_chord           { $$ = $1; }
773         | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm     {
774                 SCM pred = $2;
775                 if (!gh_symbol_p ($3))
776                 {
777                         THIS->parser_error (_ ("Second argument must be a symbol")); 
778                 }
779                 /*hould check # args */
780                 if (!gh_procedure_p (pred))
781                 {
782                         THIS->parser_error (_ ("First argument must be a procedure taking 1 argument"));
783                 }
784
785                 Music *m = new Music (SCM_EOL);
786                 m->set_mus_property ("predicate", pred);
787                 m->set_mus_property ("grob-property", $3);
788                 m->set_mus_property ("grob-value",  $5);
789                 m->set_mus_property ("iterator-ctor",
790                 Output_property_music_iterator::constructor_cxx_function);
791
792                 $$ = m;
793         }
794         | MUSIC_IDENTIFIER {
795                 $$ = unsmob_music ($1)->clone ();
796         }
797         | property_def
798         | translator_change
799         ;
800
801
802 Composite_music:
803         CONTEXT STRING Music    {
804                 Context_specced_music *csm =  new Context_specced_music (SCM_EOL);
805                 csm->set_mus_property ("element", $3->self_scm ());
806                 scm_unprotect_object ($3->self_scm ());
807
808                 csm->set_mus_property ("context-type",$2);
809                 csm->set_mus_property ("context-id", ly_str02scm (""));
810
811                 $$ = csm;
812         }
813         | AUTOCHANGE STRING Music       {
814                 Music * chm = new Music_wrapper (SCM_EOL);
815                 chm->set_mus_property ("element", $3->self_scm ());
816                 chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_cxx_function);
817
818                 scm_unprotect_object ($3->self_scm ());
819                 chm->set_mus_property ("what", $2); 
820
821                 $$ = chm;
822                 chm->set_spot (*$3->origin ());
823         }
824         | GRACE Music {
825                 $$ = new Grace_music (SCM_EOL);
826                 $$->set_mus_property ("element", $2->self_scm ());
827                 scm_unprotect_object ($2->self_scm ());
828
829         }
830         | CONTEXT string '=' string Music {
831                 Context_specced_music *csm =  new Context_specced_music (SCM_EOL);
832                 csm->set_mus_property ("element", $5->self_scm ());
833                 scm_unprotect_object ($5->self_scm ());
834
835                 csm->set_mus_property ("context-type", $2);
836                 csm->set_mus_property ("context-id", $4);
837
838                 $$ = csm;
839         }
840         | TIMES {
841                 THIS->remember_spot ();
842         }
843         /* CONTINUED */ 
844                 bare_unsigned '/' bare_unsigned Music   
845
846         {
847                 int n = $3; int d = $5;
848                 Music *mp = $6;
849                 $$ = new Time_scaled_music (SCM_EOL);
850                 $$->set_spot (THIS->pop_spot ());
851
852
853                 $$->set_mus_property ("element", mp->self_scm ());
854                 scm_unprotect_object (mp->self_scm ());
855                 $$->set_mus_property ("numerator", gh_int2scm (n));
856                 $$->set_mus_property ("denominator", gh_int2scm (d));
857                 $$->compress (Moment (n,d));
858
859         }
860         | Repeated_music                { $$ = $1; }
861         | Simultaneous_music            { $$ = $1; }
862         | Sequential_music              { $$ = $1; }
863         | TRANSPOSE pitch Music {
864                 $$ = new Transposed_music (SCM_EOL);
865                 Music *p = $3;
866                 Pitch pit = *unsmob_pitch ($2);
867
868                 p->transpose (pit);
869                 $$->set_mus_property ("element", p->self_scm ());
870                 scm_unprotect_object (p->self_scm ());
871         }
872         | TRANSPOSE steno_tonic_pitch Music {
873                 $$ = new Transposed_music (SCM_EOL);
874                 Music *p = $3;
875                 Pitch pit = *unsmob_pitch ($2);
876
877                 p->transpose (pit);
878                 $$->set_mus_property ("element", p->self_scm ());
879                 scm_unprotect_object (p->self_scm ());
880         
881         }
882         | APPLY embedded_scm Music  {
883                 SCM ret = gh_call1 ($2, $3->self_scm ());
884                 Music *m = unsmob_music (ret);
885                 if (!m) {
886                         THIS->parser_error ("\\apply must return a Music");
887                         m = new Music (SCM_EOL);
888                         }
889                 $$ = m;
890         }
891         | NOTES
892                 { THIS->lexer_p_->push_note_state (); }
893         Music
894                 { $$ = $3;
895                   THIS->lexer_p_->pop_state ();
896                 }
897         | CHORDS
898                 { THIS->lexer_p_->push_chord_state (); }
899         Music
900                 {
901                   Music * chm = new Un_relativable_music ;
902                   chm->set_mus_property ("element", $3->self_scm ());
903                   $$ = chm;
904
905                   THIS->lexer_p_->pop_state ();
906         }
907         | LYRICS
908                 { THIS->lexer_p_->push_lyric_state (); }
909         Music
910                 {
911                   $$ = $3;
912                   THIS->lexer_p_->pop_state ();
913         }
914         | relative_music        { $$ = $1; }
915         | re_rhythmed_music     { $$ = $1; } 
916         | part_combined_music   { $$ = $1; } 
917         ;
918
919 relative_music:
920         RELATIVE absolute_pitch Music {
921                 Music * p = $3;
922                 Pitch pit = *unsmob_pitch ($2);
923                 $$ = new Relative_octave_music (SCM_EOL);
924
925                 $$->set_mus_property ("element", p->self_scm ());
926                 scm_unprotect_object (p->self_scm ());
927
928                 $$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ());
929
930         }
931         ;
932
933 re_rhythmed_music:
934         ADDLYRICS Music Music {
935           Lyric_combine_music * l = new Lyric_combine_music (SCM_EOL);
936           l->set_mus_property ("music", $2->self_scm ());
937           l->set_mus_property ("lyrics", $3->self_scm ());
938           scm_unprotect_object ($3->self_scm ());
939           scm_unprotect_object ($2->self_scm ());
940           $$ = l;
941         }
942         ;
943
944 part_combined_music:
945         PARTCOMBINE STRING Music Music {
946                 Part_combine_music * p = new Part_combine_music (SCM_EOL);
947
948                 p->set_mus_property ("what", $2);
949                 p->set_mus_property ("one", $3->self_scm ());
950                 p->set_mus_property ("two", $4->self_scm ());  
951
952                 scm_unprotect_object ($3->self_scm ());
953                 scm_unprotect_object ($4->self_scm ());  
954
955
956                 $$ = p;
957         }
958         ;
959
960 translator_change:
961         TRANSLATOR STRING '=' STRING  {
962                 Music * t = new Music (SCM_EOL);
963                 t->set_mus_property ("iterator-ctor",
964                         Change_iterator::constructor_cxx_function);
965                 t-> set_mus_property ("change-to-type", $2);
966                 t-> set_mus_property ("change-to-id", $4);
967
968                 $$ = t;
969                 $$->set_spot (THIS->here_input ());
970         }
971         ;
972
973 property_def:
974         PROPERTY STRING '.' STRING '='  scalar {
975                 Music *t = new Music (SCM_EOL);
976
977                 t->set_mus_property ("iterator-ctor",
978                         Property_iterator::constructor_cxx_function);
979                 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
980                 t->set_mus_property ("value", $6);
981
982                 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
983
984                 csm->set_mus_property ("element", t->self_scm ());
985                 scm_unprotect_object (t->self_scm ());
986
987                 $$ = csm;
988                 $$->set_spot (THIS->here_input ());
989
990                 csm-> set_mus_property ("context-type", $2);
991         }
992         | PROPERTY STRING '.' STRING UNSET {
993                 Music *t = new Music (SCM_EOL);
994
995                 t->set_mus_property ("iterator-ctor",
996                         Property_unset_iterator::constructor_cxx_function);
997                 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
998
999                 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1000                 csm->set_mus_property ("element", t->self_scm ());
1001                 scm_unprotect_object (t->self_scm ());
1002
1003                 $$ = csm;
1004                 $$->set_spot (THIS->here_input ());
1005
1006                 csm-> set_mus_property ("context-type", $2);
1007         }
1008         | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm {
1009                 Music *t = new Music (SCM_EOL);
1010                 t->set_mus_property ("iterator-ctor",
1011                         Push_property_iterator::constructor_cxx_function);
1012                 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1013                 t->set_mus_property ("pop-first", SCM_BOOL_T);
1014                 t->set_mus_property ("grob-property", $6);
1015                 t->set_mus_property ("grob-value", $8);
1016                 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1017                 csm->set_mus_property ("element", t->self_scm ());
1018                 scm_unprotect_object (t->self_scm ());
1019                 $$ = csm;
1020                 $$->set_spot (THIS->here_input ());
1021
1022                 csm-> set_mus_property ("context-type", $2);
1023         }
1024         | PROPERTY STRING '.' STRING OVERRIDE embedded_scm '=' embedded_scm {
1025                 Music *t = new Music (SCM_EOL);
1026                 t->set_mus_property ("iterator-ctor",
1027                         Push_property_iterator::constructor_cxx_function);
1028                 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1029                 t->set_mus_property ("grob-property", $6);
1030                 t->set_mus_property ("grob-value", $8);
1031                 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1032                 csm->set_mus_property ("element", t->self_scm ());
1033                 scm_unprotect_object (t->self_scm ());
1034
1035                 $$ = csm;
1036                 $$->set_spot (THIS->here_input ());
1037
1038                 csm-> set_mus_property ("context-type", $2);
1039         }
1040         | PROPERTY STRING '.' STRING REVERT embedded_scm {
1041                 Music *t = new Music (SCM_EOL);
1042                 t->set_mus_property ("iterator-ctor",
1043                         Pop_property_iterator::constructor_cxx_function);
1044                 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1045                 t->set_mus_property ("grob-property", $6);
1046
1047                 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1048                 csm->set_mus_property ("element", t->self_scm ());
1049                 scm_unprotect_object (t->self_scm ());
1050
1051                 $$ = csm;
1052                 $$->set_spot (THIS->here_input ());
1053
1054                 csm-> set_mus_property ("context-type", $2);
1055         }
1056         ;
1057
1058 scalar:
1059         string          { $$ = $1; }
1060         | bare_int      { $$ = gh_int2scm ($1); }
1061         | embedded_scm  { $$ = $1; }
1062         ;
1063
1064
1065 request_chord:
1066         pre_requests simple_element post_requests       {
1067                 Music_sequence *l = dynamic_cast<Music_sequence*> ($2);
1068                 if (l) {
1069                         for (int i=0; i < $1->size (); i++)
1070                                 l->append_music ($1->elem (i));
1071                         for (int i=0; i < $3->size (); i++)
1072                                 l->append_music ($3->elem (i));
1073                         }
1074                 else
1075                         programming_error ("Need Sequence to add music to");
1076                 $$ = $2;
1077                 
1078         }
1079         | command_element
1080         ;
1081
1082 command_element:
1083         command_req {
1084                 $$ = new Request_chord (SCM_EOL);
1085                 $$->set_mus_property ("elements", gh_cons ($1->self_scm (), SCM_EOL));
1086                 $$-> set_spot (THIS->here_input ());
1087                 $1-> set_spot (THIS->here_input ());
1088         }
1089         | BAR STRING                    {
1090                 Music *t = new Music (SCM_EOL);
1091
1092                 t->set_mus_property ("iterator-ctor",
1093                         Property_iterator::constructor_cxx_function);
1094                 t->set_mus_property ("symbol", ly_symbol2scm ("whichBar"));
1095                 t->set_mus_property ("value", $2);
1096
1097                 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1098                 csm->set_mus_property ("element", t->self_scm ());
1099                 scm_unprotect_object (t->self_scm ());
1100
1101                 $$ = csm;
1102                 $$->set_spot (THIS->here_input ());
1103
1104                 csm->set_mus_property ("context-type", ly_str02scm ("Score"));
1105         }
1106         | PARTIAL duration_length       {
1107                 Music * p = new Music (SCM_EOL);
1108                 p->set_mus_property ("symbol", ly_symbol2scm ( "measurePosition"));
1109                 p->set_mus_property ("iterator-ctor",
1110                         Property_iterator::constructor_cxx_function);
1111
1112                 Moment m = - unsmob_duration ($2)->length_mom ();
1113                 p->set_mus_property ("value", m.smobbed_copy ());
1114
1115                 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1116                 sp->set_mus_property ("element", p->self_scm ());
1117                 scm_unprotect_object (p->self_scm ());
1118
1119                 $$ =sp ;
1120                 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1121         }
1122         | CLEF STRING  {
1123                 SCM func = scm_eval2 (ly_symbol2scm ("clef-name-to-properties"), SCM_EOL);
1124                 SCM result = gh_call1 (func, $2);
1125
1126                 SCM l = SCM_EOL;
1127                 for (SCM s = result ; gh_pair_p (s); s = gh_cdr (s)) {
1128                         Music * p = new Music (SCM_EOL);
1129                         set_music_properties (p, gh_car (s));
1130                         l = gh_cons (p->self_scm (), l);
1131                         scm_unprotect_object (p->self_scm ());
1132                 }
1133                 Sequential_music * seq = new Sequential_music (SCM_EOL);
1134                 seq->set_mus_property ("elements", l);
1135
1136                 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1137                 sp->set_mus_property ("element", seq->self_scm ());
1138                 scm_unprotect_object (seq->self_scm ());
1139
1140                 $$ =sp ;
1141                 sp-> set_mus_property ("context-type", ly_str02scm ("Staff"));
1142         }
1143         | TIME_T bare_unsigned '/' bare_unsigned  {
1144                 Music * p = new Music (SCM_EOL);
1145                 p->set_mus_property ("symbol",
1146                         ly_symbol2scm ( "timeSignatureFraction"));
1147                 p->set_mus_property ("iterator-ctor",
1148                         Property_iterator::constructor_cxx_function);
1149
1150                 p->set_mus_property ("value", gh_cons (gh_int2scm ($2),
1151                                                         gh_int2scm ($4)));
1152
1153                 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1154                 sp->set_mus_property ("element", p->self_scm ());
1155                 scm_unprotect_object (p->self_scm ());
1156
1157                 $$ = sp;
1158
1159 /*
1160  TODO: should make alias TimingContext for Score
1161 */
1162
1163                 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1164         }
1165         ;
1166
1167 command_req:
1168         shorthand_command_req   { $$ = $1; }
1169         | verbose_command_req   { $$ = $1; }
1170         ;
1171
1172 shorthand_command_req:
1173         extender_req {
1174                 $$ = $1;
1175         }
1176         | hyphen_req {
1177                 $$ = $1;
1178         }
1179         | '|'                           {
1180                 $$ = new Barcheck_req;
1181         }
1182         | '~'   {
1183                 $$ = new Tie_req;
1184         }
1185         | '['           {
1186                 Span_req*b= new Span_req;
1187                 b->set_span_dir (START);
1188                 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1189                 $$ =b;
1190         }
1191         | ']'           {
1192                 Span_req*b= new Span_req;
1193                 b->set_span_dir ( STOP);
1194                 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1195                 $$ = b;
1196         }
1197         | BREATHE {
1198                 $$ = new Breathing_sign_req;
1199         }
1200         ;
1201
1202
1203 verbose_command_req:
1204         COMMANDSPANREQUEST bare_int STRING { /*TODO: junkme */
1205                 Span_req * sp_p = new Span_req;
1206                 sp_p-> set_span_dir ( Direction ($2));
1207                 sp_p->set_mus_property ("span-type",$3);
1208                 sp_p->set_spot (THIS->here_input ());
1209                 $$ = sp_p;
1210         }
1211         | MARK DEFAULT  {
1212                 Mark_req * m = new Mark_req;
1213                 $$ = m;
1214         }
1215         | MARK scalar {
1216                 Mark_req *m = new Mark_req;
1217                 m->set_mus_property ("label", $2);
1218                 $$ = m;
1219
1220         }
1221         | PENALTY SCM_T         {
1222
1223                 
1224                 Break_req * b = new Break_req;
1225                 SCM s = $2;
1226                 if (!gh_number_p (s))
1227                         s  =gh_int2scm (0);
1228
1229                 b->set_mus_property ("penalty", s);
1230                 b->set_spot (THIS->here_input ());
1231                 $$ = b;
1232         }
1233         | SKIP duration_length {
1234                 Skip_req * skip_p = new Skip_req;
1235                 skip_p->set_mus_property ("duration", $2);
1236
1237                 $$ = skip_p;
1238         }
1239         | tempo_request {
1240                 $$ = $1;
1241         }
1242         | KEY DEFAULT {
1243                 Key_change_req *key_p= new Key_change_req;
1244                 $$ = key_p;
1245         }
1246         | KEY NOTENAME_PITCH SCM_IDENTIFIER     {
1247                 Key_change_req *key_p= new Key_change_req;
1248                 
1249                 key_p->set_mus_property ("pitch-alist", $3);
1250  ((Music* )key_p)->transpose (* unsmob_pitch ($2));
1251                 $$ = key_p; 
1252         }
1253         ;
1254
1255 post_requests:
1256         {
1257                 $$ = new Link_array<Request>;
1258         }
1259         | post_requests post_request {
1260                 $2->set_spot (THIS->here_input ());
1261                 $$->push ($2);
1262         }
1263         ;
1264
1265 post_request:
1266         verbose_request
1267         | request_with_dir
1268         | close_request
1269         ;
1270
1271
1272 request_that_take_dir:
1273         gen_text_def
1274         | verbose_request
1275         | script_abbreviation {
1276                 SCM s = THIS->lexer_p_->lookup_identifier ("dash" + ly_scm2string ($1));
1277                 Articulation_req *a = new Articulation_req;
1278                 if (gh_string_p (s))
1279                         a->set_mus_property ("articulation-type", s);
1280                 else THIS->parser_error (_ ("Expecting string as script definition"));
1281                 $$ = a;
1282         }
1283         ;
1284
1285 request_with_dir:
1286         script_dir request_that_take_dir        {
1287                 if (Script_req * gs = dynamic_cast<Script_req*> ($2))
1288                         gs->set_direction (Direction ($1));
1289                 else if ($1)
1290                         $2->origin ()->warning (_ ("Can't specify direction for this request"));
1291                 $$ = $2;
1292         }
1293         ;
1294         
1295 verbose_request:
1296         REQUEST_IDENTIFIER      {
1297                 $$ = dynamic_cast<Request*> (unsmob_music ($1)->clone ());
1298                 $$->set_spot (THIS->here_input ());
1299         }
1300         | DYNAMICSCRIPT embedded_scm {
1301                 /*
1302                         TODO: junkme, use text-type == dynamic
1303                 */
1304                 Text_script_req *d = new Text_script_req;
1305                 d->set_mus_property ("text-type" , ly_symbol2scm ("dynamic"));
1306                 d->set_mus_property ("text", $2);
1307                 d->set_spot (THIS->here_input ());
1308                 $$ = d;
1309         }
1310         | SPANREQUEST bare_int STRING {
1311                 Span_req * sp_p = new Span_req;
1312                 sp_p->set_span_dir ( Direction ($2));
1313                 sp_p->set_mus_property ("span-type", $3);
1314                 sp_p->set_spot (THIS->here_input ());
1315                 $$ = sp_p;
1316         }
1317         | tremolo_type  {
1318                Tremolo_req* a = new Tremolo_req;
1319                a->set_spot (THIS->here_input ());
1320                a->set_mus_property ("tremolo-type", gh_int2scm ($1));
1321                $$ = a;
1322         }
1323         | SCRIPT STRING         { 
1324                 Articulation_req * a = new Articulation_req;
1325                 a->set_mus_property ("articulation-type", $2);
1326                 a->set_spot (THIS->here_input ());
1327                 $$ = a;
1328         }
1329         /*
1330 duh, junk this syntax from the parser, if possible. 
1331         */
1332         | ARPEGGIO {
1333                 Arpeggio_req *a = new Arpeggio_req;
1334                 a->set_spot (THIS->here_input ());
1335                 $$ = a;
1336         }
1337         | GLISSANDO {
1338                 Glissando_req *g = new Glissando_req;
1339                 g->set_spot /* No pun intended */ (THIS->here_input ());
1340                 $$ = g;
1341         }       
1342         ;
1343
1344 sup_quotes:
1345         '\'' {
1346                 $$ = 1;
1347         }
1348         | sup_quotes '\'' {
1349                 $$ ++;
1350         }
1351         ;
1352
1353 sub_quotes:
1354         ',' {
1355                 $$ = 1;
1356         }
1357         | sub_quotes ',' {
1358                 $$ ++ ;
1359         }
1360         ;
1361
1362 steno_pitch:
1363         NOTENAME_PITCH  {
1364                 $$ = $1;
1365         }
1366         | NOTENAME_PITCH sup_quotes     {
1367                 Pitch p = *unsmob_pitch ($1);
1368                 p.octave_i_ +=  $2;
1369                 $$ = p.smobbed_copy ();
1370         }
1371         | NOTENAME_PITCH sub_quotes      {
1372                 Pitch p =* unsmob_pitch ($1);
1373
1374                 p.octave_i_ +=  -$2;
1375                 $$ = p.smobbed_copy ();
1376
1377         }
1378         ;
1379
1380 /*
1381 ugh. duplication
1382 */
1383
1384 steno_tonic_pitch:
1385         TONICNAME_PITCH {
1386                 $$ = $1;
1387         }
1388         | TONICNAME_PITCH sup_quotes    {
1389                 Pitch p = *unsmob_pitch ($1);
1390                 p.octave_i_ +=  $2;
1391                 $$ = p.smobbed_copy ();
1392         }
1393         | TONICNAME_PITCH sub_quotes     {
1394                 Pitch p =* unsmob_pitch ($1);
1395
1396                 p.octave_i_ +=  -$2;
1397                 $$ = p.smobbed_copy ();
1398
1399         }
1400         ;
1401
1402 pitch:
1403         steno_pitch {
1404                 $$ = $1;
1405         }
1406         | explicit_pitch {
1407                 $$ = $1;
1408         }
1409         ;
1410
1411 explicit_pitch:
1412         PITCH embedded_scm {
1413                 $$ = $2;
1414                 if (!unsmob_pitch ($2)) {
1415                         THIS->parser_error (_f ("Expecting musical-pitch value", 3));
1416                          $$ = Pitch ().smobbed_copy ();
1417                 }
1418         }
1419         ;
1420
1421 explicit_duration:
1422         DURATION embedded_scm   {
1423                 $$ = $2;
1424                 if (!unsmob_duration ($2))
1425                 {
1426                         THIS->parser_error (_ ("Must have duration object"));
1427                         $$ = Duration ().smobbed_copy ();
1428                 }
1429         }
1430         ;
1431
1432 extender_req:
1433         EXTENDER {
1434                 if (!THIS->lexer_p_->lyric_state_b ())
1435                         THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1436                 $$ = new Extender_req;
1437         }
1438         ;
1439
1440 hyphen_req:
1441         HYPHEN {
1442                 if (!THIS->lexer_p_->lyric_state_b ())
1443                         THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1444                 $$ = new Hyphen_req;
1445         }
1446         ;
1447
1448 close_request:
1449         close_request_parens {
1450                 $$ = $1;
1451                 dynamic_cast<Span_req*> ($$)->set_span_dir ( START);
1452         }
1453         
1454 close_request_parens:
1455         '('     {
1456                 Span_req* s= new Span_req;
1457                 $$ = s;
1458                 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1459         }
1460         | E_OPEN        {
1461                 Span_req* s= new Span_req;
1462                 $$ = s;
1463                 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1464         }
1465         | E_SMALLER {
1466                 Span_req*s =new Span_req;
1467                 $$ = s;
1468                 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1469         }
1470         | E_BIGGER {
1471                 Span_req*s =new Span_req;
1472                 $$ = s;
1473                 s->set_mus_property ("span-type", ly_str02scm ("decrescendo"));
1474         }
1475         ;
1476
1477
1478 open_request:
1479         open_request_parens {
1480                 $$ = $1;
1481                 dynamic_cast<Span_req*> ($$)->set_span_dir (STOP);
1482         }
1483         ;
1484
1485 open_request_parens:
1486         E_EXCLAMATION   {
1487                 Span_req *s =  new Span_req;
1488                 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1489
1490                 $$ = s;
1491         }
1492         | ')'   {
1493                 Span_req* s= new Span_req;
1494                 $$ = s;
1495                 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1496         }
1497         | E_CLOSE       {
1498                 Span_req* s= new Span_req;
1499                 $$ = s;
1500                 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1501         }
1502         ;
1503
1504 gen_text_def:
1505         embedded_scm {
1506                 Text_script_req *t = new Text_script_req;
1507                 t->set_mus_property ("text", $1);
1508                 t->set_spot (THIS->here_input ());
1509                 $$ = t;
1510         }
1511         | string {
1512                 Text_script_req *t = new Text_script_req;
1513                 t->set_mus_property ("text", $1);
1514                 t->set_spot (THIS->here_input ());
1515                 $$ = t;
1516         }
1517         | DIGIT {
1518                 String ds = to_str ($1);
1519                 Text_script_req* t = new Text_script_req;
1520
1521                 t->set_mus_property ("text",  ly_str02scm (ds.ch_C ()));
1522                 t->set_mus_property ("text-type" , ly_symbol2scm ("finger"));
1523                 t->set_spot (THIS->here_input ());
1524                 $$ = t;
1525         }
1526         ;
1527
1528 script_abbreviation:
1529         '^'             {
1530                 $$ = gh_str02scm ("Hat");
1531         }
1532         | '+'           {
1533                 $$ = gh_str02scm ("Plus");
1534         }
1535         | '-'           {
1536                 $$ = gh_str02scm ("Dash");
1537         }
1538         | '|'           {
1539                 $$ = gh_str02scm ("Bar");
1540         }
1541         | '>'           {
1542                 $$ = gh_str02scm ("Larger");
1543         }
1544         | '.'           {
1545                 $$ = gh_str02scm ("Dot");
1546         }
1547         ;
1548
1549
1550 script_dir:
1551         '_'     { $$ = DOWN; }
1552         | '^'   { $$ = UP; }
1553         | '-'   { $$ = CENTER; }
1554         ;
1555
1556 pre_requests:
1557         {
1558                 $$ = new Link_array<Request>;
1559         }
1560         | pre_requests open_request {
1561                 $$->push ($2);
1562         }
1563         ;
1564
1565 absolute_pitch:
1566         steno_pitch     {
1567                 $$ = $1;
1568         }
1569         ;
1570
1571 duration_length:
1572         multiplied_duration {
1573                 $$ = $1;
1574         }
1575         | explicit_duration {
1576                 $$ = $1;
1577         }       
1578         ;
1579
1580 optional_notemode_duration:
1581         {
1582                 $$ = THIS->default_duration_.smobbed_copy ();
1583         }
1584         | multiplied_duration   {
1585                 $$ = $1;
1586         }
1587         | explicit_duration {
1588                 $$ = $1;
1589         }       
1590         ;
1591
1592 steno_duration:
1593         bare_unsigned dots              {
1594                 int l = 0;
1595                 if (!is_duration_b ($1))
1596                         THIS->parser_error (_f ("not a duration: %d", $1));
1597                 else
1598                         l =  intlog2 ($1);
1599
1600                 $$ = Duration (l, $2).smobbed_copy ();
1601
1602                 THIS->set_last_duration (unsmob_duration ($$));
1603         }
1604         | DURATION_IDENTIFIER dots      {
1605                 Duration *d =unsmob_duration ($1);
1606                 Duration k (d->duration_log (),d->dot_count () + $2);
1607                 $$ = k.smobbed_copy ();
1608
1609                 THIS->set_last_duration (unsmob_duration ($$));
1610         }
1611         ;
1612
1613
1614
1615
1616 /*
1617   Multiplied durations are always multiplied, ie,
1618   c1 * INT or c1 * RAT.
1619
1620   No support for c1 /4 and c1 /2/2.
1621
1622   '*' and '/' are declared %left, with makes them reduce rather than
1623   shift.
1624
1625   Because there are no a/b/c association problems anymore, it is
1626   safe to allow '*' and '/' to shift.
1627
1628    * 1 / 4 shifts to match second rule: '* 1 / 4'
1629
1630    '/' TONIC_NAME shifts to match rule: chord_inversion
1631
1632  */
1633 multiplied_duration:
1634         steno_duration {
1635                 $$ = $1;
1636         }
1637         | multiplied_duration '*' bare_unsigned %prec MUL1 {
1638                 $$ = unsmob_duration ($$)->compressed ($3).smobbed_copy ();
1639         }
1640         | multiplied_duration '*' bare_unsigned '/' bare_unsigned %prec MUL2 {
1641                 $$ = unsmob_duration ($$)->compressed (Moment ($3, $5)).smobbed_copy ();
1642         }
1643         ;
1644
1645 dots:
1646         /* empty */     {
1647                 $$ = 0;
1648         }
1649         | dots '.' {
1650                 $$ ++;
1651         }
1652         ;
1653
1654
1655 tremolo_type: 
1656         ':'     {
1657                 $$ =0;
1658         }
1659         | ':' bare_unsigned {
1660                 if (!is_duration_b ($2))
1661                         THIS->parser_error (_f ("not a duration: %d", $2));
1662                 $$ = $2;
1663         }
1664         ;
1665
1666
1667 simple_element:
1668         pitch exclamations questions optional_notemode_duration {
1669                 if (!THIS->lexer_p_->note_state_b ())
1670                         THIS->parser_error (_ ("Have to be in Note mode for notes"));
1671
1672                 Note_req *n = new Note_req;
1673                 
1674                 n->set_mus_property ("pitch", $1);
1675                 n->set_mus_property ("duration", $4);
1676
1677                 if ($3 % 2)
1678                         n->set_mus_property ("cautionary", SCM_BOOL_T);
1679                 if ($2 % 2 || $3 % 2)
1680                         n->set_mus_property ("force-accidental", SCM_BOOL_T);
1681
1682                 Simultaneous_music*v = new Request_chord (SCM_EOL);
1683                 v->set_mus_property ("elements", gh_list (n->self_scm (), SCM_UNDEFINED));
1684                 
1685 /*
1686 FIXME: location is one off, since ptich & duration don't contain origin refs. 
1687 */
1688                 v->set_spot (THIS->here_input ());
1689                 n->set_spot (THIS->here_input ());
1690
1691                 $$ = v;
1692         }
1693         | RESTNAME optional_notemode_duration           {
1694
1695                 SCM e = SCM_UNDEFINED;
1696                   if (ly_scm2string ($1) =="s")
1697                     { /* Space */
1698                       Skip_req * skip_p = new Skip_req;
1699                       skip_p->set_mus_property ("duration" ,$2);
1700
1701                       skip_p->set_spot (THIS->here_input ());
1702                         e = skip_p->self_scm ();
1703                     }
1704                   else
1705                     {
1706                       Rest_req * rest_req_p = new Rest_req;
1707                       rest_req_p->set_mus_property ("duration", $2);
1708                       rest_req_p->set_spot (THIS->here_input ());
1709                         e = rest_req_p->self_scm ();
1710                     }
1711                   Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1712                 velt_p-> set_mus_property ("elements", gh_list (e,SCM_UNDEFINED));
1713                   velt_p->set_spot (THIS->here_input ());
1714
1715
1716                   $$ = velt_p;
1717         }
1718         | MULTI_MEASURE_REST optional_notemode_duration         {
1719                 Skip_req * sk = new Skip_req;
1720                 sk->set_mus_property ("duration", $2);
1721                 Span_req *sp1 = new Span_req;
1722                 Span_req *sp2 = new Span_req;
1723                 sp1-> set_span_dir ( START);
1724                 sp2-> set_span_dir ( STOP);
1725                 SCM r = ly_str02scm ("rest");
1726                 sp1->set_mus_property ("span-type", r);
1727                 sp2->set_mus_property ("span-type", r);
1728
1729                 Request_chord * rqc1 = new Request_chord (SCM_EOL);
1730                 rqc1->set_mus_property ("elements", gh_list (sp1->self_scm (), SCM_UNDEFINED));
1731                 Request_chord * rqc2 = new Request_chord (SCM_EOL);
1732                 rqc2->set_mus_property ("elements", gh_list (sk->self_scm (), SCM_UNDEFINED));;
1733                 Request_chord * rqc3 = new Request_chord (SCM_EOL);
1734                 rqc3->set_mus_property ("elements", gh_list (sp2->self_scm (), SCM_UNDEFINED));;
1735
1736                 SCM ms = gh_list (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED);
1737
1738                 $$ = new Sequential_music (SCM_EOL);
1739                 $$->set_mus_property ("elements", ms);
1740         }
1741         | STRING optional_notemode_duration     {
1742
1743                 Lyric_req* lreq_p = new Lyric_req;
1744                 lreq_p->set_mus_property ("text", $1);
1745                 lreq_p->set_mus_property ("duration",$2);
1746                 lreq_p->set_spot (THIS->here_input ());
1747                 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1748                 velt_p->set_mus_property ("elements", gh_list (lreq_p->self_scm (), SCM_UNDEFINED));
1749
1750
1751                 $$= velt_p;
1752
1753         }
1754         | chord {
1755                 if (!THIS->lexer_p_->chord_state_b ())
1756                         THIS->parser_error (_ ("Have to be in Chord mode for chords"));
1757                 $$ = $1;
1758         }
1759         ;
1760
1761
1762 chord:
1763         steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
1764                 $$ = Chord::get_chord ($1, $3, $4, $5, $6, $2);
1765                 $$->set_spot (THIS->here_input ());
1766         };
1767
1768 chord_additions: 
1769         {
1770                 $$ = SCM_EOL;
1771         } 
1772         | CHORD_COLON chord_notes {
1773                 $$ = $2;
1774         }
1775         ;
1776
1777 chord_notes:
1778         chord_step {
1779                 $$ = $1
1780         }
1781         | chord_notes '.' chord_step {
1782                 $$ = gh_append2 ($$, $3);
1783         }
1784         ;
1785
1786 chord_subtractions: 
1787         {
1788                 $$ = SCM_EOL;
1789         } 
1790         | CHORD_CARET chord_notes {
1791                 $$ = $2;
1792         }
1793         ;
1794
1795
1796 chord_inversion:
1797         {
1798                 $$ = SCM_EOL;
1799         }
1800         | '/' steno_tonic_pitch %prec INVERSION {
1801                 $$ = $2;
1802         }
1803         ;
1804
1805 chord_bass:
1806         {
1807                 $$ = SCM_EOL;
1808         }
1809         | CHORD_BASS steno_tonic_pitch {
1810                 $$ = $2;
1811         }
1812         ;
1813
1814 chord_step:
1815         chord_note {
1816                 $$ = gh_cons ($1, SCM_EOL);
1817         }
1818         | CHORDMODIFIER_PITCH {
1819                 $$ = gh_cons ($1, SCM_EOL);
1820         }
1821         | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
1822                 $$ = gh_list ($1, $2, SCM_UNDEFINED);
1823         }
1824         ;
1825
1826 chord_note:
1827         bare_unsigned {
1828                  Pitch m;
1829                 m.notename_i_ = ($1 - 1) % 7;
1830                 m.octave_i_ = $1 > 7 ? 1 : 0;
1831                 m.alteration_i_ = 0;
1832
1833                 $$ = m.smobbed_copy ();
1834         } 
1835         | bare_unsigned '+' {
1836                 Pitch m;
1837                 m.notename_i_ = ($1 - 1) % 7;
1838                 m.octave_i_ = $1 > 7 ? 1 : 0;
1839                 m.alteration_i_ = 1;
1840
1841
1842                 $$ = m.smobbed_copy ();
1843         }
1844         | bare_unsigned CHORD_MINUS {
1845                 Pitch m;
1846                 m.notename_i_ = ($1 - 1) % 7;
1847                 m.octave_i_ = $1 > 7 ? 1 : 0;
1848                 m.alteration_i_ = -1;
1849
1850                 $$ = m.smobbed_copy ();
1851         }
1852         ;
1853
1854 /*
1855         UTILITIES
1856  */
1857 number_expression:
1858         bare_number {
1859                 $$ = $1;
1860         }
1861         | '-'  number_expression %prec UNARY_MINUS {
1862                 $$ = scm_difference ($2, SCM_UNDEFINED);
1863         }
1864         | number_expression '*' number_expression {
1865                 $$ = scm_product ($1, $3);
1866         }
1867         | number_expression '/' number_expression {
1868                 $$ = scm_divide ($1, $3);
1869         }
1870         | number_expression '+' number_expression {
1871                 $$ = scm_sum ($1, $3);
1872         }
1873         | number_expression '-' number_expression {
1874                 $$ = scm_difference ($1, $3);
1875         }
1876         | '(' number_expression ')'     {
1877                 $$ = $2;
1878         }
1879         ;
1880
1881 bare_number:
1882         UNSIGNED        {
1883                 $$ = gh_int2scm ($1);
1884         }
1885         | REAL          {
1886                 $$ = $1;
1887         }
1888         | NUMBER_IDENTIFIER             {
1889                 $$ = $1;
1890         }
1891         | REAL CM_T     {
1892                 $$ = gh_double2scm (gh_scm2double ($1) CM );
1893         }
1894         | REAL PT_T     {
1895                 $$ = gh_double2scm (gh_scm2double ($1) PT);
1896         }
1897         | REAL IN_T     {
1898                 $$ = gh_double2scm (gh_scm2double ($1) INCH);
1899         }
1900         | REAL MM_T     {
1901                 $$ = gh_double2scm (gh_scm2double ($1) MM);
1902         }
1903         | REAL CHAR_T   {
1904                 $$ = gh_double2scm (gh_scm2double ($1) CHAR);
1905         }
1906         ;
1907
1908
1909 bare_unsigned:
1910         UNSIGNED {
1911                         $$ = $1;
1912         }
1913         | DIGIT {
1914                 $$ = $1;
1915         }
1916         ;
1917
1918 bare_int:
1919         bare_number {
1920                 if (scm_integer_p ($1) == SCM_BOOL_T)
1921                 {
1922                         int k = gh_scm2int ($1);
1923                         $$ = k;
1924                 } else
1925                 {
1926                         THIS->parser_error (_ ("need integer number arg"));
1927                         $$ = 0;
1928                 }
1929         }
1930         | '-' bare_int {
1931                 $$ = -$2;
1932         }
1933         ;
1934
1935
1936 string:
1937         STRING          {
1938                 $$ = $1;
1939         }
1940         | STRING_IDENTIFIER     {
1941                 $$ = $1;
1942         }
1943         | string '+' string {
1944                 $$ = scm_string_append (scm_listify ($1, $3, SCM_UNDEFINED));
1945         }
1946         ;
1947
1948
1949 exclamations:
1950                 { $$ = 0; }
1951         | exclamations '!'      { $$ ++; }
1952         ;
1953
1954 questions:
1955                 { $$ = 0; }
1956         | questions '?' { $$ ++; }
1957         ;
1958
1959
1960 %%
1961
1962 void
1963 My_lily_parser::set_yydebug (bool b)
1964 {
1965 #ifdef YYDEBUG
1966         yydebug = b;
1967 #endif
1968 }
1969
1970 extern My_lily_parser * current_parser;
1971
1972 void
1973 My_lily_parser::do_yyparse ()
1974 {
1975
1976         current_parser = this;;
1977         yyparse ((void*)this);
1978 }
1979
1980