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> markup markup_line markup_list markup_list_body full_markup
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_cdr ($1));
1107 if (unsmob_music (m))
1109 $$ = unsmob_music (m);
1110 scm_gc_protect_object (m);
1115 loc->error (_ ("Music head function should return Music object."));
1116 $$ = MY_MAKE_MUSIC ("Music");
1118 $$->set_spot (*loc);
1123 Prefix_composite_music:
1124 Generic_prefix_music {
1127 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1128 $$ = context_spec_music ($2, $4, $6, $5);
1131 | CONTEXT simple_string optional_context_mod Music {
1132 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1134 | NEWCONTEXT simple_string optional_context_mod Music {
1135 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1146 int n = scm_to_int (scm_car ($3)); int d = scm_to_int (scm_cdr ($3));
1149 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1150 $$->set_spot (THIS->pop_spot ());
1152 $$->set_property ("element", mp->self_scm ());
1153 scm_gc_unprotect_object (mp->self_scm ());
1154 $$->set_property ("numerator", scm_int2num (n));
1155 $$->set_property ("denominator", scm_int2num (d));
1156 $$->compress (Moment (Rational (n,d)));
1159 | Repeated_music { $$ = $1; }
1160 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1161 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1163 Pitch from = *unsmob_pitch ($2);
1164 Pitch to = *unsmob_pitch ($3);
1166 p->transpose (pitch_interval (from, to));
1167 $$->set_property ("element", p->self_scm ());
1168 scm_gc_unprotect_object (p->self_scm ());
1170 | mode_changing_head Grouped_music_list {
1171 if ($1 == ly_symbol2scm ("chords"))
1173 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1174 chm->set_property ("element", $2->self_scm ());
1176 scm_gc_unprotect_object ($2->self_scm ());
1182 THIS->lexer_->pop_state ();
1184 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1185 $$ = context_spec_music ($1, get_next_unique_context_id (),
1187 if ($1 == ly_symbol2scm ("ChordNames"))
1189 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1190 chm->set_property ("element", $$->self_scm ());
1191 scm_gc_unprotect_object ($$->self_scm ());
1194 THIS->lexer_->pop_state ();
1196 | relative_music { $$ = $1; }
1197 | re_rhythmed_music { $$ = $1; }
1198 | TAG embedded_scm Music {
1199 tag_music ($3, $2, THIS->here_input ());
1206 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1207 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1209 $$ = ly_symbol2scm ("notes");
1213 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1214 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1216 $$ = ly_symbol2scm ("drums");
1219 THIS->lexer_->push_figuredbass_state ();
1221 $$ = ly_symbol2scm ("figures");
1224 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1225 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1226 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1227 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1228 $$ = ly_symbol2scm ("chords");
1232 { THIS->lexer_->push_lyric_state ();
1233 $$ = ly_symbol2scm ("lyrics");
1237 mode_changing_head_with_context:
1239 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1240 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1242 $$ = ly_symbol2scm ("DrumStaff");
1245 THIS->lexer_->push_figuredbass_state ();
1247 $$ = ly_symbol2scm ("FiguredBass");
1250 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1251 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1252 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1253 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1254 $$ = ly_symbol2scm ("ChordNames");
1257 { THIS->lexer_->push_lyric_state ();
1258 $$ = ly_symbol2scm ("Lyrics");
1264 RELATIVE absolute_pitch Music {
1266 Pitch start = *unsmob_pitch ($2);
1267 $$ = make_music_relative (start, m);
1268 scm_gc_unprotect_object (m->self_scm ());
1270 | RELATIVE Composite_music {
1273 Pitch middle_c (0, 0, 0);
1274 $$ = make_music_relative (middle_c, m);
1275 scm_gc_unprotect_object (m->self_scm ());
1280 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1282 Grouped_music_list {
1283 /* Can also use Music at the expensive of two S/Rs similar to
1284 \repeat \alternative */
1285 THIS->lexer_->pop_state ();
1287 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1289 | new_lyrics ADDLYRICS {
1290 THIS->lexer_->push_lyric_state ();
1291 } Grouped_music_list {
1292 THIS->lexer_->pop_state ();
1293 $$ = scm_cons ($4->self_scm (), $1);
1298 Grouped_music_list new_lyrics {
1300 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1301 if (!scm_is_string (name))
1303 name = get_next_unique_lyrics_context_id ();
1304 voice = context_spec_music (scm_makfrom0str ("Voice"),
1309 SCM context = scm_makfrom0str ("Lyrics");
1310 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1313 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1315 Music *music = unsmob_music (scm_car (s));
1316 Music *com = make_lyric_combine_music (name, music);
1317 Music *csm = context_spec_music (context,
1318 get_next_unique_context_id (), com, SCM_EOL);
1319 lst = scm_cons (csm->self_scm (), lst);
1321 all->set_property ("elements", scm_cons (voice->self_scm (),
1324 scm_gc_unprotect_object (voice->self_scm ());
1327 THIS->lexer_->push_lyric_state ();
1328 } simple_string Music {
1329 THIS->lexer_->pop_state ();
1332 $$ = make_lyric_combine_music (name, music);
1333 scm_gc_unprotect_object (music->self_scm ());
1338 CHANGE STRING '=' STRING {
1339 Music*t= MY_MAKE_MUSIC ("ContextChange");
1340 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1341 t-> set_property ("change-to-id", $4);
1344 $$->set_spot (THIS->here_input ());
1350 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1351 scm_string_to_symbol ($1), $3);
1353 | UNSET simple_string {
1354 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1355 scm_string_to_symbol ($2));
1357 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1358 $$ = scm_list_4 (ly_symbol2scm ("push"),
1359 scm_string_to_symbol ($2), $3, $5);
1361 | REVERT simple_string embedded_scm {
1362 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1363 scm_string_to_symbol ($2), $3);
1368 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1369 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1371 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1372 | DENIES { $$ = ly_symbol2scm ("denies"); }
1374 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1375 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1376 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1377 | NAME { $$ = ly_symbol2scm ("context-name"); }
1381 property_operation { $$ = $1; }
1382 | context_def_mod STRING {
1383 $$ = scm_list_2 ($1, $2);
1389 if (!is_regular_identifier ($1))
1391 THIS->here_input ().error (_("Grob name should be alphanumeric"));
1394 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1395 scm_string_to_symbol ($1));
1397 | simple_string '.' simple_string {
1398 $$ = scm_list_2 (scm_string_to_symbol ($1),
1399 scm_string_to_symbol ($3));
1404 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1405 $$ = property_op_to_music (scm_list_4 (
1406 ly_symbol2scm ("poppush"),
1409 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1411 | REVERT context_prop_spec embedded_scm {
1412 $$ = property_op_to_music (scm_list_3 (
1413 ly_symbol2scm ("pop"),
1417 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1419 | SET context_prop_spec '=' scalar {
1420 $$ = property_op_to_music (scm_list_3 (
1421 ly_symbol2scm ("assign"),
1424 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1426 | UNSET context_prop_spec {
1427 $$ = property_op_to_music (scm_list_2 (
1428 ly_symbol2scm ("unset"),
1430 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1432 | ONCE music_property_def {
1433 SCM e = $2->get_property ("element");
1434 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1445 | STRING_IDENTIFIER {
1448 | string '+' string {
1449 $$ = scm_string_append (scm_list_2 ($1, $3));
1453 simple_string: STRING {
1468 $$ = scm_int2num ($1);
1477 $$ = scm_int2num ($1);
1483 pre_events doesn't contain anything. It is a trick:
1485 Adding pre_events to the simple_element
1486 makes the choice between
1492 simple_element: STRING
1494 a single shift/reduction conflict.
1496 nevertheless, this is not very clean, and we should find a different
1506 pre_events simple_element post_events {
1507 SCM elts = $2-> get_property ("elements");
1509 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1511 $2->set_property ("elements", elts);
1515 | note_chord_element
1520 chord_body optional_notemode_duration post_events
1522 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1523 SCM es = $1->get_property ("elements");
1524 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1526 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1527 unsmob_music (scm_car (s))->set_property ("duration", dur);
1528 es = ly_append2 (es, postevs);
1530 $1-> set_property ("elements", es);
1541 simul_open: DOUBLE_ANGLE_OPEN
1544 simul_close: DOUBLE_ANGLE_CLOSE
1548 chord_open chord_body_elements chord_close
1550 $$ = MY_MAKE_MUSIC ("EventChord");
1551 $$->set_property ("elements",
1552 scm_reverse_x ($2, SCM_EOL));
1556 chord_body_elements:
1557 /* empty */ { $$ = SCM_EOL; }
1558 | chord_body_elements chord_body_element {
1559 $$ = scm_cons ($2->self_scm (), $1);
1560 scm_gc_unprotect_object ($2->self_scm ());
1565 pitch exclamations questions octave_check post_events
1572 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1573 n->set_property ("pitch", $1);
1575 n->set_property ("cautionary", SCM_BOOL_T);
1576 if (ex % 2 || q % 2)
1577 n->set_property ("force-accidental", SCM_BOOL_T);
1579 if (scm_is_pair (post)) {
1580 SCM arts = scm_reverse_x (post, SCM_EOL);
1581 n->set_property ("articulations", arts);
1583 if (scm_is_number (check))
1585 int q = scm_to_int (check);
1586 n->set_property ("absolute-octave", scm_int2num (q-1));
1592 | DRUM_PITCH post_events {
1593 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1594 n->set_property ("duration", $2);
1595 n->set_property ("drum-type", $1);
1596 n->set_spot (THIS->here_input ());
1598 if (scm_is_pair ($2)) {
1599 SCM arts = scm_reverse_x ($2, SCM_EOL);
1600 n->set_property ("articulations", arts);
1607 ADDQUOTE string Music {
1608 SCM adder = ly_scheme_function ("add-quotable");
1610 scm_call_2 (adder, $2, $3->self_scm ());
1611 scm_gc_unprotect_object ($3->self_scm ());
1617 $$ = MY_MAKE_MUSIC ("EventChord");
1618 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1619 scm_gc_unprotect_object ($1->self_scm ());
1621 $$-> set_spot (THIS->here_input ());
1622 $1-> set_spot (THIS->here_input ());
1624 | SKIP duration_length {
1625 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1626 skip->set_property ("duration", $2);
1630 | OCTAVE { THIS->push_spot (); }
1632 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1634 $$->set_spot (THIS->pop_spot ());
1635 $$->set_property ("pitch", $3);
1638 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1639 m->set_property ("span-direction", scm_int2num (START));
1640 m->set_spot (THIS->here_input ());
1642 $$ = MY_MAKE_MUSIC ("EventChord");
1643 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1644 scm_gc_unprotect_object (m->self_scm ());
1645 $$->set_spot (THIS->here_input ());
1648 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1649 m->set_property ("span-direction", scm_int2num (STOP));
1650 m->set_spot (THIS->here_input ());
1652 $$ = MY_MAKE_MUSIC ("EventChord");
1653 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1654 $$->set_spot (THIS->here_input ());
1655 scm_gc_unprotect_object (m->self_scm ());
1658 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1659 $$->set_spot (THIS->here_input ());
1662 SCM pipe =THIS->lexer_->lookup_identifier ("pipeSymbol");
1664 if (Music * m = unsmob_music (pipe))
1667 $$ = MY_MAKE_MUSIC ("BarCheck");
1669 $$->set_spot (THIS->here_input ());
1671 | TRANSPOSITION pitch {
1673 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1674 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1675 sounds_as_c.smobbed_copy());
1676 $$->set_spot (THIS-> here_input ());
1677 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1681 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1683 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1685 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1686 $$->set_spot (THIS->here_input ());
1687 t->set_spot (THIS->here_input ());
1689 | PARTIAL duration_length {
1690 Moment m = - unsmob_duration ($2)->get_length ();
1691 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1692 p->set_spot (THIS->here_input ());
1693 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1695 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1700 SCM proc = ly_scheme_function ("make-clef-set");
1702 SCM result = scm_call_1 (proc, $2);
1703 scm_gc_protect_object (result);
1704 $$ = unsmob_music (result);
1707 SCM proc= ly_scheme_function ("make-time-signature-set");
1709 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1710 scm_gc_protect_object (result);
1711 $$ = unsmob_music (result);
1714 SCM proc = ly_scheme_function ("make-mark-set");
1716 SCM result = scm_call_1 (proc, $2);
1717 scm_gc_protect_object (result);
1718 $$ = unsmob_music (result);
1724 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1727 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1734 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1737 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1739 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1740 if (scm_ilength ($3) > 0)
1742 key->set_property ("pitch-alist", $3);
1743 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1744 key->transpose (* unsmob_pitch ($2));
1746 THIS->parser_error (_ ("Second argument must be pitch list."));
1757 | post_events post_event {
1758 $2->set_spot (THIS->here_input ());
1759 $$ = scm_cons ($2->self_scm (), $$);
1760 scm_gc_unprotect_object ($2->self_scm ());
1762 | post_events tagged_post_event {
1763 $2 -> set_spot (THIS->here_input ());
1764 $$ = scm_cons ($2->self_scm (), $$);
1765 scm_gc_unprotect_object ($2->self_scm ());
1771 '-' TAG embedded_scm post_event {
1772 tag_music ($4, $3, THIS->here_input ());
1778 direction_less_event {
1782 if (!THIS->lexer_->is_lyric_state ())
1783 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1784 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1787 if (!THIS->lexer_->is_lyric_state ())
1788 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1789 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1791 | script_dir direction_reqd_event {
1793 $2->set_property ("direction", scm_int2num ($1));
1796 | script_dir direction_less_event {
1798 $2->set_property ("direction", scm_int2num ($1));
1801 | string_number_event
1804 string_number_event:
1806 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1807 s->set_property ("string-number", scm_int2num ($1));
1808 s->set_spot (THIS->here_input ());
1813 direction_less_char:
1815 $$ = ly_symbol2scm ("bracketOpenSymbol");
1818 $$ = ly_symbol2scm ("bracketCloseSymbol");
1821 $$ = ly_symbol2scm ("tildeSymbol");
1824 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1827 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1830 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1833 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1836 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1839 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1842 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1846 direction_less_event:
1847 direction_less_char {
1848 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1850 if (unsmob_music (predefd))
1852 m = unsmob_music (predefd)->clone ();
1856 m = MY_MAKE_MUSIC ("Music");
1858 m->set_spot (THIS->here_input ());
1861 | EVENT_IDENTIFIER {
1862 $$ = unsmob_music ($1);
1865 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1866 a->set_spot (THIS->here_input ());
1867 a->set_property ("tremolo-type", scm_int2num ($1));
1872 direction_reqd_event:
1876 | script_abbreviation {
1877 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1878 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1879 if (scm_is_string (s))
1880 a->set_property ("articulation-type", s);
1881 else THIS->parser_error (_ ("Expecting string as script definition"));
1887 /**/ { $$ = SCM_EOL; }
1888 | '=' { $$ = scm_int2num (0); }
1889 | '=' sub_quotes { $$ = scm_int2num ($2); }
1890 | '=' sup_quotes { $$ = scm_int2num ($2); }
1915 | NOTENAME_PITCH sup_quotes {
1916 Pitch p = *unsmob_pitch ($1);
1917 p = p.transposed (Pitch ($2,0,0));
1918 $$ = p.smobbed_copy ();
1920 | NOTENAME_PITCH sub_quotes {
1921 Pitch p =* unsmob_pitch ($1);
1922 p = p.transposed (Pitch (-$2,0,0));
1923 $$ = p.smobbed_copy ();
1935 | TONICNAME_PITCH sup_quotes {
1936 Pitch p = *unsmob_pitch ($1);
1937 p = p.transposed (Pitch ($2,0,0));
1938 $$ = p.smobbed_copy ();
1940 | TONICNAME_PITCH sub_quotes {
1941 Pitch p =* unsmob_pitch ($1);
1943 p = p.transposed (Pitch (-$2,0,0));
1944 $$ = p.smobbed_copy ();
1954 pitch_also_in_chords:
1961 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1962 t->set_property ("text", $1);
1963 t->set_spot (THIS->here_input ());
1967 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1968 t->set_property ("text",
1969 make_simple_markup (THIS->lexer_->encoding (), $1));
1970 t->set_spot (THIS->here_input ());
1975 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1976 t->set_property ("digit", scm_int2num ($1));
1977 t->set_spot (THIS->here_input ());
1982 script_abbreviation:
1984 $$ = scm_makfrom0str ("Hat");
1987 $$ = scm_makfrom0str ("Plus");
1990 $$ = scm_makfrom0str ("Dash");
1993 $$ = scm_makfrom0str ("Bar");
1996 $$ = scm_makfrom0str ("Larger");
1999 $$ = scm_makfrom0str ("Dot");
2002 $$ = scm_makfrom0str ("Underscore");
2009 | '-' { $$ = CENTER; }
2020 multiplied_duration {
2025 optional_notemode_duration:
2027 Duration dd = THIS->default_duration_;
2028 $$ = dd.smobbed_copy ();
2030 THIS->beam_check ($$);
2032 | multiplied_duration {
2034 THIS->default_duration_ = *unsmob_duration ($$);
2036 THIS->beam_check ($$);
2041 bare_unsigned dots {
2043 if (!is_duration ($1))
2044 THIS->parser_error (_f ("not a duration: %d", $1));
2048 $$ = Duration (len, $2).smobbed_copy ();
2050 | DURATION_IDENTIFIER dots {
2051 Duration *d = unsmob_duration ($1);
2052 Duration k (d->duration_log (), d->dot_count () + $2);
2058 multiplied_duration:
2062 | multiplied_duration '*' bare_unsigned {
2063 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2065 | multiplied_duration '*' FRACTION {
2066 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2068 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2073 FRACTION { $$ = $1; }
2074 | UNSIGNED '/' UNSIGNED {
2075 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2092 | ':' bare_unsigned {
2093 if (!is_duration ($2))
2094 THIS->parser_error (_f ("not a duration: %d", $2));
2101 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2102 $$ = scm_list_2 (ly_scheme_function ("number-markup"),
2106 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2107 $$ = scm_list_2 (ly_scheme_function ("number-markup"),
2110 | STRING { $$ = $1; }
2121 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2122 $$ = bfr->self_scm ();
2123 scm_gc_unprotect_object ($$);
2126 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2127 $$ = bfr->self_scm ();
2129 bfr->set_property ("figure", $1);
2131 scm_gc_unprotect_object ($$);
2133 | bass_figure bass_mod {
2134 Music *m = unsmob_music ($1);
2136 SCM salter = m->get_property ("alteration");
2137 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2138 m->set_property ("alteration",
2139 scm_int2num (alter + $2));
2141 m->set_property ("alteration", scm_int2num (0));
2149 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2154 | br_bass_figure ']' {
2156 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2164 | figure_list br_bass_figure {
2165 $$ = scm_cons ($2, $1);
2170 FIGURE_OPEN figure_list FIGURE_CLOSE {
2171 Music *m = MY_MAKE_MUSIC ("EventChord");
2172 $2 = scm_reverse_x ($2, SCM_EOL);
2173 m->set_property ("elements", $2);
2174 $$ = m->self_scm ();
2185 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2187 Input i = THIS->pop_spot ();
2188 if (!THIS->lexer_->is_note_state ())
2189 THIS->parser_error (_ ("Have to be in Note mode for notes"));
2193 n = MY_MAKE_MUSIC ("RestEvent");
2195 n = MY_MAKE_MUSIC ("NoteEvent");
2197 n->set_property ("pitch", $1);
2198 n->set_property ("duration", $5);
2200 if (scm_is_number ($4))
2202 int q = scm_to_int ($4);
2203 n->set_property ("absolute-octave", scm_int2num (q-1));
2207 n->set_property ("cautionary", SCM_BOOL_T);
2208 if ($2 % 2 || $3 % 2)
2209 n->set_property ("force-accidental", SCM_BOOL_T);
2211 Music *v = MY_MAKE_MUSIC ("EventChord");
2212 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2213 scm_gc_unprotect_object (n->self_scm ());
2219 | DRUM_PITCH optional_notemode_duration {
2220 Input i = THIS->pop_spot ();
2222 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2223 n->set_property ("duration", $2);
2224 n->set_property ("drum-type", $1);
2226 Music *v = MY_MAKE_MUSIC ("EventChord");
2227 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2228 scm_gc_unprotect_object (n->self_scm ());
2234 | figure_spec optional_notemode_duration {
2235 Music *m = unsmob_music ($1);
2236 Input i = THIS->pop_spot ();
2238 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2240 unsmob_music (scm_car (s))->set_property ("duration", $2);
2244 | RESTNAME optional_notemode_duration {
2246 Input i = THIS->pop_spot ();
2248 if (ly_scm2string ($1) == "s") {
2250 ev = MY_MAKE_MUSIC ("SkipEvent");
2253 ev = MY_MAKE_MUSIC ("RestEvent");
2256 ev->set_property ("duration", $2);
2258 Music *velt = MY_MAKE_MUSIC ("EventChord");
2259 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2262 scm_gc_unprotect_object (ev->self_scm ());
2266 | MULTI_MEASURE_REST optional_notemode_duration {
2269 SCM proc = ly_scheme_function ("make-multi-measure-rest");
2270 SCM mus = scm_call_2 (proc, $2,
2271 make_input (THIS->here_input ()));
2272 scm_gc_protect_object (mus);
2273 $$ = unsmob_music (mus);
2276 | lyric_element optional_notemode_duration {
2277 Input i = THIS->pop_spot ();
2278 if (!THIS->lexer_->is_lyric_state ())
2279 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
2281 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2282 lreq->set_property ("text", $1);
2283 lreq->set_property ("duration",$2);
2285 Music *velt = MY_MAKE_MUSIC ("EventChord");
2286 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2293 if (!THIS->lexer_->is_chord_state ())
2294 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
2295 $$ = unsmob_music ($1);
2300 /* FIXME: lyric flavoured markup would be better */
2305 $$ = make_simple_markup (THIS->lexer_->encoding (), $1);
2310 steno_tonic_pitch optional_notemode_duration {
2311 $$ = make_chord ($1, $2, SCM_EOL);
2313 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2314 SCM its = scm_reverse_x ($4, SCM_EOL);
2315 $$ = make_chord ($1, $2, scm_cons ($3, its));
2323 | chord_items chord_item {
2324 $$ = scm_cons ($2, $$);
2330 $$ = ly_symbol2scm ("chord-colon");
2333 $$ = ly_symbol2scm ("chord-caret");
2335 | CHORD_SLASH steno_tonic_pitch {
2336 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2338 | CHORD_BASS steno_tonic_pitch {
2339 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2348 $$ = scm_reverse_x ($1, SCM_EOL);
2356 step_number { $$ = scm_cons ($1, SCM_EOL); }
2357 | step_numbers '.' step_number {
2358 $$ = scm_cons ($3, $$);
2364 $$ = make_chord_step ($1, 0);
2366 | bare_unsigned '+' {
2367 $$ = make_chord_step ($1, SHARP);
2369 | bare_unsigned CHORD_MINUS {
2370 $$ = make_chord_step ($1, FLAT);
2377 TODO: should deprecate in favor of Scheme?
2381 number_expression '+' number_term {
2382 $$ = scm_sum ($1, $3);
2384 | number_expression '-' number_term {
2385 $$ = scm_difference ($1, $3);
2394 | number_factor '*' number_factor {
2395 $$ = scm_product ($1, $3);
2397 | number_factor '/' number_factor {
2398 $$ = scm_divide ($1, $3);
2403 '-' number_factor { /* %prec UNARY_MINUS */
2404 $$ = scm_difference ($2, SCM_UNDEFINED);
2412 $$ = scm_int2num ($1);
2417 | NUMBER_IDENTIFIER {
2420 | REAL NUMBER_IDENTIFIER {
2421 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2423 | UNSIGNED NUMBER_IDENTIFIER {
2424 $$ = scm_make_real ($1 *scm_to_double ($2));
2440 if (scm_integer_p ($1) == SCM_BOOL_T)
2442 int k = scm_to_int ($1);
2446 THIS->parser_error (_ ("need integer number arg"));
2457 | exclamations '!' { $$ ++; }
2462 | questions '?' { $$ ++; }
2472 { THIS->lexer_->push_markup_state (); }
2475 THIS->lexer_->pop_state ();
2481 This should be done more dynamically if possible.
2485 $$ = make_simple_markup (THIS->lexer_->encoding (), $1);
2487 | MARKUP_HEAD_EMPTY {
2488 $$ = scm_list_1 ($1);
2490 | MARKUP_HEAD_MARKUP0 markup {
2491 $$ = scm_list_2 ($1, $2);
2493 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2494 $$ = scm_list_3 ($1, $2, $3);
2496 | MARKUP_HEAD_SCM0_MARKUP1 SCM_T markup {
2497 $$ = scm_list_3 ($1, $2, $3);
2502 | MARKUP_HEAD_LIST0 markup_list {
2503 $$ = scm_list_2 ($1,$2);
2505 | MARKUP_HEAD_SCM0 embedded_scm {
2506 $$ = scm_list_2 ($1, $2);
2508 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup {
2509 $$ = scm_list_4 ($1, $2, $3, $4);
2511 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2512 $$ = scm_list_4 ($1, $2, $3, $4);
2514 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2515 $$ = scm_list_3 ($1, $2, $3);
2517 | MARKUP_IDENTIFIER {
2520 | STRING_IDENTIFIER {
2524 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2525 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2526 } '{' score_body '}' {
2528 $$ = scm_list_2 (ly_scheme_function ("score-markup"), sc->self_scm ());
2529 scm_gc_unprotect_object (sc->self_scm ());
2530 THIS->lexer_->pop_state ();
2535 chord_open markup_list_body chord_close { $$ = scm_reverse_x ($2, SCM_EOL); }
2539 '{' markup_list_body '}' {
2540 SCM line = ly_scheme_function ("line-markup");
2542 $$ = scm_list_2 (line, scm_reverse_x ($2, SCM_EOL));
2547 /**/ { $$ = SCM_EOL; }
2548 | markup_list_body markup {
2549 $$ = scm_cons ($2, $1);
2557 Lily_parser::set_yydebug (bool )
2565 Lily_parser::do_yyparse ()
2567 yyparse ((void*)this);
2572 Should make this optional? It will also complain when you do
2576 which is entirely legitimate.
2578 Or we can scrap it. Barchecks should detect wrong durations, and
2579 skipTypesetting speeds it up a lot.
2583 Lily_parser::beam_check (SCM dur)
2585 Duration *d = unsmob_duration (dur);
2586 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2588 Music *m = unsmob_music (last_beam_start_);
2589 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2591 last_beam_start_ = SCM_EOL;
2599 It is a little strange to have this function in this file, but
2600 otherwise, we have to import music classes into the lexer.
2604 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2606 if (scm_is_string (sid)) {
2608 return STRING_IDENTIFIER;
2609 } else if (scm_is_number (sid)) {
2611 return NUMBER_IDENTIFIER;
2612 } else if (unsmob_context_def (sid)) {
2613 *destination = unsmob_context_def (sid)->clone_scm ();
2614 return CONTEXT_DEF_IDENTIFIER;
2615 } else if (unsmob_score (sid)) {
2616 Score *score = new Score (*unsmob_score (sid));
2617 *destination = score->self_scm ();
2618 return SCORE_IDENTIFIER;
2619 } else if (Music *mus = unsmob_music (sid)) {
2620 mus = mus->clone ();
2621 *destination = mus->self_scm ();
2622 unsmob_music (*destination)->
2623 set_property ("origin", make_input (last_input_));
2624 return dynamic_cast<Event*> (mus)
2625 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2626 } else if (unsmob_duration (sid)) {
2627 *destination = unsmob_duration (sid)->smobbed_copy ();
2628 return DURATION_IDENTIFIER;
2629 } else if (unsmob_output_def (sid)) {
2630 Output_def *p = unsmob_output_def (sid);
2633 *destination = p->self_scm ();
2634 return OUTPUT_DEF_IDENTIFIER;
2635 } else if (Text_interface::markup_p (sid)) {
2637 return MARKUP_IDENTIFIER;
2644 property_op_to_music (SCM op)
2647 SCM tag = scm_car (op);
2648 SCM symbol = scm_cadr (op);
2649 SCM args = scm_cddr (op);
2650 SCM grob_val = SCM_UNDEFINED;
2651 SCM grob_sym = SCM_UNDEFINED;
2652 SCM val = SCM_UNDEFINED;
2654 if (tag == ly_symbol2scm ("assign"))
2656 m = MY_MAKE_MUSIC ("PropertySet");
2657 val = scm_car (args);
2659 else if (tag == ly_symbol2scm ("unset"))
2660 m = MY_MAKE_MUSIC ("PropertyUnset");
2661 else if (tag == ly_symbol2scm ("poppush")
2662 || tag == ly_symbol2scm ("push"))
2664 m = MY_MAKE_MUSIC ("OverrideProperty");
2665 grob_sym = scm_car (args);
2666 grob_val = scm_cadr (args);
2668 else if (tag == ly_symbol2scm ("pop")) {
2669 m = MY_MAKE_MUSIC ("RevertProperty");
2670 grob_sym = scm_car (args);
2673 m->set_property ("symbol", symbol);
2675 if (val != SCM_UNDEFINED)
2676 m->set_property ("value", val);
2677 if (grob_val != SCM_UNDEFINED)
2678 m->set_property ("grob-value", grob_val);
2680 if (grob_sym != SCM_UNDEFINED)
2682 bool itc = internal_type_checking_global_b;
2685 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2687 internal_type_checking_global_b = false;
2688 m->set_property ("grob-property", grob_sym);
2690 internal_type_checking_global_b = itc;
2693 if (tag == ly_symbol2scm ("poppush"))
2694 m->set_property ("pop-first", SCM_BOOL_T);
2701 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2703 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2705 csm->set_property ("element", m->self_scm ());
2706 scm_gc_unprotect_object (m->self_scm ());
2708 csm->set_property ("context-type",
2709 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2710 csm->set_property ("property-operations", ops);
2712 if (scm_is_string (id))
2713 csm->set_property ("context-id", id);
2718 get_next_unique_context_id ()
2720 return scm_makfrom0str ("$uniqueContextId");
2725 get_next_unique_lyrics_context_id ()
2727 static int new_context_count;
2729 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2730 return scm_makfrom0str (s);