1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for lilypond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
13 Four shift/reduce problems:
17 "bar" -> String -> Lyric -> Music -> music-assignment
19 "bar" -> String -> string-assignment
29 \repeat .. \alternative
32 \repeat { \repeat .. \alternative }
36 \repeat { \repeat } \alternative
48 * The rules for who is protecting what are very shady. Uniformise
51 * There are too many lexical modes?
59 #include "scm-option.hh"
60 #include "translator-def.hh"
61 #include "lily-guile.hh"
63 #include "my-lily-lexer.hh"
64 #include "paper-def.hh"
65 #include "midi-def.hh"
67 #include "file-path.hh"
69 #include "dimensions.hh"
70 #include "my-lily-parser.hh"
72 #include "input-file-results.hh"
74 #include "lilypond-input-version.hh"
75 #include "scm-hash.hh"
76 #include "auto-change-iterator.hh"
77 #include "ly-modules.hh"
78 #include "music-sequence.hh"
79 #include "input-smob.hh"
81 #include "text-item.hh"
82 #include "music-list.hh"
85 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
89 #define YYERROR_VERBOSE 1
91 My_lily_parser* my_lily_parser;
92 #define YYPARSE_PARAM my_lily_parser
93 #define YYLEX_PARAM my_lily_parser
95 ((My_lily_parser *) my_lily_parser)
97 #define yyerror THIS->parser_error
100 Add symbols to the TAGS field of a music object.
104 tag_music (Music*m, SCM tag, Input ip)
106 SCM tags = m->get_mus_property ("tags");
107 if (gh_symbol_p (tag))
108 tags = scm_cons (tag, tags);
109 else if (gh_list_p (tag))
110 tags = gh_append2 (tag, tags);
112 ip.warning (_("Tag must be symbol or list of symbols."));
114 m->set_mus_property ("tags", tags);
120 regular_identifier_b (SCM id)
122 String str = ly_scm2string (id);
123 char const *s = str.to_str0 () ;
128 v = v && isalpha (*s);
135 make_simple_markup (SCM a)
139 simple = scm_c_eval_string ("simple-markup");
141 return scm_list_n (simple, a, SCM_UNDEFINED);
146 is_duration_b (int t)
148 return t && t == 1 << intlog2 (t);
152 set_music_properties (Music *p, SCM a)
154 for (SCM k = a; gh_pair_p (k); k = ly_cdr (k))
156 p->internal_set_mus_property (ly_caar (k), ly_cdar (k));
161 make_chord_step (int step, int alter)
166 /* ugh: fucks up above 13 */
167 Pitch m(step > 7 ? 1 : 0,(step - 1) % 7, alter);
168 return m.smobbed_copy ();
173 make_chord (SCM pitch, SCM dur, SCM modification_list)
175 static SCM chord_ctor;
177 chord_ctor= scm_c_eval_string ("construct-chord");
178 SCM ch= scm_call_3 (chord_ctor, pitch, dur, modification_list);
179 scm_gc_protect_object (ch);
184 Todo: actually also use apply iso. call too ...
187 ly_input_procedure_p (SCM x)
189 return gh_procedure_p (x)
190 || (gh_pair_p (x) && gh_procedure_p (gh_car (x)));
194 set_property_music (SCM sym, SCM value)
196 Music * p = MY_MAKE_MUSIC("PropertySet");
197 p->set_mus_property ("symbol", sym);
198 p->set_mus_property ("value", value);
204 /* We use SCMs to do strings, because it saves us the trouble of
205 deleting them. Let's hope that a stack overflow doesnt trigger a move
206 of the parse stack onto the heap. */
213 Music_output_def * outputdef;
220 yylex (YYSTYPE *s, void * v)
222 My_lily_parser *pars = (My_lily_parser*) v;
223 My_lily_lexer * lex = pars->lexer_;
225 lex->lexval = (void*) s;
226 lex->prepare_for_next_token();
227 return lex->yylex ();
246 %token CHORDMODIFIERS
251 %token COMMANDSPANREQUEST
260 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
261 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
265 %token GROBDESCRIPTIONS
273 %token MULTI_MEASURE_REST
279 %token OUTPUTPROPERTY
280 %token OVERRIDE SET REVERT
308 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
309 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
311 %token <i> E_UNSIGNED
312 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
315 %type <i> exclamations questions dots optional_rest
317 %type <scm> grace_head
318 %type <scm> lyric_element
319 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
321 %token <scm> NOTENAME_PITCH
322 %token <scm> TONICNAME_PITCH
323 %token <scm> CHORDMODIFIER_PITCH
324 %token <scm> DURATION_IDENTIFIER
325 %token <scm> FRACTION
326 %token <id> IDENTIFIER
327 %token <scm> CHORDNAMES
329 %token <scm> CHORD_MODIFIER
331 %token <scm> SCORE_IDENTIFIER
332 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
333 %token <scm> NUMBER_IDENTIFIER
334 %token <scm> EVENT_IDENTIFIER
335 %token <scm> MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
336 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
337 %token <scm> RESTNAME
344 %token <scm> MARKUP_HEAD_MARKUP0
345 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
346 %token <scm> MARKUP_HEAD_SCM0
347 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
348 %token <scm> MARKUP_HEAD_SCM0_SCM1
349 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
350 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
352 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
353 %type <scm> markup markup_line markup_list markup_list_body full_markup
355 %type <outputdef> output_def
356 %type <scm> lilypond_header lilypond_header_body
357 %type <music> open_event close_event
358 %type <i> sub_quotes sup_quotes
359 %type <music> simple_element event_chord command_element Simple_music Composite_music
360 %type <music> Repeated_music
361 %type <scm> Alternative_music
362 %type <i> tremolo_type
363 %type <i> bare_int bare_unsigned
365 %type <scm> identifier_init
367 %type <music> note_chord_element chord_body chord_body_element
368 %type <scm> chord_body_elements
369 %type <scm> steno_duration optional_notemode_duration multiplied_duration
370 %type <scm> verbose_duration
372 %type <scm> post_events
373 %type <music> gen_text_def direction_less_event direction_reqd_event
374 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
375 %type <scm> explicit_pitch steno_tonic_pitch
376 %type <scm> duration_length fraction
378 %type <scm> new_chord step_number chord_items chord_item chord_separator step_numbers
380 %type <scm> embedded_scm scalar
381 %type <music> Music Sequential_music Simultaneous_music
382 %type <music> relative_music re_rhythmed_music part_combined_music
383 %type <music> property_def translator_change simple_property_def
384 %type <scm> Music_list
385 %type <outputdef> music_output_def_body
386 %type <music> shorthand_command_req
387 %type <music> post_event tagged_post_event
388 %type <music> command_req verbose_command_req
389 %type <music> extender_req
390 %type <music> hyphen_req
391 %type <music> string_number_event
392 %type <scm> string bare_number number_expression number_term number_factor
393 %type <score> score_block score_body
395 %type <scm> translator_spec_block translator_spec_body
396 %type <music> tempo_event
397 %type <scm> notenames_body notenames_block chordmodifiers_block
398 %type <scm> script_abbreviation
404 /* We don't assign precedence to / and *, because we might need varied
405 prec levels in different prods */
411 lilypond: /* empty */
412 | lilypond toplevel_expression {}
413 | lilypond assignment { }
415 THIS->error_level_ = 1;
418 THIS->error_level_ = 1;
424 THIS->lexer_->pitchname_tab_ = $1;
426 | chordmodifiers_block {
427 THIS->lexer_->chordmodifier_tab_ = $1;
430 THIS->input_file_->header_ = $1;
433 THIS->input_file_->scores_.push ($1);
436 if (dynamic_cast<Paper_def*> ($1))
437 THIS->lexer_->set_identifier (scm_makfrom0str ("$defaultpaper"), $1->self_scm ());
438 else if (dynamic_cast<Midi_def*> ($1))
439 THIS->lexer_->set_identifier (scm_makfrom0str ("$defaultmidi"), $1->self_scm ());
449 chordmodifiers_block:
450 CHORDMODIFIERS notenames_body { $$ = $2; }
454 PITCHNAMES notenames_body { $$ = $2; }
459 int i = scm_ilength ($1);
461 SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
462 for (SCM s = $1; gh_pair_p (s); s = ly_cdr (s)) {
463 SCM pt = ly_cdar (s);
464 scm_hashq_set_x (tab, ly_caar (s), pt);
470 lilypond_header_body:
472 $$ = ly_make_anonymous_module ();
473 THIS->lexer_->add_scope ($$);
475 | lilypond_header_body assignment {
481 HEADER '{' lilypond_header_body '}' {
482 $$ = THIS->lexer_-> remove_scope();
494 /* cont */ '=' identifier_init {
497 Should find generic way of associating input with objects.
499 Input ip = THIS->pop_spot ();
501 if (! regular_identifier_b ($1))
503 ip.warning (_ ("Identifier should have alphabetic characters only"));
506 THIS->lexer_->set_identifier ($1, $4);
509 TODO: devise standard for protection in parser.
511 The parser stack lives on the C-stack, which means that
512 all objects can be unprotected as soon as they're here.
523 $$ = $1->self_scm ();
524 scm_gc_unprotect_object ($$);
530 $$ = $1->self_scm ();
531 scm_gc_unprotect_object ($$);
533 | translator_spec_block {
537 $$ = $1->self_scm ();
538 scm_gc_unprotect_object ($$);
541 $$ = $1->self_scm ();
542 scm_gc_unprotect_object ($$);
547 | number_expression {
558 translator_spec_block:
559 TRANSLATOR '{' translator_spec_body '}'
565 translator_spec_body:
566 TRANSLATOR_IDENTIFIER {
568 unsmob_translator_def ($$)-> set_spot (THIS->here_input ());
571 $$ = Translator_def::make_scm ();
572 Translator_def*td = unsmob_translator_def ($$);
573 td->translator_group_type_ = $2;
574 td->set_spot (THIS->here_input ());
576 | translator_spec_body DESCRIPTION string {
577 unsmob_translator_def ($$)->description_ = $3;
579 | translator_spec_body STRING '=' embedded_scm {
580 unsmob_translator_def ($$)->add_property_assign ($2, $4);
582 | translator_spec_body STRING OVERRIDE embedded_scm '=' embedded_scm {
583 unsmob_translator_def ($$)
584 ->add_push_property (scm_string_to_symbol ($2), $4, $6);
586 | translator_spec_body STRING SET embedded_scm '=' embedded_scm {
587 unsmob_translator_def ($$)
588 ->add_push_property (scm_string_to_symbol ($2), $4, $6);
590 | translator_spec_body STRING REVERT embedded_scm {
591 unsmob_translator_def ($$)->add_pop_property (
592 scm_string_to_symbol ($2), $4);
594 | translator_spec_body NAME STRING {
595 unsmob_translator_def ($$)->type_name_ = scm_string_to_symbol ($3);
597 | translator_spec_body CONSISTS STRING {
598 unsmob_translator_def ($$)->add_element ($3);
600 | translator_spec_body ALIAS STRING {
601 Translator_def*td = unsmob_translator_def ($$);
602 td->type_aliases_ = scm_cons (scm_string_to_symbol ($3), td->type_aliases_);
604 | translator_spec_body GROBDESCRIPTIONS embedded_scm {
605 Translator_def*td = unsmob_translator_def($$);
606 // td->add_property_assign (ly_symbol2scm ("allGrobDescriptions"), $3);
607 for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p))
608 td->add_property_assign (scm_symbol_to_string (ly_caar (p)), ly_cdar (p));
610 | translator_spec_body CONSISTSEND STRING {
611 unsmob_translator_def ($$)->add_last_element ( $3);
613 | translator_spec_body ACCEPTS STRING {
614 unsmob_translator_def ($$)->set_acceptor (scm_string_to_symbol ($3), true);
616 | translator_spec_body DENIES STRING {
617 unsmob_translator_def ($$)->set_acceptor (scm_string_to_symbol ($3), false);
619 | translator_spec_body REMOVE STRING {
620 unsmob_translator_def ($$)->remove_element ($3);
631 /*cont*/ '{' score_body '}' {
634 if (!$$->defs_.size ())
636 Music_output_def *id =
637 unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"));
638 $$->add_output (id ? id->clone () : new Paper_def );
647 $$->set_spot (THIS->here_input ());
648 SCM m = $1->self_scm ();
649 scm_gc_unprotect_object (m);
654 SCM check_funcs = scm_c_eval_string ("toplevel-music-functions");
655 for (; gh_pair_p (check_funcs); check_funcs = gh_cdr (check_funcs))
656 m = gh_call1 (gh_car (check_funcs), m);
661 $$ = unsmob_score ($1);
662 $$->set_spot (THIS->here_input ());
664 | score_body lilypond_header {
667 | score_body output_def {
680 music_output_def_body '}' {
682 THIS-> lexer_-> remove_scope ();
686 music_output_def_body:
688 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultmidi"));
693 p = dynamic_cast<Midi_def*> (id->clone ());
698 THIS->lexer_->add_scope (p->scope_);
701 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"));
704 p = dynamic_cast<Paper_def*> (id->clone ());
708 THIS->lexer_->add_scope (p->scope_);
711 | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
712 Music_output_def * o = unsmob_music_output_def ($3);
715 THIS->lexer_->add_scope (o->scope_);
717 | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
718 Music_output_def * o = unsmob_music_output_def ($3);
721 THIS->lexer_->add_scope (o->scope_);
723 | music_output_def_body assignment {
726 | music_output_def_body translator_spec_block {
727 $$->assign_translator ($2);
729 | music_output_def_body tempo_event {
731 junk this ? there already is tempo stuff in
734 int m = gh_scm2int ( $2->get_mus_property ("metronome-count"));
735 Duration *d = unsmob_duration ($2->get_mus_property ("tempo-unit"));
736 Midi_def * md = dynamic_cast<Midi_def*> ($$);
738 md->set_tempo (d->get_length (), m);
740 | music_output_def_body error {
746 TEMPO steno_duration '=' bare_unsigned {
747 $$ = MY_MAKE_MUSIC("MetronomeChangeEvent");
748 $$->set_mus_property ("tempo-unit", $2);
749 $$->set_mus_property ("metronome-count", gh_int2scm ( $4));
754 The representation of a list is the
758 to have efficient append.
762 $$ = scm_cons (SCM_EOL, SCM_EOL);
766 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
767 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
768 if (gh_pair_p (ly_cdr (s)))
769 gh_set_cdr_x (ly_cdr (s), c); /* append */
771 gh_set_car_x (s, c); /* set first cons */
772 gh_set_cdr_x (s, c) ; /* remember last cell */
788 | ALTERNATIVE '{' Music_list '}' {
794 REPEAT string bare_unsigned Music Alternative_music
798 SCM alts = gh_pair_p ($5) ? gh_car ($5) : SCM_EOL;
799 if (times < scm_ilength (alts)) {
800 unsmob_music (gh_car (alts))
801 ->origin ()->warning (
802 _("More alternatives than repeats. Junking excess alternatives."));
803 alts = ly_truncate_list (times, alts);
809 proc = scm_c_eval_string ("make-repeated-music");
811 SCM mus = scm_call_1 (proc, $2);
812 scm_gc_protect_object (mus); // UGH.
813 Music *r =unsmob_music (mus);
816 r-> set_mus_property ("element", beg->self_scm ());
817 scm_gc_unprotect_object (beg->self_scm ());
819 r->set_mus_property ("repeat-count", gh_int2scm (times >? 1));
821 r-> set_mus_property ("elements",alts);
822 if (gh_equal_p ($2, scm_makfrom0str ("tremolo"))) {
824 we can not get durations and other stuff correct down the line, so we have to
825 add to the duration log here.
830 func = scm_primitive_eval (ly_symbol2scm ("shift-duration-log"));
832 int dots = ($3 % 3) ? 0 : 1;
833 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
835 Sequential_music * seq = dynamic_cast<Sequential_music*> ($4);
838 int list_len =scm_ilength (seq->music_list ());
840 seq->origin ()->warning ("Chord tremolo must have 2 elements.");
842 r->compress (Moment (Rational (1,list_len)));
844 gh_call3 (func, r->self_scm (), gh_int2scm(shift),gh_int2scm(dots));
847 r->set_spot (*$4->origin ());
854 SEQUENTIAL '{' Music_list '}' {
855 $$ = MY_MAKE_MUSIC("SequentialMusic");
856 $$->set_mus_property ("elements", ly_car ($3));
857 $$->set_spot(THIS->here_input());
859 | '{' Music_list '}' {
860 $$ = MY_MAKE_MUSIC("SequentialMusic");
861 $$->set_mus_property ("elements", ly_car ($2));
862 $$->set_spot(THIS->here_input());
867 SIMULTANEOUS '{' Music_list '}'{
868 $$ = MY_MAKE_MUSIC("SimultaneousMusic");
869 $$->set_mus_property ("elements", ly_car ($3));
870 $$->set_spot(THIS->here_input());
873 | simul_open Music_list simul_close {
874 $$ = MY_MAKE_MUSIC("SimultaneousMusic");
875 $$->set_mus_property ("elements", ly_car ($2));
876 $$->set_spot(THIS->here_input());
881 event_chord { $$ = $1; }
882 | APPLYOUTPUT embedded_scm {
883 if (!ly_input_procedure_p ($2))
884 THIS->parser_error (_ ("\\applycontext takes function argument"));
885 $$ = MY_MAKE_MUSIC ("ApplyOutputEvent");
886 $$->set_mus_property ("procedure", $2);
887 $$->set_spot (THIS->here_input());
889 | APPLYCONTEXT embedded_scm {
890 if (!ly_input_procedure_p ($2))
891 THIS->parser_error (_ ("\\applycontext takes function argument"));
892 $$ = MY_MAKE_MUSIC ("ApplyContext");
893 $$->set_mus_property ("procedure", $2);
894 $$->set_spot (THIS->here_input());
896 | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm {
898 if (!gh_symbol_p ($3))
900 THIS->parser_error (_ ("Second argument must be a symbol"));
902 /* Should check # args */
903 if (!gh_procedure_p (pred))
905 THIS->parser_error (_ ("First argument must be a procedure taking one argument"));
908 Music*m = MY_MAKE_MUSIC("OutputPropertySetMusic");
909 m->set_mus_property ("predicate", pred);
910 m->set_mus_property ("grob-property", $3);
911 m->set_mus_property ("grob-value", $5);
916 $$ = unsmob_music ($1);
924 GRACE { $$ = scm_makfrom0str ("Grace"); }
925 | ACCIACCATURA { $$ = scm_makfrom0str ("Acciaccatura"); }
926 | APPOGGIATURA { $$ = scm_makfrom0str ("Appoggiatura"); }
931 CONTEXT STRING Music {
932 Music*csm =MY_MAKE_MUSIC("ContextSpeccedMusic");
934 csm->set_mus_property ("element", $3->self_scm ());
935 scm_gc_unprotect_object ($3->self_scm ());
937 csm->set_mus_property ("context-type", scm_string_to_symbol ($2));
938 csm->set_mus_property ("context-id", scm_makfrom0str (""));
942 | AUTOCHANGE STRING Music {
943 Music*chm = MY_MAKE_MUSIC("AutoChangeMusic");
944 chm->set_mus_property ("element", $3->self_scm ());
945 chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_proc);
947 scm_gc_unprotect_object ($3->self_scm ());
948 chm->set_mus_property ("what", scm_string_to_symbol ($2));
951 chm->set_spot (*$3->origin ());
956 The other version is for easier debugging of
957 Sequential_music_iterator in combination with grace notes.
962 TODO: should distinguish between both grace types in the
963 basic music objects too, since the meaning is different.
967 String start_str = "start" + ly_scm2string ($1) + "Music";
968 String stop_str = "stop" + ly_scm2string ($1) + "Music";
970 SCM start = THIS->lexer_->lookup_identifier (start_str);
971 SCM stop = THIS->lexer_->lookup_identifier (stop_str);
973 Music *startm = unsmob_music (start);
974 Music *stopm = unsmob_music (stop);
978 stopm = stopm->clone ();
979 ms = scm_cons (stopm->self_scm (), ms);
980 scm_gc_unprotect_object (stopm->self_scm ());
982 ms = scm_cons ($2->self_scm (), ms);
983 scm_gc_unprotect_object ($2->self_scm());
985 startm = startm->clone ();
986 ms = scm_cons (startm->self_scm () , ms);
987 scm_gc_unprotect_object (startm->self_scm ());
991 Music* seq = MY_MAKE_MUSIC("SequentialMusic");
992 seq->set_mus_property ("elements", ms);
995 $$ = MY_MAKE_MUSIC("GraceMusic");
996 $$->set_mus_property ("element", seq->self_scm ());
997 scm_gc_unprotect_object (seq->self_scm ());
999 $$ = MY_MAKE_MUSIC("GraceMusic");
1000 $$->set_mus_property ("element", $2->self_scm ());
1001 scm_gc_unprotect_object ($2->self_scm ());
1004 | CONTEXT string '=' string Music {
1005 Music * csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1007 csm->set_mus_property ("element", $5->self_scm ());
1008 scm_gc_unprotect_object ($5->self_scm ());
1010 csm->set_mus_property ("context-type", scm_string_to_symbol ($2));
1011 csm->set_mus_property ("context-id", $4);
1015 | NEWCONTEXT string Music {
1016 static int new_context_count;
1018 Music * csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1020 csm->set_mus_property ("element", $3->self_scm ());
1021 scm_gc_unprotect_object ($3->self_scm ());
1023 csm->set_mus_property ("context-type", scm_string_to_symbol ($2));
1025 SCM new_id = scm_number_to_string (gh_int2scm (new_context_count ++),
1027 csm->set_mus_property ("context-id", new_id);
1037 int n = gh_scm2int (ly_car ($3)); int d = gh_scm2int (ly_cdr ($3));
1040 $$= MY_MAKE_MUSIC("TimeScaledMusic");
1041 $$->set_spot (THIS->pop_spot ());
1043 $$->set_mus_property ("element", mp->self_scm ());
1044 scm_gc_unprotect_object (mp->self_scm ());
1045 $$->set_mus_property ("numerator", gh_int2scm (n));
1046 $$->set_mus_property ("denominator", gh_int2scm (d));
1047 $$->compress (Moment (Rational (n,d)));
1050 | Repeated_music { $$ = $1; }
1051 | Simultaneous_music { $$ = $1; }
1052 | Sequential_music { $$ = $1; }
1053 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1054 $$ = MY_MAKE_MUSIC("TransposedMusic");
1056 Pitch from = *unsmob_pitch ($2);
1057 Pitch to = *unsmob_pitch ($3);
1059 p->transpose (interval (from, to));
1060 $$->set_mus_property ("element", p->self_scm ());
1061 scm_gc_unprotect_object (p->self_scm ());
1063 | APPLY embedded_scm Music {
1064 if (!ly_input_procedure_p ($2))
1065 THIS->parser_error (_ ("\\apply takes function argument"));
1067 SCM ret = gh_call1 ($2, $3->self_scm ());
1068 Music *m = unsmob_music (ret);
1070 THIS->parser_error ("\\apply must return a Music");
1071 m = MY_MAKE_MUSIC("Music");
1076 { THIS->lexer_->push_note_state (); }
1079 THIS->lexer_->pop_state ();
1082 { THIS->lexer_->push_figuredbass_state (); }
1085 Music * chm = MY_MAKE_MUSIC("UntransposableMusic");
1086 chm->set_mus_property ("element", $3->self_scm ());
1088 scm_gc_unprotect_object ($3->self_scm());
1090 THIS->lexer_->pop_state ();
1093 { THIS->lexer_->push_chord_state (); }
1096 Music * chm = MY_MAKE_MUSIC("UnrelativableMusic");
1097 chm->set_mus_property ("element", $3->self_scm ());
1098 scm_gc_unprotect_object ($3->self_scm());
1101 THIS->lexer_->pop_state ();
1104 { THIS->lexer_->push_lyric_state (); }
1108 THIS->lexer_->pop_state ();
1110 | relative_music { $$ = $1; }
1111 | re_rhythmed_music { $$ = $1; }
1112 | part_combined_music { $$ = $1; }
1113 | TAG embedded_scm Music {
1114 tag_music ($3, $2, THIS->here_input ());
1120 RELATIVE absolute_pitch Music {
1122 Pitch pit = *unsmob_pitch ($2);
1123 $$ = MY_MAKE_MUSIC("RelativeOctaveMusic");
1125 $$->set_mus_property ("element", p->self_scm ());
1126 scm_gc_unprotect_object (p->self_scm ());
1129 Pitch retpitch = p->to_relative_octave (pit);
1130 if (lily_1_8_relative)
1131 $$->set_mus_property ("last-pitch", retpitch.smobbed_copy ());
1136 ADDLYRICS Music Music {
1137 Music*l =MY_MAKE_MUSIC("LyricCombineMusic");
1138 l->set_mus_property ("elements", gh_list ($2->self_scm (), $3->self_scm (), SCM_UNDEFINED));
1139 scm_gc_unprotect_object ($3->self_scm ());
1140 scm_gc_unprotect_object ($2->self_scm ());
1145 part_combined_music:
1146 PARTCOMBINE STRING Music Music {
1147 Music * p= MY_MAKE_MUSIC("PartCombineMusic");
1148 p->set_mus_property ("what", scm_string_to_symbol ($2));
1149 p->set_mus_property ("elements", gh_list ($3->self_scm (),$4->self_scm (), SCM_UNDEFINED));
1151 scm_gc_unprotect_object ($3->self_scm ());
1152 scm_gc_unprotect_object ($4->self_scm ());
1159 TRANSLATOR STRING '=' STRING {
1160 Music*t= MY_MAKE_MUSIC("TranslatorChange");
1161 t-> set_mus_property ("change-to-type", scm_string_to_symbol ($2));
1162 t-> set_mus_property ("change-to-id", $4);
1165 $$->set_spot (THIS->here_input ());
1171 | ONCE simple_property_def {
1173 SCM e = $2->get_mus_property ("element");
1174 unsmob_music (e)->set_mus_property ("once", SCM_BOOL_T);
1178 simple_property_def:
1179 PROPERTY STRING '.' STRING '=' scalar {
1180 Music *t = set_property_music (scm_string_to_symbol ($4), $6);
1181 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1183 csm->set_mus_property ("element", t->self_scm ());
1184 scm_gc_unprotect_object (t->self_scm ());
1187 $$->set_spot (THIS->here_input ());
1189 csm-> set_mus_property ("context-type", scm_string_to_symbol ($2));
1191 | PROPERTY STRING '.' STRING UNSET {
1193 Music *t = MY_MAKE_MUSIC("PropertyUnset");
1194 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1196 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1197 csm->set_mus_property ("element", t->self_scm ());
1198 scm_gc_unprotect_object (t->self_scm ());
1201 $$->set_spot (THIS->here_input ());
1203 csm-> set_mus_property ("context-type", scm_string_to_symbol ($2));
1205 | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm {
1207 = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings"));
1208 bool itc = internal_type_checking_global_b;
1209 Music *t = MY_MAKE_MUSIC("OverrideProperty");
1210 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1211 t->set_mus_property ("pop-first", SCM_BOOL_T);
1213 internal_type_checking_global_b = false;
1214 t->set_mus_property ("grob-property", $6);
1216 internal_type_checking_global_b = itc;
1217 t->set_mus_property ("grob-value", $8);
1219 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1220 csm->set_mus_property ("element", t->self_scm ());
1221 scm_gc_unprotect_object (t->self_scm ());
1223 $$->set_spot (THIS->here_input ());
1225 csm-> set_mus_property ("context-type", scm_string_to_symbol ($2));
1227 | PROPERTY STRING '.' STRING OVERRIDE
1228 embedded_scm '=' embedded_scm
1234 = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings"));
1235 bool itc = internal_type_checking_global_b;
1237 Music *t = MY_MAKE_MUSIC("OverrideProperty");
1238 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1240 internal_type_checking_global_b = false;
1241 t->set_mus_property ("grob-property", $6);
1242 t->set_mus_property ("grob-value", $8);
1244 internal_type_checking_global_b = itc;
1246 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1247 csm->set_mus_property ("element", t->self_scm ());
1248 scm_gc_unprotect_object (t->self_scm ());
1251 $$->set_spot (THIS->here_input ());
1253 csm-> set_mus_property ("context-type", scm_string_to_symbol ($2));
1256 | PROPERTY STRING '.' STRING REVERT embedded_scm {
1257 Music *t = MY_MAKE_MUSIC("RevertProperty");
1259 = gh_equal_p ($4, scm_makfrom0str ("autoBeamSettings"));
1260 bool itc = internal_type_checking_global_b;
1262 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1264 internal_type_checking_global_b = false;
1265 t->set_mus_property ("grob-property", $6);
1267 internal_type_checking_global_b = itc;
1269 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1270 csm->set_mus_property ("element", t->self_scm ());
1271 scm_gc_unprotect_object (t->self_scm ());
1274 $$->set_spot (THIS->here_input ());
1276 csm-> set_mus_property ("context-type", scm_string_to_symbol ($2));
1283 | bare_int { $$ = gh_int2scm ($1); }
1284 | embedded_scm { $$ = $1; }
1285 | full_markup { $$ = $1; }
1286 | DIGIT { $$ = gh_int2scm ($1); }
1294 Adding pre_events to the simple_element
1295 makes the choice between
1301 simple_element: STRING
1303 a single shift/reduction conflict.
1305 nevertheless, this is not very clean, and we should find a different
1315 pre_events simple_element post_events {
1316 SCM elts = $2-> get_mus_property ("elements");
1318 elts = gh_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1320 $2->set_mus_property ("elements", elts);
1324 | note_chord_element
1329 chord_body optional_notemode_duration post_events
1331 SCM dur = unsmob_duration ($2)->smobbed_copy();
1332 SCM es = $1->get_mus_property ("elements");
1333 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1335 for (SCM s = es; gh_pair_p (s); s = gh_cdr (s))
1336 unsmob_music (gh_car(s))->set_mus_property ("duration", dur);
1337 es = gh_append2 (es, postevs);
1339 $1-> set_mus_property ("elements", es);
1350 simul_open: LESSLESS
1353 simul_close: MOREMORE
1357 chord_open chord_body_elements chord_close
1359 $$ = MY_MAKE_MUSIC("EventChord");
1360 $$->set_mus_property ("elements",
1361 scm_reverse_x ($2, SCM_EOL));
1365 chord_body_elements:
1366 /* empty */ { $$ = SCM_EOL; }
1367 | chord_body_elements chord_body_element {
1368 $$ = gh_cons ($2->self_scm(), $1);
1369 scm_gc_unprotect_object ($2->self_scm());
1374 pitch exclamations questions post_events
1376 Music * n = MY_MAKE_MUSIC("NoteEvent");
1377 n->set_mus_property ("pitch", $1);
1379 n->set_mus_property ("cautionary", SCM_BOOL_T);
1380 if ($2 % 2 || $3 % 2)
1381 n->set_mus_property ("force-accidental", SCM_BOOL_T);
1383 SCM arts = scm_reverse_x ($4, SCM_EOL);
1384 n->set_mus_property ("articulations", arts);
1392 $$ = MY_MAKE_MUSIC("EventChord");
1393 $$->set_mus_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1394 scm_gc_unprotect_object ($1->self_scm());
1396 $$-> set_spot (THIS->here_input ());
1397 $1-> set_spot (THIS->here_input ());
1399 | OCTAVE { THIS->push_spot (); }
1401 Music *l = MY_MAKE_MUSIC("RelativeOctaveCheck");
1403 $$->set_spot (THIS->pop_spot ());
1404 $$->set_mus_property ("pitch", $3);
1407 Music *l = MY_MAKE_MUSIC("LigatureEvent");
1408 l->set_mus_property ("span-direction", gh_int2scm (START));
1409 l->set_spot (THIS->here_input ());
1411 $$ = MY_MAKE_MUSIC("EventChord");
1412 $$->set_mus_property ("elements", scm_cons (l->self_scm (), SCM_EOL));
1413 scm_gc_unprotect_object (l->self_scm());
1414 $$->set_spot (THIS->here_input ());
1417 Music *l = MY_MAKE_MUSIC("LigatureEvent");
1418 l->set_mus_property ("span-direction", gh_int2scm (STOP));
1419 l->set_spot (THIS->here_input ());
1421 $$ = MY_MAKE_MUSIC("EventChord");
1422 $$->set_mus_property ("elements", scm_cons (l->self_scm (), SCM_EOL));
1423 $$->set_spot (THIS->here_input ());
1424 scm_gc_unprotect_object (l->self_scm());
1427 $$ = MY_MAKE_MUSIC("VoiceSeparator");
1428 $$->set_spot (THIS->here_input ());
1432 $$ = MY_MAKE_MUSIC("BarCheck");
1433 $$->set_spot (THIS->here_input ());
1436 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1438 Music *csm = MY_MAKE_MUSIC("ContextSpeccedMusic");
1439 csm->set_mus_property ("element", t->self_scm ());
1440 scm_gc_unprotect_object (t->self_scm ());
1443 $$->set_spot (THIS->here_input ());
1445 csm->set_mus_property ("context-type", ly_symbol2scm ("Timing"));
1447 | PARTIAL duration_length {
1448 Moment m = - unsmob_duration ($2)->get_length ();
1449 Music * p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1451 Music * sp = MY_MAKE_MUSIC("ContextSpeccedMusic");
1452 sp->set_mus_property ("element", p->self_scm ());
1453 scm_gc_unprotect_object (p->self_scm ());
1456 sp-> set_mus_property ("context-type", ly_symbol2scm ("Timing"));
1461 proc = scm_c_eval_string ("make-clef-set");
1463 SCM result = scm_call_1 (proc, $2);
1464 scm_gc_protect_object (result);
1465 $$ = unsmob_music (result);
1470 proc = scm_c_eval_string ("make-time-signature-set");
1472 SCM result = scm_apply_2 (proc, gh_car ($2), gh_cdr ($2), SCM_EOL);
1473 scm_gc_protect_object (result);
1474 $$ = unsmob_music (result);
1479 shorthand_command_req { $$ = $1; }
1480 | verbose_command_req { $$ = $1; }
1483 shorthand_command_req:
1491 $$ = MY_MAKE_MUSIC("BreathingSignEvent");
1494 $$ = MY_MAKE_MUSIC("PesOrFlexaEvent");
1498 verbose_command_req:
1500 Music * m = MY_MAKE_MUSIC("MarkEvent");
1504 Music *m = MY_MAKE_MUSIC("MarkEvent");
1505 m->set_mus_property ("label", $2);
1508 | SKIP duration_length {
1509 Music * skip = MY_MAKE_MUSIC("SkipEvent");
1510 skip->set_mus_property ("duration", $2);
1518 Music *key= MY_MAKE_MUSIC("KeyChangeEvent");
1521 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1523 Music *key= MY_MAKE_MUSIC("KeyChangeEvent");
1524 if (scm_ilength ($3) > 0)
1526 key->set_mus_property ("pitch-alist", $3);
1527 key->set_mus_property ("tonic", Pitch (0,0,0).smobbed_copy());
1528 ((Music*)key)->transpose (* unsmob_pitch ($2));
1530 THIS->parser_error (_("Second argument must be pitch list."));
1541 | post_events post_event {
1542 $2->set_spot (THIS->here_input ());
1543 $$ = gh_cons ($2->self_scm(), $$);
1544 scm_gc_unprotect_object ($2->self_scm());
1546 | post_events tagged_post_event {
1547 $2 -> set_spot (THIS->here_input ());
1548 $$ = scm_cons ($2->self_scm(), $$);
1549 scm_gc_unprotect_object ($2->self_scm());
1555 '-' TAG embedded_scm post_event {
1556 tag_music ($4, $3, THIS->here_input ());
1562 direction_less_event {
1565 | script_dir direction_reqd_event {
1567 $2->set_mus_property ("direction", gh_int2scm ($1));
1570 | script_dir direction_less_event {
1572 $2->set_mus_property ("direction", gh_int2scm ($1));
1575 | string_number_event
1578 string_number_event:
1580 Music * s = MY_MAKE_MUSIC("StringNumberEvent");
1581 s->set_mus_property ("string-number", gh_int2scm($1));
1582 s->set_spot (THIS->here_input ());
1588 direction_less_event:
1594 TODO: should take all these defs out of the parser, adn make use
1598 (set-articulation '~ "trill")
1601 Music * m = MY_MAKE_MUSIC ("BeamEvent");
1602 m->set_spot (THIS->here_input());
1603 m->set_mus_property ("span-direction" , gh_int2scm (START));
1607 Music * m = MY_MAKE_MUSIC ("BeamEvent");
1608 m->set_spot (THIS->here_input());
1609 m->set_mus_property ("span-direction" , gh_int2scm (STOP));
1613 Music * m = MY_MAKE_MUSIC ("TieEvent");
1614 m->set_spot (THIS->here_input());
1619 dynamic_cast<Music *> ($$)->set_mus_property ("span-direction", gh_int2scm (START));
1623 dynamic_cast<Music *> ($$)->set_mus_property ("span-direction", gh_int2scm (STOP))
1625 | EVENT_IDENTIFIER {
1626 $$ = unsmob_music ($1);
1629 Music * a = MY_MAKE_MUSIC("TremoloEvent");
1630 a->set_spot (THIS->here_input ());
1631 a->set_mus_property ("tremolo-type", gh_int2scm ($1));
1636 direction_reqd_event:
1640 | script_abbreviation {
1641 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1642 Music *a = MY_MAKE_MUSIC("ArticulationEvent");
1643 if (gh_string_p (s))
1644 a->set_mus_property ("articulation-type", s);
1645 else THIS->parser_error (_ ("Expecting string as script definition"));
1672 | NOTENAME_PITCH sup_quotes {
1673 Pitch p = *unsmob_pitch ($1);
1674 p = p.transposed (Pitch ($2,0,0));
1675 $$ = p.smobbed_copy ();
1677 | NOTENAME_PITCH sub_quotes {
1678 Pitch p =* unsmob_pitch ($1);
1679 p = p.transposed (Pitch (-$2,0,0));
1680 $$ = p.smobbed_copy ();
1692 | TONICNAME_PITCH sup_quotes {
1693 Pitch p = *unsmob_pitch ($1);
1694 p = p.transposed (Pitch ($2,0,0));
1695 $$ = p.smobbed_copy ();
1697 | TONICNAME_PITCH sub_quotes {
1698 Pitch p =* unsmob_pitch ($1);
1700 p = p.transposed (Pitch (-$2,0,0));
1701 $$ = p.smobbed_copy ();
1714 pitch_also_in_chords:
1720 PITCH embedded_scm {
1722 if (!unsmob_pitch ($2)) {
1723 THIS->parser_error (_f ("Expecting musical-pitch value", 3));
1724 $$ = Pitch ().smobbed_copy ();
1730 DURATION embedded_scm {
1732 if (!unsmob_duration ($2))
1734 THIS->parser_error (_ ("Must have duration object"));
1735 $$ = Duration ().smobbed_copy ();
1742 if (!THIS->lexer_->lyric_state_b ())
1743 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1744 $$ = MY_MAKE_MUSIC("ExtenderEvent");
1750 if (!THIS->lexer_->lyric_state_b ())
1751 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1752 $$ = MY_MAKE_MUSIC("HyphenEvent");
1758 Music * s= MY_MAKE_MUSIC("SlurEvent");
1760 s->set_spot (THIS->here_input());
1763 Music * s= MY_MAKE_MUSIC("PhrasingSlurEvent");
1765 s->set_spot (THIS->here_input());
1768 Music *s =MY_MAKE_MUSIC("CrescendoEvent");
1770 s->set_spot (THIS->here_input());
1773 Music *s =MY_MAKE_MUSIC("DecrescendoEvent");
1775 s->set_spot (THIS->here_input());
1782 Music *s = MY_MAKE_MUSIC("CrescendoEvent");
1783 s->set_spot (THIS->here_input());
1788 Music * s= MY_MAKE_MUSIC("SlurEvent");
1790 s->set_spot (THIS->here_input());
1794 Music * s= MY_MAKE_MUSIC("PhrasingSlurEvent");
1796 s->set_mus_property ("span-type", scm_makfrom0str ( "phrasing-slur"));
1797 s->set_spot (THIS->here_input());
1803 Music *t = MY_MAKE_MUSIC("TextScriptEvent");
1804 t->set_mus_property ("text", $1);
1805 t->set_spot (THIS->here_input ());
1809 Music *t = MY_MAKE_MUSIC("TextScriptEvent");
1810 t->set_mus_property ("text", make_simple_markup ($1));
1811 t->set_spot (THIS->here_input ());
1816 Music * t = MY_MAKE_MUSIC("FingerEvent");
1817 t->set_mus_property ("digit", gh_int2scm ($1));
1818 t->set_spot (THIS->here_input ());
1823 script_abbreviation:
1825 $$ = scm_makfrom0str ("Hat");
1828 $$ = scm_makfrom0str ("Plus");
1831 $$ = scm_makfrom0str ("Dash");
1834 $$ = scm_makfrom0str ("Bar");
1837 $$ = scm_makfrom0str ("Larger");
1840 $$ = scm_makfrom0str ("Dot");
1843 $$ = scm_makfrom0str ("Underscore");
1850 | '-' { $$ = CENTER; }
1861 multiplied_duration {
1864 | verbose_duration {
1869 optional_notemode_duration:
1871 Duration dd = THIS->default_duration_;
1872 $$ = dd.smobbed_copy ();
1874 THIS->beam_check ($$);
1876 | multiplied_duration {
1878 THIS->default_duration_ = *unsmob_duration ($$);
1880 THIS->beam_check ($$);
1882 | verbose_duration {
1884 THIS->default_duration_ = *unsmob_duration ($$);
1889 bare_unsigned dots {
1891 if (!is_duration_b ($1))
1892 THIS->parser_error (_f ("not a duration: %d", $1));
1896 $$ = Duration (l, $2).smobbed_copy ();
1898 | DURATION_IDENTIFIER dots {
1899 Duration *d =unsmob_duration ($1);
1900 Duration k (d->duration_log (),d->dot_count () + $2);
1910 multiplied_duration:
1914 | multiplied_duration '*' bare_unsigned {
1915 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1917 | multiplied_duration '*' FRACTION {
1918 Rational m (gh_scm2int (ly_car ($3)), gh_scm2int (ly_cdr ($3)));
1920 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
1925 FRACTION { $$ = $1; }
1926 | UNSIGNED '/' UNSIGNED {
1927 $$ = scm_cons (gh_int2scm ($1), gh_int2scm ($3));
1945 | ':' bare_unsigned {
1946 if (!is_duration_b ($2))
1947 THIS->parser_error (_f ("not a duration: %d", $2));
1954 /*****************************************************************
1956 *****************************************************************/
1959 $$ = scm_number_to_string (gh_int2scm ($1), gh_int2scm (10));
1962 $$ = scm_number_to_string (gh_int2scm ($1), gh_int2scm (10));
1964 | STRING { $$ = $1 }
1975 Music *bfr = MY_MAKE_MUSIC("BassFigureEvent");
1976 $$ = bfr->self_scm();
1977 scm_gc_unprotect_object ($$);
1980 Music *bfr = MY_MAKE_MUSIC("BassFigureEvent");
1981 $$ = bfr->self_scm();
1983 bfr->set_mus_property ("figure", $1);
1985 scm_gc_unprotect_object ($$);
1987 | bass_figure bass_mod {
1988 Music *m = unsmob_music ($1);
1990 SCM salter =m->get_mus_property ("alteration");
1991 int alter = gh_number_p ( salter) ? gh_scm2int (salter) : 0;
1992 m->set_mus_property ("alteration",
1993 gh_int2scm (alter + $2));
1995 m->set_mus_property ("alteration", gh_int2scm (0));
2003 unsmob_music ($$)->set_mus_property ("bracket-start", SCM_BOOL_T);
2008 | br_bass_figure ']' {
2010 unsmob_music ($1)->set_mus_property ("bracket-stop", SCM_BOOL_T);
2018 | figure_list br_bass_figure {
2019 $$ = scm_cons ($2, $1);
2024 FIGURE_OPEN figure_list FIGURE_CLOSE {
2025 Music * m = MY_MAKE_MUSIC("EventChord");
2026 $2 = scm_reverse_x ($2, SCM_EOL);
2027 m->set_mus_property ("elements", $2);
2028 $$ = m->self_scm ();
2039 pitch exclamations questions optional_notemode_duration optional_rest {
2041 Input i = THIS->pop_spot ();
2042 if (!THIS->lexer_->note_state_b ())
2043 THIS->parser_error (_ ("Have to be in Note mode for notes"));
2047 n = MY_MAKE_MUSIC("RestEvent");
2049 n = MY_MAKE_MUSIC("NoteEvent");
2051 n->set_mus_property ("pitch", $1);
2052 n->set_mus_property ("duration", $4);
2056 n->set_mus_property ("cautionary", SCM_BOOL_T);
2057 if ($2 % 2 || $3 % 2)
2058 n->set_mus_property ("force-accidental", SCM_BOOL_T);
2060 Music *v = MY_MAKE_MUSIC("EventChord");
2061 v->set_mus_property ("elements", scm_list_n (n->self_scm (), SCM_UNDEFINED));
2062 scm_gc_unprotect_object (n->self_scm());
2068 | figure_spec optional_notemode_duration {
2069 Music * m = unsmob_music ($1);
2070 Input i = THIS->pop_spot ();
2072 for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = ly_cdr (s))
2074 unsmob_music (ly_car (s))->set_mus_property ("duration", $2);
2078 | RESTNAME optional_notemode_duration {
2080 Input i = THIS->pop_spot ();
2082 if (ly_scm2string ($1) =="s") {
2084 ev = MY_MAKE_MUSIC("SkipEvent");
2087 ev = MY_MAKE_MUSIC("RestEvent");
2090 ev->set_mus_property ("duration" ,$2);
2092 Music * velt = MY_MAKE_MUSIC("EventChord");
2093 velt->set_mus_property ("elements", scm_list_n (ev->self_scm (),SCM_UNDEFINED));
2098 | MULTI_MEASURE_REST optional_notemode_duration {
2103 proc = scm_c_eval_string ("make-multi-measure-rest");
2105 SCM mus = scm_call_2 (proc, $2,
2106 make_input (THIS->here_input()));
2107 scm_gc_protect_object (mus);
2108 $$ = unsmob_music (mus);
2111 | lyric_element optional_notemode_duration {
2112 Input i = THIS->pop_spot ();
2113 if (!THIS->lexer_->lyric_state_b ())
2114 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
2116 Music * lreq = MY_MAKE_MUSIC("LyricEvent");
2117 lreq->set_mus_property ("text", $1);
2118 lreq->set_mus_property ("duration",$2);
2120 Music * velt = MY_MAKE_MUSIC("EventChord");
2121 velt->set_mus_property ("elements", scm_list_n (lreq->self_scm (), SCM_UNDEFINED));
2128 if (!THIS->lexer_->chord_state_b ())
2129 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
2130 $$ = unsmob_music ($1);
2135 full_markup { $$ = $1 }
2136 | STRING { $$ = $1 ; }
2140 steno_tonic_pitch optional_notemode_duration {
2141 $$ = make_chord ($1, $2, SCM_EOL);
2143 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2144 SCM its = scm_reverse_x ($4, SCM_EOL);
2145 $$ = make_chord ($1, $2, gh_cons ($3, its));
2153 | chord_items chord_item {
2154 $$ = gh_cons ($2, $$);
2160 $$ = ly_symbol2scm ("chord-colon");
2163 $$ = ly_symbol2scm ("chord-caret");
2165 | CHORD_SLASH steno_tonic_pitch {
2166 $$ = scm_list_n (ly_symbol2scm ("chord-slash"), $2, SCM_UNDEFINED);
2168 | CHORD_BASS steno_tonic_pitch {
2169 $$ = scm_list_n (ly_symbol2scm ("chord-bass"), $2, SCM_UNDEFINED);
2178 $$ = scm_reverse_x ($1, SCM_EOL);
2186 step_number { $$ = gh_cons ($1, SCM_EOL); }
2187 | step_numbers '.' step_number {
2188 $$ = gh_cons ($3, $$);
2194 $$ = make_chord_step ($1, 0);
2196 | bare_unsigned '+' {
2197 $$ = make_chord_step ($1, 1);
2199 | bare_unsigned CHORD_MINUS {
2200 $$ = make_chord_step ($1,-1);
2207 TODO: should deprecate in favor of Scheme?
2211 number_expression '+' number_term {
2212 $$ = scm_sum ($1, $3);
2214 | number_expression '-' number_term {
2215 $$ = scm_difference ($1, $3);
2224 | number_factor '*' number_factor {
2225 $$ = scm_product ($1, $3);
2227 | number_factor '/' number_factor {
2228 $$ = scm_divide ($1, $3);
2233 '-' number_factor { /* %prec UNARY_MINUS */
2234 $$ = scm_difference ($2, SCM_UNDEFINED);
2242 $$ = gh_int2scm ($1);
2247 | NUMBER_IDENTIFIER {
2250 | REAL NUMBER_IDENTIFIER {
2251 $$ = gh_double2scm (gh_scm2double ($1) * gh_scm2double ($2));
2253 | UNSIGNED NUMBER_IDENTIFIER {
2254 $$ = gh_double2scm ($1 * gh_scm2double ($2));
2270 if (scm_integer_p ($1) == SCM_BOOL_T)
2272 int k = gh_scm2int ($1);
2276 THIS->parser_error (_ ("need integer number arg"));
2290 | STRING_IDENTIFIER {
2293 | string '+' string {
2294 $$ = scm_string_append (scm_list_n ($1, $3, SCM_UNDEFINED));
2301 | exclamations '!' { $$ ++; }
2306 | questions '?' { $$ ++; }
2316 { THIS->lexer_->push_markup_state (); }
2319 THIS->lexer_->pop_state ();
2325 This should be done more dynamically if possible.
2329 $$ = make_simple_markup ($1);
2331 | MARKUP_HEAD_MARKUP0 markup {
2332 $$ = scm_list_n ($1, $2, SCM_UNDEFINED);
2334 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2335 $$ = scm_list_n ($1, $2, $3, SCM_UNDEFINED);
2337 | MARKUP_HEAD_SCM0_MARKUP1 SCM_T markup {
2338 $$ = scm_list_n ($1, $2, $3, SCM_UNDEFINED);
2343 | MARKUP_HEAD_LIST0 markup_list {
2344 $$ = scm_list_n ($1,$2, SCM_UNDEFINED);
2346 | MARKUP_HEAD_SCM0 embedded_scm {
2347 $$ = scm_list_n ($1, $2, SCM_UNDEFINED);
2349 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup {
2350 $$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED);
2352 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2353 $$ = scm_list_n ($1, $2, $3, $4, SCM_UNDEFINED);
2355 | MARKUP_IDENTIFIER {
2362 chord_open markup_list_body chord_close { $$ = scm_reverse_x ($2, SCM_EOL); }
2366 '{' markup_list_body '}' {
2369 line = scm_c_eval_string ("line-markup");
2371 $$ = scm_list_n (line, scm_reverse_x ($2, SCM_EOL), SCM_UNDEFINED);
2376 /**/ { $$ = SCM_EOL; }
2377 | markup_list_body markup {
2378 $$ = gh_cons ($2, $1) ;
2386 My_lily_parser::set_yydebug (bool )
2393 extern My_lily_parser * current_parser;
2396 My_lily_parser::do_yyparse ()
2398 current_parser = this;;
2399 yyparse ((void*)this);
2404 Should make this optional? It will also complain when you do
2408 which is entirely legitimate.
2410 Or we can scrap it. Barchecks should detect wrong durations, and
2411 skipTypesetting speeds it up a lot.
2415 My_lily_parser::beam_check (SCM dur)
2417 Duration *d = unsmob_duration (dur);
2418 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2420 Music * m = unsmob_music (last_beam_start_);
2421 m->origin ()->warning (_("Suspect duration found following this beam"));
2423 last_beam_start_ = SCM_EOL;
2431 It is a little strange to have this function in this file, but
2432 otherwise, we have to import music classes into the lexer.
2436 My_lily_lexer::try_special_identifiers (SCM * destination, SCM sid)
2438 if (gh_string_p (sid)) {
2440 return STRING_IDENTIFIER;
2441 } else if (gh_number_p (sid)) {
2443 return NUMBER_IDENTIFIER;
2444 } else if (unsmob_translator_def (sid)) {
2445 *destination = unsmob_translator_def (sid)->clone_scm();
2446 return TRANSLATOR_IDENTIFIER;
2447 } else if (unsmob_score (sid)) {
2448 Score *sc = new Score (*unsmob_score (sid));
2449 *destination =sc->self_scm ();
2450 return SCORE_IDENTIFIER;
2451 } else if (Music * mus =unsmob_music (sid)) {
2452 *destination = unsmob_music (sid)->clone ()->self_scm();
2453 unsmob_music (*destination)->
2454 set_mus_property ("origin", make_input (last_input_));
2455 return dynamic_cast<Event*> (mus)
2456 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2457 } else if (unsmob_duration (sid)) {
2458 *destination = unsmob_duration (sid)->smobbed_copy();
2459 return DURATION_IDENTIFIER;
2460 } else if (unsmob_music_output_def (sid)) {
2461 Music_output_def *p = unsmob_music_output_def (sid);
2464 *destination = p->self_scm();
2465 return MUSIC_OUTPUT_DEF_IDENTIFIER;
2466 } else if (Text_item::markup_p (sid)) {
2468 return MARKUP_IDENTIFIER;