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 *l, 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 /* FIXME: The third option is an alias that will be used to display
261 the syntax error. There's a bug (reported with patch) in bison CVS
262 that prints double backslashes
264 bison.ly:1:5: error: syntax error, unexpected \\book", expecting '{'
266 \book %expect \book error here
269 /* Keyword tokens with plain escaped name. */
270 %token ACCEPTS "\\accepts"
271 %token ADDLYRICS "\\addlyrics"
272 %token ADDQUOTE "\\addquote"
273 %token ALIAS "\\alias"
274 %token ALTERNATIVE "\\alternative"
277 %token CHANGE "\\change"
278 %token CHORDMODE "\\chordmode"
279 %token CHORDS "\\chords"
281 %token CONSISTS "\\consists"
282 %token CONTEXT "\\context"
283 %token DEFAULT "\\default"
284 %token DENIES "\\denies"
285 %token DESCRIPTION "\\description"
286 %token DRUMMODE "\\drummode"
287 %token DRUMS "\\drums"
288 %token FIGUREMODE "\\figuremode"
289 %token FIGURES "\\figures"
290 %token GROBDESCRIPTIONS "\\grobdescriptions"
291 %token HEADER "\\header"
292 %token INVALID "\\invalid"
294 %token LAYOUT "\\layout"
295 %token LYRICMODE "\\lyricmode"
296 %token LYRICS "\\lyrics"
297 %token LYRICSTO "\\lyricsto"
299 %token MARKUP "\\markup"
302 %token NOTEMODE "\\notemode"
303 %token OBJECTID "\\objectid"
304 %token OCTAVE "\\octave"
306 %token OVERRIDE "\\override"
307 %token PAPER "\\paper"
308 %token PARTIAL "\\partial"
309 %token RELATIVE "\\relative"
310 %token REMOVE "\\remove"
311 %token REPEAT "\\repeat"
313 %token REVERT "\\revert"
314 %token SCORE "\\score"
315 %token SEQUENTIAL "\\sequential"
317 %token SIMULTANEOUS "\\simultaneous"
320 %token TEMPO "\\tempo"
321 %token TIMES "\\times"
322 %token TRANSPOSE "\\transpose"
323 %token TRANSPOSITION "\\transposition"
325 %token UNSET "\\unset"
328 /* Keyword token exceptions. */
329 %token TIME_T "\\time"
330 %token NEWCONTEXT "\\new"
333 /* Other string tokens. */
335 %token CHORD_BASS "/+"
336 %token CHORD_CARET "^"
337 %token CHORD_COLON ":"
338 %token CHORD_MINUS "-"
339 %token CHORD_SLASH "/"
340 %token DOUBLE_ANGLE_CLOSE ">>"
341 %token DOUBLE_ANGLE_OPEN "<<"
342 %token E_BACKSLASH "\\"
343 %token E_ANGLE_CLOSE "\\>"
344 %token E_CHAR "\\C[haracter]"
346 %token E_EXCLAMATION "\\!"
347 %token E_BRACKET_OPEN "\\["
349 %token E_BRACKET_CLOSE "\\]"
350 %token E_ANGLE_OPEN "\\<"
353 /* These used at all?
354 %token FIGURE_BRACKET_CLOSE
355 %token FIGURE_BRACKET_OPEN
357 parser.yy:348.8-25: warning: symbol `"\\>"' used more than once as a literal string
358 parser.yy:352.8-24: warning: symbol `"\\<"' used more than once as a literal string
361 %token FIGURE_CLOSE /* "\\>" */
362 %token FIGURE_OPEN /* "\\<" */
363 %token FIGURE_SPACE "_"
366 %token CHORDMODIFIERS
367 %token COMMANDSPANREQUEST
369 %token MULTI_MEASURE_REST
374 %token <i> E_UNSIGNED
377 %token <id> IDENTIFIER
379 %token <scm> CHORDMODIFIER_PITCH
380 %token <scm> CHORD_MODIFIER
381 %token <scm> CONTEXT_DEF_IDENTIFIER
382 %token <scm> DRUM_PITCH
383 %token <scm> DURATION_IDENTIFIER
384 %token <scm> EVENT_IDENTIFIER
385 %token <scm> FRACTION
386 %token <scm> LYRICS_STRING
387 %token <scm> LYRIC_MARKUP_IDENTIFIER
388 %token <scm> MARKUP_HEAD_EMPTY
389 %token <scm> MARKUP_HEAD_LIST0
390 %token <scm> MARKUP_HEAD_MARKUP0
391 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
392 %token <scm> MARKUP_HEAD_SCM0
393 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
394 %token <scm> MARKUP_HEAD_SCM0_SCM1
395 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
396 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
397 %token <scm> MARKUP_IDENTIFIER
398 %token <scm> MUSIC_FUNCTION
399 %token <scm> MUSIC_FUNCTION_MARKUP
400 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
401 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
402 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
403 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
404 %token <scm> MUSIC_FUNCTION_MUSIC
405 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
406 %token <scm> MUSIC_FUNCTION_SCM
407 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
408 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
409 %token <scm> MUSIC_FUNCTION_SCM_SCM
410 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
411 %token <scm> MUSIC_IDENTIFIER
412 %token <scm> NOTENAME_PITCH
413 %token <scm> NUMBER_IDENTIFIER
414 %token <scm> OUTPUT_DEF_IDENTIFIER
416 %token <scm> RESTNAME
417 %token <scm> SCM_IDENTIFIER
419 %token <scm> SCORE_IDENTIFIER
421 %token <scm> STRING_IDENTIFIER
422 %token <scm> TONICNAME_PITCH
425 %type <book> book_block
426 %type <book> book_body
429 %type <i> bare_unsigned
432 %type <i> exclamations
433 %type <i> optional_rest
438 %type <i> tremolo_type
440 %type <music> Composite_music
441 %type <music> Generic_prefix_music
442 %type <music> Grouped_music_list
444 %type <music> Prefix_composite_music
445 %type <music> Repeated_music
446 %type <music> Sequential_music
447 %type <music> Simple_music
448 %type <music> Simultaneous_music
449 %type <music> chord_body
450 %type <music> chord_body_element
451 %type <music> command_element
452 %type <music> command_req
453 %type <music> context_change
454 %type <music> direction_less_event
455 %type <music> direction_reqd_event
456 %type <music> event_chord
457 %type <music> gen_text_def
458 %type <music> music_property_def
459 %type <music> note_chord_element
460 %type <music> post_event
461 %type <music> re_rhythmed_music
462 %type <music> relative_music
463 %type <music> simple_element
464 %type <music> string_number_event
465 %type <music> tagged_post_event
466 %type <music> tempo_event
467 %type <music> toplevel_music
469 %type <outputdef> output_def_body
470 %type <outputdef> output_def_head
471 %type <outputdef> output_def
472 %type <outputdef> paper_block
474 %type <scm> Alternative_music
475 %type <scm> Generic_prefix_music_scm
476 %type <scm> Music_list
477 %type <scm> absolute_pitch
478 %type <scm> assignment_id
479 %type <scm> bare_number
480 %type <scm> bass_figure
481 %type <scm> bass_number
482 %type <scm> br_bass_figure
483 %type <scm> chord_body_elements
484 %type <scm> chord_item
485 %type <scm> chord_items
486 %type <scm> chord_separator
487 %type <scm> context_def_mod
488 %type <scm> context_def_spec_block
489 %type <scm> context_def_spec_body
490 %type <scm> context_mod
491 %type <scm> context_mod_list
492 %type <scm> context_prop_spec
493 %type <scm> direction_less_char
494 %type <scm> duration_length
495 %type <scm> embedded_scm
496 %type <scm> figure_list
497 %type <scm> figure_spec
499 %type <scm> full_markup
500 %type <scm> identifier_init
501 %type <scm> lilypond_header
502 %type <scm> lilypond_header_body
503 %type <scm> lyric_element
504 %type <scm> lyric_markup
506 %type <scm> markup_braced_list
507 %type <scm> markup_braced_list_body
508 %type <scm> markup_composed_list
509 %type <scm> markup_head_1_item
510 %type <scm> markup_head_1_list
511 %type <scm> markup_list
512 %type <scm> markup_top
513 %type <scm> mode_changing_head
514 %type <scm> mode_changing_head_with_context
515 %type <scm> multiplied_duration
516 %type <scm> new_chord
517 %type <scm> new_lyrics
518 %type <scm> number_expression
519 %type <scm> number_factor
520 %type <scm> number_term
521 %type <scm> object_id_setting
522 %type <scm> octave_check
523 %type <scm> optional_context_mod
524 %type <scm> optional_notemode_duration
526 %type <scm> pitch_also_in_chords
527 %type <scm> post_events
528 %type <scm> property_operation
530 %type <scm> script_abbreviation
531 %type <scm> simple_markup
532 %type <scm> simple_string
533 %type <scm> steno_duration
534 %type <scm> steno_pitch
535 %type <scm> steno_tonic_pitch
536 %type <scm> step_number
537 %type <scm> step_numbers
540 %type <score> score_block
541 %type <score> score_body
546 /* We don't assign precedence to / and *, because we might need varied
547 prec levels in different prods */
553 lilypond: /* empty */
554 | lilypond toplevel_expression {
556 | lilypond assignment {
559 THIS->error_level_ = 1;
562 THIS->error_level_ = 1;
568 OBJECTID STRING { $$ = $2; }
573 THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1);
580 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
581 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
582 scm_gc_unprotect_object (book->self_scm ());
587 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
588 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
589 scm_gc_unprotect_object (score->self_scm ());
593 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
594 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
595 scm_gc_unprotect_object (music->self_scm ());
598 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-text-handler");
599 scm_call_2 (proc, THIS->self_scm (), $1);
603 Output_def * od = $1;
605 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
606 id = ly_symbol2scm ("$defaultpaper");
607 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
608 id = ly_symbol2scm ("$defaultmidi");
609 else if ($1->c_variable ("is-layout") == SCM_BOOL_T)
610 id = ly_symbol2scm ("$defaultlayout");
612 THIS->lexer_->set_identifier (id, od->self_scm ());
613 scm_gc_unprotect_object (od->self_scm ());
628 lilypond_header_body:
630 $$ = ly_make_anonymous_module (be_safe_global);
631 THIS->lexer_->add_scope ($$);
633 | lilypond_header_body assignment {
639 HEADER '{' lilypond_header_body '}' {
640 $$ = THIS->lexer_->remove_scope ();
649 | LYRICS_STRING { $$ = $1; }
653 assignment_id '=' identifier_init {
654 if (! is_regular_identifier ($1))
656 @1.warning (_ ("identifier should have alphabetic characters only"));
659 THIS->lexer_->set_identifier ($1, $3);
662 TODO: devise standard for protection in parser.
664 The parser stack lives on the C-stack, which means that
665 all objects can be unprotected as soon as they're here.
675 $$ = $1->self_scm ();
676 scm_gc_unprotect_object ($$);
679 $$ = $1->self_scm ();
680 scm_gc_unprotect_object ($$);
682 | context_def_spec_block {
686 $$ = $1->self_scm ();
687 scm_gc_unprotect_object ($$);
690 $$ = $1->self_scm ();
691 scm_gc_unprotect_object ($$);
693 | number_expression {
706 $$ = scm_int2num ($1);
710 context_def_spec_block:
711 CONTEXT '{' context_def_spec_body '}'
717 context_def_spec_body:
719 $$ = Context_def::make_scm ();
720 unsmob_context_def ($$)->set_spot (@$);
722 | CONTEXT_DEF_IDENTIFIER {
724 unsmob_context_def ($$)->set_spot (@$);
726 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
727 Context_def*td = unsmob_context_def ($$);
729 for (SCM p = $3; scm_is_pair (p); p = scm_cdr (p)) {
730 SCM tag = scm_caar (p);
732 /* TODO: should make new tag "grob-definition" ? */
733 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
734 tag, scm_cons (scm_cdar (p), SCM_EOL)));
737 | context_def_spec_body context_mod {
738 unsmob_context_def ($$)->add_context_mod ($2);
745 BOOK '{' book_body '}' {
751 * Use 'handlers' like for toplevel-* stuff?
752 * grok \layout and \midi? */
757 $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
758 scm_gc_unprotect_object ($$->paper_->self_scm ());
759 $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader");
761 | book_body paper_block {
763 scm_gc_unprotect_object ($2->self_scm ());
765 | book_body score_block {
766 SCM s = $2->self_scm ();
768 scm_gc_unprotect_object (s);
770 | book_body full_markup {
773 | book_body lilypond_header {
778 $$->scores_ = SCM_EOL;
780 | book_body object_id_setting {
781 $$->user_key_ = ly_scm2string ($2);
786 SCORE '{' score_body '}' {
797 $$ = new Score ( *unsmob_score ($1));
800 | score_body object_id_setting {
801 $$->user_key_ = ly_scm2string ($2);
804 SCM m = $2->self_scm ();
805 scm_gc_unprotect_object (m);
806 $$->set_music (m, THIS->self_scm ());
808 | score_body lilypond_header {
811 | score_body output_def {
812 if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
814 THIS->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
821 scm_gc_unprotect_object ($2->self_scm ());
824 $$->error_found_ = true;
836 if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
838 THIS->parser_error (@1, _ ("need \\paper for paper block"));
839 $$ = get_paper (THIS);
846 output_def_body '}' {
849 THIS->lexer_->remove_scope ();
850 THIS->lexer_->pop_state ();
856 $$ = get_paper (THIS);
857 $$->input_origin_ = @$;
858 THIS->lexer_->add_scope ($$->scope_);
861 Output_def *p = get_midi (THIS);
863 THIS->lexer_->add_scope (p->scope_);
866 Output_def *p = get_layout (THIS);
868 THIS->lexer_->add_scope (p->scope_);
875 output_def_head '{' {
877 $$->input_origin_.set_spot (@$);
878 THIS->lexer_->push_initial_state ();
880 | output_def_head '{' OUTPUT_DEF_IDENTIFIER {
881 scm_gc_unprotect_object ($1->self_scm ());
882 Output_def *o = unsmob_output_def ($3);
883 o->input_origin_.set_spot (@$);
885 THIS->lexer_->remove_scope ();
886 THIS->lexer_->add_scope (o->scope_);
887 THIS->lexer_->push_initial_state ();
889 | output_def_body assignment {
892 | output_def_body context_def_spec_block {
893 assign_context_def ($$, $2);
895 | output_def_body tempo_event {
897 junk this ? there already is tempo stuff in
900 int m = scm_to_int ($2->get_property ("metronome-count"));
901 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
902 set_tempo ($$, d->get_length (), m);
903 scm_gc_unprotect_object ($2->self_scm ());
905 | output_def_body error {
911 TEMPO steno_duration '=' bare_unsigned {
912 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
913 $$->set_property ("tempo-unit", $2);
914 $$->set_property ("metronome-count", scm_int2num ( $4));
919 The representation of a list is the
923 to have efficient append. */
927 $$ = scm_cons (SCM_EOL, SCM_EOL);
931 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
932 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
934 if (scm_is_pair (scm_cdr (s)))
935 scm_set_cdr_x (scm_cdr (s), c); /* append */
937 scm_set_car_x (s, c); /* set first cons */
938 scm_set_cdr_x (s, c); /* remember last cell */
940 | Music_list embedded_scm {
944 Music * m = MY_MAKE_MUSIC("Music");
946 m->set_property ("error-found", SCM_BOOL_T);
948 SCM c = scm_cons (m->self_scm (), SCM_EOL);
949 scm_gc_unprotect_object (m->self_scm ()); /* UGH */
951 if (scm_is_pair (scm_cdr (s)))
952 scm_set_cdr_x (scm_cdr (s), c); /* append */
954 scm_set_car_x (s, c); /* set first cons */
955 scm_set_cdr_x (s, c); /* remember last cell */
968 | ALTERNATIVE '{' Music_list '}' {
975 REPEAT simple_string bare_unsigned Music Alternative_music
979 SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
980 if (times < scm_ilength (alts)) {
981 unsmob_music (scm_car (alts))
982 ->origin ()->warning (
983 _ ("more alternatives than repeats"));
984 warning ("junking excess alternatives");
985 alts = ly_truncate_list (times, alts);
989 SCM proc = ly_lily_module_constant ("make-repeated-music");
991 SCM mus = scm_call_1 (proc, $2);
992 scm_gc_protect_object (mus); // UGH.
993 Music *r = unsmob_music (mus);
996 r-> set_property ("element", beg->self_scm ());
997 scm_gc_unprotect_object (beg->self_scm ());
999 r->set_property ("repeat-count", scm_int2num (times >? 1));
1001 r-> set_property ("elements",alts);
1002 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
1004 TODO: move this code to Scheme.
1007 /* we cannot get durations and other stuff
1008 correct down the line,
1009 so we have to add to the duration log here. */
1010 SCM func = ly_lily_module_constant ("shift-duration-log");
1012 int dots = ($3 % 3) ? 0 : 1;
1013 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
1016 if ($4->is_mus_type ("sequential-music"))
1018 int list_len = scm_ilength ($4->get_property ("elements"));
1020 $4->origin ()->warning (_f ("expect 2 elements for Chord tremolo, found %d", list_len));
1022 r->compress (Moment (Rational (1, list_len)));
1024 scm_call_3 (func, r->self_scm (), scm_int2num (shift), scm_int2num (dots));
1027 r->set_spot (*$4->origin ());
1034 SEQUENTIAL '{' Music_list '}' {
1035 $$ = MY_MAKE_MUSIC ("SequentialMusic");
1036 $$->set_property ("elements", scm_car ($3));
1039 | '{' Music_list '}' {
1040 $$ = MY_MAKE_MUSIC ("SequentialMusic");
1041 $$->set_property ("elements", scm_car ($2));
1047 SIMULTANEOUS '{' Music_list '}'{
1048 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
1049 $$->set_property ("elements", scm_car ($3));
1053 | simul_open Music_list simul_close {
1054 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
1055 $$->set_property ("elements", scm_car ($2));
1061 event_chord { $$ = $1; }
1062 | MUSIC_IDENTIFIER {
1063 $$ = unsmob_music ($1);
1065 | music_property_def
1070 optional_context_mod:
1071 /**/ { $$ = SCM_EOL; }
1072 | WITH { THIS->lexer_->push_initial_state (); }
1073 '{' context_mod_list '}'
1075 THIS->lexer_->pop_state ();
1081 /* */ { $$ = SCM_EOL; }
1082 | context_mod_list context_mod {
1083 $$ = scm_cons ($2, $1);
1089 Prefix_composite_music { $$ = $1; }
1090 | Grouped_music_list { $$ = $1; }
1094 Simultaneous_music { $$ = $1; }
1095 | Sequential_music { $$ = $1; }
1098 Generic_prefix_music_scm:
1100 $$ = scm_list_2 ($1, make_input (@$));
1102 | MUSIC_FUNCTION_SCM embedded_scm {
1103 $$ = scm_list_3 ($1, make_input (@$), $2);
1105 | MUSIC_FUNCTION_MARKUP full_markup {
1106 $$ = scm_list_3 ($1, make_input (@$), $2);
1108 | MUSIC_FUNCTION_MUSIC Music {
1109 $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
1110 scm_gc_unprotect_object ($2->self_scm ());
1112 | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
1113 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1114 scm_gc_unprotect_object ($3->self_scm ());
1116 | MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
1117 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1119 | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
1120 $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
1122 | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
1123 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1124 scm_gc_unprotect_object ($3->self_scm ());
1126 | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
1127 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1129 | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
1130 $$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
1131 scm_gc_unprotect_object ($2->self_scm ());
1132 scm_gc_unprotect_object ($3->self_scm ());
1134 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
1135 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1136 scm_gc_unprotect_object ($4->self_scm ());
1137 scm_gc_unprotect_object ($3->self_scm ());
1139 | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
1140 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1141 scm_gc_unprotect_object ($3->self_scm ());
1142 scm_gc_unprotect_object ($4->self_scm ());
1146 Generic_prefix_music:
1147 Generic_prefix_music_scm {
1148 SCM func = scm_car ($1);
1149 Input *loc = unsmob_input (scm_cadr ($1));
1150 SCM args = scm_cddr ($1);
1151 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1153 SCM type_check_proc = ly_lily_module_constant ("type-check-list");
1156 if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr ($1), sig, args)))
1158 THIS->error_level_ = 1;
1164 m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
1167 if (unsmob_music (m))
1169 $$ = unsmob_music (m);
1170 scm_gc_protect_object (m);
1175 loc->error (_ ("music head function must return Music object"));
1176 $$ = MY_MAKE_MUSIC ("Music");
1178 $$->set_spot (*loc);
1183 Prefix_composite_music:
1184 Generic_prefix_music {
1187 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1188 $$ = context_spec_music ($2, $4, $6, $5);
1191 | CONTEXT simple_string optional_context_mod Music {
1192 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1194 | NEWCONTEXT simple_string optional_context_mod Music {
1195 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1199 | TIMES fraction Music
1202 int n = scm_to_int (scm_car ($2)); int d = scm_to_int (scm_cdr ($2));
1205 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1208 $$->set_property ("element", mp->self_scm ());
1209 scm_gc_unprotect_object (mp->self_scm ());
1210 $$->set_property ("numerator", scm_int2num (n));
1211 $$->set_property ("denominator", scm_int2num (d));
1212 $$->compress (Moment (Rational (n,d)));
1215 | Repeated_music { $$ = $1; }
1216 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1217 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1219 Pitch from = *unsmob_pitch ($2);
1220 Pitch to = *unsmob_pitch ($3);
1222 p->transpose (pitch_interval (from, to));
1223 $$->set_property ("element", p->self_scm ());
1224 scm_gc_unprotect_object (p->self_scm ());
1226 | mode_changing_head Grouped_music_list {
1227 if ($1 == ly_symbol2scm ("chords"))
1229 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1230 chm->set_property ("element", $2->self_scm ());
1232 scm_gc_unprotect_object ($2->self_scm ());
1238 THIS->lexer_->pop_state ();
1240 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1241 $$ = context_spec_music ($1, get_next_unique_context_id (),
1243 if ($1 == ly_symbol2scm ("ChordNames"))
1245 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1246 chm->set_property ("element", $$->self_scm ());
1247 scm_gc_unprotect_object ($$->self_scm ());
1250 THIS->lexer_->pop_state ();
1252 | relative_music { $$ = $1; }
1253 | re_rhythmed_music { $$ = $1; }
1254 | TAG embedded_scm Music {
1255 tag_music ($3, $2, @$);
1262 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1263 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1265 $$ = ly_symbol2scm ("notes");
1269 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1270 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1272 $$ = ly_symbol2scm ("drums");
1275 THIS->lexer_->push_figuredbass_state ();
1277 $$ = ly_symbol2scm ("figures");
1280 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1281 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1282 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1283 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1284 $$ = ly_symbol2scm ("chords");
1288 { THIS->lexer_->push_lyric_state ();
1289 $$ = ly_symbol2scm ("lyrics");
1293 mode_changing_head_with_context:
1295 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1296 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1298 $$ = ly_symbol2scm ("DrumStaff");
1301 THIS->lexer_->push_figuredbass_state ();
1303 $$ = ly_symbol2scm ("FiguredBass");
1306 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1307 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1308 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1309 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1310 $$ = ly_symbol2scm ("ChordNames");
1313 { THIS->lexer_->push_lyric_state ();
1314 $$ = ly_symbol2scm ("Lyrics");
1320 RELATIVE absolute_pitch Music {
1322 Pitch start = *unsmob_pitch ($2);
1323 $$ = make_music_relative (start, m);
1324 scm_gc_unprotect_object (m->self_scm ());
1326 | RELATIVE Composite_music {
1329 Pitch middle_c (0, 0, 0);
1330 $$ = make_music_relative (middle_c, m);
1331 scm_gc_unprotect_object (m->self_scm ());
1336 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1338 Grouped_music_list {
1339 /* Can also use Music at the expensive of two S/Rs similar to
1340 \repeat \alternative */
1341 THIS->lexer_->pop_state ();
1343 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1345 | new_lyrics ADDLYRICS {
1346 THIS->lexer_->push_lyric_state ();
1347 } Grouped_music_list {
1348 THIS->lexer_->pop_state ();
1349 $$ = scm_cons ($4->self_scm (), $1);
1354 Grouped_music_list new_lyrics {
1356 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1357 if (!scm_is_string (name))
1359 name = get_next_unique_lyrics_context_id ();
1360 voice = context_spec_music (scm_makfrom0str ("Voice"),
1365 SCM context = scm_makfrom0str ("Lyrics");
1366 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1369 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1371 Music *music = unsmob_music (scm_car (s));
1372 Music *com = make_lyric_combine_music (name, music);
1373 Music *csm = context_spec_music (context,
1374 get_next_unique_context_id (), com, SCM_EOL);
1375 lst = scm_cons (csm->self_scm (), lst);
1377 all->set_property ("elements", scm_cons (voice->self_scm (),
1380 scm_gc_unprotect_object (voice->self_scm ());
1382 | LYRICSTO simple_string {
1383 THIS->lexer_->push_lyric_state ();
1385 THIS->lexer_->pop_state ();
1388 $$ = make_lyric_combine_music (name, music);
1389 scm_gc_unprotect_object (music->self_scm ());
1394 CHANGE STRING '=' STRING {
1395 Music*t = MY_MAKE_MUSIC ("ContextChange");
1396 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1397 t-> set_property ("change-to-id", $4);
1406 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1407 scm_string_to_symbol ($1), $3);
1409 | UNSET simple_string {
1410 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1411 scm_string_to_symbol ($2));
1413 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1414 $$ = scm_list_4 (ly_symbol2scm ("push"),
1415 scm_string_to_symbol ($2), $3, $5);
1417 | REVERT simple_string embedded_scm {
1418 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1419 scm_string_to_symbol ($2), $3);
1424 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1425 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1427 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
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_list (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_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2662 Lily_parser::set_yydebug (bool )
2670 Lily_parser::do_yyparse ()
2672 yyparse ((void*)this);
2677 Should make this optional? It will also complain when you do
2681 which is entirely legitimate.
2683 Or we can scrap it. Barchecks should detect wrong durations, and
2684 skipTypesetting speeds it up a lot.
2688 Lily_parser::beam_check (SCM dur)
2690 Duration *d = unsmob_duration (dur);
2691 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2693 Music *m = unsmob_music (last_beam_start_);
2694 m->origin ()->warning (_f ("suspect duration in beam: %s",
2697 last_beam_start_ = SCM_EOL;
2705 It is a little strange to have this function in this file, but
2706 otherwise, we have to import music classes into the lexer.
2710 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2712 if (scm_is_string (sid)) {
2714 return STRING_IDENTIFIER;
2715 } else if (scm_is_number (sid)) {
2717 return NUMBER_IDENTIFIER;
2718 } else if (unsmob_context_def (sid)) {
2719 *destination = unsmob_context_def (sid)->clone_scm ();
2720 return CONTEXT_DEF_IDENTIFIER;
2721 } else if (unsmob_score (sid)) {
2722 Score *score = new Score (*unsmob_score (sid));
2723 *destination = score->self_scm ();
2724 return SCORE_IDENTIFIER;
2725 } else if (Music *mus = unsmob_music (sid)) {
2726 mus = mus->clone ();
2727 *destination = mus->self_scm ();
2728 unsmob_music (*destination)->
2729 set_property ("origin", make_input (last_input_));
2730 return dynamic_cast<Event*> (mus)
2731 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2732 } else if (unsmob_duration (sid)) {
2733 *destination = unsmob_duration (sid)->smobbed_copy ();
2734 return DURATION_IDENTIFIER;
2735 } else if (unsmob_output_def (sid)) {
2736 Output_def *p = unsmob_output_def (sid);
2739 *destination = p->self_scm ();
2740 return OUTPUT_DEF_IDENTIFIER;
2741 } else if (Text_interface::markup_p (sid)) {
2743 if (is_lyric_state ())
2744 return LYRIC_MARKUP_IDENTIFIER;
2745 return MARKUP_IDENTIFIER;
2752 property_op_to_music (SCM op)
2755 SCM tag = scm_car (op);
2756 SCM symbol = scm_cadr (op);
2757 SCM args = scm_cddr (op);
2758 SCM grob_val = SCM_UNDEFINED;
2759 SCM grob_sym = SCM_UNDEFINED;
2760 SCM val = SCM_UNDEFINED;
2762 if (tag == ly_symbol2scm ("assign"))
2764 m = MY_MAKE_MUSIC ("PropertySet");
2765 val = scm_car (args);
2767 else if (tag == ly_symbol2scm ("unset"))
2768 m = MY_MAKE_MUSIC ("PropertyUnset");
2769 else if (tag == ly_symbol2scm ("poppush")
2770 || tag == ly_symbol2scm ("push"))
2772 m = MY_MAKE_MUSIC ("OverrideProperty");
2773 grob_sym = scm_car (args);
2774 grob_val = scm_cadr (args);
2776 else if (tag == ly_symbol2scm ("pop")) {
2777 m = MY_MAKE_MUSIC ("RevertProperty");
2778 grob_sym = scm_car (args);
2781 m->set_property ("symbol", symbol);
2783 if (val != SCM_UNDEFINED)
2784 m->set_property ("value", val);
2785 if (grob_val != SCM_UNDEFINED)
2786 m->set_property ("grob-value", grob_val);
2788 if (grob_sym != SCM_UNDEFINED)
2790 bool itc = do_internal_type_checking_global;
2793 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2795 do_internal_type_checking_global = false;
2796 m->set_property ("grob-property", grob_sym);
2798 do_internal_type_checking_global = itc;
2801 if (tag == ly_symbol2scm ("poppush"))
2802 m->set_property ("pop-first", SCM_BOOL_T);
2809 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2811 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2813 csm->set_property ("element", m->self_scm ());
2814 scm_gc_unprotect_object (m->self_scm ());
2816 csm->set_property ("context-type",
2817 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2818 csm->set_property ("property-operations", ops);
2820 if (scm_is_string (id))
2821 csm->set_property ("context-id", id);
2826 get_next_unique_context_id ()
2828 return scm_makfrom0str ("$uniqueContextId");
2833 get_next_unique_lyrics_context_id ()
2835 static int new_context_count;
2837 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2838 return scm_makfrom0str (s);