1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for LilyPond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2005 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?
29 #include "context-def.hh"
30 #include "dimensions.hh"
32 #include "file-path.hh"
33 #include "input-smob.hh"
35 #include "lily-guile.hh"
36 #include "lilypond-input-version.hh"
39 #include "lily-lexer.hh"
40 #include "lily-parser.hh"
41 #include "paper-book.hh"
42 #include "output-def.hh"
43 #include "scm-hash.hh"
44 #include "scm-option.hh"
46 #include "text-item.hh"
49 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
51 Music *property_op_to_music (SCM op);
52 Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
53 SCM get_next_unique_context_id ();
54 SCM get_next_unique_lyrics_context_id ();
56 #define YYERROR_VERBOSE 1
58 #define YYPARSE_PARAM my_lily_parser
59 #define YYLEX_PARAM my_lily_parser
61 ((Lily_parser *) my_lily_parser)
63 #define yyerror THIS->parser_error
65 /* We use custom location type: Input objects */
67 #define YYLLOC_DEFAULT(Current,Rhs,N) \
68 ((Current).set_location ((Rhs)[1], (Rhs)[N]))
71 /* Add symbols to the TAGS field of a music object. */
74 tag_music (Music *m, SCM tag, Input ip)
76 SCM tags = m->get_property ("tags");
77 if (scm_is_symbol (tag))
78 tags = scm_cons (tag, tags);
79 else if (ly_c_list_p (tag))
80 tags = ly_append2 (tag, tags);
82 ip.warning (_ ("Tag must be symbol or list of symbols."));
84 m->set_property ("tags", tags);
88 is_regular_identifier (SCM id)
90 String str = ly_scm2string (id);
91 char const *s = str.to_str0 ();
100 v = v && isalnum (*s);
108 get_first_context_id (SCM type, Music *m)
110 SCM id = m->get_property ("context-id");
111 if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
112 && scm_is_string (m->get_property ("context-id"))
113 && scm_c_string_length (id) > 0)
121 make_simple_markup (SCM a)
123 SCM simple = ly_lily_module_constant ("simple-markup");
124 return scm_list_2 (simple, a);
130 return t && t == 1 << intlog2 (t);
134 set_music_properties (Music *p, SCM a)
136 for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
137 p->internal_set_property (scm_caar (k), scm_cdar (k));
141 make_chord_step (int step, int alter)
148 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
149 return m.smobbed_copy ();
154 make_chord (SCM pitch, SCM dur, SCM modification_list)
156 SCM chord_ctor = ly_lily_module_constant ("construct-chord");
157 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
158 scm_gc_protect_object (ch);
162 /* Todo: actually also use apply iso. call too ... */
164 ly_input_procedure_p (SCM x)
166 return ly_c_procedure_p (x)
167 || (scm_is_pair (x) && ly_c_procedure_p (scm_car (x)));
171 set_property_music (SCM sym, SCM value)
173 Music *p = MY_MAKE_MUSIC ("PropertySet");
174 p->set_property ("symbol", sym);
175 p->set_property ("value", value);
180 make_music_relative (Pitch start, Music *music)
182 Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
183 relative->set_property ("element", music->self_scm ());
185 Pitch last = music->to_relative_octave (start);
186 if (lily_1_8_relative)
187 music->set_property ("last-pitch", last.smobbed_copy ());
192 make_lyric_combine_music (SCM name, Music *music)
194 Music *combine = MY_MAKE_MUSIC ("NewLyricCombineMusic");
195 combine->set_property ("element", music->self_scm ());
196 combine->set_property ("associated-context", name);
202 /* We use SCMs to do strings, because it saves us the trouble of
203 deleting them. Let's hope that a stack overflow doesnt trigger a move
204 of the parse stack onto the heap. */
210 Output_def *outputdef;
220 yylex (YYSTYPE *s, YYLTYPE *l, void *v)
222 Lily_parser *pars = (Lily_parser*) v;
223 Lily_lexer *lex = pars->lexer_;
225 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
273 %token CHORDMODIFIERS
276 %token DOUBLE_ANGLE_OPEN
277 %token DOUBLE_ANGLE_CLOSE
279 %token COMMANDSPANREQUEST
288 %token FIGURE_OPEN FIGURE_CLOSE
289 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
290 %token GROBDESCRIPTIONS
300 %token MULTI_MEASURE_REST
307 %token OVERRIDE SET REVERT
334 /* FIXME: this sucks. The user will get to see these names:
335 syntax error, unexpected E_CHAR:
340 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
341 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
343 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
348 %token <i> E_UNSIGNED
349 %token <id> IDENTIFIER
350 %token <scm> CHORDMODIFIER_PITCH
351 %token <scm> DRUM_PITCH
352 %token <scm> DURATION_IDENTIFIER
353 %token <scm> EVENT_IDENTIFIER
354 %token <scm> MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
355 %token <scm> NOTENAME_PITCH
356 %token <scm> NUMBER_IDENTIFIER
357 %token <scm> OUTPUT_DEF_IDENTIFIER
358 %token <scm> RESTNAME
359 %token <scm> LYRICS_STRING
361 %token <scm> SCORE_IDENTIFIER
363 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
364 %token <scm> TONICNAME_PITCH
365 %token <scm> CHORD_MODIFIER
366 %token <scm> FRACTION
368 %token <scm> MARKUP_HEAD_EMPTY
369 %token <scm> MARKUP_HEAD_MARKUP0
370 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
371 %token <scm> MARKUP_HEAD_SCM0
372 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
373 %token <scm> MARKUP_HEAD_SCM0_SCM1
374 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
375 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
376 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
377 %token <scm> MUSIC_FUNCTION
378 %token <scm> MUSIC_FUNCTION_MUSIC
379 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
380 %token <scm> MUSIC_FUNCTION_SCM
381 %token <scm> MUSIC_FUNCTION_SCM_SCM
382 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
383 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
384 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
385 %token <scm> MUSIC_FUNCTION_MARKUP
386 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
387 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
388 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
389 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
395 %type <book> book_block book_body
396 %type <i> bare_int bare_unsigned
397 %type <i> exclamations questions dots optional_rest
399 %type <i> sub_quotes sup_quotes
400 %type <i> tremolo_type
403 %type <music> Composite_music Simple_music Prefix_composite_music Generic_prefix_music
404 %type <music> Grouped_music_list
405 %type <music> Music Sequential_music Simultaneous_music
406 %type <music> Repeated_music
407 %type <music> command_req
408 %type <music> gen_text_def direction_less_event direction_reqd_event
409 %type <music> music_property_def context_change
410 %type <music> note_chord_element chord_body chord_body_element
411 %type <music> post_event tagged_post_event
412 %type <music> relative_music re_rhythmed_music
413 %type <music> simple_element event_chord command_element
414 %type <music> string_number_event
415 %type <music> toplevel_music
416 %type <music> tempo_event
418 %type <outputdef> output_def_body output_def_head
419 %type <outputdef> output_def paper_block
421 %type <scm> assignment_id
422 %type <scm> Music_list
423 %type <scm> chord_body_elements
424 %type <scm> chord_item chord_items chord_separator new_chord
425 %type <scm> context_def_spec_block context_def_spec_body
426 %type <scm> context_mod context_def_mod optional_context_mod
427 %type <scm> context_prop_spec
428 %type <scm> direction_less_char
429 %type <scm> duration_length fraction
430 %type <scm> embedded_scm scalar
431 %type <scm> identifier_init
432 %type <scm> lilypond_header lilypond_header_body
433 %type <scm> new_lyrics
434 %type <scm> post_events
435 %type <scm> property_operation
436 %type <scm> script_abbreviation
437 %type <scm> simple_string
438 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
439 %type <scm> steno_tonic_pitch
440 %type <scm> step_number step_numbers
441 %type <scm> string bare_number number_expression number_term number_factor
442 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
443 %type <scm> context_mod_list
444 %type <scm> octave_check
445 %type <scm> steno_duration optional_notemode_duration multiplied_duration
446 %type <scm> Generic_prefix_music_scm
447 %type <scm> lyric_element
448 %type <scm> Alternative_music
449 %type <scm> full_markup markup_list markup_composed_list markup_braced_list markup_braced_list_body
450 %type <scm> markup_head_1_item markup_head_1_list markup simple_markup markup_top
451 %type <scm> mode_changing_head
452 %type <scm> mode_changing_head_with_context
453 %type <scm> object_id_setting
455 %type <score> score_block score_body
460 /* We don't assign precedence to / and *, because we might need varied
461 prec levels in different prods */
467 lilypond: /* empty */
468 | lilypond toplevel_expression {
470 | lilypond assignment {
473 THIS->error_level_ = 1;
476 THIS->error_level_ = 1;
482 OBJECTID STRING { $$ = $2; }
487 THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1);
494 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
495 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
496 scm_gc_unprotect_object (book->self_scm ());
501 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
502 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
503 scm_gc_unprotect_object (score->self_scm ());
507 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
508 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
509 scm_gc_unprotect_object (music->self_scm ());
513 Output_def * od = $1;
515 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
516 id = ly_symbol2scm ("$defaultpaper");
517 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
518 id = ly_symbol2scm ("$defaultmidi");
519 else if ($1->c_variable ("is-layout") == SCM_BOOL_T)
520 id = ly_symbol2scm ("$defaultlayout");
522 THIS->lexer_->set_identifier (id, od->self_scm ());
523 scm_gc_unprotect_object (od->self_scm ());
538 lilypond_header_body:
540 $$ = ly_make_anonymous_module (be_safe_global);
541 THIS->lexer_->add_scope ($$);
543 | lilypond_header_body assignment {
549 HEADER '{' lilypond_header_body '}' {
550 $$ = THIS->lexer_->remove_scope ();
560 | LYRICS_STRING { $$ = $1; }
564 assignment_id '=' identifier_init {
565 if (! is_regular_identifier ($1))
567 @1.warning (_ ("Identifier should have alphabetic characters only"));
570 THIS->lexer_->set_identifier ($1, $3);
573 TODO: devise standard for protection in parser.
575 The parser stack lives on the C-stack, which means that
576 all objects can be unprotected as soon as they're here.
586 $$ = $1->self_scm ();
587 scm_gc_unprotect_object ($$);
590 $$ = $1->self_scm ();
591 scm_gc_unprotect_object ($$);
593 | context_def_spec_block {
597 $$ = $1->self_scm ();
598 scm_gc_unprotect_object ($$);
601 $$ = $1->self_scm ();
602 scm_gc_unprotect_object ($$);
604 | number_expression {
617 $$ = scm_int2num ($1);
621 context_def_spec_block:
622 CONTEXT '{' context_def_spec_body '}'
628 context_def_spec_body:
630 $$ = Context_def::make_scm ();
631 unsmob_context_def ($$)->set_spot (@$);
633 | CONTEXT_DEF_IDENTIFIER {
635 unsmob_context_def ($$)->set_spot (@$);
637 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
638 Context_def*td = unsmob_context_def ($$);
640 for (SCM p = $3; scm_is_pair (p); p = scm_cdr (p)) {
641 SCM tag = scm_caar (p);
643 /* TODO: should make new tag "grob-definition" ? */
644 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
645 tag, scm_cons (scm_cdar (p), SCM_EOL)));
648 | context_def_spec_body context_mod {
649 unsmob_context_def ($$)->add_context_mod ($2);
656 BOOK '{' book_body '}' {
662 * Use 'handlers' like for toplevel-* stuff?
663 * grok \layout and \midi? */
668 $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
669 scm_gc_unprotect_object ($$->paper_->self_scm ());
670 $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader");
672 | book_body paper_block {
674 scm_gc_unprotect_object ($2->self_scm ());
676 | book_body score_block {
678 $$->add_score (score);
680 | book_body lilypond_header {
687 | book_body object_id_setting {
688 $$->user_key_ = ly_scm2string ($2);
693 SCORE '{' score_body '}' {
704 $$ = new Score ( *unsmob_score ($1));
707 | score_body object_id_setting {
708 $$->user_key_ = ly_scm2string ($2);
711 SCM m = $2->self_scm ();
712 scm_gc_unprotect_object (m);
713 $$->set_music (m, THIS->self_scm ());
715 | score_body lilypond_header {
718 | score_body output_def {
719 if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
721 THIS->parser_error (@2, _("\\paper cannot be in \\score. Use \\layout instead"));
728 scm_gc_unprotect_object ($2->self_scm ());
731 $$->error_found_ = true;
743 if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
745 THIS->parser_error (@1, _("Need \\paper for paper block."));
746 $$ = get_paper (THIS);
753 output_def_body '}' {
756 THIS->lexer_->remove_scope ();
757 THIS->lexer_->pop_state ();
763 $$ = get_paper (THIS);
764 $$->input_origin_ = @$;
765 THIS->lexer_->add_scope ($$->scope_);
768 Output_def *p = get_midi (THIS);
770 THIS->lexer_->add_scope (p->scope_);
773 Output_def *p = get_layout (THIS);
775 THIS->lexer_->add_scope (p->scope_);
782 output_def_head '{' {
784 $$->input_origin_.set_spot (@$);
785 THIS->lexer_->push_initial_state ();
787 | output_def_head '{' OUTPUT_DEF_IDENTIFIER {
788 scm_gc_unprotect_object ($1->self_scm ());
789 Output_def *o = unsmob_output_def ($3);
790 o->input_origin_.set_spot (@$);
792 THIS->lexer_->remove_scope ();
793 THIS->lexer_->add_scope (o->scope_);
794 THIS->lexer_->push_initial_state ();
796 | output_def_body assignment {
799 | output_def_body context_def_spec_block {
800 assign_context_def ($$, $2);
802 | output_def_body tempo_event {
804 junk this ? there already is tempo stuff in
807 int m = scm_to_int ($2->get_property ("metronome-count"));
808 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
809 set_tempo ($$, d->get_length (), m);
810 scm_gc_unprotect_object ($2->self_scm ());
812 | output_def_body error {
818 TEMPO steno_duration '=' bare_unsigned {
819 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
820 $$->set_property ("tempo-unit", $2);
821 $$->set_property ("metronome-count", scm_int2num ( $4));
826 The representation of a list is the
830 to have efficient append. */
834 $$ = scm_cons (SCM_EOL, SCM_EOL);
838 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
839 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
841 if (scm_is_pair (scm_cdr (s)))
842 scm_set_cdr_x (scm_cdr (s), c); /* append */
844 scm_set_car_x (s, c); /* set first cons */
845 scm_set_cdr_x (s, c); /* remember last cell */
847 | Music_list embedded_scm {
851 Music * m = MY_MAKE_MUSIC("Music");
853 m->set_property ("error-found", SCM_BOOL_T);
855 SCM c = scm_cons (m->self_scm (), SCM_EOL);
856 scm_gc_unprotect_object (m->self_scm ()); /* UGH */
858 if (scm_is_pair (scm_cdr (s)))
859 scm_set_cdr_x (scm_cdr (s), c); /* append */
861 scm_set_car_x (s, c); /* set first cons */
862 scm_set_cdr_x (s, c); /* remember last cell */
875 | ALTERNATIVE '{' Music_list '}' {
882 REPEAT simple_string bare_unsigned Music Alternative_music
886 SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
887 if (times < scm_ilength (alts)) {
888 unsmob_music (scm_car (alts))
889 ->origin ()->warning (
890 _ ("More alternatives than repeats. Junking excess alternatives."));
891 alts = ly_truncate_list (times, alts);
895 SCM proc = ly_lily_module_constant ("make-repeated-music");
897 SCM mus = scm_call_1 (proc, $2);
898 scm_gc_protect_object (mus); // UGH.
899 Music *r = unsmob_music (mus);
902 r-> set_property ("element", beg->self_scm ());
903 scm_gc_unprotect_object (beg->self_scm ());
905 r->set_property ("repeat-count", scm_int2num (times >? 1));
907 r-> set_property ("elements",alts);
908 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
910 TODO: move this code to Scheme.
914 we can not get durations and other stuff correct down the line, so we have to
915 add to the duration log here.
917 SCM func = ly_lily_module_constant ("shift-duration-log");
919 int dots = ($3 % 3) ? 0 : 1;
920 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
923 if ($4->is_mus_type ("sequential-music"))
925 int list_len = scm_ilength ($4->get_property ("elements"));
927 $4->origin ()->warning ("Chord tremolo must have 2 elements.");
929 r->compress (Moment (Rational (1, list_len)));
931 scm_call_3 (func, r->self_scm (), scm_int2num (shift), scm_int2num (dots));
934 r->set_spot (*$4->origin ());
941 SEQUENTIAL '{' Music_list '}' {
942 $$ = MY_MAKE_MUSIC ("SequentialMusic");
943 $$->set_property ("elements", scm_car ($3));
946 | '{' Music_list '}' {
947 $$ = MY_MAKE_MUSIC ("SequentialMusic");
948 $$->set_property ("elements", scm_car ($2));
954 SIMULTANEOUS '{' Music_list '}'{
955 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
956 $$->set_property ("elements", scm_car ($3));
960 | simul_open Music_list simul_close {
961 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
962 $$->set_property ("elements", scm_car ($2));
968 event_chord { $$ = $1; }
970 $$ = unsmob_music ($1);
977 optional_context_mod:
978 /**/ { $$ = SCM_EOL; }
979 | WITH { THIS->lexer_->push_initial_state (); }
980 '{' context_mod_list '}'
982 THIS->lexer_->pop_state ();
988 /* */ { $$ = SCM_EOL; }
989 | context_mod_list context_mod {
990 $$ = scm_cons ($2, $1);
996 Prefix_composite_music { $$ = $1; }
997 | Grouped_music_list { $$ = $1; }
1001 Simultaneous_music { $$ = $1; }
1002 | Sequential_music { $$ = $1; }
1005 Generic_prefix_music_scm:
1007 $$ = scm_list_2 ($1, make_input (@$));
1009 | MUSIC_FUNCTION_SCM embedded_scm {
1010 $$ = scm_list_3 ($1, make_input (@$), $2);
1012 | MUSIC_FUNCTION_MARKUP full_markup {
1013 $$ = scm_list_3 ($1, make_input (@$), $2);
1015 | MUSIC_FUNCTION_MUSIC Music {
1016 $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
1017 scm_gc_unprotect_object ($2->self_scm ());
1019 | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
1020 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1021 scm_gc_unprotect_object ($3->self_scm ());
1023 | MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
1024 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1026 | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
1027 $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
1029 | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
1030 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1031 scm_gc_unprotect_object ($3->self_scm ());
1033 | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
1034 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1036 | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
1037 $$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
1038 scm_gc_unprotect_object ($2->self_scm ());
1039 scm_gc_unprotect_object ($3->self_scm ());
1041 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
1042 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1043 scm_gc_unprotect_object ($4->self_scm ());
1044 scm_gc_unprotect_object ($3->self_scm ());
1046 | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
1047 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1048 scm_gc_unprotect_object ($3->self_scm ());
1049 scm_gc_unprotect_object ($4->self_scm ());
1053 Generic_prefix_music:
1054 Generic_prefix_music_scm {
1055 SCM func = scm_car ($1);
1056 Input *loc = unsmob_input (scm_cadr ($1));
1057 SCM args = scm_cddr ($1);
1058 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1060 SCM type_check_proc = ly_lily_module_constant ("type-check-list");
1063 if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr ($1), sig, args)))
1065 THIS->error_level_ = 1;
1071 m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
1074 if (unsmob_music (m))
1076 $$ = unsmob_music (m);
1077 scm_gc_protect_object (m);
1082 loc->error (_ ("Music head function should return Music object."));
1083 $$ = MY_MAKE_MUSIC ("Music");
1085 $$->set_spot (*loc);
1090 Prefix_composite_music:
1091 Generic_prefix_music {
1094 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1095 $$ = context_spec_music ($2, $4, $6, $5);
1098 | CONTEXT simple_string optional_context_mod Music {
1099 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1101 | NEWCONTEXT simple_string optional_context_mod Music {
1102 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1106 | TIMES fraction Music
1109 int n = scm_to_int (scm_car ($2)); int d = scm_to_int (scm_cdr ($2));
1112 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1115 $$->set_property ("element", mp->self_scm ());
1116 scm_gc_unprotect_object (mp->self_scm ());
1117 $$->set_property ("numerator", scm_int2num (n));
1118 $$->set_property ("denominator", scm_int2num (d));
1119 $$->compress (Moment (Rational (n,d)));
1122 | Repeated_music { $$ = $1; }
1123 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1124 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1126 Pitch from = *unsmob_pitch ($2);
1127 Pitch to = *unsmob_pitch ($3);
1129 p->transpose (pitch_interval (from, to));
1130 $$->set_property ("element", p->self_scm ());
1131 scm_gc_unprotect_object (p->self_scm ());
1133 | mode_changing_head Grouped_music_list {
1134 if ($1 == ly_symbol2scm ("chords"))
1136 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1137 chm->set_property ("element", $2->self_scm ());
1139 scm_gc_unprotect_object ($2->self_scm ());
1145 THIS->lexer_->pop_state ();
1147 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1148 $$ = context_spec_music ($1, get_next_unique_context_id (),
1150 if ($1 == ly_symbol2scm ("ChordNames"))
1152 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1153 chm->set_property ("element", $$->self_scm ());
1154 scm_gc_unprotect_object ($$->self_scm ());
1157 THIS->lexer_->pop_state ();
1159 | relative_music { $$ = $1; }
1160 | re_rhythmed_music { $$ = $1; }
1161 | TAG embedded_scm Music {
1162 tag_music ($3, $2, @$);
1169 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1170 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1172 $$ = ly_symbol2scm ("notes");
1176 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1177 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1179 $$ = ly_symbol2scm ("drums");
1182 THIS->lexer_->push_figuredbass_state ();
1184 $$ = ly_symbol2scm ("figures");
1187 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1188 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1189 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1190 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1191 $$ = ly_symbol2scm ("chords");
1195 { THIS->lexer_->push_lyric_state ();
1196 $$ = ly_symbol2scm ("lyrics");
1200 mode_changing_head_with_context:
1202 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1203 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1205 $$ = ly_symbol2scm ("DrumStaff");
1208 THIS->lexer_->push_figuredbass_state ();
1210 $$ = ly_symbol2scm ("FiguredBass");
1213 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1214 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1215 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1216 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1217 $$ = ly_symbol2scm ("ChordNames");
1220 { THIS->lexer_->push_lyric_state ();
1221 $$ = ly_symbol2scm ("Lyrics");
1227 RELATIVE absolute_pitch Music {
1229 Pitch start = *unsmob_pitch ($2);
1230 $$ = make_music_relative (start, m);
1231 scm_gc_unprotect_object (m->self_scm ());
1233 | RELATIVE Composite_music {
1236 Pitch middle_c (0, 0, 0);
1237 $$ = make_music_relative (middle_c, m);
1238 scm_gc_unprotect_object (m->self_scm ());
1243 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1245 Grouped_music_list {
1246 /* Can also use Music at the expensive of two S/Rs similar to
1247 \repeat \alternative */
1248 THIS->lexer_->pop_state ();
1250 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1252 | new_lyrics ADDLYRICS {
1253 THIS->lexer_->push_lyric_state ();
1254 } Grouped_music_list {
1255 THIS->lexer_->pop_state ();
1256 $$ = scm_cons ($4->self_scm (), $1);
1261 Grouped_music_list new_lyrics {
1263 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1264 if (!scm_is_string (name))
1266 name = get_next_unique_lyrics_context_id ();
1267 voice = context_spec_music (scm_makfrom0str ("Voice"),
1272 SCM context = scm_makfrom0str ("Lyrics");
1273 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1276 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1278 Music *music = unsmob_music (scm_car (s));
1279 Music *com = make_lyric_combine_music (name, music);
1280 Music *csm = context_spec_music (context,
1281 get_next_unique_context_id (), com, SCM_EOL);
1282 lst = scm_cons (csm->self_scm (), lst);
1284 all->set_property ("elements", scm_cons (voice->self_scm (),
1287 scm_gc_unprotect_object (voice->self_scm ());
1289 | LYRICSTO simple_string {
1290 THIS->lexer_->push_lyric_state ();
1292 THIS->lexer_->pop_state ();
1295 $$ = make_lyric_combine_music (name, music);
1296 scm_gc_unprotect_object (music->self_scm ());
1301 CHANGE STRING '=' STRING {
1302 Music*t = MY_MAKE_MUSIC ("ContextChange");
1303 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1304 t-> set_property ("change-to-id", $4);
1313 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1314 scm_string_to_symbol ($1), $3);
1316 | UNSET simple_string {
1317 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1318 scm_string_to_symbol ($2));
1320 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1321 $$ = scm_list_4 (ly_symbol2scm ("push"),
1322 scm_string_to_symbol ($2), $3, $5);
1324 | REVERT simple_string embedded_scm {
1325 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1326 scm_string_to_symbol ($2), $3);
1331 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1332 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1334 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1335 | DENIES { $$ = ly_symbol2scm ("denies"); }
1337 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1338 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1339 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1340 | NAME { $$ = ly_symbol2scm ("context-name"); }
1344 property_operation { $$ = $1; }
1345 | context_def_mod STRING {
1346 $$ = scm_list_2 ($1, $2);
1352 if (!is_regular_identifier ($1))
1354 @$.error (_("Grob name should be alphanumeric"));
1357 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1358 scm_string_to_symbol ($1));
1360 | simple_string '.' simple_string {
1361 $$ = scm_list_2 (scm_string_to_symbol ($1),
1362 scm_string_to_symbol ($3));
1367 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1368 $$ = property_op_to_music (scm_list_4 (
1369 ly_symbol2scm ("poppush"),
1372 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1374 | REVERT context_prop_spec embedded_scm {
1375 $$ = property_op_to_music (scm_list_3 (
1376 ly_symbol2scm ("pop"),
1380 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1382 | SET context_prop_spec '=' scalar {
1383 $$ = property_op_to_music (scm_list_3 (
1384 ly_symbol2scm ("assign"),
1387 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1389 | UNSET context_prop_spec {
1390 $$ = property_op_to_music (scm_list_2 (
1391 ly_symbol2scm ("unset"),
1393 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1395 | ONCE music_property_def {
1396 SCM e = $2->get_property ("element");
1397 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1408 | STRING_IDENTIFIER {
1411 | string '+' string {
1412 $$ = scm_string_append (scm_list_2 ($1, $3));
1416 simple_string: STRING {
1431 $$ = scm_int2num ($1);
1440 $$ = scm_int2num ($1);
1446 pre_events doesn't contain anything. It is a trick:
1448 Adding pre_events to the simple_element
1449 makes the choice between
1455 simple_element: STRING
1457 a single shift/reduction conflict.
1459 nevertheless, this is not very clean, and we should find a different
1463 pre_events: /* empty */
1467 pre_events simple_element post_events {
1468 SCM elts = $2-> get_property ("elements");
1470 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1472 $2->set_property ("elements", elts);
1473 /* why is this giving wrong start location? -ns
1474 * $2->set_spot (@$); */
1476 i.set_location (@2, @3);
1481 | note_chord_element
1486 chord_body optional_notemode_duration post_events
1488 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1489 SCM es = $1->get_property ("elements");
1490 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1492 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1493 unsmob_music (scm_car (s))->set_property ("duration", dur);
1494 es = ly_append2 (es, postevs);
1496 $1-> set_property ("elements", es);
1508 simul_open: DOUBLE_ANGLE_OPEN
1511 simul_close: DOUBLE_ANGLE_CLOSE
1515 chord_open chord_body_elements chord_close
1517 $$ = MY_MAKE_MUSIC ("EventChord");
1519 $$->set_property ("elements",
1520 scm_reverse_x ($2, SCM_EOL));
1524 chord_body_elements:
1525 /* empty */ { $$ = SCM_EOL; }
1526 | chord_body_elements chord_body_element {
1527 $$ = scm_cons ($2->self_scm (), $1);
1528 scm_gc_unprotect_object ($2->self_scm ());
1533 pitch exclamations questions octave_check post_events
1540 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1541 n->set_property ("pitch", $1);
1544 n->set_property ("cautionary", SCM_BOOL_T);
1545 if (ex % 2 || q % 2)
1546 n->set_property ("force-accidental", SCM_BOOL_T);
1548 if (scm_is_pair (post)) {
1549 SCM arts = scm_reverse_x (post, SCM_EOL);
1550 n->set_property ("articulations", arts);
1552 if (scm_is_number (check))
1554 int q = scm_to_int (check);
1555 n->set_property ("absolute-octave", scm_int2num (q-1));
1561 | DRUM_PITCH post_events {
1562 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1563 n->set_property ("duration", $2);
1564 n->set_property ("drum-type", $1);
1567 if (scm_is_pair ($2)) {
1568 SCM arts = scm_reverse_x ($2, SCM_EOL);
1569 n->set_property ("articulations", arts);
1576 ADDQUOTE string Music {
1577 SCM adder = ly_lily_module_constant ("add-quotable");
1579 scm_call_2 (adder, $2, $3->self_scm ());
1580 scm_gc_unprotect_object ($3->self_scm ());
1586 $$ = MY_MAKE_MUSIC ("EventChord");
1587 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1588 scm_gc_unprotect_object ($1->self_scm ());
1593 | SKIP duration_length {
1594 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1595 skip->set_property ("duration", $2);
1596 skip->set_spot (@$);
1600 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1603 $$->set_property ("pitch", $2);
1606 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1607 m->set_property ("span-direction", scm_int2num (START));
1610 $$ = MY_MAKE_MUSIC ("EventChord");
1611 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1612 scm_gc_unprotect_object (m->self_scm ());
1616 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1617 m->set_property ("span-direction", scm_int2num (STOP));
1620 $$ = MY_MAKE_MUSIC ("EventChord");
1621 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1623 scm_gc_unprotect_object (m->self_scm ());
1626 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1630 SCM pipe = THIS->lexer_->lookup_identifier ("pipeSymbol");
1632 if (Music * m = unsmob_music (pipe))
1635 $$ = MY_MAKE_MUSIC ("BarCheck");
1639 | TRANSPOSITION pitch {
1641 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1642 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1643 sounds_as_c.smobbed_copy());
1645 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1649 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1651 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1653 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1657 | PARTIAL duration_length {
1658 Moment m = - unsmob_duration ($2)->get_length ();
1659 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1661 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1663 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1668 SCM proc = ly_lily_module_constant ("make-clef-set");
1670 SCM result = scm_call_1 (proc, $2);
1671 scm_gc_protect_object (result);
1672 $$ = unsmob_music (result);
1675 SCM proc = ly_lily_module_constant ("make-time-signature-set");
1677 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1678 scm_gc_protect_object (result);
1679 $$ = unsmob_music (result);
1682 SCM proc = ly_lily_module_constant ("make-mark-set");
1684 SCM result = scm_call_1 (proc, $2);
1685 scm_gc_protect_object (result);
1686 $$ = unsmob_music (result);
1692 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1695 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1702 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1705 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1707 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1708 if (scm_ilength ($3) > 0)
1710 key->set_property ("pitch-alist", $3);
1711 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1712 key->transpose (* unsmob_pitch ($2));
1714 THIS->parser_error (@3, _ ("Second argument must be pitch list."));
1726 | post_events post_event {
1728 $$ = scm_cons ($2->self_scm (), $$);
1729 scm_gc_unprotect_object ($2->self_scm ());
1731 | post_events tagged_post_event {
1732 $2 -> set_spot (@2);
1733 $$ = scm_cons ($2->self_scm (), $$);
1734 scm_gc_unprotect_object ($2->self_scm ());
1740 '-' TAG embedded_scm post_event {
1741 tag_music ($4, $3, @$);
1748 direction_less_event {
1752 if (!THIS->lexer_->is_lyric_state ())
1753 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
1754 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1757 if (!THIS->lexer_->is_lyric_state ())
1758 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
1759 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1761 | script_dir direction_reqd_event {
1763 $2->set_property ("direction", scm_int2num ($1));
1766 | script_dir direction_less_event {
1768 $2->set_property ("direction", scm_int2num ($1));
1771 | string_number_event
1774 string_number_event:
1776 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1777 s->set_property ("string-number", scm_int2num ($1));
1783 direction_less_char:
1785 $$ = ly_symbol2scm ("bracketOpenSymbol");
1788 $$ = ly_symbol2scm ("bracketCloseSymbol");
1791 $$ = ly_symbol2scm ("tildeSymbol");
1794 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1797 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1800 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1803 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1806 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1809 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1812 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1816 direction_less_event:
1817 direction_less_char {
1818 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1820 if (unsmob_music (predefd))
1822 m = unsmob_music (predefd)->clone ();
1826 m = MY_MAKE_MUSIC ("Music");
1831 | EVENT_IDENTIFIER {
1832 $$ = unsmob_music ($1);
1835 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1837 a->set_property ("tremolo-type", scm_int2num ($1));
1842 direction_reqd_event:
1846 | script_abbreviation {
1847 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1848 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1849 if (scm_is_string (s))
1850 a->set_property ("articulation-type", s);
1851 else THIS->parser_error (@1, _ ("Expecting string as script definition"));
1857 /**/ { $$ = SCM_EOL; }
1858 | '=' { $$ = scm_int2num (0); }
1859 | '=' sub_quotes { $$ = scm_int2num ($2); }
1860 | '=' sup_quotes { $$ = scm_int2num ($2); }
1885 | NOTENAME_PITCH sup_quotes {
1886 Pitch p = *unsmob_pitch ($1);
1887 p = p.transposed (Pitch ($2,0,0));
1888 $$ = p.smobbed_copy ();
1890 | NOTENAME_PITCH sub_quotes {
1891 Pitch p =* unsmob_pitch ($1);
1892 p = p.transposed (Pitch (-$2,0,0));
1893 $$ = p.smobbed_copy ();
1905 | TONICNAME_PITCH sup_quotes {
1906 Pitch p = *unsmob_pitch ($1);
1907 p = p.transposed (Pitch ($2,0,0));
1908 $$ = p.smobbed_copy ();
1910 | TONICNAME_PITCH sub_quotes {
1911 Pitch p =* unsmob_pitch ($1);
1913 p = p.transposed (Pitch (-$2,0,0));
1914 $$ = p.smobbed_copy ();
1924 pitch_also_in_chords:
1931 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1932 t->set_property ("text", $1);
1937 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1938 t->set_property ("text",
1939 make_simple_markup ($1));
1945 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1946 t->set_property ("digit", scm_int2num ($1));
1952 script_abbreviation:
1954 $$ = scm_makfrom0str ("Hat");
1957 $$ = scm_makfrom0str ("Plus");
1960 $$ = scm_makfrom0str ("Dash");
1963 $$ = scm_makfrom0str ("Bar");
1966 $$ = scm_makfrom0str ("Larger");
1969 $$ = scm_makfrom0str ("Dot");
1972 $$ = scm_makfrom0str ("Underscore");
1979 | '-' { $$ = CENTER; }
1990 multiplied_duration {
1995 optional_notemode_duration:
1997 Duration dd = THIS->default_duration_;
1998 $$ = dd.smobbed_copy ();
2000 THIS->beam_check ($$);
2002 | multiplied_duration {
2004 THIS->default_duration_ = *unsmob_duration ($$);
2006 THIS->beam_check ($$);
2011 bare_unsigned dots {
2013 if (!is_duration ($1))
2014 THIS->parser_error (@1, _f ("not a duration: %d", $1));
2018 $$ = Duration (len, $2).smobbed_copy ();
2020 | DURATION_IDENTIFIER dots {
2021 Duration *d = unsmob_duration ($1);
2022 Duration k (d->duration_log (), d->dot_count () + $2);
2028 multiplied_duration:
2032 | multiplied_duration '*' bare_unsigned {
2033 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2035 | multiplied_duration '*' FRACTION {
2036 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2038 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2043 FRACTION { $$ = $1; }
2044 | UNSIGNED '/' UNSIGNED {
2045 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2062 | ':' bare_unsigned {
2063 if (!is_duration ($2))
2064 THIS->parser_error (@2, _f ("not a duration: %d", $2));
2071 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2072 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2076 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2077 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2080 | STRING { $$ = $1; }
2091 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2092 $$ = bfr->self_scm ();
2093 scm_gc_unprotect_object ($$);
2096 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2097 $$ = bfr->self_scm ();
2099 bfr->set_property ("figure", $1);
2101 scm_gc_unprotect_object ($$);
2103 | bass_figure bass_mod {
2104 Music *m = unsmob_music ($1);
2106 SCM salter = m->get_property ("alteration");
2107 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2108 m->set_property ("alteration",
2109 scm_int2num (alter + $2));
2111 m->set_property ("alteration", scm_int2num (0));
2119 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2124 | br_bass_figure ']' {
2126 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2134 | figure_list br_bass_figure {
2135 $$ = scm_cons ($2, $1);
2140 FIGURE_OPEN figure_list FIGURE_CLOSE {
2141 Music *m = MY_MAKE_MUSIC ("EventChord");
2142 $2 = scm_reverse_x ($2, SCM_EOL);
2143 m->set_property ("elements", $2);
2144 $$ = m->self_scm ();
2155 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2156 if (!THIS->lexer_->is_note_state ())
2157 THIS->parser_error (@1, _ ("Have to be in Note mode for notes"));
2161 n = MY_MAKE_MUSIC ("RestEvent");
2163 n = MY_MAKE_MUSIC ("NoteEvent");
2165 n->set_property ("pitch", $1);
2166 n->set_property ("duration", $5);
2168 if (scm_is_number ($4))
2170 int q = scm_to_int ($4);
2171 n->set_property ("absolute-octave", scm_int2num (q-1));
2175 n->set_property ("cautionary", SCM_BOOL_T);
2176 if ($2 % 2 || $3 % 2)
2177 n->set_property ("force-accidental", SCM_BOOL_T);
2179 Music *v = MY_MAKE_MUSIC ("EventChord");
2180 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2181 scm_gc_unprotect_object (n->self_scm ());
2187 | DRUM_PITCH optional_notemode_duration {
2188 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2189 n->set_property ("duration", $2);
2190 n->set_property ("drum-type", $1);
2192 Music *v = MY_MAKE_MUSIC ("EventChord");
2193 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2194 scm_gc_unprotect_object (n->self_scm ());
2200 | figure_spec optional_notemode_duration {
2201 Music *m = unsmob_music ($1);
2203 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2205 unsmob_music (scm_car (s))->set_property ("duration", $2);
2209 | RESTNAME optional_notemode_duration {
2211 if (ly_scm2string ($1) == "s") {
2213 ev = MY_MAKE_MUSIC ("SkipEvent");
2216 ev = MY_MAKE_MUSIC ("RestEvent");
2219 ev->set_property ("duration", $2);
2221 Music *velt = MY_MAKE_MUSIC ("EventChord");
2222 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2223 velt->set_spot (@$);
2225 scm_gc_unprotect_object (ev->self_scm ());
2229 | MULTI_MEASURE_REST optional_notemode_duration {
2230 SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
2231 SCM mus = scm_call_2 (proc, $2, make_input (@$));
2232 scm_gc_protect_object (mus);
2233 $$ = unsmob_music (mus);
2236 | lyric_element optional_notemode_duration {
2237 if (!THIS->lexer_->is_lyric_state ())
2238 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
2240 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2241 lreq->set_property ("text", $1);
2242 lreq->set_property ("duration",$2);
2243 lreq->set_spot (@$);
2244 Music *velt = MY_MAKE_MUSIC ("EventChord");
2245 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2250 if (!THIS->lexer_->is_chord_state ())
2251 THIS->parser_error (@1, _ ("Have to be in Chord mode for chords"));
2252 $$ = unsmob_music ($1);
2257 /* FIXME: lyric flavoured markup would be better */
2262 $$ = make_simple_markup ($1);
2267 steno_tonic_pitch optional_notemode_duration {
2268 $$ = make_chord ($1, $2, SCM_EOL);
2270 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2271 SCM its = scm_reverse_x ($4, SCM_EOL);
2272 $$ = make_chord ($1, $2, scm_cons ($3, its));
2280 | chord_items chord_item {
2281 $$ = scm_cons ($2, $$);
2287 $$ = ly_symbol2scm ("chord-colon");
2290 $$ = ly_symbol2scm ("chord-caret");
2292 | CHORD_SLASH steno_tonic_pitch {
2293 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2295 | CHORD_BASS steno_tonic_pitch {
2296 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2305 $$ = scm_reverse_x ($1, SCM_EOL);
2313 step_number { $$ = scm_cons ($1, SCM_EOL); }
2314 | step_numbers '.' step_number {
2315 $$ = scm_cons ($3, $$);
2321 $$ = make_chord_step ($1, 0);
2323 | bare_unsigned '+' {
2324 $$ = make_chord_step ($1, SHARP);
2326 | bare_unsigned CHORD_MINUS {
2327 $$ = make_chord_step ($1, FLAT);
2334 TODO: should deprecate in favor of Scheme?
2338 number_expression '+' number_term {
2339 $$ = scm_sum ($1, $3);
2341 | number_expression '-' number_term {
2342 $$ = scm_difference ($1, $3);
2351 | number_factor '*' number_factor {
2352 $$ = scm_product ($1, $3);
2354 | number_factor '/' number_factor {
2355 $$ = scm_divide ($1, $3);
2360 '-' number_factor { /* %prec UNARY_MINUS */
2361 $$ = scm_difference ($2, SCM_UNDEFINED);
2369 $$ = scm_int2num ($1);
2374 | NUMBER_IDENTIFIER {
2377 | REAL NUMBER_IDENTIFIER {
2378 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2380 | UNSIGNED NUMBER_IDENTIFIER {
2381 $$ = scm_make_real ($1 *scm_to_double ($2));
2397 if (scm_integer_p ($1) == SCM_BOOL_T)
2399 int k = scm_to_int ($1);
2403 THIS->parser_error (@1, _ ("need integer number arg"));
2414 | exclamations '!' { $$ ++; }
2419 | questions '?' { $$ ++; }
2423 This should be done more dynamically if possible.
2431 { THIS->lexer_->push_markup_state (); }
2434 THIS->lexer_->pop_state ();
2440 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
2442 | markup_head_1_list simple_markup {
2443 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2451 markup_composed_list {
2454 | markup_braced_list {
2459 markup_composed_list:
2460 markup_head_1_list markup_braced_list {
2461 $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
2467 '{' markup_braced_list_body '}' {
2468 $$ = scm_reverse_x ($2, SCM_EOL);
2472 markup_braced_list_body:
2473 /* empty */ { $$ = scm_list (SCM_EOL); }
2474 | markup_braced_list_body markup {
2475 $$ = scm_cons ($2, $1);
2477 | markup_braced_list_body markup_list {
2478 $$ = scm_append_x (scm_list_2 (scm_reverse_x ($2, SCM_EOL), $1));
2483 MARKUP_HEAD_MARKUP0 {
2484 $$ = scm_list_1 ($1);
2486 | MARKUP_HEAD_SCM0_MARKUP1 embedded_scm {
2487 $$ = scm_list_2 ($1, $2);
2489 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm {
2490 $$ = scm_list_3 ($1, $2, $3);
2495 markup_head_1_item {
2496 $$ = scm_list_1 ($1);
2498 | markup_head_1_list markup_head_1_item {
2499 $$ = scm_cons ($2, $1);
2505 $$ = make_simple_markup ($1);
2507 | MARKUP_IDENTIFIER {
2510 | STRING_IDENTIFIER {
2514 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2515 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2516 } '{' score_body '}' {
2518 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());
2519 scm_gc_unprotect_object (sc->self_scm ());
2520 THIS->lexer_->pop_state ();
2522 | MARKUP_HEAD_SCM0 embedded_scm {
2523 $$ = scm_list_2 ($1, $2);
2525 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2526 $$ = scm_list_4 ($1, $2, $3, $4);
2528 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2529 $$ = scm_list_3 ($1, $2, $3);
2531 | MARKUP_HEAD_EMPTY {
2532 $$ = scm_list_1 ($1);
2534 | MARKUP_HEAD_LIST0 markup_list {
2535 $$ = scm_list_2 ($1,$2);
2537 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2538 $$ = scm_list_3 ($1, $2, $3);
2543 markup_head_1_list simple_markup {
2544 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2554 Lily_parser::set_yydebug (bool )
2562 Lily_parser::do_yyparse ()
2564 yyparse ((void*)this);
2569 Should make this optional? It will also complain when you do
2573 which is entirely legitimate.
2575 Or we can scrap it. Barchecks should detect wrong durations, and
2576 skipTypesetting speeds it up a lot.
2580 Lily_parser::beam_check (SCM dur)
2582 Duration *d = unsmob_duration (dur);
2583 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2585 Music *m = unsmob_music (last_beam_start_);
2586 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2588 last_beam_start_ = SCM_EOL;
2596 It is a little strange to have this function in this file, but
2597 otherwise, we have to import music classes into the lexer.
2601 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2603 if (scm_is_string (sid)) {
2605 return STRING_IDENTIFIER;
2606 } else if (scm_is_number (sid)) {
2608 return NUMBER_IDENTIFIER;
2609 } else if (unsmob_context_def (sid)) {
2610 *destination = unsmob_context_def (sid)->clone_scm ();
2611 return CONTEXT_DEF_IDENTIFIER;
2612 } else if (unsmob_score (sid)) {
2613 Score *score = new Score (*unsmob_score (sid));
2614 *destination = score->self_scm ();
2615 return SCORE_IDENTIFIER;
2616 } else if (Music *mus = unsmob_music (sid)) {
2617 mus = mus->clone ();
2618 *destination = mus->self_scm ();
2619 unsmob_music (*destination)->
2620 set_property ("origin", make_input (last_input_));
2621 return dynamic_cast<Event*> (mus)
2622 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2623 } else if (unsmob_duration (sid)) {
2624 *destination = unsmob_duration (sid)->smobbed_copy ();
2625 return DURATION_IDENTIFIER;
2626 } else if (unsmob_output_def (sid)) {
2627 Output_def *p = unsmob_output_def (sid);
2630 *destination = p->self_scm ();
2631 return OUTPUT_DEF_IDENTIFIER;
2632 } else if (Text_interface::markup_p (sid)) {
2634 return MARKUP_IDENTIFIER;
2641 property_op_to_music (SCM op)
2644 SCM tag = scm_car (op);
2645 SCM symbol = scm_cadr (op);
2646 SCM args = scm_cddr (op);
2647 SCM grob_val = SCM_UNDEFINED;
2648 SCM grob_sym = SCM_UNDEFINED;
2649 SCM val = SCM_UNDEFINED;
2651 if (tag == ly_symbol2scm ("assign"))
2653 m = MY_MAKE_MUSIC ("PropertySet");
2654 val = scm_car (args);
2656 else if (tag == ly_symbol2scm ("unset"))
2657 m = MY_MAKE_MUSIC ("PropertyUnset");
2658 else if (tag == ly_symbol2scm ("poppush")
2659 || tag == ly_symbol2scm ("push"))
2661 m = MY_MAKE_MUSIC ("OverrideProperty");
2662 grob_sym = scm_car (args);
2663 grob_val = scm_cadr (args);
2665 else if (tag == ly_symbol2scm ("pop")) {
2666 m = MY_MAKE_MUSIC ("RevertProperty");
2667 grob_sym = scm_car (args);
2670 m->set_property ("symbol", symbol);
2672 if (val != SCM_UNDEFINED)
2673 m->set_property ("value", val);
2674 if (grob_val != SCM_UNDEFINED)
2675 m->set_property ("grob-value", grob_val);
2677 if (grob_sym != SCM_UNDEFINED)
2679 bool itc = do_internal_type_checking_global;
2682 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2684 do_internal_type_checking_global = false;
2685 m->set_property ("grob-property", grob_sym);
2687 do_internal_type_checking_global = itc;
2690 if (tag == ly_symbol2scm ("poppush"))
2691 m->set_property ("pop-first", SCM_BOOL_T);
2698 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2700 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2702 csm->set_property ("element", m->self_scm ());
2703 scm_gc_unprotect_object (m->self_scm ());
2705 csm->set_property ("context-type",
2706 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2707 csm->set_property ("property-operations", ops);
2709 if (scm_is_string (id))
2710 csm->set_property ("context-id", id);
2715 get_next_unique_context_id ()
2717 return scm_makfrom0str ("$uniqueContextId");
2722 get_next_unique_lyrics_context_id ()
2724 static int new_context_count;
2726 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2727 return scm_makfrom0str (s);