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