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>
15 * The rules for who is protecting what are very shady. Uniformise
18 * 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 ();
61 #define _(x) gettext (x)
64 #define YYERROR_VERBOSE 1
66 #define YYPARSE_PARAM my_lily_parser
67 #define YYLEX_PARAM my_lily_parser
69 ((Lily_parser *) my_lily_parser)
71 #define yyerror THIS->parser_error
73 /* We use custom location type: Input objects */
75 #define YYLLOC_DEFAULT(Current,Rhs,N) \
76 ((Current).set_location ((Rhs)[1], (Rhs)[N]))
79 /* Add symbols to the TAGS field of a music object. */
82 tag_music (Music *m, SCM tag, Input ip)
84 SCM tags = m->get_property ("tags");
85 if (scm_is_symbol (tag))
86 tags = scm_cons (tag, tags);
87 else if (ly_c_list_p (tag))
88 tags = ly_append2 (tag, tags);
90 ip.warning (_ ("tag must be symbol or list of symbols"));
92 m->set_property ("tags", tags);
96 is_regular_identifier (SCM id)
98 String str = ly_scm2string (id);
99 char const *s = str.to_str0 ();
108 v = v && isalnum (*s);
116 get_first_context_id (SCM type, Music *m)
118 SCM id = m->get_property ("context-id");
119 if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
120 && scm_is_string (m->get_property ("context-id"))
121 && scm_c_string_length (id) > 0)
129 make_simple_markup (SCM a)
131 SCM simple = ly_lily_module_constant ("simple-markup");
132 return scm_list_2 (simple, a);
138 return t && t == 1 << intlog2 (t);
142 set_music_properties (Music *p, SCM a)
144 for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
145 p->internal_set_property (scm_caar (k), scm_cdar (k));
149 make_chord_step (int step, int alter)
156 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
157 return m.smobbed_copy ();
162 make_chord (SCM pitch, SCM dur, SCM modification_list)
164 SCM chord_ctor = ly_lily_module_constant ("construct-chord");
165 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
166 scm_gc_protect_object (ch);
170 /* Todo: actually also use apply iso. call too ... */
172 ly_input_procedure_p (SCM x)
174 return ly_c_procedure_p (x)
175 || (scm_is_pair (x) && ly_c_procedure_p (scm_car (x)));
179 set_property_music (SCM sym, SCM value)
181 Music *p = MY_MAKE_MUSIC ("PropertySet");
182 p->set_property ("symbol", sym);
183 p->set_property ("value", value);
188 make_music_relative (Pitch start, Music *music)
190 Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
191 relative->set_property ("element", music->self_scm ());
193 Pitch last = music->to_relative_octave (start);
194 if (lily_1_8_relative)
195 music->set_property ("last-pitch", last.smobbed_copy ());
200 make_lyric_combine_music (SCM name, Music *music)
202 Music *combine = MY_MAKE_MUSIC ("NewLyricCombineMusic");
203 combine->set_property ("element", music->self_scm ());
204 combine->set_property ("associated-context", name);
210 /* We use SCMs to do strings, because it saves us the trouble of
211 deleting them. Let's hope that a stack overflow doesnt trigger a move
212 of the parse stack onto the heap. */
218 Output_def *outputdef;
228 yylex (YYSTYPE *s, YYLTYPE *loc, void *v)
230 Lily_parser *pars = (Lily_parser*) v;
231 Lily_lexer *lex = pars->lexer_;
233 lex->lexval = (void*) s;
235 lex->prepare_for_next_token ();
236 return lex->yylex ();
244 /* One shift/reduce problem
247 \repeat .. \alternative
249 \repeat { \repeat .. \alternative }
253 \repeat { \repeat } \alternative
260 /* The third option is an alias that will be used to display the
261 syntax error. Bison CVS now correctly handles backslash escapes.
263 FIXME: Bison needs to translate some of these, eg, STRING.
267 /* Keyword tokens with plain escaped name. */
268 %token ACCEPTS "\\accepts"
269 %token ADDLYRICS "\\addlyrics"
270 %token ADDQUOTE "\\addquote"
271 %token ALIAS "\\alias"
272 %token ALTERNATIVE "\\alternative"
275 %token CHANGE "\\change"
276 %token CHORDMODE "\\chordmode"
277 %token CHORDS "\\chords"
279 %token CONSISTS "\\consists"
280 %token CONTEXT "\\context"
281 %token DEFAULT "\\default"
282 %token DEFAULTCHILD "\\defaultchild"
283 %token DENIES "\\denies"
284 %token DESCRIPTION "\\description"
285 %token DRUMMODE "\\drummode"
286 %token DRUMS "\\drums"
287 %token FIGUREMODE "\\figuremode"
288 %token FIGURES "\\figures"
289 %token GROBDESCRIPTIONS "\\grobdescriptions"
290 %token HEADER "\\header"
291 %token INVALID "\\invalid"
293 %token LAYOUT "\\layout"
294 %token LYRICMODE "\\lyricmode"
295 %token LYRICS "\\lyrics"
296 %token LYRICSTO "\\lyricsto"
298 %token MARKUP "\\markup"
301 %token NOTEMODE "\\notemode"
302 %token OBJECTID "\\objectid"
303 %token OCTAVE "\\octave"
305 %token OVERRIDE "\\override"
306 %token PAPER "\\paper"
307 %token PARTIAL "\\partial"
308 %token RELATIVE "\\relative"
309 %token REMOVE "\\remove"
310 %token REPEAT "\\repeat"
312 %token REVERT "\\revert"
313 %token SCORE "\\score"
314 %token SEQUENTIAL "\\sequential"
316 %token SIMULTANEOUS "\\simultaneous"
319 %token TEMPO "\\tempo"
320 %token TIMES "\\times"
321 %token TRANSPOSE "\\transpose"
322 %token TRANSPOSITION "\\transposition"
324 %token UNSET "\\unset"
327 /* Keyword token exceptions. */
328 %token TIME_T "\\time"
329 %token NEWCONTEXT "\\new"
332 /* Other string tokens. */
334 %token CHORD_BASS "/+"
335 %token CHORD_CARET "^"
336 %token CHORD_COLON ":"
337 %token CHORD_MINUS "-"
338 %token CHORD_SLASH "/"
339 %token DOUBLE_ANGLE_CLOSE ">>"
340 %token DOUBLE_ANGLE_OPEN "<<"
341 %token E_BACKSLASH "\\"
342 %token E_ANGLE_CLOSE "\\>"
343 %token E_CHAR "\\C[haracter]"
345 %token E_EXCLAMATION "\\!"
346 %token E_BRACKET_OPEN "\\["
348 %token E_BRACKET_CLOSE "\\]"
349 %token E_ANGLE_OPEN "\\<"
352 /* These used at all?
353 %token FIGURE_BRACKET_CLOSE
354 %token FIGURE_BRACKET_OPEN
356 parser.yy:348.8-25: warning: symbol `"\\>"' used more than once as a literal string
357 parser.yy:352.8-24: warning: symbol `"\\<"' used more than once as a literal string
360 %token FIGURE_CLOSE /* "\\>" */
361 %token FIGURE_OPEN /* "\\<" */
362 %token FIGURE_SPACE "_"
365 %token CHORDMODIFIERS
366 %token COMMANDSPANREQUEST
368 %token MULTI_MEASURE_REST
373 %token <i> E_UNSIGNED
376 %token <id> IDENTIFIER
378 %token <scm> CHORDMODIFIER_PITCH
379 %token <scm> CHORD_MODIFIER
380 %token <scm> CONTEXT_DEF_IDENTIFIER
381 %token <scm> DRUM_PITCH
382 %token <scm> DURATION_IDENTIFIER
383 %token <scm> EVENT_IDENTIFIER
384 %token <scm> FRACTION
385 %token <scm> LYRICS_STRING
386 %token <scm> LYRIC_MARKUP_IDENTIFIER
387 %token <scm> MARKUP_HEAD_EMPTY
388 %token <scm> MARKUP_HEAD_LIST0
389 %token <scm> MARKUP_HEAD_MARKUP0
390 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
391 %token <scm> MARKUP_HEAD_SCM0
392 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
393 %token <scm> MARKUP_HEAD_SCM0_SCM1
394 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
395 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
396 %token <scm> MARKUP_IDENTIFIER
397 %token <scm> MUSIC_FUNCTION
398 %token <scm> MUSIC_FUNCTION_MARKUP
399 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
400 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
401 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
402 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
403 %token <scm> MUSIC_FUNCTION_MUSIC
404 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
405 %token <scm> MUSIC_FUNCTION_SCM
406 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
407 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
408 %token <scm> MUSIC_FUNCTION_SCM_SCM
409 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
410 %token <scm> MUSIC_IDENTIFIER
411 %token <scm> NOTENAME_PITCH
412 %token <scm> NUMBER_IDENTIFIER
413 %token <scm> OUTPUT_DEF_IDENTIFIER
415 %token <scm> RESTNAME
416 %token <scm> SCM_IDENTIFIER
418 %token <scm> SCORE_IDENTIFIER
420 %token <scm> STRING_IDENTIFIER
421 %token <scm> TONICNAME_PITCH
424 %type <book> book_block
425 %type <book> book_body
428 %type <i> bare_unsigned
431 %type <i> exclamations
432 %type <i> optional_rest
437 %type <i> tremolo_type
439 %type <music> Composite_music
440 %type <music> Generic_prefix_music
441 %type <music> Grouped_music_list
443 %type <music> Prefix_composite_music
444 %type <music> Repeated_music
445 %type <music> Sequential_music
446 %type <music> Simple_music
447 %type <music> Simultaneous_music
448 %type <music> chord_body
449 %type <music> chord_body_element
450 %type <music> command_element
451 %type <music> command_req
452 %type <music> context_change
453 %type <music> direction_less_event
454 %type <music> direction_reqd_event
455 %type <music> event_chord
456 %type <music> gen_text_def
457 %type <music> music_property_def
458 %type <music> note_chord_element
459 %type <music> post_event
460 %type <music> re_rhythmed_music
461 %type <music> relative_music
462 %type <music> simple_element
463 %type <music> string_number_event
464 %type <music> tagged_post_event
465 %type <music> tempo_event
466 %type <music> toplevel_music
468 %type <outputdef> output_def_body
469 %type <outputdef> output_def_head
470 %type <outputdef> output_def
471 %type <outputdef> paper_block
473 %type <scm> Alternative_music
474 %type <scm> Generic_prefix_music_scm
475 %type <scm> Music_list
476 %type <scm> absolute_pitch
477 %type <scm> assignment_id
478 %type <scm> bare_number
479 %type <scm> bass_figure
480 %type <scm> bass_number
481 %type <scm> br_bass_figure
482 %type <scm> chord_body_elements
483 %type <scm> chord_item
484 %type <scm> chord_items
485 %type <scm> chord_separator
486 %type <scm> context_def_mod
487 %type <scm> context_def_spec_block
488 %type <scm> context_def_spec_body
489 %type <scm> context_mod
490 %type <scm> context_mod_list
491 %type <scm> context_prop_spec
492 %type <scm> direction_less_char
493 %type <scm> duration_length
494 %type <scm> embedded_scm
495 %type <scm> figure_list
496 %type <scm> figure_spec
498 %type <scm> full_markup
499 %type <scm> identifier_init
500 %type <scm> lilypond_header
501 %type <scm> lilypond_header_body
502 %type <scm> lyric_element
503 %type <scm> lyric_markup
505 %type <scm> markup_braced_list
506 %type <scm> markup_braced_list_body
507 %type <scm> markup_composed_list
508 %type <scm> markup_head_1_item
509 %type <scm> markup_head_1_list
510 %type <scm> markup_list
511 %type <scm> markup_top
512 %type <scm> mode_changing_head
513 %type <scm> mode_changing_head_with_context
514 %type <scm> multiplied_duration
515 %type <scm> new_chord
516 %type <scm> new_lyrics
517 %type <scm> number_expression
518 %type <scm> number_factor
519 %type <scm> number_term
520 %type <scm> object_id_setting
521 %type <scm> octave_check
522 %type <scm> optional_context_mod
523 %type <scm> optional_notemode_duration
525 %type <scm> pitch_also_in_chords
526 %type <scm> post_events
527 %type <scm> property_operation
529 %type <scm> script_abbreviation
530 %type <scm> simple_markup
531 %type <scm> simple_string
532 %type <scm> steno_duration
533 %type <scm> steno_pitch
534 %type <scm> steno_tonic_pitch
535 %type <scm> step_number
536 %type <scm> step_numbers
539 %type <score> score_block
540 %type <score> score_body
545 /* We don't assign precedence to / and *, because we might need varied
546 prec levels in different prods */
552 lilypond: /* empty */
553 | lilypond toplevel_expression {
555 | lilypond assignment {
558 THIS->error_level_ = 1;
561 THIS->error_level_ = 1;
567 OBJECTID STRING { $$ = $2; }
572 THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1);
579 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
580 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
581 scm_gc_unprotect_object (book->self_scm ());
586 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
587 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
588 scm_gc_unprotect_object (score->self_scm ());
592 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
593 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
594 scm_gc_unprotect_object (music->self_scm ());
597 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-text-handler");
598 scm_call_2 (proc, THIS->self_scm (), $1);
602 Output_def * od = $1;
604 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
605 id = ly_symbol2scm ("$defaultpaper");
606 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
607 id = ly_symbol2scm ("$defaultmidi");
608 else if ($1->c_variable ("is-layout") == SCM_BOOL_T)
609 id = ly_symbol2scm ("$defaultlayout");
611 THIS->lexer_->set_identifier (id, od->self_scm ());
612 scm_gc_unprotect_object (od->self_scm ());
627 lilypond_header_body:
629 $$ = ly_make_anonymous_module (be_safe_global);
630 THIS->lexer_->add_scope ($$);
632 | lilypond_header_body assignment {
638 HEADER '{' lilypond_header_body '}' {
639 $$ = THIS->lexer_->remove_scope ();
648 | LYRICS_STRING { $$ = $1; }
652 assignment_id '=' identifier_init {
653 if (! is_regular_identifier ($1))
655 @1.warning (_ ("identifier should have alphabetic characters only"));
658 THIS->lexer_->set_identifier ($1, $3);
661 TODO: devise standard for protection in parser.
663 The parser stack lives on the C-stack, which means that
664 all objects can be unprotected as soon as they're here.
674 $$ = $1->self_scm ();
675 scm_gc_unprotect_object ($$);
678 $$ = $1->self_scm ();
679 scm_gc_unprotect_object ($$);
681 | context_def_spec_block {
685 $$ = $1->self_scm ();
686 scm_gc_unprotect_object ($$);
689 $$ = $1->self_scm ();
690 scm_gc_unprotect_object ($$);
692 | number_expression {
705 $$ = scm_int2num ($1);
709 context_def_spec_block:
710 CONTEXT '{' context_def_spec_body '}'
716 context_def_spec_body:
718 $$ = Context_def::make_scm ();
719 unsmob_context_def ($$)->set_spot (@$);
721 | CONTEXT_DEF_IDENTIFIER {
723 unsmob_context_def ($$)->set_spot (@$);
725 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
726 Context_def*td = unsmob_context_def ($$);
728 for (SCM p = $3; scm_is_pair (p); p = scm_cdr (p)) {
729 SCM tag = scm_caar (p);
731 /* TODO: should make new tag "grob-definition" ? */
732 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
733 tag, scm_cons (scm_cdar (p), SCM_EOL)));
736 | context_def_spec_body context_mod {
737 unsmob_context_def ($$)->add_context_mod ($2);
744 BOOK '{' book_body '}' {
750 * Use 'handlers' like for toplevel-* stuff?
751 * grok \layout and \midi? */
756 $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
757 scm_gc_unprotect_object ($$->paper_->self_scm ());
758 $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader");
760 | book_body paper_block {
762 scm_gc_unprotect_object ($2->self_scm ());
764 | book_body score_block {
765 SCM s = $2->self_scm ();
767 scm_gc_unprotect_object (s);
769 | book_body full_markup {
772 | book_body lilypond_header {
777 $$->scores_ = SCM_EOL;
779 | book_body object_id_setting {
780 $$->user_key_ = ly_scm2string ($2);
785 SCORE '{' score_body '}' {
796 $$ = new Score ( *unsmob_score ($1));
799 | score_body object_id_setting {
800 $$->user_key_ = ly_scm2string ($2);
803 SCM m = $2->self_scm ();
804 scm_gc_unprotect_object (m);
805 $$->set_music (m, THIS->self_scm ());
807 | score_body lilypond_header {
810 | score_body output_def {
811 if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
813 THIS->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
820 scm_gc_unprotect_object ($2->self_scm ());
823 $$->error_found_ = true;
835 if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
837 THIS->parser_error (@1, _ ("need \\paper for paper block"));
838 $$ = get_paper (THIS);
845 output_def_body '}' {
848 THIS->lexer_->remove_scope ();
849 THIS->lexer_->pop_state ();
855 $$ = get_paper (THIS);
856 $$->input_origin_ = @$;
857 THIS->lexer_->add_scope ($$->scope_);
860 Output_def *p = get_midi (THIS);
862 THIS->lexer_->add_scope (p->scope_);
865 Output_def *p = get_layout (THIS);
867 THIS->lexer_->add_scope (p->scope_);
874 output_def_head '{' {
876 $$->input_origin_.set_spot (@$);
877 THIS->lexer_->push_initial_state ();
879 | output_def_head '{' OUTPUT_DEF_IDENTIFIER {
880 scm_gc_unprotect_object ($1->self_scm ());
881 Output_def *o = unsmob_output_def ($3);
882 o->input_origin_.set_spot (@$);
884 THIS->lexer_->remove_scope ();
885 THIS->lexer_->add_scope (o->scope_);
886 THIS->lexer_->push_initial_state ();
888 | output_def_body assignment {
891 | output_def_body context_def_spec_block {
892 assign_context_def ($$, $2);
894 | output_def_body tempo_event {
896 junk this ? there already is tempo stuff in
899 int m = scm_to_int ($2->get_property ("metronome-count"));
900 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
901 set_tempo ($$, d->get_length (), m);
902 scm_gc_unprotect_object ($2->self_scm ());
904 | output_def_body error {
910 TEMPO steno_duration '=' bare_unsigned {
911 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
912 $$->set_property ("tempo-unit", $2);
913 $$->set_property ("metronome-count", scm_int2num ( $4));
918 The representation of a list is the
922 to have efficient append. */
926 $$ = scm_cons (SCM_EOL, SCM_EOL);
930 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
931 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
933 if (scm_is_pair (scm_cdr (s)))
934 scm_set_cdr_x (scm_cdr (s), c); /* append */
936 scm_set_car_x (s, c); /* set first cons */
937 scm_set_cdr_x (s, c); /* remember last cell */
939 | Music_list embedded_scm {
943 Music * m = MY_MAKE_MUSIC("Music");
945 m->set_property ("error-found", SCM_BOOL_T);
947 SCM c = scm_cons (m->self_scm (), SCM_EOL);
948 scm_gc_unprotect_object (m->self_scm ()); /* UGH */
950 if (scm_is_pair (scm_cdr (s)))
951 scm_set_cdr_x (scm_cdr (s), c); /* append */
953 scm_set_car_x (s, c); /* set first cons */
954 scm_set_cdr_x (s, c); /* remember last cell */
967 | ALTERNATIVE '{' Music_list '}' {
974 REPEAT simple_string bare_unsigned Music Alternative_music
978 SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
979 if (times < scm_ilength (alts)) {
980 unsmob_music (scm_car (alts))
981 ->origin ()->warning (
982 _ ("more alternatives than repeats"));
983 warning ("junking excess alternatives");
984 alts = ly_truncate_list (times, alts);
988 SCM proc = ly_lily_module_constant ("make-repeated-music");
990 SCM mus = scm_call_1 (proc, $2);
991 scm_gc_protect_object (mus); // UGH.
992 Music *r = unsmob_music (mus);
995 r-> set_property ("element", beg->self_scm ());
996 scm_gc_unprotect_object (beg->self_scm ());
998 r->set_property ("repeat-count", scm_int2num (times >? 1));
1000 r-> set_property ("elements",alts);
1001 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
1003 TODO: move this code to Scheme.
1006 /* we cannot get durations and other stuff
1007 correct down the line,
1008 so we have to add to the duration log here. */
1009 SCM func = ly_lily_module_constant ("shift-duration-log");
1011 int dots = ($3 % 3) ? 0 : 1;
1012 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
1015 if ($4->is_mus_type ("sequential-music"))
1017 int list_len = scm_ilength ($4->get_property ("elements"));
1019 $4->origin ()->warning (_f ("expect 2 elements for Chord tremolo, found %d", list_len));
1021 r->compress (Moment (Rational (1, list_len)));
1023 scm_call_3 (func, r->self_scm (), scm_int2num (shift), scm_int2num (dots));
1026 r->set_spot (*$4->origin ());
1033 SEQUENTIAL '{' Music_list '}' {
1034 $$ = MY_MAKE_MUSIC ("SequentialMusic");
1035 $$->set_property ("elements", scm_car ($3));
1038 | '{' Music_list '}' {
1039 $$ = MY_MAKE_MUSIC ("SequentialMusic");
1040 $$->set_property ("elements", scm_car ($2));
1046 SIMULTANEOUS '{' Music_list '}'{
1047 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
1048 $$->set_property ("elements", scm_car ($3));
1052 | simul_open Music_list simul_close {
1053 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
1054 $$->set_property ("elements", scm_car ($2));
1060 event_chord { $$ = $1; }
1061 | MUSIC_IDENTIFIER {
1062 $$ = unsmob_music ($1);
1064 | music_property_def
1069 optional_context_mod:
1070 /**/ { $$ = SCM_EOL; }
1071 | WITH { THIS->lexer_->push_initial_state (); }
1072 '{' context_mod_list '}'
1074 THIS->lexer_->pop_state ();
1080 /* */ { $$ = SCM_EOL; }
1081 | context_mod_list context_mod {
1082 $$ = scm_cons ($2, $1);
1088 Prefix_composite_music { $$ = $1; }
1089 | Grouped_music_list { $$ = $1; }
1093 Simultaneous_music { $$ = $1; }
1094 | Sequential_music { $$ = $1; }
1097 Generic_prefix_music_scm:
1099 $$ = scm_list_2 ($1, make_input (@$));
1101 | MUSIC_FUNCTION_SCM embedded_scm {
1102 $$ = scm_list_3 ($1, make_input (@$), $2);
1104 | MUSIC_FUNCTION_MARKUP full_markup {
1105 $$ = scm_list_3 ($1, make_input (@$), $2);
1107 | MUSIC_FUNCTION_MUSIC Music {
1108 $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
1109 scm_gc_unprotect_object ($2->self_scm ());
1111 | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
1112 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1113 scm_gc_unprotect_object ($3->self_scm ());
1115 | MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
1116 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1118 | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
1119 $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
1121 | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
1122 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1123 scm_gc_unprotect_object ($3->self_scm ());
1125 | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
1126 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1128 | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
1129 $$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
1130 scm_gc_unprotect_object ($2->self_scm ());
1131 scm_gc_unprotect_object ($3->self_scm ());
1133 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
1134 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1135 scm_gc_unprotect_object ($4->self_scm ());
1136 scm_gc_unprotect_object ($3->self_scm ());
1138 | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
1139 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1140 scm_gc_unprotect_object ($3->self_scm ());
1141 scm_gc_unprotect_object ($4->self_scm ());
1145 Generic_prefix_music:
1146 Generic_prefix_music_scm {
1147 SCM func = scm_car ($1);
1148 Input *loc = unsmob_input (scm_cadr ($1));
1149 SCM args = scm_cddr ($1);
1150 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1152 SCM type_check_proc = ly_lily_module_constant ("type-check-list");
1155 if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr ($1), sig, args)))
1157 THIS->error_level_ = 1;
1163 m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
1166 if (unsmob_music (m))
1168 $$ = unsmob_music (m);
1169 scm_gc_protect_object (m);
1174 loc->error (_ ("music head function must return Music object"));
1175 $$ = MY_MAKE_MUSIC ("Music");
1177 $$->set_spot (*loc);
1182 Prefix_composite_music:
1183 Generic_prefix_music {
1186 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1187 $$ = context_spec_music ($2, $4, $6, $5);
1190 | CONTEXT simple_string optional_context_mod Music {
1191 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1193 | NEWCONTEXT simple_string optional_context_mod Music {
1194 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1198 | TIMES fraction Music
1201 int n = scm_to_int (scm_car ($2)); int d = scm_to_int (scm_cdr ($2));
1204 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1207 $$->set_property ("element", mp->self_scm ());
1208 scm_gc_unprotect_object (mp->self_scm ());
1209 $$->set_property ("numerator", scm_int2num (n));
1210 $$->set_property ("denominator", scm_int2num (d));
1211 $$->compress (Moment (Rational (n,d)));
1214 | Repeated_music { $$ = $1; }
1215 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1216 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1218 Pitch from = *unsmob_pitch ($2);
1219 Pitch to = *unsmob_pitch ($3);
1221 p->transpose (pitch_interval (from, to));
1222 $$->set_property ("element", p->self_scm ());
1223 scm_gc_unprotect_object (p->self_scm ());
1225 | mode_changing_head Grouped_music_list {
1226 if ($1 == ly_symbol2scm ("chords"))
1228 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1229 chm->set_property ("element", $2->self_scm ());
1231 scm_gc_unprotect_object ($2->self_scm ());
1237 THIS->lexer_->pop_state ();
1239 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1240 $$ = context_spec_music ($1, get_next_unique_context_id (),
1242 if ($1 == ly_symbol2scm ("ChordNames"))
1244 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1245 chm->set_property ("element", $$->self_scm ());
1246 scm_gc_unprotect_object ($$->self_scm ());
1249 THIS->lexer_->pop_state ();
1251 | relative_music { $$ = $1; }
1252 | re_rhythmed_music { $$ = $1; }
1253 | TAG embedded_scm Music {
1254 tag_music ($3, $2, @$);
1261 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1262 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1264 $$ = ly_symbol2scm ("notes");
1268 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1269 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1271 $$ = ly_symbol2scm ("drums");
1274 THIS->lexer_->push_figuredbass_state ();
1276 $$ = ly_symbol2scm ("figures");
1279 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1280 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1281 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1282 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1283 $$ = ly_symbol2scm ("chords");
1287 { THIS->lexer_->push_lyric_state ();
1288 $$ = ly_symbol2scm ("lyrics");
1292 mode_changing_head_with_context:
1294 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1295 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1297 $$ = ly_symbol2scm ("DrumStaff");
1300 THIS->lexer_->push_figuredbass_state ();
1302 $$ = ly_symbol2scm ("FiguredBass");
1305 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1306 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1307 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1308 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1309 $$ = ly_symbol2scm ("ChordNames");
1312 { THIS->lexer_->push_lyric_state ();
1313 $$ = ly_symbol2scm ("Lyrics");
1319 RELATIVE absolute_pitch Music {
1321 Pitch start = *unsmob_pitch ($2);
1322 $$ = make_music_relative (start, m);
1323 scm_gc_unprotect_object (m->self_scm ());
1325 | RELATIVE Composite_music {
1328 Pitch middle_c (0, 0, 0);
1329 $$ = make_music_relative (middle_c, m);
1330 scm_gc_unprotect_object (m->self_scm ());
1335 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1337 Grouped_music_list {
1338 /* Can also use Music at the expensive of two S/Rs similar to
1339 \repeat \alternative */
1340 THIS->lexer_->pop_state ();
1342 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1344 | new_lyrics ADDLYRICS {
1345 THIS->lexer_->push_lyric_state ();
1346 } Grouped_music_list {
1347 THIS->lexer_->pop_state ();
1348 $$ = scm_cons ($4->self_scm (), $1);
1353 Grouped_music_list new_lyrics {
1355 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1356 if (!scm_is_string (name))
1358 name = get_next_unique_lyrics_context_id ();
1359 voice = context_spec_music (scm_makfrom0str ("Voice"),
1364 SCM context = scm_makfrom0str ("Lyrics");
1365 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1368 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1370 Music *music = unsmob_music (scm_car (s));
1371 Music *com = make_lyric_combine_music (name, music);
1372 Music *csm = context_spec_music (context,
1373 get_next_unique_context_id (), com, SCM_EOL);
1374 lst = scm_cons (csm->self_scm (), lst);
1376 all->set_property ("elements", scm_cons (voice->self_scm (),
1379 scm_gc_unprotect_object (voice->self_scm ());
1381 | LYRICSTO simple_string {
1382 THIS->lexer_->push_lyric_state ();
1384 THIS->lexer_->pop_state ();
1387 $$ = make_lyric_combine_music (name, music);
1388 scm_gc_unprotect_object (music->self_scm ());
1393 CHANGE STRING '=' STRING {
1394 Music*t = MY_MAKE_MUSIC ("ContextChange");
1395 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1396 t-> set_property ("change-to-id", $4);
1405 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1406 scm_string_to_symbol ($1), $3);
1408 | UNSET simple_string {
1409 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1410 scm_string_to_symbol ($2));
1412 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1413 $$ = scm_list_4 (ly_symbol2scm ("push"),
1414 scm_string_to_symbol ($2), $3, $5);
1416 | REVERT simple_string embedded_scm {
1417 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1418 scm_string_to_symbol ($2), $3);
1423 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1424 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1426 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1427 | DEFAULTCHILD { $$ = ly_symbol2scm ("default-child"); }
1428 | DENIES { $$ = ly_symbol2scm ("denies"); }
1430 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1431 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1432 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1433 | NAME { $$ = ly_symbol2scm ("context-name"); }
1437 property_operation { $$ = $1; }
1438 | context_def_mod STRING {
1439 $$ = scm_list_2 ($1, $2);
1445 if (!is_regular_identifier ($1))
1447 @$.error (_("Grob name should be alphanumeric"));
1450 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1451 scm_string_to_symbol ($1));
1453 | simple_string '.' simple_string {
1454 $$ = scm_list_2 (scm_string_to_symbol ($1),
1455 scm_string_to_symbol ($3));
1460 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1461 $$ = property_op_to_music (scm_list_4 (
1462 ly_symbol2scm ("poppush"),
1465 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1467 | REVERT context_prop_spec embedded_scm {
1468 $$ = property_op_to_music (scm_list_3 (
1469 ly_symbol2scm ("pop"),
1473 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1475 | SET context_prop_spec '=' scalar {
1476 $$ = property_op_to_music (scm_list_3 (
1477 ly_symbol2scm ("assign"),
1480 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1482 | UNSET context_prop_spec {
1483 $$ = property_op_to_music (scm_list_2 (
1484 ly_symbol2scm ("unset"),
1486 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1488 | ONCE music_property_def {
1489 SCM e = $2->get_property ("element");
1490 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1501 | STRING_IDENTIFIER {
1504 | string '+' string {
1505 $$ = scm_string_append (scm_list_2 ($1, $3));
1509 simple_string: STRING {
1524 $$ = scm_int2num ($1);
1533 $$ = scm_int2num ($1);
1539 pre_events doesn't contain anything. It is a trick:
1541 Adding pre_events to the simple_element
1542 makes the choice between
1548 simple_element: STRING
1550 a single shift/reduction conflict.
1552 nevertheless, this is not very clean, and we should find a different
1556 pre_events: /* empty */
1560 pre_events simple_element post_events {
1561 SCM elts = $2-> get_property ("elements");
1563 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1565 $2->set_property ("elements", elts);
1566 /* why is this giving wrong start location? -ns
1567 * $2->set_spot (@$); */
1569 i.set_location (@2, @3);
1574 | note_chord_element
1579 chord_body optional_notemode_duration post_events
1581 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1582 SCM es = $1->get_property ("elements");
1583 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1585 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1586 unsmob_music (scm_car (s))->set_property ("duration", dur);
1587 es = ly_append2 (es, postevs);
1589 $1-> set_property ("elements", es);
1601 simul_open: DOUBLE_ANGLE_OPEN
1604 simul_close: DOUBLE_ANGLE_CLOSE
1608 chord_open chord_body_elements chord_close
1610 $$ = MY_MAKE_MUSIC ("EventChord");
1612 $$->set_property ("elements",
1613 scm_reverse_x ($2, SCM_EOL));
1617 chord_body_elements:
1618 /* empty */ { $$ = SCM_EOL; }
1619 | chord_body_elements chord_body_element {
1620 $$ = scm_cons ($2->self_scm (), $1);
1621 scm_gc_unprotect_object ($2->self_scm ());
1626 pitch exclamations questions octave_check post_events
1633 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1634 n->set_property ("pitch", $1);
1637 n->set_property ("cautionary", SCM_BOOL_T);
1638 if (ex % 2 || q % 2)
1639 n->set_property ("force-accidental", SCM_BOOL_T);
1641 if (scm_is_pair (post)) {
1642 SCM arts = scm_reverse_x (post, SCM_EOL);
1643 n->set_property ("articulations", arts);
1645 if (scm_is_number (check))
1647 int q = scm_to_int (check);
1648 n->set_property ("absolute-octave", scm_int2num (q-1));
1654 | DRUM_PITCH post_events {
1655 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1656 n->set_property ("duration", $2);
1657 n->set_property ("drum-type", $1);
1660 if (scm_is_pair ($2)) {
1661 SCM arts = scm_reverse_x ($2, SCM_EOL);
1662 n->set_property ("articulations", arts);
1669 ADDQUOTE string Music {
1670 SCM adder = ly_lily_module_constant ("add-quotable");
1672 scm_call_2 (adder, $2, $3->self_scm ());
1673 scm_gc_unprotect_object ($3->self_scm ());
1679 $$ = MY_MAKE_MUSIC ("EventChord");
1680 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1681 scm_gc_unprotect_object ($1->self_scm ());
1686 | SKIP duration_length {
1687 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1688 skip->set_property ("duration", $2);
1689 skip->set_spot (@$);
1693 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1696 $$->set_property ("pitch", $2);
1699 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1700 m->set_property ("span-direction", scm_int2num (START));
1703 $$ = MY_MAKE_MUSIC ("EventChord");
1704 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1705 scm_gc_unprotect_object (m->self_scm ());
1709 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1710 m->set_property ("span-direction", scm_int2num (STOP));
1713 $$ = MY_MAKE_MUSIC ("EventChord");
1714 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1716 scm_gc_unprotect_object (m->self_scm ());
1719 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1723 SCM pipe = THIS->lexer_->lookup_identifier ("pipeSymbol");
1725 if (Music * m = unsmob_music (pipe))
1728 $$ = MY_MAKE_MUSIC ("BarCheck");
1732 | TRANSPOSITION pitch {
1734 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1735 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1736 sounds_as_c.smobbed_copy());
1738 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1742 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1744 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1746 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1750 | PARTIAL duration_length {
1751 Moment m = - unsmob_duration ($2)->get_length ();
1752 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1754 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1756 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1761 SCM proc = ly_lily_module_constant ("make-clef-set");
1763 SCM result = scm_call_1 (proc, $2);
1764 scm_gc_protect_object (result);
1765 $$ = unsmob_music (result);
1768 SCM proc = ly_lily_module_constant ("make-time-signature-set");
1770 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1771 scm_gc_protect_object (result);
1772 $$ = unsmob_music (result);
1775 SCM proc = ly_lily_module_constant ("make-mark-set");
1777 SCM result = scm_call_1 (proc, $2);
1778 scm_gc_protect_object (result);
1779 $$ = unsmob_music (result);
1785 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1788 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1795 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1798 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1800 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1801 if (scm_ilength ($3) > 0)
1803 key->set_property ("pitch-alist", $3);
1804 key->set_property ("tonic", Pitch (0, 0, 0).smobbed_copy ());
1805 key->transpose (* unsmob_pitch ($2));
1807 THIS->parser_error (@3, _ ("second argument must be pitch list"));
1819 | post_events post_event {
1821 $$ = scm_cons ($2->self_scm (), $$);
1822 scm_gc_unprotect_object ($2->self_scm ());
1824 | post_events tagged_post_event {
1825 $2 -> set_spot (@2);
1826 $$ = scm_cons ($2->self_scm (), $$);
1827 scm_gc_unprotect_object ($2->self_scm ());
1833 '-' TAG embedded_scm post_event {
1834 tag_music ($4, $3, @$);
1841 direction_less_event {
1845 if (!THIS->lexer_->is_lyric_state ())
1846 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
1847 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1850 if (!THIS->lexer_->is_lyric_state ())
1851 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
1852 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1854 | script_dir direction_reqd_event {
1856 $2->set_property ("direction", scm_int2num ($1));
1859 | script_dir direction_less_event {
1861 $2->set_property ("direction", scm_int2num ($1));
1864 | string_number_event
1867 string_number_event:
1869 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1870 s->set_property ("string-number", scm_int2num ($1));
1876 direction_less_char:
1878 $$ = ly_symbol2scm ("bracketOpenSymbol");
1881 $$ = ly_symbol2scm ("bracketCloseSymbol");
1884 $$ = ly_symbol2scm ("tildeSymbol");
1887 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1890 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1893 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1896 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1899 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1902 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1905 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1909 direction_less_event:
1910 direction_less_char {
1911 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1913 if (unsmob_music (predefd))
1915 m = unsmob_music (predefd)->clone ();
1919 m = MY_MAKE_MUSIC ("Music");
1924 | EVENT_IDENTIFIER {
1925 $$ = unsmob_music ($1);
1928 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1930 a->set_property ("tremolo-type", scm_int2num ($1));
1935 direction_reqd_event:
1939 | script_abbreviation {
1940 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1941 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1942 if (scm_is_string (s))
1943 a->set_property ("articulation-type", s);
1944 else THIS->parser_error (@1, _ ("expecting string as script definition"));
1950 /**/ { $$ = SCM_EOL; }
1951 | '=' { $$ = scm_int2num (0); }
1952 | '=' sub_quotes { $$ = scm_int2num ($2); }
1953 | '=' sup_quotes { $$ = scm_int2num ($2); }
1978 | NOTENAME_PITCH sup_quotes {
1979 Pitch p = *unsmob_pitch ($1);
1980 p = p.transposed (Pitch ($2,0,0));
1981 $$ = p.smobbed_copy ();
1983 | NOTENAME_PITCH sub_quotes {
1984 Pitch p =* unsmob_pitch ($1);
1985 p = p.transposed (Pitch (-$2,0,0));
1986 $$ = p.smobbed_copy ();
1998 | TONICNAME_PITCH sup_quotes {
1999 Pitch p = *unsmob_pitch ($1);
2000 p = p.transposed (Pitch ($2,0,0));
2001 $$ = p.smobbed_copy ();
2003 | TONICNAME_PITCH sub_quotes {
2004 Pitch p =* unsmob_pitch ($1);
2006 p = p.transposed (Pitch (-$2,0,0));
2007 $$ = p.smobbed_copy ();
2017 pitch_also_in_chords:
2024 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
2025 t->set_property ("text", $1);
2030 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
2031 t->set_property ("text",
2032 make_simple_markup ($1));
2038 Music *t = MY_MAKE_MUSIC ("FingerEvent");
2039 t->set_property ("digit", scm_int2num ($1));
2045 script_abbreviation:
2047 $$ = scm_makfrom0str ("Hat");
2050 $$ = scm_makfrom0str ("Plus");
2053 $$ = scm_makfrom0str ("Dash");
2056 $$ = scm_makfrom0str ("Bar");
2059 $$ = scm_makfrom0str ("Larger");
2062 $$ = scm_makfrom0str ("Dot");
2065 $$ = scm_makfrom0str ("Underscore");
2072 | '-' { $$ = CENTER; }
2083 multiplied_duration {
2088 optional_notemode_duration:
2090 Duration dd = THIS->default_duration_;
2091 $$ = dd.smobbed_copy ();
2093 THIS->beam_check ($$);
2095 | multiplied_duration {
2097 THIS->default_duration_ = *unsmob_duration ($$);
2099 THIS->beam_check ($$);
2104 bare_unsigned dots {
2106 if (!is_duration ($1))
2107 THIS->parser_error (@1, _f ("not a duration: %d", $1));
2111 $$ = Duration (len, $2).smobbed_copy ();
2113 | DURATION_IDENTIFIER dots {
2114 Duration *d = unsmob_duration ($1);
2115 Duration k (d->duration_log (), d->dot_count () + $2);
2121 multiplied_duration:
2125 | multiplied_duration '*' bare_unsigned {
2126 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2128 | multiplied_duration '*' FRACTION {
2129 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2131 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2136 FRACTION { $$ = $1; }
2137 | UNSIGNED '/' UNSIGNED {
2138 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2155 | ':' bare_unsigned {
2156 if (!is_duration ($2))
2157 THIS->parser_error (@2, _f ("not a duration: %d", $2));
2164 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2165 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2169 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2170 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2173 | STRING { $$ = $1; }
2174 | full_markup { $$ = $1; }
2185 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2186 $$ = bfr->self_scm ();
2187 scm_gc_unprotect_object ($$);
2190 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2191 $$ = bfr->self_scm ();
2193 bfr->set_property ("figure", $1);
2195 scm_gc_unprotect_object ($$);
2197 | bass_figure bass_mod {
2198 Music *m = unsmob_music ($1);
2200 SCM salter = m->get_property ("alteration");
2201 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2202 m->set_property ("alteration",
2203 scm_int2num (alter + $2));
2205 m->set_property ("alteration", scm_int2num (0));
2213 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2218 | br_bass_figure ']' {
2220 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2228 | figure_list br_bass_figure {
2229 $$ = scm_cons ($2, $1);
2234 FIGURE_OPEN figure_list FIGURE_CLOSE {
2235 Music *m = MY_MAKE_MUSIC ("EventChord");
2236 $2 = scm_reverse_x ($2, SCM_EOL);
2237 m->set_property ("elements", $2);
2238 $$ = m->self_scm ();
2249 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2250 if (!THIS->lexer_->is_note_state ())
2251 THIS->parser_error (@1, _ ("have to be in Note mode for notes"));
2255 n = MY_MAKE_MUSIC ("RestEvent");
2257 n = MY_MAKE_MUSIC ("NoteEvent");
2259 n->set_property ("pitch", $1);
2260 n->set_property ("duration", $5);
2262 if (scm_is_number ($4))
2264 int q = scm_to_int ($4);
2265 n->set_property ("absolute-octave", scm_int2num (q-1));
2269 n->set_property ("cautionary", SCM_BOOL_T);
2270 if ($2 % 2 || $3 % 2)
2271 n->set_property ("force-accidental", SCM_BOOL_T);
2273 Music *v = MY_MAKE_MUSIC ("EventChord");
2274 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2275 scm_gc_unprotect_object (n->self_scm ());
2281 | DRUM_PITCH optional_notemode_duration {
2282 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2283 n->set_property ("duration", $2);
2284 n->set_property ("drum-type", $1);
2286 Music *v = MY_MAKE_MUSIC ("EventChord");
2287 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2288 scm_gc_unprotect_object (n->self_scm ());
2294 | figure_spec optional_notemode_duration {
2295 Music *m = unsmob_music ($1);
2297 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2299 unsmob_music (scm_car (s))->set_property ("duration", $2);
2303 | RESTNAME optional_notemode_duration {
2305 if (ly_scm2string ($1) == "s") {
2307 ev = MY_MAKE_MUSIC ("SkipEvent");
2310 ev = MY_MAKE_MUSIC ("RestEvent");
2313 ev->set_property ("duration", $2);
2315 Music *velt = MY_MAKE_MUSIC ("EventChord");
2316 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2317 velt->set_spot (@$);
2319 scm_gc_unprotect_object (ev->self_scm ());
2323 | MULTI_MEASURE_REST optional_notemode_duration {
2324 SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
2325 SCM mus = scm_call_2 (proc, $2, make_input (@$));
2326 scm_gc_protect_object (mus);
2327 $$ = unsmob_music (mus);
2330 | lyric_element optional_notemode_duration {
2331 if (!THIS->lexer_->is_lyric_state ())
2332 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2334 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2335 lreq->set_property ("text", $1);
2336 lreq->set_property ("duration",$2);
2337 lreq->set_spot (@$);
2338 Music *velt = MY_MAKE_MUSIC ("EventChord");
2339 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2344 if (!THIS->lexer_->is_chord_state ())
2345 THIS->parser_error (@1, _ ("have to be in Chord mode for chords"));
2346 $$ = unsmob_music ($1);
2355 $$ = make_simple_markup ($1);
2360 steno_tonic_pitch optional_notemode_duration {
2361 $$ = make_chord ($1, $2, SCM_EOL);
2363 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2364 SCM its = scm_reverse_x ($4, SCM_EOL);
2365 $$ = make_chord ($1, $2, scm_cons ($3, its));
2373 | chord_items chord_item {
2374 $$ = scm_cons ($2, $$);
2380 $$ = ly_symbol2scm ("chord-colon");
2383 $$ = ly_symbol2scm ("chord-caret");
2385 | CHORD_SLASH steno_tonic_pitch {
2386 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2388 | CHORD_BASS steno_tonic_pitch {
2389 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2398 $$ = scm_reverse_x ($1, SCM_EOL);
2406 step_number { $$ = scm_cons ($1, SCM_EOL); }
2407 | step_numbers '.' step_number {
2408 $$ = scm_cons ($3, $$);
2414 $$ = make_chord_step ($1, 0);
2416 | bare_unsigned '+' {
2417 $$ = make_chord_step ($1, SHARP);
2419 | bare_unsigned CHORD_MINUS {
2420 $$ = make_chord_step ($1, FLAT);
2427 TODO: should deprecate in favor of Scheme?
2431 number_expression '+' number_term {
2432 $$ = scm_sum ($1, $3);
2434 | number_expression '-' number_term {
2435 $$ = scm_difference ($1, $3);
2444 | number_factor '*' number_factor {
2445 $$ = scm_product ($1, $3);
2447 | number_factor '/' number_factor {
2448 $$ = scm_divide ($1, $3);
2453 '-' number_factor { /* %prec UNARY_MINUS */
2454 $$ = scm_difference ($2, SCM_UNDEFINED);
2462 $$ = scm_int2num ($1);
2467 | NUMBER_IDENTIFIER {
2470 | REAL NUMBER_IDENTIFIER {
2471 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2473 | UNSIGNED NUMBER_IDENTIFIER {
2474 $$ = scm_make_real ($1 *scm_to_double ($2));
2490 if (scm_integer_p ($1) == SCM_BOOL_T)
2492 int k = scm_to_int ($1);
2496 THIS->parser_error (@1, _ ("need integer number arg"));
2507 | exclamations '!' { $$ ++; }
2512 | questions '?' { $$ ++; }
2516 This should be done more dynamically if possible.
2520 LYRIC_MARKUP_IDENTIFIER {
2524 { THIS->lexer_->push_markup_state (); }
2527 THIS->lexer_->pop_state ();
2536 { THIS->lexer_->push_markup_state (); }
2539 THIS->lexer_->pop_state ();
2545 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
2547 | markup_head_1_list simple_markup {
2548 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2556 markup_composed_list {
2559 | markup_braced_list {
2564 markup_composed_list:
2565 markup_head_1_list markup_braced_list {
2566 $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
2572 '{' markup_braced_list_body '}' {
2573 $$ = scm_reverse_x ($2, SCM_EOL);
2577 markup_braced_list_body:
2578 /* empty */ { $$ = SCM_EOL; }
2579 | markup_braced_list_body markup {
2580 $$ = scm_cons ($2, $1);
2582 | markup_braced_list_body markup_list {
2583 $$ = scm_append_x (scm_list_2 (scm_reverse_x ($2, SCM_EOL), $1));
2588 MARKUP_HEAD_MARKUP0 {
2589 $$ = scm_list_1 ($1);
2591 | MARKUP_HEAD_SCM0_MARKUP1 embedded_scm {
2592 $$ = scm_list_2 ($1, $2);
2594 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm {
2595 $$ = scm_list_3 ($1, $2, $3);
2600 markup_head_1_item {
2601 $$ = scm_list_1 ($1);
2603 | markup_head_1_list markup_head_1_item {
2604 $$ = scm_cons ($2, $1);
2610 $$ = make_simple_markup ($1);
2612 | MARKUP_IDENTIFIER {
2615 | LYRIC_MARKUP_IDENTIFIER {
2618 | STRING_IDENTIFIER {
2622 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2623 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2624 } '{' score_body '}' {
2626 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());
2627 scm_gc_unprotect_object (sc->self_scm ());
2628 THIS->lexer_->pop_state ();
2630 | MARKUP_HEAD_SCM0 embedded_scm {
2631 $$ = scm_list_2 ($1, $2);
2633 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2634 $$ = scm_list_4 ($1, $2, $3, $4);
2636 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2637 $$ = scm_list_3 ($1, $2, $3);
2639 | MARKUP_HEAD_EMPTY {
2640 $$ = scm_list_1 ($1);
2642 | MARKUP_HEAD_LIST0 markup_list {
2643 $$ = scm_list_2 ($1,$2);
2645 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2646 $$ = scm_list_3 ($1, $2, $3);
2651 markup_head_1_list simple_markup {
2652 SCM mapper = ly_lily_module_constant ("map-markup-command-list");
2653 $$ = scm_car (scm_call_2 (mapper, $1, scm_list_1 ($2)));
2663 Lily_parser::set_yydebug (bool )
2671 Lily_parser::do_yyparse ()
2673 yyparse ((void*)this);
2677 /* FIXME: Should make this optional? It will also complain at
2681 which is entirely legitimate.
2683 Or we can scrap it. Barchecks should detect wrong durations, and
2684 skipTypesetting speeds it up a lot. */
2687 Lily_parser::beam_check (SCM dur)
2689 Duration *d = unsmob_duration (dur);
2690 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2692 Music *m = unsmob_music (last_beam_start_);
2693 m->origin ()->warning (_f ("suspect duration in beam: %s",
2696 last_beam_start_ = SCM_EOL;
2704 It is a little strange to have this function in this file, but
2705 otherwise, we have to import music classes into the lexer.
2709 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2711 if (scm_is_string (sid)) {
2713 return STRING_IDENTIFIER;
2714 } else if (scm_is_number (sid)) {
2716 return NUMBER_IDENTIFIER;
2717 } else if (unsmob_context_def (sid)) {
2718 *destination = unsmob_context_def (sid)->clone_scm ();
2719 return CONTEXT_DEF_IDENTIFIER;
2720 } else if (unsmob_score (sid)) {
2721 Score *score = new Score (*unsmob_score (sid));
2722 *destination = score->self_scm ();
2723 return SCORE_IDENTIFIER;
2724 } else if (Music *mus = unsmob_music (sid)) {
2725 mus = mus->clone ();
2726 *destination = mus->self_scm ();
2727 unsmob_music (*destination)->
2728 set_property ("origin", make_input (last_input_));
2729 return dynamic_cast<Event*> (mus)
2730 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2731 } else if (unsmob_duration (sid)) {
2732 *destination = unsmob_duration (sid)->smobbed_copy ();
2733 return DURATION_IDENTIFIER;
2734 } else if (unsmob_output_def (sid)) {
2735 Output_def *p = unsmob_output_def (sid);
2738 *destination = p->self_scm ();
2739 return OUTPUT_DEF_IDENTIFIER;
2740 } else if (Text_interface::markup_p (sid)) {
2742 if (is_lyric_state ())
2743 return LYRIC_MARKUP_IDENTIFIER;
2744 return MARKUP_IDENTIFIER;
2751 property_op_to_music (SCM op)
2754 SCM tag = scm_car (op);
2755 SCM symbol = scm_cadr (op);
2756 SCM args = scm_cddr (op);
2757 SCM grob_val = SCM_UNDEFINED;
2758 SCM grob_sym = SCM_UNDEFINED;
2759 SCM val = SCM_UNDEFINED;
2761 if (tag == ly_symbol2scm ("assign"))
2763 m = MY_MAKE_MUSIC ("PropertySet");
2764 val = scm_car (args);
2766 else if (tag == ly_symbol2scm ("unset"))
2767 m = MY_MAKE_MUSIC ("PropertyUnset");
2768 else if (tag == ly_symbol2scm ("poppush")
2769 || tag == ly_symbol2scm ("push"))
2771 m = MY_MAKE_MUSIC ("OverrideProperty");
2772 grob_sym = scm_car (args);
2773 grob_val = scm_cadr (args);
2775 else if (tag == ly_symbol2scm ("pop")) {
2776 m = MY_MAKE_MUSIC ("RevertProperty");
2777 grob_sym = scm_car (args);
2780 m->set_property ("symbol", symbol);
2782 if (val != SCM_UNDEFINED)
2783 m->set_property ("value", val);
2784 if (grob_val != SCM_UNDEFINED)
2785 m->set_property ("grob-value", grob_val);
2787 if (grob_sym != SCM_UNDEFINED)
2789 bool itc = do_internal_type_checking_global;
2792 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2794 do_internal_type_checking_global = false;
2795 m->set_property ("grob-property", grob_sym);
2797 do_internal_type_checking_global = itc;
2800 if (tag == ly_symbol2scm ("poppush"))
2801 m->set_property ("pop-first", SCM_BOOL_T);
2808 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2810 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2812 csm->set_property ("element", m->self_scm ());
2813 scm_gc_unprotect_object (m->self_scm ());
2815 csm->set_property ("context-type",
2816 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2817 csm->set_property ("property-operations", ops);
2819 if (scm_is_string (id))
2820 csm->set_property ("context-id", id);
2825 get_next_unique_context_id ()
2827 return scm_makfrom0str ("$uniqueContextId");
2832 get_next_unique_lyrics_context_id ()
2834 static int new_context_count;
2836 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2837 return scm_makfrom0str (s);