1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for LilyPond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
16 * The rules for who is protecting what are very shady. Uniformise
19 * There are too many lexical modes?
30 #include "context-def.hh"
31 #include "dimensions.hh"
33 #include "file-path.hh"
34 #include "input-smob.hh"
36 #include "lily-guile.hh"
37 #include "lilypond-input-version.hh"
38 #include "ly-module.hh"
41 #include "music-list.hh"
42 #include "music-sequence.hh"
43 #include "lily-lexer.hh"
44 #include "lily-parser.hh"
45 #include "paper-book.hh"
46 #include "output-def.hh"
47 #include "scm-hash.hh"
48 #include "scm-option.hh"
50 #include "text-item.hh"
53 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
55 Music *property_op_to_music (SCM op);
56 Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
57 SCM get_next_unique_context_id ();
58 SCM get_next_unique_lyrics_context_id ();
60 #define YYERROR_VERBOSE 1
62 #define YYPARSE_PARAM my_lily_parser
63 #define YYLEX_PARAM my_lily_parser
65 ((Lily_parser *) my_lily_parser)
67 #define yyerror THIS->parser_error
69 /* Add symbols to the TAGS field of a music object. */
72 tag_music (Music *m, SCM tag, Input ip)
74 SCM tags = m->get_property ("tags");
75 if (scm_is_symbol (tag))
76 tags = scm_cons (tag, tags);
77 else if (ly_c_list_p (tag))
78 tags = ly_append2 (tag, tags);
80 ip.warning (_ ("Tag must be symbol or list of symbols."));
82 m->set_property ("tags", tags);
86 is_regular_identifier (SCM id)
88 String str = ly_scm2string (id);
89 char const *s = str.to_str0 ();
98 v = v && isalnum (*s);
106 get_first_context_id (SCM type, Music *m)
108 SCM id = m->get_property ("context-id");
109 if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
110 && scm_is_string (m->get_property ("context-id"))
111 && scm_c_string_length (id) > 0)
119 make_simple_markup (SCM encoding, SCM a)
121 SCM simple = ly_scheme_function ("simple-markup");
122 if (scm_is_symbol (encoding))
123 return scm_list_3 (ly_scheme_function ("encoded-simple-markup"),
125 return scm_list_2 (simple, a);
131 return t && t == 1 << intlog2 (t);
135 set_music_properties (Music *p, SCM a)
137 for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
138 p->internal_set_property (scm_caar (k), scm_cdar (k));
142 make_chord_step (int step, int alter)
149 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
150 return m.smobbed_copy ();
155 make_chord (SCM pitch, SCM dur, SCM modification_list)
157 SCM chord_ctor = ly_scheme_function ("construct-chord");
158 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
159 scm_gc_protect_object (ch);
163 /* Todo: actually also use apply iso. call too ... */
165 ly_input_procedure_p (SCM x)
167 return ly_c_procedure_p (x)
168 || (scm_is_pair (x) && ly_c_procedure_p (scm_car (x)));
172 set_property_music (SCM sym, SCM value)
174 Music *p = MY_MAKE_MUSIC ("PropertySet");
175 p->set_property ("symbol", sym);
176 p->set_property ("value", value);
181 make_music_relative (Pitch start, Music *music)
183 Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
184 relative->set_property ("element", music->self_scm ());
186 Pitch last = music->to_relative_octave (start);
187 if (lily_1_8_relative)
188 music->set_property ("last-pitch", last.smobbed_copy ());
193 make_lyric_combine_music (SCM name, Music *music)
195 Music *combine = MY_MAKE_MUSIC ("NewLyricCombineMusic");
196 combine->set_property ("element", music->self_scm ());
197 combine->set_property ("associated-context", name);
203 /* We use SCMs to do strings, because it saves us the trouble of
204 deleting them. Let's hope that a stack overflow doesnt trigger a move
205 of the parse stack onto the heap. */
211 Output_def *outputdef;
221 yylex (YYSTYPE *s, void *v)
223 Lily_parser *pars = (Lily_parser*) v;
224 Lily_lexer *lex = pars->lexer_;
226 lex->lexval = (void*) s;
227 lex->prepare_for_next_token ();
228 return lex->yylex ();
237 Three shift/reduce problems:
239 2. \markup identifier.
249 \repeat .. \alternative
252 \repeat { \repeat .. \alternative }
256 \repeat { \repeat } \alternative
272 %token CHORDMODIFIERS
275 %token DOUBLE_ANGLE_OPEN
276 %token DOUBLE_ANGLE_CLOSE
278 %token COMMANDSPANREQUEST
287 %token FIGURE_OPEN FIGURE_CLOSE
288 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
289 %token GROBDESCRIPTIONS
299 %token MULTI_MEASURE_REST
306 %token OVERRIDE SET REVERT
333 /* FIXME: this sucks. The user will get to see these names:
334 syntax error, unexpected E_CHAR:
339 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
340 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
342 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
347 %token <i> E_UNSIGNED
348 %token <id> IDENTIFIER
349 %token <scm> CHORDMODIFIER_PITCH
350 %token <scm> DRUM_PITCH
351 %token <scm> DURATION_IDENTIFIER
352 %token <scm> EVENT_IDENTIFIER
353 %token <scm> MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
354 %token <scm> NOTENAME_PITCH
355 %token <scm> NUMBER_IDENTIFIER
356 %token <scm> OUTPUT_DEF_IDENTIFIER
357 %token <scm> RESTNAME
358 %token <scm> LYRICS_STRING
360 %token <scm> SCORE_IDENTIFIER
362 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
363 %token <scm> TONICNAME_PITCH
364 %token <scm> CHORD_MODIFIER
365 %token <scm> FRACTION
367 %token <scm> MARKUP_HEAD_EMPTY
368 %token <scm> MARKUP_HEAD_MARKUP0
369 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
370 %token <scm> MARKUP_HEAD_SCM0
371 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
372 %token <scm> MARKUP_HEAD_SCM0_SCM1
373 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
374 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
375 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
376 %token <scm> MUSIC_FUNCTION
377 %token <scm> MUSIC_FUNCTION_MUSIC
378 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
379 %token <scm> MUSIC_FUNCTION_SCM
380 %token <scm> MUSIC_FUNCTION_SCM_SCM
381 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
382 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
383 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
384 %token <scm> MUSIC_FUNCTION_MARKUP
385 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
386 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
387 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
388 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
394 %type <book> book_block book_body
395 %type <i> bare_int bare_unsigned
396 %type <i> exclamations questions dots optional_rest
398 %type <i> sub_quotes sup_quotes
399 %type <i> tremolo_type
402 %type <music> Composite_music Simple_music Prefix_composite_music Generic_prefix_music
403 %type <music> Grouped_music_list
404 %type <music> Music Sequential_music Simultaneous_music
405 %type <music> Repeated_music
406 %type <music> command_req
407 %type <music> gen_text_def direction_less_event direction_reqd_event
408 %type <music> music_property_def context_change
409 %type <music> note_chord_element chord_body chord_body_element
410 %type <music> post_event tagged_post_event
411 %type <music> relative_music re_rhythmed_music
412 %type <music> simple_element event_chord command_element
413 %type <music> string_number_event
414 %type <music> toplevel_music
415 %type <music> tempo_event
417 %type <outputdef> output_def_body output_def_head
418 %type <outputdef> output_def paper_block
420 %type <scm> Music_list
421 %type <scm> chord_body_elements
422 %type <scm> chord_item chord_items chord_separator new_chord
423 %type <scm> context_def_spec_block context_def_spec_body
424 %type <scm> context_mod context_def_mod optional_context_mod
425 %type <scm> context_prop_spec
426 %type <scm> direction_less_char
427 %type <scm> duration_length fraction
428 %type <scm> embedded_scm scalar
429 %type <scm> identifier_init
430 %type <scm> lilypond_header lilypond_header_body
431 %type <scm> new_lyrics
432 %type <scm> post_events
433 %type <scm> property_operation
434 %type <scm> script_abbreviation
435 %type <scm> simple_string
436 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
437 %type <scm> steno_tonic_pitch
438 %type <scm> step_number step_numbers
439 %type <scm> string bare_number number_expression number_term number_factor
440 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
441 %type <scm> context_mod_list
442 %type <scm> octave_check
443 %type <scm> steno_duration optional_notemode_duration multiplied_duration
444 %type <scm> Generic_prefix_music_scm
445 %type <scm> lyric_element
446 %type <scm> Alternative_music
447 %type <scm> full_markup markup_composed_list markup_braced_list markup_braced_list_body markup_head_1_item markup_head_1_list markup simple_markup markup_top
448 %type <scm> mode_changing_head
449 %type <scm> mode_changing_head_with_context
450 %type <scm> object_id_setting
452 %type <score> score_block score_body
457 /* We don't assign precedence to / and *, because we might need varied
458 prec levels in different prods */
464 lilypond: /* empty */
465 | lilypond toplevel_expression {
467 | lilypond assignment {
470 THIS->error_level_ = 1;
473 THIS->error_level_ = 1;
479 OBJECTID STRING { $$ = $2; }
484 THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1);
491 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
492 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
493 scm_gc_unprotect_object (book->self_scm ());
498 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
499 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
500 scm_gc_unprotect_object (score->self_scm ());
504 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
505 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
506 scm_gc_unprotect_object (music->self_scm ());
510 Output_def * od = $1;
512 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
513 id = ly_symbol2scm ("$defaultpaper");
514 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
515 id = ly_symbol2scm ("$defaultmidi");
516 else if ($1->c_variable ("is-layout") == SCM_BOOL_T)
517 id = ly_symbol2scm ("$defaultlayout");
519 THIS->lexer_->set_identifier (id, od->self_scm ());
520 scm_gc_unprotect_object (od->self_scm ());
535 lilypond_header_body:
537 $$ = ly_make_anonymous_module (safe_global_b);
538 THIS->lexer_->add_scope ($$);
540 | lilypond_header_body assignment {
546 HEADER '{' lilypond_header_body '}' {
547 $$ = THIS->lexer_->remove_scope ();
559 /* cont */ '=' identifier_init {
562 Should find generic way of associating input with objects.
564 Input ip = THIS->pop_spot ();
566 if (! is_regular_identifier ($1))
568 ip.warning (_ ("Identifier should have alphabetic characters only"));
571 THIS->lexer_->set_identifier ($1, $4);
574 TODO: devise standard for protection in parser.
576 The parser stack lives on the C-stack, which means that
577 all objects can be unprotected as soon as they're here.
587 $$ = $1->self_scm ();
588 scm_gc_unprotect_object ($$);
591 $$ = $1->self_scm ();
592 scm_gc_unprotect_object ($$);
594 | context_def_spec_block {
598 $$ = $1->self_scm ();
599 scm_gc_unprotect_object ($$);
602 $$ = $1->self_scm ();
603 scm_gc_unprotect_object ($$);
605 | number_expression {
618 $$ = scm_int2num ($1);
622 context_def_spec_block:
623 CONTEXT '{' context_def_spec_body '}'
629 context_def_spec_body:
631 $$ = Context_def::make_scm ();
632 unsmob_context_def ($$)->set_spot (THIS->here_input ());
634 | CONTEXT_DEF_IDENTIFIER {
636 unsmob_context_def ($$)->set_spot (THIS->here_input ());
638 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
639 Context_def*td = unsmob_context_def ($$);
641 for (SCM p = $3; scm_is_pair (p); p = scm_cdr (p)) {
642 SCM tag = scm_caar (p);
644 /* TODO: should make new tag "grob-definition" ? */
645 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
646 tag, scm_cons (scm_cdar (p), SCM_EOL)));
649 | context_def_spec_body context_mod {
650 unsmob_context_def ($$)->add_context_mod ($2);
660 /*cont*/ '{' book_body '}' {
667 * Use 'handlers' like for toplevel-* stuff?
668 * grok \layout and \midi? */
672 $$->set_spot (THIS->here_input ());
673 $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
674 scm_gc_unprotect_object ($$->paper_->self_scm ());
675 $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader");
677 | book_body paper_block {
679 scm_gc_unprotect_object ($2->self_scm ());
681 | book_body score_block {
683 $$->add_score (score);
685 | book_body lilypond_header {
692 | book_body object_id_setting {
693 $$->user_key_ = ly_scm2string ($2);
701 /*cont*/ '{' score_body '}' {
711 $$->set_spot (THIS->here_input ());
714 $$ = new Score ( *unsmob_score ($1));
715 $$->set_spot (THIS->here_input ());
717 | score_body object_id_setting {
718 $$->user_key_ = ly_scm2string ($2);
721 SCM m = $2->self_scm ();
722 scm_gc_unprotect_object (m);
723 $$->set_music (m, THIS->self_scm ());
725 | score_body lilypond_header {
728 | score_body output_def {
729 if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
731 THIS->parser_error (_("\\paper cannot be in \\score. Use \\layout instead"));
738 scm_gc_unprotect_object ($2->self_scm ());
741 $$->error_found_ = true;
753 if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
755 THIS->parser_error (_("Need \\paper for paper block."));
756 $$ = get_paper (THIS);
763 output_def_body '}' {
766 THIS->lexer_->remove_scope ();
767 THIS->lexer_->pop_state ();
773 $$ = get_paper (THIS);
774 $$->input_origin_ = THIS->here_input ();
775 THIS->lexer_->add_scope ($$->scope_);
778 Output_def *p = get_midi (THIS);
780 THIS->lexer_->add_scope (p->scope_);
783 Output_def *p = get_layout (THIS);
785 THIS->lexer_->add_scope (p->scope_);
792 output_def_head '{' {
794 $$->input_origin_.set_spot (THIS->here_input ());
795 THIS->lexer_->push_initial_state ();
797 | output_def_head '{' OUTPUT_DEF_IDENTIFIER {
798 scm_gc_unprotect_object ($1->self_scm ());
799 Output_def *o = unsmob_output_def ($3);
800 o->input_origin_.set_spot (THIS->here_input ());
802 THIS->lexer_->remove_scope ();
803 THIS->lexer_->add_scope (o->scope_);
804 THIS->lexer_->push_initial_state ();
806 | output_def_body assignment {
809 | output_def_body context_def_spec_block {
810 assign_context_def ($$, $2);
812 | output_def_body tempo_event {
814 junk this ? there already is tempo stuff in
817 int m = scm_to_int ($2->get_property ("metronome-count"));
818 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
819 set_tempo ($$, d->get_length (), m);
820 scm_gc_unprotect_object ($2->self_scm ());
822 | output_def_body error {
828 TEMPO steno_duration '=' bare_unsigned {
829 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
830 $$->set_property ("tempo-unit", $2);
831 $$->set_property ("metronome-count", scm_int2num ( $4));
836 The representation of a list is the
840 to have efficient append. */
844 $$ = scm_cons (SCM_EOL, SCM_EOL);
848 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
849 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
851 if (scm_is_pair (scm_cdr (s)))
852 scm_set_cdr_x (scm_cdr (s), c); /* append */
854 scm_set_car_x (s, c); /* set first cons */
855 scm_set_cdr_x (s, c); /* remember last cell */
857 | Music_list embedded_scm {
861 Music * m = MY_MAKE_MUSIC("Music");
863 m->set_property ("error-found", SCM_BOOL_T);
865 SCM c = scm_cons (m->self_scm (), SCM_EOL);
866 scm_gc_unprotect_object (m->self_scm ()); /* UGH */
868 if (scm_is_pair (scm_cdr (s)))
869 scm_set_cdr_x (scm_cdr (s), c); /* append */
871 scm_set_car_x (s, c); /* set first cons */
872 scm_set_cdr_x (s, c); /* remember last cell */
885 | ALTERNATIVE '{' Music_list '}' {
892 REPEAT simple_string bare_unsigned Music Alternative_music
896 SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
897 if (times < scm_ilength (alts)) {
898 unsmob_music (scm_car (alts))
899 ->origin ()->warning (
900 _ ("More alternatives than repeats. Junking excess alternatives."));
901 alts = ly_truncate_list (times, alts);
905 SCM proc = ly_scheme_function ("make-repeated-music");
907 SCM mus = scm_call_1 (proc, $2);
908 scm_gc_protect_object (mus); // UGH.
909 Music *r = unsmob_music (mus);
912 r-> set_property ("element", beg->self_scm ());
913 scm_gc_unprotect_object (beg->self_scm ());
915 r->set_property ("repeat-count", scm_int2num (times >? 1));
917 r-> set_property ("elements",alts);
918 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
920 TODO: move this code to Scheme.
924 we can not get durations and other stuff correct down the line, so we have to
925 add to the duration log here.
927 SCM func = ly_scheme_function ("shift-duration-log");
929 int dots = ($3 % 3) ? 0 : 1;
930 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
932 Sequential_music *seq = dynamic_cast<Sequential_music*> ($4);
935 int list_len = scm_ilength (seq->music_list ());
937 seq->origin ()->warning ("Chord tremolo must have 2 elements.");
939 r->compress (Moment (Rational (1, list_len)));
941 scm_call_3 (func, r->self_scm (), scm_int2num (shift),scm_int2num (dots));
944 r->set_spot (*$4->origin ());
951 SEQUENTIAL '{' Music_list '}' {
952 $$ = MY_MAKE_MUSIC ("SequentialMusic");
953 $$->set_property ("elements", scm_car ($3));
954 $$->set_spot (THIS->here_input ());
956 | '{' Music_list '}' {
957 $$ = MY_MAKE_MUSIC ("SequentialMusic");
958 $$->set_property ("elements", scm_car ($2));
959 $$->set_spot (THIS->here_input ());
964 SIMULTANEOUS '{' Music_list '}'{
965 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
966 $$->set_property ("elements", scm_car ($3));
967 $$->set_spot (THIS->here_input ());
970 | simul_open Music_list simul_close {
971 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
972 $$->set_property ("elements", scm_car ($2));
973 $$->set_spot (THIS->here_input ());
978 event_chord { $$ = $1; }
980 $$ = unsmob_music ($1);
987 optional_context_mod:
988 /**/ { $$ = SCM_EOL; }
989 | WITH { THIS->lexer_->push_initial_state (); }
990 '{' context_mod_list '}'
992 THIS->lexer_->pop_state ();
998 /* */ { $$ = SCM_EOL; }
999 | context_mod_list context_mod {
1000 $$ = scm_cons ($2, $1);
1006 Prefix_composite_music { $$ = $1; }
1007 | Grouped_music_list { $$ = $1; }
1011 Simultaneous_music { $$ = $1; }
1012 | Sequential_music { $$ = $1; }
1015 Generic_prefix_music_scm:
1017 $$ = scm_list_2 ($1, make_input (THIS->here_input ()));
1019 | MUSIC_FUNCTION_SCM {
1022 $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3);
1024 | MUSIC_FUNCTION_MARKUP {
1027 $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3);
1029 | MUSIC_FUNCTION_MUSIC {
1032 $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3->self_scm ());
1033 scm_gc_unprotect_object ($3->self_scm ());
1035 | MUSIC_FUNCTION_SCM_MUSIC {
1037 } embedded_scm Music {
1038 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4->self_scm ());
1039 scm_gc_unprotect_object ($4->self_scm ());
1041 | MUSIC_FUNCTION_SCM_SCM {
1043 } embedded_scm embedded_scm {
1044 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4);
1046 | MUSIC_FUNCTION_SCM_SCM_MUSIC {
1048 } embedded_scm embedded_scm Music {
1049 $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()), $3, $4, $5->self_scm ());
1051 | MUSIC_FUNCTION_MARKUP_MUSIC {
1053 } full_markup Music {
1054 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4->self_scm ());
1055 scm_gc_unprotect_object ($4->self_scm ());
1057 | MUSIC_FUNCTION_MARKUP_MARKUP {
1059 } full_markup full_markup {
1060 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4);
1062 | MUSIC_FUNCTION_MUSIC_MUSIC {
1065 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3->self_scm (), $4->self_scm ());
1066 scm_gc_unprotect_object ($3->self_scm ());
1067 scm_gc_unprotect_object ($4->self_scm ());
1069 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC {
1071 } embedded_scm Music Music {
1072 $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()),
1073 $3, $4->self_scm (), $5->self_scm ());
1074 scm_gc_unprotect_object ($5->self_scm ());
1075 scm_gc_unprotect_object ($4->self_scm ());
1077 | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC {
1079 } full_markup Music Music {
1080 $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()),
1081 $3, $4->self_scm (), $5->self_scm ());
1082 scm_gc_unprotect_object ($5->self_scm ());
1083 scm_gc_unprotect_object ($4->self_scm ());
1087 Generic_prefix_music:
1088 Generic_prefix_music_scm {
1089 SCM func = scm_car ($1);
1090 Input *loc = unsmob_input (scm_cadr ($1));
1091 SCM args = scm_cddr ($1);
1092 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1094 SCM type_check_proc = ly_scheme_function ("type-check-list");
1097 if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr ($1), sig, args)))
1099 THIS->error_level_ = 1;
1105 m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
1108 if (unsmob_music (m))
1110 $$ = unsmob_music (m);
1111 scm_gc_protect_object (m);
1116 loc->error (_ ("Music head function should return Music object."));
1117 $$ = MY_MAKE_MUSIC ("Music");
1119 $$->set_spot (*loc);
1124 Prefix_composite_music:
1125 Generic_prefix_music {
1128 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1129 $$ = context_spec_music ($2, $4, $6, $5);
1132 | CONTEXT simple_string optional_context_mod Music {
1133 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1135 | NEWCONTEXT simple_string optional_context_mod Music {
1136 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1147 int n = scm_to_int (scm_car ($3)); int d = scm_to_int (scm_cdr ($3));
1150 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1151 $$->set_spot (THIS->pop_spot ());
1153 $$->set_property ("element", mp->self_scm ());
1154 scm_gc_unprotect_object (mp->self_scm ());
1155 $$->set_property ("numerator", scm_int2num (n));
1156 $$->set_property ("denominator", scm_int2num (d));
1157 $$->compress (Moment (Rational (n,d)));
1160 | Repeated_music { $$ = $1; }
1161 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1162 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1164 Pitch from = *unsmob_pitch ($2);
1165 Pitch to = *unsmob_pitch ($3);
1167 p->transpose (pitch_interval (from, to));
1168 $$->set_property ("element", p->self_scm ());
1169 scm_gc_unprotect_object (p->self_scm ());
1171 | mode_changing_head Grouped_music_list {
1172 if ($1 == ly_symbol2scm ("chords"))
1174 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1175 chm->set_property ("element", $2->self_scm ());
1177 scm_gc_unprotect_object ($2->self_scm ());
1183 THIS->lexer_->pop_state ();
1185 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1186 $$ = context_spec_music ($1, get_next_unique_context_id (),
1188 if ($1 == ly_symbol2scm ("ChordNames"))
1190 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1191 chm->set_property ("element", $$->self_scm ());
1192 scm_gc_unprotect_object ($$->self_scm ());
1195 THIS->lexer_->pop_state ();
1197 | relative_music { $$ = $1; }
1198 | re_rhythmed_music { $$ = $1; }
1199 | TAG embedded_scm Music {
1200 tag_music ($3, $2, THIS->here_input ());
1207 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1208 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1210 $$ = ly_symbol2scm ("notes");
1214 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1215 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1217 $$ = ly_symbol2scm ("drums");
1220 THIS->lexer_->push_figuredbass_state ();
1222 $$ = ly_symbol2scm ("figures");
1225 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1226 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1227 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1228 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1229 $$ = ly_symbol2scm ("chords");
1233 { THIS->lexer_->push_lyric_state ();
1234 $$ = ly_symbol2scm ("lyrics");
1238 mode_changing_head_with_context:
1240 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1241 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1243 $$ = ly_symbol2scm ("DrumStaff");
1246 THIS->lexer_->push_figuredbass_state ();
1248 $$ = ly_symbol2scm ("FiguredBass");
1251 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1252 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1253 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1254 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1255 $$ = ly_symbol2scm ("ChordNames");
1258 { THIS->lexer_->push_lyric_state ();
1259 $$ = ly_symbol2scm ("Lyrics");
1265 RELATIVE absolute_pitch Music {
1267 Pitch start = *unsmob_pitch ($2);
1268 $$ = make_music_relative (start, m);
1269 scm_gc_unprotect_object (m->self_scm ());
1271 | RELATIVE Composite_music {
1274 Pitch middle_c (0, 0, 0);
1275 $$ = make_music_relative (middle_c, m);
1276 scm_gc_unprotect_object (m->self_scm ());
1281 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1283 Grouped_music_list {
1284 /* Can also use Music at the expensive of two S/Rs similar to
1285 \repeat \alternative */
1286 THIS->lexer_->pop_state ();
1288 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1290 | new_lyrics ADDLYRICS {
1291 THIS->lexer_->push_lyric_state ();
1292 } Grouped_music_list {
1293 THIS->lexer_->pop_state ();
1294 $$ = scm_cons ($4->self_scm (), $1);
1299 Grouped_music_list new_lyrics {
1301 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1302 if (!scm_is_string (name))
1304 name = get_next_unique_lyrics_context_id ();
1305 voice = context_spec_music (scm_makfrom0str ("Voice"),
1310 SCM context = scm_makfrom0str ("Lyrics");
1311 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1314 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1316 Music *music = unsmob_music (scm_car (s));
1317 Music *com = make_lyric_combine_music (name, music);
1318 Music *csm = context_spec_music (context,
1319 get_next_unique_context_id (), com, SCM_EOL);
1320 lst = scm_cons (csm->self_scm (), lst);
1322 all->set_property ("elements", scm_cons (voice->self_scm (),
1325 scm_gc_unprotect_object (voice->self_scm ());
1328 THIS->lexer_->push_lyric_state ();
1329 } simple_string Music {
1330 THIS->lexer_->pop_state ();
1333 $$ = make_lyric_combine_music (name, music);
1334 scm_gc_unprotect_object (music->self_scm ());
1339 CHANGE STRING '=' STRING {
1340 Music*t= MY_MAKE_MUSIC ("ContextChange");
1341 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1342 t-> set_property ("change-to-id", $4);
1345 $$->set_spot (THIS->here_input ());
1351 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1352 scm_string_to_symbol ($1), $3);
1354 | UNSET simple_string {
1355 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1356 scm_string_to_symbol ($2));
1358 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1359 $$ = scm_list_4 (ly_symbol2scm ("push"),
1360 scm_string_to_symbol ($2), $3, $5);
1362 | REVERT simple_string embedded_scm {
1363 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1364 scm_string_to_symbol ($2), $3);
1369 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1370 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1372 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1373 | DENIES { $$ = ly_symbol2scm ("denies"); }
1375 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1376 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1377 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1378 | NAME { $$ = ly_symbol2scm ("context-name"); }
1382 property_operation { $$ = $1; }
1383 | context_def_mod STRING {
1384 $$ = scm_list_2 ($1, $2);
1390 if (!is_regular_identifier ($1))
1392 THIS->here_input ().error (_("Grob name should be alphanumeric"));
1395 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1396 scm_string_to_symbol ($1));
1398 | simple_string '.' simple_string {
1399 $$ = scm_list_2 (scm_string_to_symbol ($1),
1400 scm_string_to_symbol ($3));
1405 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1406 $$ = property_op_to_music (scm_list_4 (
1407 ly_symbol2scm ("poppush"),
1410 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1412 | REVERT context_prop_spec embedded_scm {
1413 $$ = property_op_to_music (scm_list_3 (
1414 ly_symbol2scm ("pop"),
1418 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1420 | SET context_prop_spec '=' scalar {
1421 $$ = property_op_to_music (scm_list_3 (
1422 ly_symbol2scm ("assign"),
1425 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1427 | UNSET context_prop_spec {
1428 $$ = property_op_to_music (scm_list_2 (
1429 ly_symbol2scm ("unset"),
1431 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1433 | ONCE music_property_def {
1434 SCM e = $2->get_property ("element");
1435 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1446 | STRING_IDENTIFIER {
1449 | string '+' string {
1450 $$ = scm_string_append (scm_list_2 ($1, $3));
1454 simple_string: STRING {
1469 $$ = scm_int2num ($1);
1478 $$ = scm_int2num ($1);
1484 pre_events doesn't contain anything. It is a trick:
1486 Adding pre_events to the simple_element
1487 makes the choice between
1493 simple_element: STRING
1495 a single shift/reduction conflict.
1497 nevertheless, this is not very clean, and we should find a different
1507 pre_events simple_element post_events {
1508 SCM elts = $2-> get_property ("elements");
1510 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1512 $2->set_property ("elements", elts);
1516 | note_chord_element
1521 chord_body optional_notemode_duration post_events
1523 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1524 SCM es = $1->get_property ("elements");
1525 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1527 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1528 unsmob_music (scm_car (s))->set_property ("duration", dur);
1529 es = ly_append2 (es, postevs);
1531 $1-> set_property ("elements", es);
1542 simul_open: DOUBLE_ANGLE_OPEN
1545 simul_close: DOUBLE_ANGLE_CLOSE
1549 chord_open chord_body_elements chord_close
1551 $$ = MY_MAKE_MUSIC ("EventChord");
1552 $$->set_property ("elements",
1553 scm_reverse_x ($2, SCM_EOL));
1557 chord_body_elements:
1558 /* empty */ { $$ = SCM_EOL; }
1559 | chord_body_elements chord_body_element {
1560 $$ = scm_cons ($2->self_scm (), $1);
1561 scm_gc_unprotect_object ($2->self_scm ());
1566 pitch exclamations questions octave_check post_events
1573 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1574 n->set_property ("pitch", $1);
1576 n->set_property ("cautionary", SCM_BOOL_T);
1577 if (ex % 2 || q % 2)
1578 n->set_property ("force-accidental", SCM_BOOL_T);
1580 if (scm_is_pair (post)) {
1581 SCM arts = scm_reverse_x (post, SCM_EOL);
1582 n->set_property ("articulations", arts);
1584 if (scm_is_number (check))
1586 int q = scm_to_int (check);
1587 n->set_property ("absolute-octave", scm_int2num (q-1));
1593 | DRUM_PITCH post_events {
1594 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1595 n->set_property ("duration", $2);
1596 n->set_property ("drum-type", $1);
1597 n->set_spot (THIS->here_input ());
1599 if (scm_is_pair ($2)) {
1600 SCM arts = scm_reverse_x ($2, SCM_EOL);
1601 n->set_property ("articulations", arts);
1608 ADDQUOTE string Music {
1609 SCM adder = ly_scheme_function ("add-quotable");
1611 scm_call_2 (adder, $2, $3->self_scm ());
1612 scm_gc_unprotect_object ($3->self_scm ());
1618 $$ = MY_MAKE_MUSIC ("EventChord");
1619 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1620 scm_gc_unprotect_object ($1->self_scm ());
1622 $$-> set_spot (THIS->here_input ());
1623 $1-> set_spot (THIS->here_input ());
1625 | SKIP duration_length {
1626 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1627 skip->set_property ("duration", $2);
1631 | OCTAVE { THIS->push_spot (); }
1633 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1635 $$->set_spot (THIS->pop_spot ());
1636 $$->set_property ("pitch", $3);
1639 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1640 m->set_property ("span-direction", scm_int2num (START));
1641 m->set_spot (THIS->here_input ());
1643 $$ = MY_MAKE_MUSIC ("EventChord");
1644 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1645 scm_gc_unprotect_object (m->self_scm ());
1646 $$->set_spot (THIS->here_input ());
1649 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1650 m->set_property ("span-direction", scm_int2num (STOP));
1651 m->set_spot (THIS->here_input ());
1653 $$ = MY_MAKE_MUSIC ("EventChord");
1654 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1655 $$->set_spot (THIS->here_input ());
1656 scm_gc_unprotect_object (m->self_scm ());
1659 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1660 $$->set_spot (THIS->here_input ());
1663 SCM pipe =THIS->lexer_->lookup_identifier ("pipeSymbol");
1665 if (Music * m = unsmob_music (pipe))
1668 $$ = MY_MAKE_MUSIC ("BarCheck");
1670 $$->set_spot (THIS->here_input ());
1672 | TRANSPOSITION pitch {
1674 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1675 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1676 sounds_as_c.smobbed_copy());
1677 $$->set_spot (THIS-> here_input ());
1678 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1682 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1684 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1686 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1687 $$->set_spot (THIS->here_input ());
1688 t->set_spot (THIS->here_input ());
1690 | PARTIAL duration_length {
1691 Moment m = - unsmob_duration ($2)->get_length ();
1692 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1693 p->set_spot (THIS->here_input ());
1694 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1696 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1701 SCM proc = ly_scheme_function ("make-clef-set");
1703 SCM result = scm_call_1 (proc, $2);
1704 scm_gc_protect_object (result);
1705 $$ = unsmob_music (result);
1708 SCM proc= ly_scheme_function ("make-time-signature-set");
1710 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1711 scm_gc_protect_object (result);
1712 $$ = unsmob_music (result);
1715 SCM proc = ly_scheme_function ("make-mark-set");
1717 SCM result = scm_call_1 (proc, $2);
1718 scm_gc_protect_object (result);
1719 $$ = unsmob_music (result);
1725 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1728 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1735 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1738 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1740 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1741 if (scm_ilength ($3) > 0)
1743 key->set_property ("pitch-alist", $3);
1744 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1745 key->transpose (* unsmob_pitch ($2));
1747 THIS->parser_error (_ ("Second argument must be pitch list."));
1758 | post_events post_event {
1759 $2->set_spot (THIS->here_input ());
1760 $$ = scm_cons ($2->self_scm (), $$);
1761 scm_gc_unprotect_object ($2->self_scm ());
1763 | post_events tagged_post_event {
1764 $2 -> set_spot (THIS->here_input ());
1765 $$ = scm_cons ($2->self_scm (), $$);
1766 scm_gc_unprotect_object ($2->self_scm ());
1772 '-' TAG embedded_scm post_event {
1773 tag_music ($4, $3, THIS->here_input ());
1779 direction_less_event {
1783 if (!THIS->lexer_->is_lyric_state ())
1784 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1785 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1788 if (!THIS->lexer_->is_lyric_state ())
1789 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1790 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1792 | script_dir direction_reqd_event {
1794 $2->set_property ("direction", scm_int2num ($1));
1797 | script_dir direction_less_event {
1799 $2->set_property ("direction", scm_int2num ($1));
1802 | string_number_event
1805 string_number_event:
1807 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1808 s->set_property ("string-number", scm_int2num ($1));
1809 s->set_spot (THIS->here_input ());
1814 direction_less_char:
1816 $$ = ly_symbol2scm ("bracketOpenSymbol");
1819 $$ = ly_symbol2scm ("bracketCloseSymbol");
1822 $$ = ly_symbol2scm ("tildeSymbol");
1825 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1828 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1831 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1834 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1837 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1840 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1843 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1847 direction_less_event:
1848 direction_less_char {
1849 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1851 if (unsmob_music (predefd))
1853 m = unsmob_music (predefd)->clone ();
1857 m = MY_MAKE_MUSIC ("Music");
1859 m->set_spot (THIS->here_input ());
1862 | EVENT_IDENTIFIER {
1863 $$ = unsmob_music ($1);
1866 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1867 a->set_spot (THIS->here_input ());
1868 a->set_property ("tremolo-type", scm_int2num ($1));
1873 direction_reqd_event:
1877 | script_abbreviation {
1878 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1879 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1880 if (scm_is_string (s))
1881 a->set_property ("articulation-type", s);
1882 else THIS->parser_error (_ ("Expecting string as script definition"));
1888 /**/ { $$ = SCM_EOL; }
1889 | '=' { $$ = scm_int2num (0); }
1890 | '=' sub_quotes { $$ = scm_int2num ($2); }
1891 | '=' sup_quotes { $$ = scm_int2num ($2); }
1916 | NOTENAME_PITCH sup_quotes {
1917 Pitch p = *unsmob_pitch ($1);
1918 p = p.transposed (Pitch ($2,0,0));
1919 $$ = p.smobbed_copy ();
1921 | NOTENAME_PITCH sub_quotes {
1922 Pitch p =* unsmob_pitch ($1);
1923 p = p.transposed (Pitch (-$2,0,0));
1924 $$ = p.smobbed_copy ();
1936 | TONICNAME_PITCH sup_quotes {
1937 Pitch p = *unsmob_pitch ($1);
1938 p = p.transposed (Pitch ($2,0,0));
1939 $$ = p.smobbed_copy ();
1941 | TONICNAME_PITCH sub_quotes {
1942 Pitch p =* unsmob_pitch ($1);
1944 p = p.transposed (Pitch (-$2,0,0));
1945 $$ = p.smobbed_copy ();
1955 pitch_also_in_chords:
1962 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1963 t->set_property ("text", $1);
1964 t->set_spot (THIS->here_input ());
1968 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1969 t->set_property ("text",
1970 make_simple_markup (THIS->lexer_->encoding (), $1));
1971 t->set_spot (THIS->here_input ());
1976 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1977 t->set_property ("digit", scm_int2num ($1));
1978 t->set_spot (THIS->here_input ());
1983 script_abbreviation:
1985 $$ = scm_makfrom0str ("Hat");
1988 $$ = scm_makfrom0str ("Plus");
1991 $$ = scm_makfrom0str ("Dash");
1994 $$ = scm_makfrom0str ("Bar");
1997 $$ = scm_makfrom0str ("Larger");
2000 $$ = scm_makfrom0str ("Dot");
2003 $$ = scm_makfrom0str ("Underscore");
2010 | '-' { $$ = CENTER; }
2021 multiplied_duration {
2026 optional_notemode_duration:
2028 Duration dd = THIS->default_duration_;
2029 $$ = dd.smobbed_copy ();
2031 THIS->beam_check ($$);
2033 | multiplied_duration {
2035 THIS->default_duration_ = *unsmob_duration ($$);
2037 THIS->beam_check ($$);
2042 bare_unsigned dots {
2044 if (!is_duration ($1))
2045 THIS->parser_error (_f ("not a duration: %d", $1));
2049 $$ = Duration (len, $2).smobbed_copy ();
2051 | DURATION_IDENTIFIER dots {
2052 Duration *d = unsmob_duration ($1);
2053 Duration k (d->duration_log (), d->dot_count () + $2);
2059 multiplied_duration:
2063 | multiplied_duration '*' bare_unsigned {
2064 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2066 | multiplied_duration '*' FRACTION {
2067 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2069 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2074 FRACTION { $$ = $1; }
2075 | UNSIGNED '/' UNSIGNED {
2076 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2093 | ':' bare_unsigned {
2094 if (!is_duration ($2))
2095 THIS->parser_error (_f ("not a duration: %d", $2));
2102 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2103 $$ = scm_list_2 (ly_scheme_function ("number-markup"),
2107 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2108 $$ = scm_list_2 (ly_scheme_function ("number-markup"),
2111 | STRING { $$ = $1; }
2122 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2123 $$ = bfr->self_scm ();
2124 scm_gc_unprotect_object ($$);
2127 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2128 $$ = bfr->self_scm ();
2130 bfr->set_property ("figure", $1);
2132 scm_gc_unprotect_object ($$);
2134 | bass_figure bass_mod {
2135 Music *m = unsmob_music ($1);
2137 SCM salter = m->get_property ("alteration");
2138 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2139 m->set_property ("alteration",
2140 scm_int2num (alter + $2));
2142 m->set_property ("alteration", scm_int2num (0));
2150 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2155 | br_bass_figure ']' {
2157 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2165 | figure_list br_bass_figure {
2166 $$ = scm_cons ($2, $1);
2171 FIGURE_OPEN figure_list FIGURE_CLOSE {
2172 Music *m = MY_MAKE_MUSIC ("EventChord");
2173 $2 = scm_reverse_x ($2, SCM_EOL);
2174 m->set_property ("elements", $2);
2175 $$ = m->self_scm ();
2186 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2188 Input i = THIS->pop_spot ();
2189 if (!THIS->lexer_->is_note_state ())
2190 THIS->parser_error (_ ("Have to be in Note mode for notes"));
2194 n = MY_MAKE_MUSIC ("RestEvent");
2196 n = MY_MAKE_MUSIC ("NoteEvent");
2198 n->set_property ("pitch", $1);
2199 n->set_property ("duration", $5);
2201 if (scm_is_number ($4))
2203 int q = scm_to_int ($4);
2204 n->set_property ("absolute-octave", scm_int2num (q-1));
2208 n->set_property ("cautionary", SCM_BOOL_T);
2209 if ($2 % 2 || $3 % 2)
2210 n->set_property ("force-accidental", SCM_BOOL_T);
2212 Music *v = MY_MAKE_MUSIC ("EventChord");
2213 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2214 scm_gc_unprotect_object (n->self_scm ());
2220 | DRUM_PITCH optional_notemode_duration {
2221 Input i = THIS->pop_spot ();
2223 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2224 n->set_property ("duration", $2);
2225 n->set_property ("drum-type", $1);
2227 Music *v = MY_MAKE_MUSIC ("EventChord");
2228 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2229 scm_gc_unprotect_object (n->self_scm ());
2235 | figure_spec optional_notemode_duration {
2236 Music *m = unsmob_music ($1);
2237 Input i = THIS->pop_spot ();
2239 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2241 unsmob_music (scm_car (s))->set_property ("duration", $2);
2245 | RESTNAME optional_notemode_duration {
2247 Input i = THIS->pop_spot ();
2249 if (ly_scm2string ($1) == "s") {
2251 ev = MY_MAKE_MUSIC ("SkipEvent");
2254 ev = MY_MAKE_MUSIC ("RestEvent");
2257 ev->set_property ("duration", $2);
2259 Music *velt = MY_MAKE_MUSIC ("EventChord");
2260 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2263 scm_gc_unprotect_object (ev->self_scm ());
2267 | MULTI_MEASURE_REST optional_notemode_duration {
2270 SCM proc = ly_scheme_function ("make-multi-measure-rest");
2271 SCM mus = scm_call_2 (proc, $2,
2272 make_input (THIS->here_input ()));
2273 scm_gc_protect_object (mus);
2274 $$ = unsmob_music (mus);
2277 | lyric_element optional_notemode_duration {
2278 Input i = THIS->pop_spot ();
2279 if (!THIS->lexer_->is_lyric_state ())
2280 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
2282 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2283 lreq->set_property ("text", $1);
2284 lreq->set_property ("duration",$2);
2286 Music *velt = MY_MAKE_MUSIC ("EventChord");
2287 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2294 if (!THIS->lexer_->is_chord_state ())
2295 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
2296 $$ = unsmob_music ($1);
2301 /* FIXME: lyric flavoured markup would be better */
2306 $$ = make_simple_markup (THIS->lexer_->encoding (), $1);
2311 steno_tonic_pitch optional_notemode_duration {
2312 $$ = make_chord ($1, $2, SCM_EOL);
2314 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2315 SCM its = scm_reverse_x ($4, SCM_EOL);
2316 $$ = make_chord ($1, $2, scm_cons ($3, its));
2324 | chord_items chord_item {
2325 $$ = scm_cons ($2, $$);
2331 $$ = ly_symbol2scm ("chord-colon");
2334 $$ = ly_symbol2scm ("chord-caret");
2336 | CHORD_SLASH steno_tonic_pitch {
2337 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2339 | CHORD_BASS steno_tonic_pitch {
2340 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2349 $$ = scm_reverse_x ($1, SCM_EOL);
2357 step_number { $$ = scm_cons ($1, SCM_EOL); }
2358 | step_numbers '.' step_number {
2359 $$ = scm_cons ($3, $$);
2365 $$ = make_chord_step ($1, 0);
2367 | bare_unsigned '+' {
2368 $$ = make_chord_step ($1, SHARP);
2370 | bare_unsigned CHORD_MINUS {
2371 $$ = make_chord_step ($1, FLAT);
2378 TODO: should deprecate in favor of Scheme?
2382 number_expression '+' number_term {
2383 $$ = scm_sum ($1, $3);
2385 | number_expression '-' number_term {
2386 $$ = scm_difference ($1, $3);
2395 | number_factor '*' number_factor {
2396 $$ = scm_product ($1, $3);
2398 | number_factor '/' number_factor {
2399 $$ = scm_divide ($1, $3);
2404 '-' number_factor { /* %prec UNARY_MINUS */
2405 $$ = scm_difference ($2, SCM_UNDEFINED);
2413 $$ = scm_int2num ($1);
2418 | NUMBER_IDENTIFIER {
2421 | REAL NUMBER_IDENTIFIER {
2422 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2424 | UNSIGNED NUMBER_IDENTIFIER {
2425 $$ = scm_make_real ($1 *scm_to_double ($2));
2441 if (scm_integer_p ($1) == SCM_BOOL_T)
2443 int k = scm_to_int ($1);
2447 THIS->parser_error (_ ("need integer number arg"));
2458 | exclamations '!' { $$ ++; }
2463 | questions '?' { $$ ++; }
2467 This should be done more dynamically if possible.
2475 { THIS->lexer_->push_markup_state (); }
2478 THIS->lexer_->pop_state ();
2483 markup_composed_list {
2484 $$ = scm_list_2 (ly_scheme_function ("line-markup"), $1);
2486 | markup_head_1_list simple_markup {
2487 $$ = scm_car (scm_call_2 (ly_scheme_function ("map-markup-command-list"), $1, scm_list_1 ($2)));
2492 | markup_braced_list {
2493 $$ = scm_list_2 (ly_scheme_function ("line-markup"), $1);
2497 markup_composed_list:
2498 markup_head_1_list markup_braced_list {
2499 $$ = scm_call_2 (ly_scheme_function ("map-markup-command-list"), $1, $2);
2505 '{' markup_braced_list_body '}' {
2506 $$ = scm_reverse_x ($2, SCM_EOL);
2510 markup_braced_list_body:
2511 /* empty */ { $$ = scm_list (SCM_EOL); }
2512 | markup_braced_list_body markup {
2513 $$ = scm_cons ($2, $1);
2515 | markup_braced_list_body markup_composed_list {
2516 $$ = scm_append_x (scm_list_2 (scm_reverse_x ($2, SCM_EOL), $1));
2521 MARKUP_HEAD_MARKUP0 {
2522 $$ = scm_list_1 ($1);
2524 | MARKUP_HEAD_SCM0_MARKUP1 embedded_scm {
2525 $$ = scm_list_2 ($1, $2);
2527 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm {
2528 $$ = scm_list_3 ($1, $2, $3);
2533 markup_head_1_item {
2534 $$ = scm_list_1 ($1);
2536 | markup_head_1_list markup_head_1_item {
2537 $$ = scm_cons ($2, $1);
2543 $$ = make_simple_markup (THIS->lexer_->encoding (), $1);
2545 | MARKUP_IDENTIFIER {
2548 | STRING_IDENTIFIER {
2552 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2553 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2554 } '{' score_body '}' {
2556 $$ = scm_list_2 (ly_scheme_function ("score-markup"), sc->self_scm ());
2557 scm_gc_unprotect_object (sc->self_scm ());
2558 THIS->lexer_->pop_state ();
2560 | MARKUP_HEAD_SCM0 embedded_scm {
2561 $$ = scm_list_2 ($1, $2);
2563 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2564 $$ = scm_list_4 ($1, $2, $3, $4);
2566 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2567 $$ = scm_list_3 ($1, $2, $3);
2569 | MARKUP_HEAD_EMPTY {
2570 $$ = scm_list_1 ($1);
2572 | MARKUP_HEAD_LIST0 markup_braced_list {
2573 $$ = scm_list_2 ($1,$2);
2575 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2576 $$ = scm_list_3 ($1, $2, $3);
2581 markup_head_1_list simple_markup {
2582 $$ = scm_car (scm_call_2 (ly_scheme_function ("map-markup-command-list"), $1, scm_list_1 ($2)));
2587 | markup_braced_list {
2588 $$ = scm_list_2 (ly_scheme_function ("line-markup"), $1);
2595 Lily_parser::set_yydebug (bool )
2603 Lily_parser::do_yyparse ()
2605 yyparse ((void*)this);
2610 Should make this optional? It will also complain when you do
2614 which is entirely legitimate.
2616 Or we can scrap it. Barchecks should detect wrong durations, and
2617 skipTypesetting speeds it up a lot.
2621 Lily_parser::beam_check (SCM dur)
2623 Duration *d = unsmob_duration (dur);
2624 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2626 Music *m = unsmob_music (last_beam_start_);
2627 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2629 last_beam_start_ = SCM_EOL;
2637 It is a little strange to have this function in this file, but
2638 otherwise, we have to import music classes into the lexer.
2642 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2644 if (scm_is_string (sid)) {
2646 return STRING_IDENTIFIER;
2647 } else if (scm_is_number (sid)) {
2649 return NUMBER_IDENTIFIER;
2650 } else if (unsmob_context_def (sid)) {
2651 *destination = unsmob_context_def (sid)->clone_scm ();
2652 return CONTEXT_DEF_IDENTIFIER;
2653 } else if (unsmob_score (sid)) {
2654 Score *score = new Score (*unsmob_score (sid));
2655 *destination = score->self_scm ();
2656 return SCORE_IDENTIFIER;
2657 } else if (Music *mus = unsmob_music (sid)) {
2658 mus = mus->clone ();
2659 *destination = mus->self_scm ();
2660 unsmob_music (*destination)->
2661 set_property ("origin", make_input (last_input_));
2662 return dynamic_cast<Event*> (mus)
2663 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2664 } else if (unsmob_duration (sid)) {
2665 *destination = unsmob_duration (sid)->smobbed_copy ();
2666 return DURATION_IDENTIFIER;
2667 } else if (unsmob_output_def (sid)) {
2668 Output_def *p = unsmob_output_def (sid);
2671 *destination = p->self_scm ();
2672 return OUTPUT_DEF_IDENTIFIER;
2673 } else if (Text_interface::markup_p (sid)) {
2675 return MARKUP_IDENTIFIER;
2682 property_op_to_music (SCM op)
2685 SCM tag = scm_car (op);
2686 SCM symbol = scm_cadr (op);
2687 SCM args = scm_cddr (op);
2688 SCM grob_val = SCM_UNDEFINED;
2689 SCM grob_sym = SCM_UNDEFINED;
2690 SCM val = SCM_UNDEFINED;
2692 if (tag == ly_symbol2scm ("assign"))
2694 m = MY_MAKE_MUSIC ("PropertySet");
2695 val = scm_car (args);
2697 else if (tag == ly_symbol2scm ("unset"))
2698 m = MY_MAKE_MUSIC ("PropertyUnset");
2699 else if (tag == ly_symbol2scm ("poppush")
2700 || tag == ly_symbol2scm ("push"))
2702 m = MY_MAKE_MUSIC ("OverrideProperty");
2703 grob_sym = scm_car (args);
2704 grob_val = scm_cadr (args);
2706 else if (tag == ly_symbol2scm ("pop")) {
2707 m = MY_MAKE_MUSIC ("RevertProperty");
2708 grob_sym = scm_car (args);
2711 m->set_property ("symbol", symbol);
2713 if (val != SCM_UNDEFINED)
2714 m->set_property ("value", val);
2715 if (grob_val != SCM_UNDEFINED)
2716 m->set_property ("grob-value", grob_val);
2718 if (grob_sym != SCM_UNDEFINED)
2720 bool itc = internal_type_checking_global_b;
2723 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2725 internal_type_checking_global_b = false;
2726 m->set_property ("grob-property", grob_sym);
2728 internal_type_checking_global_b = itc;
2731 if (tag == ly_symbol2scm ("poppush"))
2732 m->set_property ("pop-first", SCM_BOOL_T);
2739 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2741 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2743 csm->set_property ("element", m->self_scm ());
2744 scm_gc_unprotect_object (m->self_scm ());
2746 csm->set_property ("context-type",
2747 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2748 csm->set_property ("property-operations", ops);
2750 if (scm_is_string (id))
2751 csm->set_property ("context-id", id);
2756 get_next_unique_context_id ()
2758 return scm_makfrom0str ("$uniqueContextId");
2763 get_next_unique_lyrics_context_id ()
2765 static int new_context_count;
2767 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2768 return scm_makfrom0str (s);