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
28 #include "translator-def.hh"
29 #include "lily-guile.hh"
31 #include "my-lily-lexer.hh"
32 #include "paper-def.hh"
33 #include "midi-def.hh"
35 #include "file-path.hh"
37 #include "dimensions.hh"
38 #include "my-lily-parser.hh"
40 #include "input-file-results.hh"
42 #include "lilypond-input-version.hh"
43 #include "scm-hash.hh"
44 #include "auto-change-iterator.hh"
46 #include "ly-modules.hh"
47 #include "music-sequence.hh"
48 #include "input-smob.hh"
52 regular_identifier_b (SCM id)
54 String str = ly_scm2string (id);
55 char const *s = str.to_str0 () ;
60 v = v && isalpha (*s);
71 return t && t == 1 << intlog2 (t);
75 set_music_properties (Music *p, SCM a)
77 for (SCM k = a; gh_pair_p (k); k = ly_cdr (k))
79 p->internal_set_mus_property (ly_caar (k), ly_cdar (k));
85 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
88 set_property_music (SCM sym, SCM value)
90 Music * p = MY_MAKE_MUSIC("PropertySet");
91 p->set_mus_property ("symbol", sym);
92 p->set_mus_property ("value", value);
97 // needed for bison.simple's malloc () and free ()
99 // #include <malloc.h>
104 #define YYERROR_VERBOSE 1
106 My_lily_parser* my_lily_parser;
107 #define YYPARSE_PARAM my_lily_parser
108 #define YYLEX_PARAM my_lily_parser
110 ((My_lily_parser *) my_lily_parser)
112 #define yyerror THIS->parser_error
116 /* We use SCMs to do strings, because it saves us the trouble of
117 deleting them. Let's hope that a stack overflow doesnt trigger a move
118 of the parse stack onto the heap. */
123 Link_array<Music> *reqvec;
125 String *string; // needed by the lexer as temporary scratch area.
128 Music_output_def * outputdef;
135 yylex (YYSTYPE *s, void * v)
137 My_lily_parser *pars = (My_lily_parser*) v;
138 My_lily_lexer * lex = pars->lexer_;
140 lex->lexval = (void*) s;
141 lex->prepare_for_next_token();
142 return lex->yylex ();
150 /* tokens which are not keywords */
158 %token CHORDMODIFIERS
166 %token GROBDESCRIPTIONS
171 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
172 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
181 %token MULTI_MEASURE_REST
193 %token OVERRIDE SET REVERT
204 %token COMMANDSPANREQUEST
206 %token OUTPUTPROPERTY
217 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
218 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
220 %token <i> E_UNSIGNED
221 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
224 %type <i> exclamations questions dots optional_rest
225 %type <i> bass_number bass_mod
226 %type <scm> br_bass_figure bass_figure figure_list figure_spec
228 %token <scm> NOTENAME_PITCH
229 %token <scm> TONICNAME_PITCH
230 %token <scm> CHORDMODIFIER_PITCH
231 %token <scm> DURATION_IDENTIFIER
232 %token <scm> FRACTION
233 %token <id> IDENTIFIER
236 %token <scm> SCORE_IDENTIFIER
237 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
238 %token <scm> NUMBER_IDENTIFIER
239 %token <scm> EVENT_IDENTIFIER
240 %token <scm> MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
241 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
242 %token <scm> RESTNAME
248 %type <outputdef> output_def
249 %type <scm> lilypond_header lilypond_header_body
250 %type <music> open_event_parens close_event_parens open_event close_event
251 %type <music> event_with_dir event_that_take_dir verbose_event
252 %type <i> sub_quotes sup_quotes
253 %type <music> simple_element event_chord command_element Simple_music Composite_music
254 %type <music> Repeated_music
255 %type <scm> Alternative_music
256 %type <i> tremolo_type
257 %type <i> bare_int bare_unsigned
259 %type <scm> identifier_init
261 %type <scm> steno_duration optional_notemode_duration multiplied_duration
262 %type <scm> verbose_duration
264 %type <reqvec> pre_events post_events
265 %type <music> gen_text_def
266 %type <scm> steno_pitch pitch absolute_pitch
267 %type <scm> explicit_pitch steno_tonic_pitch
269 %type <scm> chord_additions chord_subtractions chord_notes chord_step
271 %type <scm> chord_note chord_inversion chord_bass
272 %type <scm> duration_length fraction
274 %type <scm> embedded_scm scalar
275 %type <music> Music Sequential_music Simultaneous_music
276 %type <music> relative_music re_rhythmed_music part_combined_music
277 %type <music> property_def translator_change simple_property_def
278 %type <scm> Music_list
279 %type <outputdef> music_output_def_body
280 %type <music> shorthand_command_req
281 %type <music> post_event
282 %type <music> command_req verbose_command_req
283 %type <music> extender_req
284 %type <music> hyphen_req
285 %type <music> string_event
286 %type <scm> string bare_number number_expression number_term number_factor
288 %type <score> score_block score_body
290 %type <scm> translator_spec_block translator_spec_body
291 %type <music> tempo_event
292 %type <scm> notenames_body notenames_block chordmodifiers_block
293 %type <scm> script_abbreviation
299 /* We don't assign precedence to / and *, because we might need varied
300 prec levels in different prods */
306 lilypond: /* empty */
307 | lilypond toplevel_expression {}
308 | lilypond assignment { }
310 THIS->error_level_ = 1;
313 THIS->error_level_ = 1;
319 THIS->lexer_->pitchname_tab_ = $1;
321 | chordmodifiers_block {
322 THIS->lexer_->chordmodifier_tab_ = $1;
325 THIS->input_file_->header_ = $1;
328 THIS->input_file_->scores_.push ($1);
331 if (dynamic_cast<Paper_def*> ($1))
332 THIS->lexer_->set_identifier (scm_makfrom0str ("$defaultpaper"), $1->self_scm ());
333 else if (dynamic_cast<Midi_def*> ($1))
334 THIS->lexer_->set_identifier (scm_makfrom0str ("$defaultmidi"), $1->self_scm ());
344 chordmodifiers_block:
345 CHORDMODIFIERS notenames_body { $$ = $2; }
349 PITCHNAMES notenames_body { $$ = $2; }
354 int i = scm_ilength ($1);
356 SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
357 for (SCM s = $1; gh_pair_p (s); s = ly_cdr (s)) {
358 SCM pt = ly_cdar (s);
359 if (!unsmob_pitch (pt))
360 THIS->parser_error ("Need pitch object.");
362 scm_hashq_set_x (tab, ly_caar (s), pt);
369 lilypond_header_body:
371 $$ = ly_make_anonymous_module ();
372 THIS->lexer_->add_scope ($$);
374 | lilypond_header_body assignment {
380 HEADER '{' lilypond_header_body '}' {
381 $$ = THIS->lexer_-> remove_scope();
393 /* cont */ '=' identifier_init {
396 Should find generic way of associating input with objects.
398 Input ip = THIS->pop_spot ();
400 if (! regular_identifier_b ($1))
402 ip.warning (_ ("Identifier should have alphabetic characters only"));
405 THIS->lexer_->set_identifier ($1, $4);
408 TODO: devise standard for protection in parser.
410 The parser stack lives on the C-stack, which means that
411 all objects can be unprotected as soon as they're here.
422 $$ = $1->self_scm ();
423 scm_gc_unprotect_object ($$);
426 $$ = $1->self_scm ();
427 scm_gc_unprotect_object ($$);
429 | translator_spec_block {
433 $$ = $1->self_scm ();
434 scm_gc_unprotect_object ($$);
437 $$ = $1->self_scm ();
438 scm_gc_unprotect_object ($$);
443 | number_expression {
454 translator_spec_block:
455 TRANSLATOR '{' translator_spec_body '}'
461 translator_spec_body:
462 TRANSLATOR_IDENTIFIER {
464 unsmob_translator_def ($$)-> set_spot (THIS->here_input ());
467 $$ = Translator_def::make_scm ();
468 Translator_def*td = unsmob_translator_def ($$);
469 td->translator_group_type_ = $2;
470 td->set_spot (THIS->here_input ());
472 | translator_spec_body STRING '=' embedded_scm {
473 unsmob_translator_def ($$)->add_property_assign ($2, $4);
475 | translator_spec_body STRING OVERRIDE embedded_scm '=' embedded_scm {
476 unsmob_translator_def ($$)
477 ->add_push_property (scm_string_to_symbol ($2), $4, $6);
479 | translator_spec_body STRING SET embedded_scm '=' embedded_scm {
480 unsmob_translator_def ($$)
481 ->add_push_property (scm_string_to_symbol ($2), $4, $6);
483 | translator_spec_body STRING REVERT embedded_scm {
484 unsmob_translator_def ($$)->add_pop_property (
485 scm_string_to_symbol ($2), $4);
487 | translator_spec_body NAME STRING {
488 unsmob_translator_def ($$)->type_name_ = $3;
490 | translator_spec_body CONSISTS STRING {
491 unsmob_translator_def ($$)->add_element ($3);
493 | translator_spec_body ALIAS STRING {
494 Translator_def*td = unsmob_translator_def ($$);
495 td->type_aliases_ = scm_cons ($3, td->type_aliases_);
497 | translator_spec_body GROBDESCRIPTIONS embedded_scm {
498 Translator_def*td = unsmob_translator_def($$);
499 // td->add_property_assign (ly_symbol2scm ("allGrobDescriptions"), $3);
500 for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p))
501 td->add_property_assign (scm_symbol_to_string (ly_caar (p)), ly_cdar (p));
503 | translator_spec_body CONSISTSEND STRING {
504 unsmob_translator_def ($$)->add_last_element ( $3);
506 | translator_spec_body ACCEPTS STRING {
507 unsmob_translator_def ($$)->set_acceptor ($3,true);
509 | translator_spec_body DENIES STRING {
510 unsmob_translator_def ($$)->set_acceptor ($3,false);
512 | translator_spec_body REMOVE STRING {
513 unsmob_translator_def ($$)->remove_element ($3);
524 /*cont*/ '{' score_body '}' {
527 if (!$$->defs_.size ())
529 Music_output_def *id =
530 unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"));
531 $$->add_output (id ? id->clone () : new Paper_def );
540 $$->set_spot (THIS->here_input ());
541 SCM m = $1->self_scm ();
542 scm_gc_unprotect_object (m);
547 SCM check_funcs = scm_c_eval_string ("toplevel-music-functions");
548 for (; gh_pair_p (check_funcs); check_funcs = gh_cdr (check_funcs))
549 m = gh_call1 (gh_car (check_funcs), m);
554 $$ = unsmob_score ($1);
555 $$->set_spot (THIS->here_input ());
557 | score_body lilypond_header {
560 | score_body output_def {
573 music_output_def_body '}' {
575 THIS-> lexer_-> remove_scope ();
579 music_output_def_body:
581 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultmidi"));
586 p = dynamic_cast<Midi_def*> (id->clone ());
591 THIS->lexer_->add_scope (p->scope_);
594 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"));
597 p = dynamic_cast<Paper_def*> (id->clone ());
601 THIS->lexer_->add_scope (p->scope_);
604 | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
605 Music_output_def * o = unsmob_music_output_def ($3);
608 THIS->lexer_->add_scope (o->scope_);
610 | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
611 Music_output_def * o = unsmob_music_output_def ($3);
614 THIS->lexer_->add_scope (o->scope_);
616 | music_output_def_body assignment {
619 | music_output_def_body translator_spec_block {
620 $$->assign_translator ($2);
622 | music_output_def_body tempo_event {
624 junk this ? there already is tempo stuff in
627 int m = gh_scm2int ( $2->get_mus_property ("metronome-count"));
628 Duration *d = unsmob_duration ($2->get_mus_property ("duration"));
629 Midi_def * md = dynamic_cast<Midi_def*> ($$);
631 md->set_tempo (d->get_length (), m);
633 | music_output_def_body error {
639 TEMPO steno_duration '=' bare_unsigned {
640 $$ = MY_MAKE_MUSIC("TempoEvent");
641 $$->set_mus_property ("duration", $2);
642 $$->set_mus_property ("metronome-count", gh_int2scm ( $4));
647 The representation of a list is the
651 to have efficient append.
653 Music_list: /* empty */ {
654 $$ = scm_cons (SCM_EOL, SCM_EOL);
658 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
659 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
660 if (gh_pair_p (ly_cdr (s)))
661 gh_set_cdr_x (ly_cdr (s), c); /* append */
663 gh_set_car_x (s, c); /* set first cons */
664 gh_set_cdr_x (s, c) ; /* remember last cell */
680 | ALTERNATIVE '{' Music_list '}' {
686 REPEAT string bare_unsigned Music Alternative_music
690 SCM alts = gh_pair_p ($5) ? gh_car ($5) : SCM_EOL;
691 if (times < scm_ilength (alts)) {
692 unsmob_music (gh_car (alts))
693 ->origin ()->warning (
694 _("More alternatives than repeats. Junking excess alternatives."));
695 alts = ly_truncate_list (times, alts);
701 proc = scm_c_eval_string ("make-repeated-music");
703 SCM mus = scm_call_1 (proc, $2);
704 scm_gc_protect_object (mus); // UGH.
705 Music *r =unsmob_music (mus);
708 r-> set_mus_property ("element", beg->self_scm ());
709 scm_gc_unprotect_object (beg->self_scm ());
711 r->set_mus_property ("repeat-count", gh_int2scm (times >? 1));
713 r-> set_mus_property ("elements",alts);
714 if (gh_equal_p ($2, scm_makfrom0str ("tremolo")))
717 we can not get durations and other stuff correct down the line, so we have to
718 add to the duration log here.
720 SCM func = scm_primitive_eval (ly_symbol2scm ("shift-duration-log"));
722 gh_call3 (func, r->self_scm (), gh_int2scm(-intlog2 ($3*2/3)),gh_int2scm(1));
724 gh_call3 (func, r->self_scm (), gh_int2scm(-intlog2 ($3)), gh_int2scm(0));
726 r->set_spot (*$4->origin ());
733 SEQUENTIAL '{' Music_list '}' {
734 $$ = MY_MAKE_MUSIC("SequentialMusic");
735 $$->set_mus_property ("elements", ly_car ($3));
736 $$->set_spot(THIS->here_input());
738 | '{' Music_list '}' {
739 $$ = MY_MAKE_MUSIC("SequentialMusic");
740 $$->set_mus_property ("elements", ly_car ($2));
741 $$->set_spot(THIS->here_input());
746 SIMULTANEOUS '{' Music_list '}'{
747 $$ = MY_MAKE_MUSIC("SimultaneousMusic");
748 $$->set_mus_property ("elements", ly_car ($3));
749 $$->set_spot(THIS->here_input());
752 | '<' Music_list '>' {
753 $$ = MY_MAKE_MUSIC("SimultaneousMusic");
754 $$->set_mus_property ("elements", ly_car ($2));
755 $$->set_spot(THIS->here_input());
760 event_chord { $$ = $1; }
761 | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm {
763 if (!gh_symbol_p ($3))
765 THIS->parser_error (_ ("Second argument must be a symbol"));
767 /* Should check # args */
768 if (!gh_procedure_p (pred))
770 THIS->parser_error (_ ("First argument must be a procedure taking one argument"));
773 Music*m = MY_MAKE_MUSIC("OutputPropertySetMusic");
774 m->set_mus_property ("predicate", pred);
775 m->set_mus_property ("grob-property", $3);
776 m->set_mus_property ("grob-value", $5);
781 $$ = unsmob_music ($1);
789 CONTEXT STRING Music {
790 Music*csm =MY_MAKE_MUSIC("ContextSpeccedMusic");
792 csm->set_mus_property ("element", $3->self_scm ());
793 scm_gc_unprotect_object ($3->self_scm ());
795 csm->set_mus_property ("context-type",$2);
796 csm->set_mus_property ("context-id", scm_makfrom0str (""));
800 | AUTOCHANGE STRING Music {
801 Music*chm = MY_MAKE_MUSIC("AutoChangeMusic");
802 chm->set_mus_property ("element", $3->self_scm ());
803 chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_proc);
805 scm_gc_unprotect_object ($3->self_scm ());
806 chm->set_mus_property ("what", $2);
809 chm->set_spot (*$3->origin ());
814 The other version is for easier debugging of
815 Sequential_music_iterator in combination with grace notes.
818 SCM start = THIS->lexer_->lookup_identifier ("startGraceMusic");
819 SCM stop = THIS->lexer_->lookup_identifier ("stopGraceMusic");
820 Music *startm = unsmob_music (start);
821 Music *stopm = unsmob_music (stop);
825 stopm = stopm->clone ();
826 ms = scm_cons (stopm->self_scm (), ms);
827 scm_gc_unprotect_object (stopm->self_scm ());
829 ms = scm_cons ($2->self_scm (), ms);
830 scm_gc_unprotect_object ($2->self_scm());
832 startm = startm->clone ();
833 ms = scm_cons (startm->self_scm () , ms);
834 scm_gc_unprotect_object (startm->self_scm ());
838 Music* seq = MY_MAKE_MUSIC("SequentialMusic");
839 seq->set_mus_property ("elements", ms);
842 $$ = MY_MAKE_MUSIC("GraceMusic");
843 $$->set_mus_property ("element", seq->self_scm ());
844 scm_gc_unprotect_object (seq->self_scm ());
846 $$ = MY_MAKE_MUSIC("GraceMusic");
847 $$->set_mus_property ("element", $2->self_scm ());
848 scm_gc_unprotect_object ($2->self_scm ());
851 | CONTEXT string '=' string Music {
852 Music * csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
854 csm->set_mus_property ("element", $5->self_scm ());
855 scm_gc_unprotect_object ($5->self_scm ());
857 csm->set_mus_property ("context-type", $2);
858 csm->set_mus_property ("context-id", $4);
869 int n = gh_scm2int (ly_car ($3)); int d = gh_scm2int (ly_cdr ($3));
871 $$= MY_MAKE_MUSIC("TimeScaledMusic");
872 $$->set_spot (THIS->pop_spot ());
875 $$->set_mus_property ("element", mp->self_scm ());
876 scm_gc_unprotect_object (mp->self_scm ());
877 $$->set_mus_property ("numerator", gh_int2scm (n));
878 $$->set_mus_property ("denominator", gh_int2scm (d));
879 $$->compress (Moment (Rational (n,d)));
882 | Repeated_music { $$ = $1; }
883 | Simultaneous_music { $$ = $1; }
884 | Sequential_music { $$ = $1; }
885 | TRANSPOSE pitch Music {
886 $$ = MY_MAKE_MUSIC("TransposedMusic");
888 Pitch pit = *unsmob_pitch ($2);
891 $$->set_mus_property ("element", p->self_scm ());
892 scm_gc_unprotect_object (p->self_scm ());
894 | TRANSPOSE steno_tonic_pitch Music {
895 $$ = MY_MAKE_MUSIC("TransposedMusic");
897 Pitch pit = *unsmob_pitch ($2);
900 $$->set_mus_property ("element", p->self_scm ());
901 scm_gc_unprotect_object (p->self_scm ());
904 | APPLY embedded_scm Music {
905 SCM ret = gh_call1 ($2, $3->self_scm ());
906 Music *m = unsmob_music (ret);
908 THIS->parser_error ("\\apply must return a Music");
909 m = MY_MAKE_MUSIC("Music");
914 { THIS->lexer_->push_note_state (); }
917 THIS->lexer_->pop_state ();
920 { THIS->lexer_->push_figuredbass_state (); }
923 Music * chm = MY_MAKE_MUSIC("UntransposableMusic");
924 chm->set_mus_property ("element", $3->self_scm ());
926 scm_gc_unprotect_object ($3->self_scm());
928 THIS->lexer_->pop_state ();
931 { THIS->lexer_->push_chord_state (); }
934 Music * chm = MY_MAKE_MUSIC("UnrelativableMusic");
935 chm->set_mus_property ("element", $3->self_scm ());
936 scm_gc_unprotect_object ($3->self_scm());
939 THIS->lexer_->pop_state ();
942 { THIS->lexer_->push_lyric_state (); }
946 THIS->lexer_->pop_state ();
948 | relative_music { $$ = $1; }
949 | re_rhythmed_music { $$ = $1; }
950 | part_combined_music { $$ = $1; }
954 RELATIVE absolute_pitch Music {
956 Pitch pit = *unsmob_pitch ($2);
957 $$ = MY_MAKE_MUSIC("RelativeOctaveMusic");
959 $$->set_mus_property ("element", p->self_scm ());
960 scm_gc_unprotect_object (p->self_scm ());
962 $$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ());
968 ADDLYRICS Music Music {
969 Music*l =MY_MAKE_MUSIC("LyricCombineMusic");
970 l->set_mus_property ("elements", gh_list ($2->self_scm (), $3->self_scm (), SCM_UNDEFINED));
971 scm_gc_unprotect_object ($3->self_scm ());
972 scm_gc_unprotect_object ($2->self_scm ());
978 PARTCOMBINE STRING Music Music {
979 Music * p= MY_MAKE_MUSIC("PartCombineMusic");
980 p->set_mus_property ("what", $2);
981 p->set_mus_property ("elements", gh_list ($3->self_scm (),$4->self_scm (), SCM_UNDEFINED));
983 scm_gc_unprotect_object ($3->self_scm ());
984 scm_gc_unprotect_object ($4->self_scm ());
991 TRANSLATOR STRING '=' STRING {
992 Music*t= MY_MAKE_MUSIC("TranslatorChange");
993 t-> set_mus_property ("change-to-type", $2);
994 t-> set_mus_property ("change-to-id", $4);
997 $$->set_spot (THIS->here_input ());
1003 | ONCE simple_property_def {
1005 SCM e = $2->get_mus_property ("element");
1006 unsmob_music (e)->set_mus_property ("once", SCM_BOOL_T);
1010 simple_property_def:
1011 PROPERTY STRING '.' STRING '=' scalar {
1012 Music *t = set_property_music (scm_string_to_symbol ($4), $6);
1013 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1015 csm->set_mus_property ("element", t->self_scm ());
1016 scm_gc_unprotect_object (t->self_scm ());
1019 $$->set_spot (THIS->here_input ());
1021 csm-> set_mus_property ("context-type", $2);
1023 | PROPERTY STRING '.' STRING UNSET {
1025 Music *t = MY_MAKE_MUSIC("PropertyUnset");
1026 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1028 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1029 csm->set_mus_property ("element", t->self_scm ());
1030 scm_gc_unprotect_object (t->self_scm ());
1033 $$->set_spot (THIS->here_input ());
1035 csm-> set_mus_property ("context-type", $2);
1037 | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm {
1039 = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings"));
1040 bool itc = internal_type_checking_global_b;
1041 Music *t = MY_MAKE_MUSIC("OverrideProperty");
1042 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1043 t->set_mus_property ("pop-first", SCM_BOOL_T);
1045 internal_type_checking_global_b = false;
1046 t->set_mus_property ("grob-property", $6);
1048 internal_type_checking_global_b = itc;
1049 t->set_mus_property ("grob-value", $8);
1051 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1052 csm->set_mus_property ("element", t->self_scm ());
1053 scm_gc_unprotect_object (t->self_scm ());
1055 $$->set_spot (THIS->here_input ());
1057 csm-> set_mus_property ("context-type", $2);
1059 | PROPERTY STRING '.' STRING OVERRIDE
1060 embedded_scm '=' embedded_scm
1066 = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings"));
1067 bool itc = internal_type_checking_global_b;
1069 Music *t = MY_MAKE_MUSIC("OverrideProperty");
1070 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1072 internal_type_checking_global_b = false;
1073 t->set_mus_property ("grob-property", $6);
1074 t->set_mus_property ("grob-value", $8);
1076 internal_type_checking_global_b = itc;
1078 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1079 csm->set_mus_property ("element", t->self_scm ());
1080 scm_gc_unprotect_object (t->self_scm ());
1083 $$->set_spot (THIS->here_input ());
1085 csm-> set_mus_property ("context-type", $2);
1088 | PROPERTY STRING '.' STRING REVERT embedded_scm {
1089 Music *t = MY_MAKE_MUSIC("RevertProperty");
1091 = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings"));
1092 bool itc = internal_type_checking_global_b;
1094 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1096 internal_type_checking_global_b = false;
1097 t->set_mus_property ("grob-property", $6);
1099 internal_type_checking_global_b = itc;
1101 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1102 csm->set_mus_property ("element", t->self_scm ());
1103 scm_gc_unprotect_object (t->self_scm ());
1106 $$->set_spot (THIS->here_input ());
1108 csm-> set_mus_property ("context-type", $2);
1115 | bare_int { $$ = gh_int2scm ($1); }
1116 | embedded_scm { $$ = $1; }
1123 } /*cont */ simple_element post_events {
1124 Music_sequence *l = dynamic_cast<Music_sequence*> ($3);
1127 for (int i=0; i < $1->size (); i++) {
1128 Music * m = $1->elem (i);
1129 l->append_music (m);
1141 $$ = MY_MAKE_MUSIC("EventChord");
1142 $$->set_mus_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1143 scm_gc_unprotect_object ($1->self_scm());
1145 $$-> set_spot (THIS->here_input ());
1146 $1-> set_spot (THIS->here_input ());
1149 Music *l = MY_MAKE_MUSIC("LigatureEvent");
1150 l->set_mus_property ("span-direction", gh_int2scm (START));
1151 l->set_spot (THIS->here_input ());
1153 $$ = MY_MAKE_MUSIC("EventChord");
1154 $$->set_mus_property ("elements", scm_cons (l->self_scm (), SCM_EOL));
1155 scm_gc_unprotect_object (l->self_scm());
1156 $$->set_spot (THIS->here_input ());
1159 Music *l = MY_MAKE_MUSIC("LigatureEvent");
1160 l->set_mus_property ("span-direction", gh_int2scm (STOP));
1161 l->set_spot (THIS->here_input ());
1163 $$ = MY_MAKE_MUSIC("EventChord");
1164 $$->set_mus_property ("elements", scm_cons (l->self_scm (), SCM_EOL));
1165 $$->set_spot (THIS->here_input ());
1166 scm_gc_unprotect_object (l->self_scm());
1170 $$ = MY_MAKE_MUSIC("VoiceSeparator");
1171 $$->set_spot (THIS->here_input ());
1175 $$ = MY_MAKE_MUSIC("BarCheck");
1176 $$->set_spot (THIS->here_input ());
1179 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1181 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1182 csm->set_mus_property ("element", t->self_scm ());
1183 scm_gc_unprotect_object (t->self_scm ());
1186 $$->set_spot (THIS->here_input ());
1188 csm->set_mus_property ("context-type", scm_makfrom0str ("Timing"));
1190 | PARTIAL duration_length {
1191 Moment m = - unsmob_duration ($2)->get_length ();
1192 Music * p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1194 Music * sp = MY_MAKE_MUSIC("ContextSpeccedMusic");
1195 sp->set_mus_property ("element", p->self_scm ());
1196 scm_gc_unprotect_object (p->self_scm ());
1199 sp-> set_mus_property ("context-type", scm_makfrom0str ("Timing"));
1204 proc = scm_c_eval_string ("make-clef-set");
1206 SCM result = scm_call_1 (proc, $2);
1207 scm_gc_protect_object (result);
1208 $$ = unsmob_music (result);
1211 Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2);
1213 int l = gh_scm2int (ly_car ($2));
1214 int o = gh_scm2int (ly_cdr ($2));
1216 Moment one_beat = Moment (1)/Moment (o);
1217 Moment len = Moment (l) * one_beat;
1220 Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ());
1221 Music *p3 = set_property_music (ly_symbol2scm ("beatLength"), one_beat.smobbed_copy ());
1223 SCM list = scm_list_n (p1->self_scm (), p2->self_scm (), p3->self_scm(), SCM_UNDEFINED);
1224 Music *seq = MY_MAKE_MUSIC("SequentialMusic");
1225 seq->set_mus_property ("elements", list);
1228 Music * sp = MY_MAKE_MUSIC("ContextSpeccedMusic");
1229 sp->set_mus_property ("element", seq->self_scm ());
1231 scm_gc_unprotect_object (p3->self_scm ());
1232 scm_gc_unprotect_object (p2->self_scm ());
1233 scm_gc_unprotect_object (p1->self_scm ());
1234 scm_gc_unprotect_object (seq->self_scm ());
1238 sp-> set_mus_property ("context-type", scm_makfrom0str ( "Timing"));
1243 shorthand_command_req { $$ = $1; }
1244 | verbose_command_req { $$ = $1; }
1247 shorthand_command_req:
1255 $$ = MY_MAKE_MUSIC("TieEvent");
1258 Music *b= MY_MAKE_MUSIC("BeamEvent");
1259 b->set_mus_property ("span-direction", gh_int2scm (START))
1264 THIS->last_beam_start_ = b->self_scm ();
1267 Music *b= MY_MAKE_MUSIC("BeamEvent");
1268 b->set_mus_property ("span-direction", gh_int2scm (STOP));
1272 $$ = MY_MAKE_MUSIC("BreathingSignEvent");
1275 $$ = MY_MAKE_MUSIC("PorrectusEvent");
1279 verbose_command_req:
1281 Music * m = MY_MAKE_MUSIC("MarkEvent");
1285 Music *m = MY_MAKE_MUSIC("MarkEvent");
1286 m->set_mus_property ("label", $2);
1289 | SKIP duration_length {
1290 Music * skip = MY_MAKE_MUSIC("SkipEvent");
1291 skip->set_mus_property ("duration", $2);
1299 Music *key= MY_MAKE_MUSIC("KeyChangeEvent");
1302 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1303 Music *key= MY_MAKE_MUSIC("KeyChangeEvent");
1305 key->set_mus_property ("pitch-alist", $3);
1306 ((Music*)key)->transpose (* unsmob_pitch ($2));
1313 $$ = new Link_array<Music>;
1315 | post_events post_event {
1316 $2->set_spot (THIS->here_input ());
1330 Music * s = MY_MAKE_MUSIC("StringNumberEvent");
1331 s->set_mus_property ("string-number", gh_int2scm($1));
1332 s->set_spot (THIS->here_input ());
1338 event_that_take_dir:
1343 | script_abbreviation {
1344 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1345 Music *a = MY_MAKE_MUSIC("ArticulationEvent");
1346 if (gh_string_p (s))
1347 a->set_mus_property ("articulation-type", s);
1348 else THIS->parser_error (_ ("Expecting string as script definition"));
1354 script_dir event_that_take_dir {
1355 $2->set_mus_property ("direction", gh_int2scm ($1));
1362 $$ = unsmob_music ($1);
1365 Music * a = MY_MAKE_MUSIC("TremoloEvent");
1366 a->set_spot (THIS->here_input ());
1367 a->set_mus_property ("tremolo-type", gh_int2scm ($1));
1394 | NOTENAME_PITCH sup_quotes {
1395 Pitch p = *unsmob_pitch ($1);
1397 $$ = p.smobbed_copy ();
1399 | NOTENAME_PITCH sub_quotes {
1400 Pitch p =* unsmob_pitch ($1);
1403 $$ = p.smobbed_copy ();
1416 | TONICNAME_PITCH sup_quotes {
1417 Pitch p = *unsmob_pitch ($1);
1419 $$ = p.smobbed_copy ();
1421 | TONICNAME_PITCH sub_quotes {
1422 Pitch p =* unsmob_pitch ($1);
1425 $$ = p.smobbed_copy ();
1440 PITCH embedded_scm {
1442 if (!unsmob_pitch ($2)) {
1443 THIS->parser_error (_f ("Expecting musical-pitch value", 3));
1444 $$ = Pitch ().smobbed_copy ();
1450 DURATION embedded_scm {
1452 if (!unsmob_duration ($2))
1454 THIS->parser_error (_ ("Must have duration object"));
1455 $$ = Duration ().smobbed_copy ();
1462 if (!THIS->lexer_->lyric_state_b ())
1463 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1464 $$ = MY_MAKE_MUSIC("ExtenderEvent");
1470 if (!THIS->lexer_->lyric_state_b ())
1471 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1472 $$ = MY_MAKE_MUSIC("HyphenEvent");
1477 close_event_parens {
1479 dynamic_cast<Music *> ($$)->set_mus_property ("span-direction", gh_int2scm (START))
1486 Music * s= MY_MAKE_MUSIC("SlurEvent");
1488 s->set_spot (THIS->here_input());
1491 Music * s= MY_MAKE_MUSIC("PhrasingSlurEvent");
1493 s->set_spot (THIS->here_input());
1496 Music *s =MY_MAKE_MUSIC("CrescendoEvent");
1498 s->set_spot (THIS->here_input());
1501 Music *s =MY_MAKE_MUSIC("DecrescendoEvent");
1503 s->set_spot (THIS->here_input());
1511 dynamic_cast<Music *> ($$)->set_mus_property ("span-direction", gh_int2scm (STOP))
1518 Music *s = MY_MAKE_MUSIC("CrescendoEvent");
1519 s->set_spot (THIS->here_input());
1524 Music * s= MY_MAKE_MUSIC("SlurEvent");
1526 s->set_spot (THIS->here_input());
1530 Music * s= MY_MAKE_MUSIC("PhrasingSlurEvent");
1532 s->set_mus_property ("span-type", scm_makfrom0str ( "phrasing-slur"));
1533 s->set_spot (THIS->here_input());
1539 Music *t = MY_MAKE_MUSIC("TextScriptEvent");
1540 t->set_mus_property ("text", $1);
1541 t->set_spot (THIS->here_input ());
1545 Music *t = MY_MAKE_MUSIC("TextScriptEvent");
1546 t->set_mus_property ("text", $1);
1547 t->set_spot (THIS->here_input ());
1551 String ds = to_string ($1);
1552 Music * t = MY_MAKE_MUSIC("TextScriptEvent");
1553 SCM finger = ly_symbol2scm ("finger");
1554 t->set_mus_property ("text", scm_makfrom0str (ds.to_str0 ()));
1555 t->set_mus_property ("text-type" , finger);
1556 t->set_spot (THIS->here_input ());
1561 script_abbreviation:
1563 $$ = scm_makfrom0str ("Hat");
1566 $$ = scm_makfrom0str ("Plus");
1569 $$ = scm_makfrom0str ("Dash");
1572 $$ = scm_makfrom0str ("Bar");
1575 $$ = scm_makfrom0str ("Larger");
1578 $$ = scm_makfrom0str ("Dot");
1581 $$ = scm_makfrom0str ("Underscore");
1588 | '-' { $$ = CENTER; }
1593 $$ = new Link_array<Music>;
1595 | pre_events open_event {
1607 multiplied_duration {
1610 | verbose_duration {
1615 optional_notemode_duration:
1617 Duration dd = THIS->default_duration_;
1618 $$ = dd.smobbed_copy ();
1620 THIS->beam_check ($$);
1622 | multiplied_duration {
1624 THIS->default_duration_ = *unsmob_duration ($$);
1626 THIS->beam_check ($$);
1628 | verbose_duration {
1630 THIS->default_duration_ = *unsmob_duration ($$);
1635 bare_unsigned dots {
1637 if (!is_duration_b ($1))
1638 THIS->parser_error (_f ("not a duration: %d", $1));
1642 $$ = Duration (l, $2).smobbed_copy ();
1644 | DURATION_IDENTIFIER dots {
1645 Duration *d =unsmob_duration ($1);
1646 Duration k (d->duration_log (),d->dot_count () + $2);
1656 multiplied_duration:
1660 | multiplied_duration '*' bare_unsigned {
1661 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1663 | multiplied_duration '*' FRACTION {
1664 Rational m (gh_scm2int (ly_car ($3)), gh_scm2int (ly_cdr ($3)));
1666 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
1671 FRACTION { $$ = $1; }
1672 | UNSIGNED '/' UNSIGNED {
1673 $$ = scm_cons (gh_int2scm ($1), gh_int2scm ($3));
1691 | ':' bare_unsigned {
1692 if (!is_duration_b ($2))
1693 THIS->parser_error (_f ("not a duration: %d", $2));
1712 Music *bfr = MY_MAKE_MUSIC("BassFigureEvent");
1713 $$ = bfr->self_scm();
1714 scm_gc_unprotect_object ($$);
1717 Music *bfr = MY_MAKE_MUSIC("BassFigureEvent");
1718 $$ = bfr->self_scm();
1720 bfr->set_mus_property ("figure", gh_int2scm ($1));
1722 scm_gc_unprotect_object ($$);
1724 | bass_figure bass_mod {
1725 Music *m = unsmob_music ($1);
1727 SCM salter =m->get_mus_property ("alteration");
1728 int alter = gh_number_p ( salter) ? gh_scm2int (salter) : 0;
1729 m->set_mus_property ("alteration",
1730 gh_int2scm (alter + $2));
1732 m->set_mus_property ("alteration", gh_int2scm (0));
1740 unsmob_music ($$)->set_mus_property ("bracket-start", SCM_BOOL_T);
1745 | br_bass_figure ']' {
1747 unsmob_music ($1)->set_mus_property ("bracket-stop", SCM_BOOL_T);
1755 | figure_list br_bass_figure {
1756 $$ = scm_cons ($2, $1);
1761 FIGURE_OPEN figure_list FIGURE_CLOSE {
1762 Music * m = MY_MAKE_MUSIC("EventChord");
1763 $2 = scm_reverse_x ($2, SCM_EOL);
1764 m->set_mus_property ("elements", $2);
1765 $$ = m->self_scm ();
1776 pitch exclamations questions optional_notemode_duration optional_rest {
1778 Input i = THIS->pop_spot ();
1779 if (!THIS->lexer_->note_state_b ())
1780 THIS->parser_error (_ ("Have to be in Note mode for notes"));
1784 n = MY_MAKE_MUSIC("RestEvent");
1786 n = MY_MAKE_MUSIC("NoteEvent");
1788 n->set_mus_property ("pitch", $1);
1789 n->set_mus_property ("duration", $4);
1793 n->set_mus_property ("cautionary", SCM_BOOL_T);
1794 if ($2 % 2 || $3 % 2)
1795 n->set_mus_property ("force-accidental", SCM_BOOL_T);
1797 Music *v = MY_MAKE_MUSIC("EventChord");
1798 v->set_mus_property ("elements", scm_list_n (n->self_scm (), SCM_UNDEFINED));
1799 scm_gc_unprotect_object (n->self_scm());
1805 | figure_spec optional_notemode_duration {
1806 Music * m = unsmob_music ($1);
1807 Input i = THIS->pop_spot ();
1809 for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = ly_cdr (s))
1811 unsmob_music (ly_car (s))->set_mus_property ("duration", $2);
1815 | RESTNAME optional_notemode_duration {
1817 Input i = THIS->pop_spot ();
1818 SCM e = SCM_UNDEFINED;
1820 if (ly_scm2string ($1) =="s") {
1822 ev = MY_MAKE_MUSIC("SkipEvent");
1825 ev = MY_MAKE_MUSIC("RestEvent");
1828 ev->set_mus_property ("duration" ,$2);
1830 Music * velt = MY_MAKE_MUSIC("EventChord");
1831 velt->set_mus_property ("elements", scm_list_n (ev->self_scm (),SCM_UNDEFINED));
1836 | MULTI_MEASURE_REST optional_notemode_duration {
1841 proc = scm_c_eval_string ("make-multi-measure-rest");
1843 SCM mus = scm_call_2 (proc, $2,
1844 make_input (THIS->here_input()));
1845 scm_gc_protect_object (mus);
1846 $$ = unsmob_music (mus);
1848 | STRING optional_notemode_duration {
1849 Input i = THIS->pop_spot ();
1851 Music * lreq = MY_MAKE_MUSIC("LyricEvent");
1852 lreq->set_mus_property ("text", $1);
1853 lreq->set_mus_property ("duration",$2);
1855 Music * velt = MY_MAKE_MUSIC("EventChord");
1856 velt->set_mus_property ("elements", scm_list_n (lreq->self_scm (), SCM_UNDEFINED));
1863 if (!THIS->lexer_->chord_state_b ())
1864 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
1871 steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
1872 $$ = Chord::get_chord ($1, $3, $4, $5, $6, $2);
1873 $$->set_spot (THIS->here_input ());
1880 | CHORD_COLON chord_notes {
1889 | chord_notes '.' chord_step {
1890 $$ = gh_append2 ($$, $3);
1898 | CHORD_CARET chord_notes {
1908 | CHORD_SLASH steno_tonic_pitch {
1917 | CHORD_BASS steno_tonic_pitch {
1924 $$ = scm_cons ($1, SCM_EOL);
1926 | CHORDMODIFIER_PITCH {
1927 $$ = scm_cons (unsmob_pitch ($1)->smobbed_copy (), SCM_EOL);
1929 | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
1930 $$ = scm_list_n (unsmob_pitch ($1)->smobbed_copy (),
1938 m.notename_ = ($1 - 1) % 7;
1939 m.octave_ = $1 > 7 ? 1 : 0;
1942 $$ = m.smobbed_copy ();
1944 | bare_unsigned '+' {
1946 m.notename_ = ($1 - 1) % 7;
1947 m.octave_ = $1 > 7 ? 1 : 0;
1951 $$ = m.smobbed_copy ();
1953 | bare_unsigned CHORD_MINUS {
1955 m.notename_ = ($1 - 1) % 7;
1956 m.octave_ = $1 > 7 ? 1 : 0;
1959 $$ = m.smobbed_copy ();
1967 number_expression '+' number_term {
1968 $$ = scm_sum ($1, $3);
1970 | number_expression '-' number_term {
1971 $$ = scm_difference ($1, $3);
1980 | number_factor '*' number_factor {
1981 $$ = scm_product ($1, $3);
1983 | number_factor '/' number_factor {
1984 $$ = scm_divide ($1, $3);
1989 '-' number_factor { /* %prec UNARY_MINUS */
1990 $$ = scm_difference ($2, SCM_UNDEFINED);
1998 $$ = gh_int2scm ($1);
2003 | NUMBER_IDENTIFIER {
2007 $$ = gh_double2scm (gh_scm2double ($1) CM );
2010 $$ = gh_double2scm (gh_scm2double ($1) PT);
2013 $$ = gh_double2scm (gh_scm2double ($1) INCH);
2016 $$ = gh_double2scm (gh_scm2double ($1) MM);
2019 $$ = gh_double2scm (gh_scm2double ($1) CHAR);
2035 if (scm_integer_p ($1) == SCM_BOOL_T)
2037 int k = gh_scm2int ($1);
2041 THIS->parser_error (_ ("need integer number arg"));
2055 | STRING_IDENTIFIER {
2058 | string '+' string {
2059 $$ = scm_string_append (scm_list_n ($1, $3, SCM_UNDEFINED));
2066 | exclamations '!' { $$ ++; }
2071 | questions '?' { $$ ++; }
2078 My_lily_parser::set_yydebug (bool )
2085 extern My_lily_parser * current_parser;
2088 My_lily_parser::do_yyparse ()
2090 current_parser = this;;
2091 yyparse ((void*)this);
2096 Should make this optional? It will also complain when you do
2100 which is entirely legitimate.
2102 Or we can scrap it. Barchecks should detect wrong durations, and
2103 skipTypesetting speeds it up a lot.
2107 My_lily_parser::beam_check (SCM dur)
2109 Duration *d = unsmob_duration (dur);
2110 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2112 Music * m = unsmob_music (last_beam_start_);
2113 m->origin ()->warning (_("Suspect duration found following this beam"));
2115 last_beam_start_ = SCM_EOL;
2120 It is a little strange, to have this function in this file, but
2121 otherwise, we have to import music classes into the lexer.
2125 My_lily_lexer::try_special_identifiers (SCM * destination, SCM sid)
2127 if (gh_string_p (sid)) {
2129 return STRING_IDENTIFIER;
2130 } else if (gh_number_p (sid)) {
2132 return NUMBER_IDENTIFIER;
2133 } else if (unsmob_translator_def (sid)) {
2134 *destination = unsmob_translator_def (sid)->clone_scm();
2135 return TRANSLATOR_IDENTIFIER;
2136 } else if (unsmob_score (sid)) {
2137 Score *sc = new Score (*unsmob_score (sid));
2138 *destination =sc->self_scm ();
2139 return SCORE_IDENTIFIER;
2140 } else if (Music * mus =unsmob_music (sid)) {
2141 *destination = unsmob_music (sid)->clone ()->self_scm();
2142 unsmob_music (*destination)->
2143 set_mus_property ("origin", make_input (last_input_));
2144 return dynamic_cast<Event*> (mus)
2145 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2146 } else if (unsmob_duration (sid)) {
2147 *destination = unsmob_duration (sid)->smobbed_copy();
2148 return DURATION_IDENTIFIER;
2149 } else if (unsmob_music_output_def (sid)) {
2150 Music_output_def *p = unsmob_music_output_def (sid);
2153 *destination = p->self_scm();
2154 return MUSIC_OUTPUT_DEF_IDENTIFIER;