1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for lilypond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
13 Two shift/reduce problems:
20 the rules for who is protecting what are very shady. TODO: uniformise
29 #include "translator-def.hh"
30 #include "lily-guile.hh"
31 #include "change-iterator.hh"
33 #include "my-lily-lexer.hh"
34 #include "paper-def.hh"
35 #include "midi-def.hh"
37 #include "file-path.hh"
39 #include "dimensions.hh"
40 #include "command-request.hh"
41 #include "musical-request.hh"
42 #include "my-lily-parser.hh"
43 #include "context-specced-music.hh"
45 #include "music-list.hh"
46 #include "output-property-music-iterator.hh"
47 #include "property-iterator.hh"
48 #include "file-results.hh"
50 #include "relative-music.hh"
51 #include "lyric-combine-music.hh"
52 #include "transposed-music.hh"
53 #include "time-scaled-music.hh"
54 #include "repeated-music.hh"
55 #include "untransposable-music.hh"
56 #include "lilypond-input-version.hh"
57 #include "grace-music.hh"
58 #include "part-combine-music.hh"
59 #include "scm-hash.hh"
60 #include "auto-change-iterator.hh"
61 #include "un-relativable-music.hh"
65 regular_identifier_b (SCM id)
67 String str = ly_scm2string (id);
68 char const *s = str.ch_C() ;
73 v = v && isalpha (*s);
81 set_property_music (SCM sym, SCM value)
83 Music * p = new Music (SCM_EOL);
84 p->set_mus_property ("symbol", sym);
85 p->set_mus_property ("iterator-ctor",
86 Property_iterator::constructor_cxx_function);
88 p->set_mus_property ("value", value);
95 return t && t == 1 << intlog2 (t);
99 set_music_properties (Music *p, SCM a)
101 for (SCM k = a; gh_pair_p (k); k = ly_cdr (k))
103 p->internal_set_mus_property (ly_caar (k), ly_cdar (k));
113 // needed for bison.simple's malloc () and free ()
120 #define YYERROR_VERBOSE 1
122 #define YYPARSE_PARAM my_lily_parser_l
123 #define YYLEX_PARAM my_lily_parser_l
125 ((My_lily_parser *) my_lily_parser_l)
127 #define yyerror THIS->parser_error
128 #define ARRAY_SIZE(a,s) if (a.size () != s) THIS->parser_error (_f ("Expecting %d arguments", s))
132 /* We use SCMs to do strings, because it saves us the trouble of
133 deleting them. Let's hope that a stack overflow doesnt trigger a move
134 of the parse stack onto the heap. */
139 Link_array<Request> *reqvec;
141 String *string; // needed by the lexer as temporary scratch area.
144 Scheme_hash_table *scmhash;
145 Music_output_def * outputdef;
157 yylex (YYSTYPE *s, void * v_l)
159 My_lily_parser *pars_l = (My_lily_parser*) v_l;
160 My_lily_lexer * lex_l = pars_l->lexer_p_;
162 lex_l->lexval_l = (void*) s;
163 return lex_l->yylex ();
171 /* tokens which are not keywords */
181 %token CHORDMODIFIERS
189 %token GROBDESCRIPTIONS
195 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
196 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
206 %token MULTI_MEASURE_REST
218 %token OVERRIDE SET REVERT
231 %token COMMANDSPANREQUEST
233 %token OUTPUTPROPERTY
244 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
245 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
247 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET
251 %type <i> exclamations questions dots optional_rest
252 %type <i> bass_number bass_mod
253 %type <scm> br_bass_figure bass_figure figure_list figure_spec
255 %token <scm> NOTENAME_PITCH
256 %token <scm> TONICNAME_PITCH
257 %token <scm> CHORDMODIFIER_PITCH
258 %token <scm> DURATION_IDENTIFIER
259 %token <scm> FRACTION
260 %token <id> IDENTIFIER
263 %token <scm> SCORE_IDENTIFIER
264 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
266 %token <scm> NUMBER_IDENTIFIER
267 %token <scm> REQUEST_IDENTIFIER
268 %token <scm> MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
269 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
270 %token <scm> RESTNAME
276 %type <outputdef> output_def
277 %type <scmhash> lilypond_header lilypond_header_body
278 %type <request> open_request_parens close_request_parens open_request close_request
279 %type <request> request_with_dir request_that_take_dir verbose_request
280 %type <i> sub_quotes sup_quotes
281 %type <music> simple_element request_chord command_element Simple_music Composite_music
282 %type <music> Repeated_music
283 %type <scm> Alternative_music
284 %type <i> tremolo_type
285 %type <i> bare_int bare_unsigned
288 %type <scm> identifier_init
290 %type <scm> steno_duration optional_notemode_duration multiplied_duration
291 %type <scm> verbose_duration
293 %type <reqvec> pre_requests post_requests
294 %type <request> gen_text_def
295 %type <scm> steno_pitch pitch absolute_pitch
296 %type <scm> explicit_pitch steno_tonic_pitch
298 %type <scm> chord_additions chord_subtractions chord_notes chord_step
300 %type <scm> chord_note chord_inversion chord_bass
301 %type <scm> duration_length fraction
303 %type <scm> embedded_scm scalar
304 %type <music> Music Sequential_music Simultaneous_music
305 %type <music> relative_music re_rhythmed_music part_combined_music
306 %type <music> property_def translator_change
307 %type <scm> Music_list
308 %type <outputdef> music_output_def_body
309 %type <request> shorthand_command_req
310 %type <request> post_request
311 %type <music> command_req verbose_command_req
312 %type <request> extender_req
313 %type <request> hyphen_req
314 %type <scm> string bare_number number_expression number_term number_factor
316 %type <score> score_block score_body
318 %type <scm> translator_spec_block translator_spec_body
319 %type <tempo> tempo_request
320 %type <scm> notenames_body notenames_block chordmodifiers_block
321 %type <scm> script_abbreviation
327 /* We don't assign precedence to / and *, because we might need varied
328 prec levels in different prods */
334 lilypond: /* empty */
335 | lilypond toplevel_expression {}
336 | lilypond assignment { }
338 THIS->error_level_i_ = 1;
341 THIS->error_level_i_ = 1;
347 THIS->lexer_p_->pitchname_tab_ = $1;
349 | chordmodifiers_block {
350 THIS->lexer_p_->chordmodifier_tab_ = $1;
354 scm_gc_unprotect_object (global_header_p->self_scm ());
355 global_header_p = $1;
358 score_global_array.push ($1);
361 if (dynamic_cast<Paper_def*> ($1))
362 THIS->lexer_p_->set_identifier (gh_str02scm ("$defaultpaper"), $1->self_scm ());
363 else if (dynamic_cast<Midi_def*> ($1))
364 THIS->lexer_p_->set_identifier (gh_str02scm ("$defaultmidi"), $1->self_scm ());
377 chordmodifiers_block:
378 CHORDMODIFIERS notenames_body { $$ = $2; }
382 PITCHNAMES notenames_body { $$ = $2; }
387 int i = scm_ilength ($1);
389 SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
390 for (SCM s = $1; gh_pair_p (s); s = ly_cdr (s)) {
391 SCM pt = ly_cdar (s);
392 if (!unsmob_pitch (pt))
393 THIS->parser_error ("Need pitch object.");
395 scm_hashq_set_x (tab, ly_caar (s), pt);
402 lilypond_header_body:
404 $$ = new Scheme_hash_table;
405 THIS->lexer_p_-> scope_l_arr_.push ($$);
407 | lilypond_header_body assignment {
413 HEADER '{' lilypond_header_body '}' {
415 THIS->lexer_p_->scope_l_arr_.pop ();
427 /* cont */ '=' identifier_init {
430 Should find generic way of associating input with objects.
432 Input ip = THIS->pop_spot ();
434 if (! regular_identifier_b ($1))
436 ip.warning (_ ("Identifier should have alphabetic characters only"));
439 THIS->lexer_p_->set_identifier ($1, $4);
442 TODO: devise standard for protection in parser.
444 The parser stack lives on the C-stack, which means that
445 all objects can be unprotected as soon as they're here.
455 $$ = $1->self_scm ();
456 scm_gc_unprotect_object ($$);
459 $$ = $1->self_scm ();
460 scm_gc_unprotect_object ($$);
462 | translator_spec_block {
466 $$ = $1->self_scm ();
467 scm_gc_unprotect_object ($$);
470 $$ = $1->self_scm ();
471 scm_gc_unprotect_object ($$);
476 | number_expression {
487 translator_spec_block:
488 TRANSLATOR '{' translator_spec_body '}'
494 translator_spec_body:
495 TRANSLATOR_IDENTIFIER {
496 $$ = unsmob_translator_def ($1)->clone_scm ();
497 unsmob_translator_def ($$)-> set_spot (THIS->here_input ());
500 $$ = Translator_def::make_scm ();
501 Translator_def*td = unsmob_translator_def ($$);
502 td->translator_group_type_ = $2;
503 td->set_spot (THIS->here_input ());
505 | translator_spec_body STRING '=' embedded_scm {
506 unsmob_translator_def ($$)->add_property_assign ($2, $4);
508 | translator_spec_body STRING OVERRIDE embedded_scm '=' embedded_scm {
509 unsmob_translator_def ($$)
510 ->add_push_property (scm_string_to_symbol ($2), $4, $6);
512 | translator_spec_body STRING REVERT embedded_scm {
513 unsmob_translator_def ($$)->add_pop_property (
514 scm_string_to_symbol ($2), $4);
516 | translator_spec_body NAME STRING {
517 unsmob_translator_def ($$)->type_name_ = $3;
519 | translator_spec_body CONSISTS STRING {
520 unsmob_translator_def ($$)->add_element ($3);
522 | translator_spec_body ALIAS STRING {
523 Translator_def*td = unsmob_translator_def ($$);
524 td->type_aliases_ = gh_cons ($3, td->type_aliases_);
526 | translator_spec_body GROBDESCRIPTIONS embedded_scm {
527 Translator_def*td = unsmob_translator_def($$);
528 // td->add_property_assign (ly_symbol2scm ("allGrobDescriptions"), $3);
529 for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p))
530 td->add_property_assign (scm_symbol_to_string (ly_caar (p)), ly_cdar (p));
532 | translator_spec_body CONSISTSEND STRING {
533 unsmob_translator_def ($$)->add_last_element ( $3);
535 | translator_spec_body ACCEPTS STRING {
536 unsmob_translator_def ($$)->set_acceptor ($3,true);
538 | translator_spec_body DENIES STRING {
539 unsmob_translator_def ($$)->set_acceptor ($3,false);
541 | translator_spec_body REMOVE STRING {
542 unsmob_translator_def ($$)->remove_element ($3);
553 /*cont*/ '{' score_body '}' {
556 if (!$$->def_p_arr_.size ())
558 Music_output_def *id =
559 unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
560 $$->add_output (id ? id->clone () : new Paper_def );
569 $$->set_spot (THIS->here_input ());
570 SCM m = $1->self_scm ();
571 scm_gc_unprotect_object (m);
577 SCM check_func = scm_c_eval_string ("check-start-chords");
578 gh_call1 (check_func, m);
582 $$ = new Score (*unsmob_score ($1));
583 $$->set_spot (THIS->here_input ());
585 | score_body lilypond_header {
586 scm_gc_unprotect_object ($2->self_scm ());
589 | score_body output_def {
602 music_output_def_body '}' {
604 THIS-> lexer_p_-> scope_l_arr_.pop ();
608 music_output_def_body:
610 Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultmidi"));
615 p = dynamic_cast<Midi_def*> (id->clone ());
620 THIS->lexer_p_->scope_l_arr_.push (p->variable_tab_);
623 Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
626 p = dynamic_cast<Paper_def*> (id->clone ());
629 THIS-> lexer_p_-> scope_l_arr_.push (p->variable_tab_);
632 | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
633 Music_output_def *p = unsmob_music_output_def ($3);
635 THIS->lexer_p_->scope_l_arr_.push (p->variable_tab_);
638 | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
639 Music_output_def *p = unsmob_music_output_def ($3);
642 THIS->lexer_p_->scope_l_arr_.push (p->variable_tab_);
645 | music_output_def_body assignment {
648 | music_output_def_body translator_spec_block {
649 $$->assign_translator ($2);
651 | music_output_def_body STYLESHEET embedded_scm {
652 dynamic_cast<Paper_def*> ($$)-> style_sheet_ = $3;
654 | music_output_def_body tempo_request {
656 junk this ? there already is tempo stuff in
659 int m = gh_scm2int ( $2->get_mus_property ("metronome-count"));
660 Duration *d = unsmob_duration ($2->get_mus_property ("duration"));
661 dynamic_cast<Midi_def*> ($$)->set_tempo (d->length_mom (), m);
663 | music_output_def_body error {
669 TEMPO steno_duration '=' bare_unsigned {
671 $$->set_mus_property ("duration", $2);
672 $$->set_mus_property ("metronome-count", gh_int2scm ( $4));
677 The representation of a list is the
681 to have efficient append.
683 Music_list: /* empty */ {
684 $$ = gh_cons (SCM_EOL, SCM_EOL);
688 SCM c = gh_cons ($2->self_scm (), SCM_EOL);
689 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
690 if (gh_pair_p (ly_cdr (s)))
691 gh_set_cdr_x (ly_cdr (s), c); /* append */
693 gh_set_car_x (s, c); /* set first cons */
694 gh_set_cdr_x (s, c) ; /* remember last cell */
710 | ALTERNATIVE '{' Music_list '}' {
716 REPEAT string bare_unsigned Music Alternative_music
720 SCM alts = gh_pair_p ($5) ? gh_car ($5) : SCM_EOL;
721 if (times < scm_ilength (alts)) {
722 unsmob_music (gh_car (alts))
723 ->origin ()->warning (
724 _("More alternatives than repeats. Junking excess alternatives."));
725 alts = ly_truncate_list (times, alts);
728 Repeated_music * r = new Repeated_music (SCM_EOL);
731 r-> set_mus_property ("element", beg->self_scm ());
732 scm_gc_unprotect_object (beg->self_scm ());
734 r->set_mus_property ("repeat-count", gh_int2scm (times >? 1));
736 r-> set_mus_property ("elements",alts);
737 SCM func = scm_primitive_eval (ly_symbol2scm ("repeat-name-to-ctor"));
738 SCM result = gh_call1 (func, $2);
740 set_music_properties (r, result);
742 r->set_spot (*$4->origin ());
748 SEQUENTIAL '{' Music_list '}' {
749 $$ = new Sequential_music (SCM_EOL);
750 $$->set_mus_property ("elements", ly_car ($3));
751 $$->set_spot(THIS->here_input());
753 | '{' Music_list '}' {
754 $$ = new Sequential_music (SCM_EOL);
755 $$->set_mus_property ("elements", ly_car ($2));
756 $$->set_spot(THIS->here_input());
761 SIMULTANEOUS '{' Music_list '}'{
762 $$ = new Simultaneous_music (SCM_EOL);
763 $$->set_mus_property ("elements", ly_car ($3));
764 $$->set_spot(THIS->here_input());
767 | '<' Music_list '>' {
768 $$ = new Simultaneous_music (SCM_EOL);
769 $$->set_mus_property ("elements", ly_car ($2));
770 $$->set_spot(THIS->here_input());
775 request_chord { $$ = $1; }
776 | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm {
778 if (!gh_symbol_p ($3))
780 THIS->parser_error (_ ("Second argument must be a symbol"));
782 /*hould check # args */
783 if (!gh_procedure_p (pred))
785 THIS->parser_error (_ ("First argument must be a procedure taking 1 argument"));
788 Music *m = new Music (SCM_EOL);
789 m->set_mus_property ("predicate", pred);
790 m->set_mus_property ("grob-property", $3);
791 m->set_mus_property ("grob-value", $5);
792 m->set_mus_property ("iterator-ctor",
793 Output_property_music_iterator::constructor_cxx_function);
798 $$ = unsmob_music ($1)->clone ();
800 $$->set_spot (THIS->here_input());
808 CONTEXT STRING Music {
809 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
810 csm->set_mus_property ("element", $3->self_scm ());
811 scm_gc_unprotect_object ($3->self_scm ());
813 csm->set_mus_property ("context-type",$2);
814 csm->set_mus_property ("context-id", ly_str02scm (""));
818 | AUTOCHANGE STRING Music {
819 Music * chm = new Music_wrapper (SCM_EOL);
820 chm->set_mus_property ("element", $3->self_scm ());
821 chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_cxx_function);
823 scm_gc_unprotect_object ($3->self_scm ());
824 chm->set_mus_property ("what", $2);
827 chm->set_spot (*$3->origin ());
832 The other version is for easier debugging of
833 Sequential_music_iterator in combination with grace notes.
836 SCM start = THIS->lexer_p_->lookup_identifier ("startGraceMusic");
837 SCM stop = THIS->lexer_p_->lookup_identifier ("stopGraceMusic");
838 Music *startm = unsmob_music (start);
839 Music *stopm = unsmob_music (stop);
843 stopm = stopm->clone ();
844 ms = gh_cons (stopm->self_scm (), ms);
845 scm_gc_unprotect_object (stopm->self_scm ());
847 ms = gh_cons ($2->self_scm (), ms);
848 scm_gc_unprotect_object ($2->self_scm());
850 startm = startm->clone ();
851 ms = gh_cons (startm->self_scm () , ms);
852 scm_gc_unprotect_object (startm->self_scm ());
855 Music* seq = new Sequential_music (SCM_EOL);
856 seq->set_mus_property ("elements", ms);
858 $$ = new Grace_music (SCM_EOL);
859 $$->set_mus_property ("element", seq->self_scm ());
860 scm_gc_unprotect_object (seq->self_scm ());
862 $$ = new Grace_music (SCM_EOL);
863 $$->set_mus_property ("element", $2->self_scm ());
864 scm_gc_unprotect_object ($2->self_scm ());
867 | CONTEXT string '=' string Music {
868 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
869 csm->set_mus_property ("element", $5->self_scm ());
870 scm_gc_unprotect_object ($5->self_scm ());
872 csm->set_mus_property ("context-type", $2);
873 csm->set_mus_property ("context-id", $4);
884 int n = gh_scm2int (ly_car ($3)); int d = gh_scm2int (ly_cdr ($3));
886 $$ = new Time_scaled_music (SCM_EOL);
887 $$->set_spot (THIS->pop_spot ());
890 $$->set_mus_property ("element", mp->self_scm ());
891 scm_gc_unprotect_object (mp->self_scm ());
892 $$->set_mus_property ("numerator", gh_int2scm (n));
893 $$->set_mus_property ("denominator", gh_int2scm (d));
894 $$->compress (Moment (Rational (n,d)));
897 | Repeated_music { $$ = $1; }
898 | Simultaneous_music { $$ = $1; }
899 | Sequential_music { $$ = $1; }
900 | TRANSPOSE pitch Music {
901 $$ = new Transposed_music (SCM_EOL);
903 Pitch pit = *unsmob_pitch ($2);
906 $$->set_mus_property ("element", p->self_scm ());
907 scm_gc_unprotect_object (p->self_scm ());
909 | TRANSPOSE steno_tonic_pitch Music {
910 $$ = new Transposed_music (SCM_EOL);
912 Pitch pit = *unsmob_pitch ($2);
915 $$->set_mus_property ("element", p->self_scm ());
916 scm_gc_unprotect_object (p->self_scm ());
919 | APPLY embedded_scm Music {
920 SCM ret = gh_call1 ($2, $3->self_scm ());
921 Music *m = unsmob_music (ret);
923 THIS->parser_error ("\\apply must return a Music");
924 m = new Music (SCM_EOL);
929 { THIS->lexer_p_->push_note_state (); }
932 THIS->lexer_p_->pop_state ();
935 { THIS->lexer_p_->push_figuredbass_state (); }
938 Music * chm = new Untransposable_music () ;
939 chm->set_mus_property ("element", $3->self_scm ());
942 THIS->lexer_p_->pop_state ();
945 { THIS->lexer_p_->push_chord_state (); }
948 Music * chm = new Un_relativable_music ;
949 chm->set_mus_property ("element", $3->self_scm ());
952 THIS->lexer_p_->pop_state ();
955 { THIS->lexer_p_->push_lyric_state (); }
959 THIS->lexer_p_->pop_state ();
961 | relative_music { $$ = $1; }
962 | re_rhythmed_music { $$ = $1; }
963 | part_combined_music { $$ = $1; }
967 RELATIVE absolute_pitch Music {
969 Pitch pit = *unsmob_pitch ($2);
970 $$ = new Relative_octave_music (SCM_EOL);
972 $$->set_mus_property ("element", p->self_scm ());
973 scm_gc_unprotect_object (p->self_scm ());
975 $$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ());
981 ADDLYRICS Music Music {
982 Lyric_combine_music * l = new Lyric_combine_music (SCM_EOL);
983 l->set_mus_property ("elements", gh_list ($2->self_scm (), $3->self_scm (), SCM_UNDEFINED));
984 scm_gc_unprotect_object ($3->self_scm ());
985 scm_gc_unprotect_object ($2->self_scm ());
991 PARTCOMBINE STRING Music Music {
992 Part_combine_music * p = new Part_combine_music (SCM_EOL);
994 p->set_mus_property ("what", $2);
995 p->set_mus_property ("elements", gh_list ($3->self_scm (),$4->self_scm (), SCM_UNDEFINED));
997 scm_gc_unprotect_object ($3->self_scm ());
998 scm_gc_unprotect_object ($4->self_scm ());
1005 TRANSLATOR STRING '=' STRING {
1006 Music * t = new Music (SCM_EOL);
1007 t->set_mus_property ("iterator-ctor",
1008 Change_iterator::constructor_cxx_function);
1009 t-> set_mus_property ("change-to-type", $2);
1010 t-> set_mus_property ("change-to-id", $4);
1013 $$->set_spot (THIS->here_input ());
1018 PROPERTY STRING '.' STRING '=' scalar {
1020 Music *t = set_property_music (scm_string_to_symbol ($4), $6);
1021 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1023 csm->set_mus_property ("element", t->self_scm ());
1024 scm_gc_unprotect_object (t->self_scm ());
1027 $$->set_spot (THIS->here_input ());
1029 csm-> set_mus_property ("context-type", $2);
1031 | PROPERTY STRING '.' STRING UNSET {
1032 Music *t = new Music (SCM_EOL);
1034 t->set_mus_property ("iterator-ctor",
1035 Property_unset_iterator::constructor_cxx_function);
1036 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1038 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1039 csm->set_mus_property ("element", t->self_scm ());
1040 scm_gc_unprotect_object (t->self_scm ());
1043 $$->set_spot (THIS->here_input ());
1045 csm-> set_mus_property ("context-type", $2);
1047 | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm {
1048 Music *t = new Music (SCM_EOL);
1049 t->set_mus_property ("iterator-ctor",
1050 Push_property_iterator::constructor_cxx_function);
1051 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1052 t->set_mus_property ("pop-first", SCM_BOOL_T);
1053 t->set_mus_property ("grob-property", $6);
1054 t->set_mus_property ("grob-value", $8);
1055 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1056 csm->set_mus_property ("element", t->self_scm ());
1057 scm_gc_unprotect_object (t->self_scm ());
1059 $$->set_spot (THIS->here_input ());
1061 csm-> set_mus_property ("context-type", $2);
1063 | PROPERTY STRING '.' STRING OVERRIDE embedded_scm '=' embedded_scm {
1064 Music *t = new Music (SCM_EOL);
1065 t->set_mus_property ("iterator-ctor",
1066 Push_property_iterator::constructor_cxx_function);
1067 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1068 t->set_mus_property ("grob-property", $6);
1069 t->set_mus_property ("grob-value", $8);
1070 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1071 csm->set_mus_property ("element", t->self_scm ());
1072 scm_gc_unprotect_object (t->self_scm ());
1075 $$->set_spot (THIS->here_input ());
1077 csm-> set_mus_property ("context-type", $2);
1079 | PROPERTY STRING '.' STRING REVERT embedded_scm {
1080 Music *t = new Music (SCM_EOL);
1081 t->set_mus_property ("iterator-ctor",
1082 Pop_property_iterator::constructor_cxx_function);
1083 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1084 t->set_mus_property ("grob-property", $6);
1086 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1087 csm->set_mus_property ("element", t->self_scm ());
1088 scm_gc_unprotect_object (t->self_scm ());
1091 $$->set_spot (THIS->here_input ());
1093 csm-> set_mus_property ("context-type", $2);
1099 | bare_int { $$ = gh_int2scm ($1); }
1100 | embedded_scm { $$ = $1; }
1107 } /*cont */ simple_element post_requests {
1108 Music_sequence *l = dynamic_cast<Music_sequence*> ($3);
1111 for (int i=0; i < $1->size (); i++) {
1112 Music * m = $1->elem (i);
1113 l->append_music (m);
1125 $$ = new Request_chord (SCM_EOL);
1126 $$->set_mus_property ("elements", gh_cons ($1->self_scm (), SCM_EOL));
1127 $$-> set_spot (THIS->here_input ());
1128 $1-> set_spot (THIS->here_input ());
1131 Span_req *l = new Span_req;
1132 l->set_span_dir (START);
1133 l->set_mus_property ("span-type", ly_str02scm ("ligature"));
1134 l->set_spot (THIS->here_input ());
1136 $$ = new Request_chord (SCM_EOL);
1137 $$->set_mus_property ("elements", gh_cons (l->self_scm (), SCM_EOL));
1138 $$->set_spot (THIS->here_input ());
1141 Span_req *l = new Span_req;
1142 l->set_span_dir (STOP);
1143 l->set_mus_property ("span-type", ly_str02scm ("ligature"));
1144 l->set_spot (THIS->here_input ());
1146 $$ = new Request_chord (SCM_EOL);
1147 $$->set_mus_property ("elements", gh_cons (l->self_scm (), SCM_EOL));
1148 $$->set_spot (THIS->here_input ());
1151 $$ = new Music (gh_list (gh_cons (ly_symbol2scm ("name"), ly_symbol2scm ("separator")), SCM_UNDEFINED));
1152 $$->set_spot (THIS->here_input ());
1156 extern Music * get_barcheck();
1157 $$ = get_barcheck ();
1158 $$->set_spot (THIS->here_input ());
1161 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1163 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1164 csm->set_mus_property ("element", t->self_scm ());
1165 scm_gc_unprotect_object (t->self_scm ());
1168 $$->set_spot (THIS->here_input ());
1170 csm->set_mus_property ("context-type", ly_str02scm ("Score"));
1172 | PARTIAL duration_length {
1173 Moment m = - unsmob_duration ($2)->length_mom ();
1174 Music * p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1176 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1177 sp->set_mus_property ("element", p->self_scm ());
1178 scm_gc_unprotect_object (p->self_scm ());
1181 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1184 SCM func = scm_primitive_eval (ly_symbol2scm ("clef-name-to-properties"));
1185 SCM result = gh_call1 (func, $2);
1188 for (SCM s = result ; gh_pair_p (s); s = ly_cdr (s)) {
1189 Music * p = new Music (SCM_EOL);
1190 set_music_properties (p, ly_car (s));
1191 l = gh_cons (p->self_scm (), l);
1192 scm_gc_unprotect_object (p->self_scm ());
1194 Sequential_music * seq = new Sequential_music (SCM_EOL);
1195 seq->set_mus_property ("elements", l);
1197 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1198 sp->set_mus_property ("element", seq->self_scm ());
1199 scm_gc_unprotect_object (seq->self_scm ());
1202 sp-> set_mus_property ("context-type", ly_str02scm ("Staff"));
1205 Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2);
1207 int l = gh_scm2int (ly_car ($2));
1208 int o = gh_scm2int (ly_cdr ($2));
1210 Moment one_beat = Moment (1)/Moment (o);
1211 Moment len = Moment (l) * one_beat;
1214 Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ());
1215 Music *p3 = set_property_music (ly_symbol2scm ("beatLength"), one_beat.smobbed_copy ());
1217 SCM list = scm_list_n (p1->self_scm (), p2->self_scm (), p3->self_scm(), SCM_UNDEFINED);
1218 Sequential_music *seq = new Sequential_music (SCM_EOL);
1219 seq->set_mus_property ("elements", list);
1222 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1223 sp->set_mus_property ("element", seq->self_scm ());
1227 scm_gc_unprotect_object (p3->self_scm ());
1228 scm_gc_unprotect_object (p2->self_scm ());
1229 scm_gc_unprotect_object (p1->self_scm ());
1230 scm_gc_unprotect_object (seq->self_scm ());
1235 TODO: should make alias TimingContext for Score
1238 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1243 shorthand_command_req { $$ = $1; }
1244 | verbose_command_req { $$ = $1; }
1247 shorthand_command_req:
1258 Span_req*b= new Span_req;
1259 b->set_span_dir (START);
1260 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1264 THIS->last_beam_start_ = b->self_scm ();
1267 Span_req*b= new Span_req;
1268 b->set_span_dir ( STOP);
1269 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1273 $$ = new Breathing_sign_req;
1276 $$ = new Porrectus_req;
1280 verbose_command_req:
1281 COMMANDSPANREQUEST bare_int STRING { /*TODO: junkme */
1282 Span_req * sp_p = new Span_req;
1283 sp_p-> set_span_dir ( Direction ($2));
1284 sp_p->set_mus_property ("span-type",$3);
1285 sp_p->set_spot (THIS->here_input ());
1289 Mark_req * m = new Mark_req;
1293 Mark_req *m = new Mark_req;
1294 m->set_mus_property ("label", $2);
1299 Break_req * b = new Break_req;
1301 if (!gh_number_p (s))
1304 b->set_mus_property ("penalty", s);
1305 b->set_spot (THIS->here_input ());
1308 | SKIP duration_length {
1309 Skip_req * skip_p = new Skip_req;
1310 skip_p->set_mus_property ("duration", $2);
1318 Key_change_req *key_p= new Key_change_req;
1321 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1322 Key_change_req *key_p= new Key_change_req;
1324 key_p->set_mus_property ("pitch-alist", $3);
1325 ((Music*)key_p)->transpose (* unsmob_pitch ($2));
1332 $$ = new Link_array<Request>;
1334 | post_requests post_request {
1335 $2->set_spot (THIS->here_input ());
1347 request_that_take_dir:
1350 | script_abbreviation {
1351 SCM s = THIS->lexer_p_->lookup_identifier ("dash" + ly_scm2string ($1));
1352 Articulation_req *a = new Articulation_req;
1353 if (gh_string_p (s))
1354 a->set_mus_property ("articulation-type", s);
1355 else THIS->parser_error (_ ("Expecting string as script definition"));
1361 script_dir request_that_take_dir {
1362 if (Script_req * gs = dynamic_cast<Script_req*> ($2))
1363 gs->set_direction (Direction ($1));
1365 $2->origin ()->warning (_ ("Can't specify direction for this request"));
1371 REQUEST_IDENTIFIER {
1372 $$ = dynamic_cast<Request*> (unsmob_music ($1)->clone ());
1373 $$->set_spot (THIS->here_input ());
1375 | DYNAMICSCRIPT embedded_scm {
1377 TODO: junkme, use text-type == dynamic
1379 Text_script_req *d = new Text_script_req;
1380 SCM dyn = ly_symbol2scm ("dynamic");
1381 d->set_mus_property ("text-type" , dyn);
1382 d->set_mus_property ("text", $2);
1383 d->set_spot (THIS->here_input ());
1386 | SPANREQUEST bare_int STRING {
1387 Span_req * sp_p = new Span_req;
1388 sp_p->set_span_dir ( Direction ($2));
1389 sp_p->set_mus_property ("span-type", $3);
1390 sp_p->set_spot (THIS->here_input ());
1394 Tremolo_req* a = new Tremolo_req;
1395 a->set_spot (THIS->here_input ());
1396 a->set_mus_property ("tremolo-type", gh_int2scm ($1));
1400 Articulation_req * a = new Articulation_req;
1401 a->set_mus_property ("articulation-type", $2);
1402 a->set_spot (THIS->here_input ());
1406 duh, junk this syntax from the parser, if possible.
1409 Arpeggio_req *a = new Arpeggio_req;
1410 a->set_spot (THIS->here_input ());
1414 Glissando_req *g = new Glissando_req;
1415 g->set_spot /* No pun intended */ (THIS->here_input ());
1442 | NOTENAME_PITCH sup_quotes {
1443 Pitch p = *unsmob_pitch ($1);
1445 $$ = p.smobbed_copy ();
1447 | NOTENAME_PITCH sub_quotes {
1448 Pitch p =* unsmob_pitch ($1);
1451 $$ = p.smobbed_copy ();
1464 | TONICNAME_PITCH sup_quotes {
1465 Pitch p = *unsmob_pitch ($1);
1467 $$ = p.smobbed_copy ();
1469 | TONICNAME_PITCH sub_quotes {
1470 Pitch p =* unsmob_pitch ($1);
1473 $$ = p.smobbed_copy ();
1488 PITCH embedded_scm {
1490 if (!unsmob_pitch ($2)) {
1491 THIS->parser_error (_f ("Expecting musical-pitch value", 3));
1492 $$ = Pitch ().smobbed_copy ();
1498 DURATION embedded_scm {
1500 if (!unsmob_duration ($2))
1502 THIS->parser_error (_ ("Must have duration object"));
1503 $$ = Duration ().smobbed_copy ();
1510 if (!THIS->lexer_p_->lyric_state_b ())
1511 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1512 $$ = new Extender_req;
1518 if (!THIS->lexer_p_->lyric_state_b ())
1519 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1520 $$ = new Hyphen_req;
1525 close_request_parens {
1527 dynamic_cast<Span_req*> ($$)->set_span_dir ( START);
1531 close_request_parens:
1533 Span_req* s= new Span_req;
1535 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1538 Span_req* s= new Span_req;
1540 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1543 Span_req*s =new Span_req;
1545 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1548 Span_req*s =new Span_req;
1550 s->set_mus_property ("span-type", ly_str02scm ("decrescendo"));
1556 open_request_parens {
1558 dynamic_cast<Span_req*> ($$)->set_span_dir (STOP);
1562 open_request_parens:
1564 Span_req *s = new Span_req;
1565 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1570 Span_req* s= new Span_req;
1572 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1575 Span_req* s= new Span_req;
1577 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1583 Text_script_req *t = new Text_script_req;
1584 t->set_mus_property ("text", $1);
1585 t->set_spot (THIS->here_input ());
1589 Text_script_req *t = new Text_script_req;
1590 t->set_mus_property ("text", $1);
1591 t->set_spot (THIS->here_input ());
1595 String ds = to_str ($1);
1596 Text_script_req* t = new Text_script_req;
1597 SCM finger = ly_symbol2scm ("finger");
1598 t->set_mus_property ("text", ly_str02scm (ds.ch_C ()));
1599 t->set_mus_property ("text-type" , finger);
1600 t->set_spot (THIS->here_input ());
1605 script_abbreviation:
1607 $$ = gh_str02scm ("Hat");
1610 $$ = gh_str02scm ("Plus");
1613 $$ = gh_str02scm ("Dash");
1616 $$ = gh_str02scm ("Bar");
1619 $$ = gh_str02scm ("Larger");
1622 $$ = gh_str02scm ("Dot");
1629 | '-' { $$ = CENTER; }
1634 $$ = new Link_array<Request>;
1636 | pre_requests open_request {
1648 multiplied_duration {
1651 | verbose_duration {
1656 optional_notemode_duration:
1658 Duration dd = THIS->default_duration_;
1659 $$ = dd.smobbed_copy ();
1661 THIS->beam_check ($$);
1663 | multiplied_duration {
1665 THIS->default_duration_ = *unsmob_duration ($$);
1667 THIS->beam_check ($$);
1669 | verbose_duration {
1671 THIS->default_duration_ = *unsmob_duration ($$);
1676 bare_unsigned dots {
1678 if (!is_duration_b ($1))
1679 THIS->parser_error (_f ("not a duration: %d", $1));
1683 $$ = Duration (l, $2).smobbed_copy ();
1685 | DURATION_IDENTIFIER dots {
1686 Duration *d =unsmob_duration ($1);
1687 Duration k (d->duration_log (),d->dot_count () + $2);
1688 $$ = k.smobbed_copy ();
1695 multiplied_duration:
1699 | multiplied_duration '*' bare_unsigned {
1700 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1702 | multiplied_duration '*' FRACTION {
1703 Rational m (gh_scm2int (ly_car ($3)), gh_scm2int (ly_cdr ($3)));
1705 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
1710 FRACTION { $$ = $1; }
1711 | UNSIGNED '/' UNSIGNED {
1712 $$ = gh_cons (gh_int2scm ($1), gh_int2scm ($3));
1730 | ':' bare_unsigned {
1731 if (!is_duration_b ($2))
1732 THIS->parser_error (_f ("not a duration: %d", $2));
1751 Bass_figure_req *bfr = new Bass_figure_req;
1752 $$ = bfr->self_scm();
1753 scm_gc_unprotect_object ($$);
1756 Bass_figure_req *bfr = new Bass_figure_req;
1757 $$ = bfr->self_scm();
1759 bfr->set_mus_property ("figure", gh_int2scm ($1));
1761 scm_gc_unprotect_object ($$);
1763 | bass_figure bass_mod {
1764 Music *m = unsmob_music ($1);
1766 SCM salter =m->get_mus_property ("alteration");
1767 int alter = gh_number_p( salter) ? gh_scm2int (salter) : 0;
1768 m->set_mus_property ("alteration",
1769 gh_int2scm (alter + $2));
1771 m->set_mus_property ("alteration", gh_int2scm (0));
1779 unsmob_music ($$)->set_mus_property ("bracket-start", SCM_BOOL_T);
1784 | br_bass_figure ']' {
1786 unsmob_music ($1)->set_mus_property ("bracket-stop", SCM_BOOL_T);
1794 | figure_list br_bass_figure {
1795 $$ = gh_cons ($2, $1);
1800 FIGURE_OPEN figure_list FIGURE_CLOSE {
1801 Music * m = new Request_chord (SCM_EOL);
1802 $2 = scm_reverse_x ($2, SCM_EOL);
1803 m->set_mus_property ("elements", $2);
1804 $$ = m->self_scm ();
1815 pitch exclamations questions optional_notemode_duration optional_rest {
1817 Input i = THIS->pop_spot ();
1818 if (!THIS->lexer_p_->note_state_b ())
1819 THIS->parser_error (_ ("Have to be in Note mode for notes"));
1827 n->set_mus_property ("pitch", $1);
1828 n->set_mus_property ("duration", $4);
1832 n->set_mus_property ("cautionary", SCM_BOOL_T);
1833 if ($2 % 2 || $3 % 2)
1834 n->set_mus_property ("force-accidental", SCM_BOOL_T);
1836 Simultaneous_music*v = new Request_chord (SCM_EOL);
1837 v->set_mus_property ("elements", scm_list_n (n->self_scm (), SCM_UNDEFINED));
1843 | figure_spec optional_notemode_duration {
1844 Music * m = unsmob_music ($1);
1845 Input i = THIS->pop_spot ();
1847 for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = ly_cdr (s))
1849 unsmob_music (ly_car (s))->set_mus_property ("duration", $2);
1853 | RESTNAME optional_notemode_duration {
1855 Input i = THIS->pop_spot ();
1856 SCM e = SCM_UNDEFINED;
1857 if (ly_scm2string ($1) =="s") {
1859 Skip_req * skip_p = new Skip_req;
1860 skip_p->set_mus_property ("duration" ,$2);
1861 skip_p->set_spot (i);
1862 e = skip_p->self_scm ();
1865 Rest_req * rest_req_p = new Rest_req;
1866 rest_req_p->set_mus_property ("duration", $2);
1867 rest_req_p->set_spot (i);
1868 e = rest_req_p->self_scm ();
1870 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1871 velt_p-> set_mus_property ("elements", scm_list_n (e,SCM_UNDEFINED));
1872 velt_p->set_spot (i);
1876 | MULTI_MEASURE_REST optional_notemode_duration {
1877 Input i = THIS->pop_spot ();
1879 Skip_req * sk = new Skip_req;
1880 sk->set_mus_property ("duration", $2);
1881 Span_req *sp1 = new Span_req;
1882 Span_req *sp2 = new Span_req;
1883 sp1-> set_span_dir ( START);
1884 sp2-> set_span_dir ( STOP);
1885 SCM r = ly_str02scm ("rest");
1886 sp1->set_mus_property ("span-type", r);
1887 sp2->set_mus_property ("span-type", r);
1889 Request_chord * rqc1 = new Request_chord (SCM_EOL);
1890 rqc1->set_mus_property ("elements", scm_list_n (sp1->self_scm (), SCM_UNDEFINED));
1891 Request_chord * rqc2 = new Request_chord (SCM_EOL);
1892 rqc2->set_mus_property ("elements", scm_list_n (sk->self_scm (), SCM_UNDEFINED));;
1893 Request_chord * rqc3 = new Request_chord (SCM_EOL);
1894 rqc3->set_mus_property ("elements", scm_list_n (sp2->self_scm (), SCM_UNDEFINED));;
1896 SCM ms = scm_list_n (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED);
1898 $$ = new Sequential_music (SCM_EOL);
1899 $$->set_mus_property ("elements", ms);
1901 | STRING optional_notemode_duration {
1902 Input i = THIS->pop_spot ();
1904 Lyric_req* lreq_p = new Lyric_req;
1905 lreq_p->set_mus_property ("text", $1);
1906 lreq_p->set_mus_property ("duration",$2);
1907 lreq_p->set_spot (i);
1908 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1909 velt_p->set_mus_property ("elements", scm_list_n (lreq_p->self_scm (), SCM_UNDEFINED));
1914 Input i = THIS->pop_spot ();
1916 if (!THIS->lexer_p_->chord_state_b ())
1917 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
1924 steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
1925 $$ = Chord::get_chord ($1, $3, $4, $5, $6, $2);
1926 $$->set_spot (THIS->here_input ());
1933 | CHORD_COLON chord_notes {
1942 | chord_notes '.' chord_step {
1943 $$ = gh_append2 ($$, $3);
1951 | CHORD_CARET chord_notes {
1961 | '/' steno_tonic_pitch {
1970 | CHORD_BASS steno_tonic_pitch {
1977 $$ = gh_cons ($1, SCM_EOL);
1979 | CHORDMODIFIER_PITCH {
1980 $$ = gh_cons (unsmob_pitch ($1)->smobbed_copy (), SCM_EOL);
1982 | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
1983 $$ = scm_list_n (unsmob_pitch ($1)->smobbed_copy (),
1991 m.notename_i_ = ($1 - 1) % 7;
1992 m.octave_i_ = $1 > 7 ? 1 : 0;
1993 m.alteration_i_ = 0;
1995 $$ = m.smobbed_copy ();
1997 | bare_unsigned '+' {
1999 m.notename_i_ = ($1 - 1) % 7;
2000 m.octave_i_ = $1 > 7 ? 1 : 0;
2001 m.alteration_i_ = 1;
2004 $$ = m.smobbed_copy ();
2006 | bare_unsigned CHORD_MINUS {
2008 m.notename_i_ = ($1 - 1) % 7;
2009 m.octave_i_ = $1 > 7 ? 1 : 0;
2010 m.alteration_i_ = -1;
2012 $$ = m.smobbed_copy ();
2020 number_expression '+' number_term {
2021 $$ = scm_sum ($1, $3);
2023 | number_expression '-' number_term {
2024 $$ = scm_difference ($1, $3);
2033 | number_factor '*' number_factor {
2034 $$ = scm_product ($1, $3);
2036 | number_factor '/' number_factor {
2037 $$ = scm_divide ($1, $3);
2042 '(' number_expression ')' {
2045 | '-' number_factor { /* %prec UNARY_MINUS */
2046 $$ = scm_difference ($2, SCM_UNDEFINED);
2054 $$ = gh_int2scm ($1);
2059 | NUMBER_IDENTIFIER {
2063 $$ = gh_double2scm (gh_scm2double ($1) CM );
2066 $$ = gh_double2scm (gh_scm2double ($1) PT);
2069 $$ = gh_double2scm (gh_scm2double ($1) INCH);
2072 $$ = gh_double2scm (gh_scm2double ($1) MM);
2075 $$ = gh_double2scm (gh_scm2double ($1) CHAR);
2091 if (scm_integer_p ($1) == SCM_BOOL_T)
2093 int k = gh_scm2int ($1);
2097 THIS->parser_error (_ ("need integer number arg"));
2111 | STRING_IDENTIFIER {
2114 | string '+' string {
2115 $$ = scm_string_append (scm_list_n ($1, $3, SCM_UNDEFINED));
2122 | exclamations '!' { $$ ++; }
2127 | questions '?' { $$ ++; }
2134 My_lily_parser::set_yydebug (bool )
2141 extern My_lily_parser * current_parser;
2144 My_lily_parser::do_yyparse ()
2147 current_parser = this;;
2148 yyparse ((void*)this);
2153 Should make this optional? It will also complain when you do
2157 which is entirely legitimate.
2159 Or we can scrap it. Barchecks should detect wrong durations, and
2160 skipTypesetting speeds it up a lot.
2163 My_lily_parser::beam_check (SCM dur)
2165 Duration *d = unsmob_duration (dur);
2166 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2168 Music * m = unsmob_music (last_beam_start_);
2169 m->origin ()->warning (_("Suspect duration found following this beam"));
2171 last_beam_start_ = SCM_EOL;