1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for LilyPond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
16 * The rules for who is protecting what are very shady. Uniformise
19 * There are too many lexical modes?
29 #include "context-def.hh"
30 #include "dimensions.hh"
32 #include "file-path.hh"
33 #include "input-smob.hh"
35 #include "lily-guile.hh"
36 #include "lilypond-input-version.hh"
39 #include "lily-lexer.hh"
40 #include "lily-parser.hh"
41 #include "paper-book.hh"
42 #include "output-def.hh"
43 #include "scm-hash.hh"
44 #include "scm-option.hh"
46 #include "text-item.hh"
49 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
51 Music *property_op_to_music (SCM op);
52 Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
53 SCM get_next_unique_context_id ();
54 SCM get_next_unique_lyrics_context_id ();
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
268 /* Keyword tokens with plain escaped name. */
269 %token ACCEPTS "\\accepts"
270 %token ADDLYRICS "\\addlyrics"
271 %token ADDQUOTE "\\addquote"
272 %token ALIAS "\\alias"
273 %token ALTERNATIVE "\\alternative"
276 %token CHANGE "\\change"
277 %token CHORDMODE "\\chordmode"
278 %token CHORDS "\\chords"
280 %token CONSISTS "\\consists"
281 %token CONTEXT "\\context"
282 %token DEFAULT "\\default"
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 | DENIES { $$ = ly_symbol2scm ("denies"); }
1429 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1430 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1431 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1432 | NAME { $$ = ly_symbol2scm ("context-name"); }
1436 property_operation { $$ = $1; }
1437 | context_def_mod STRING {
1438 $$ = scm_list_2 ($1, $2);
1444 if (!is_regular_identifier ($1))
1446 @$.error (_("Grob name should be alphanumeric"));
1449 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1450 scm_string_to_symbol ($1));
1452 | simple_string '.' simple_string {
1453 $$ = scm_list_2 (scm_string_to_symbol ($1),
1454 scm_string_to_symbol ($3));
1459 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1460 $$ = property_op_to_music (scm_list_4 (
1461 ly_symbol2scm ("poppush"),
1464 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1466 | REVERT context_prop_spec embedded_scm {
1467 $$ = property_op_to_music (scm_list_3 (
1468 ly_symbol2scm ("pop"),
1472 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1474 | SET context_prop_spec '=' scalar {
1475 $$ = property_op_to_music (scm_list_3 (
1476 ly_symbol2scm ("assign"),
1479 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1481 | UNSET context_prop_spec {
1482 $$ = property_op_to_music (scm_list_2 (
1483 ly_symbol2scm ("unset"),
1485 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1487 | ONCE music_property_def {
1488 SCM e = $2->get_property ("element");
1489 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1500 | STRING_IDENTIFIER {
1503 | string '+' string {
1504 $$ = scm_string_append (scm_list_2 ($1, $3));
1508 simple_string: STRING {
1523 $$ = scm_int2num ($1);
1532 $$ = scm_int2num ($1);
1538 pre_events doesn't contain anything. It is a trick:
1540 Adding pre_events to the simple_element
1541 makes the choice between
1547 simple_element: STRING
1549 a single shift/reduction conflict.
1551 nevertheless, this is not very clean, and we should find a different
1555 pre_events: /* empty */
1559 pre_events simple_element post_events {
1560 SCM elts = $2-> get_property ("elements");
1562 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1564 $2->set_property ("elements", elts);
1565 /* why is this giving wrong start location? -ns
1566 * $2->set_spot (@$); */
1568 i.set_location (@2, @3);
1573 | note_chord_element
1578 chord_body optional_notemode_duration post_events
1580 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1581 SCM es = $1->get_property ("elements");
1582 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1584 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1585 unsmob_music (scm_car (s))->set_property ("duration", dur);
1586 es = ly_append2 (es, postevs);
1588 $1-> set_property ("elements", es);
1600 simul_open: DOUBLE_ANGLE_OPEN
1603 simul_close: DOUBLE_ANGLE_CLOSE
1607 chord_open chord_body_elements chord_close
1609 $$ = MY_MAKE_MUSIC ("EventChord");
1611 $$->set_property ("elements",
1612 scm_reverse_x ($2, SCM_EOL));
1616 chord_body_elements:
1617 /* empty */ { $$ = SCM_EOL; }
1618 | chord_body_elements chord_body_element {
1619 $$ = scm_cons ($2->self_scm (), $1);
1620 scm_gc_unprotect_object ($2->self_scm ());
1625 pitch exclamations questions octave_check post_events
1632 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1633 n->set_property ("pitch", $1);
1636 n->set_property ("cautionary", SCM_BOOL_T);
1637 if (ex % 2 || q % 2)
1638 n->set_property ("force-accidental", SCM_BOOL_T);
1640 if (scm_is_pair (post)) {
1641 SCM arts = scm_reverse_x (post, SCM_EOL);
1642 n->set_property ("articulations", arts);
1644 if (scm_is_number (check))
1646 int q = scm_to_int (check);
1647 n->set_property ("absolute-octave", scm_int2num (q-1));
1653 | DRUM_PITCH post_events {
1654 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1655 n->set_property ("duration", $2);
1656 n->set_property ("drum-type", $1);
1659 if (scm_is_pair ($2)) {
1660 SCM arts = scm_reverse_x ($2, SCM_EOL);
1661 n->set_property ("articulations", arts);
1668 ADDQUOTE string Music {
1669 SCM adder = ly_lily_module_constant ("add-quotable");
1671 scm_call_2 (adder, $2, $3->self_scm ());
1672 scm_gc_unprotect_object ($3->self_scm ());
1678 $$ = MY_MAKE_MUSIC ("EventChord");
1679 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1680 scm_gc_unprotect_object ($1->self_scm ());
1685 | SKIP duration_length {
1686 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1687 skip->set_property ("duration", $2);
1688 skip->set_spot (@$);
1692 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1695 $$->set_property ("pitch", $2);
1698 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1699 m->set_property ("span-direction", scm_int2num (START));
1702 $$ = MY_MAKE_MUSIC ("EventChord");
1703 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1704 scm_gc_unprotect_object (m->self_scm ());
1708 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1709 m->set_property ("span-direction", scm_int2num (STOP));
1712 $$ = MY_MAKE_MUSIC ("EventChord");
1713 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1715 scm_gc_unprotect_object (m->self_scm ());
1718 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1722 SCM pipe = THIS->lexer_->lookup_identifier ("pipeSymbol");
1724 if (Music * m = unsmob_music (pipe))
1727 $$ = MY_MAKE_MUSIC ("BarCheck");
1731 | TRANSPOSITION pitch {
1733 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1734 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1735 sounds_as_c.smobbed_copy());
1737 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1741 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1743 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1745 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1749 | PARTIAL duration_length {
1750 Moment m = - unsmob_duration ($2)->get_length ();
1751 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1753 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1755 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1760 SCM proc = ly_lily_module_constant ("make-clef-set");
1762 SCM result = scm_call_1 (proc, $2);
1763 scm_gc_protect_object (result);
1764 $$ = unsmob_music (result);
1767 SCM proc = ly_lily_module_constant ("make-time-signature-set");
1769 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1770 scm_gc_protect_object (result);
1771 $$ = unsmob_music (result);
1774 SCM proc = ly_lily_module_constant ("make-mark-set");
1776 SCM result = scm_call_1 (proc, $2);
1777 scm_gc_protect_object (result);
1778 $$ = unsmob_music (result);
1784 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1787 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1794 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1797 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1799 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1800 if (scm_ilength ($3) > 0)
1802 key->set_property ("pitch-alist", $3);
1803 key->set_property ("tonic", Pitch (0, 0, 0).smobbed_copy ());
1804 key->transpose (* unsmob_pitch ($2));
1806 THIS->parser_error (@3, _ ("second argument must be pitch list"));
1818 | post_events post_event {
1820 $$ = scm_cons ($2->self_scm (), $$);
1821 scm_gc_unprotect_object ($2->self_scm ());
1823 | post_events tagged_post_event {
1824 $2 -> set_spot (@2);
1825 $$ = scm_cons ($2->self_scm (), $$);
1826 scm_gc_unprotect_object ($2->self_scm ());
1832 '-' TAG embedded_scm post_event {
1833 tag_music ($4, $3, @$);
1840 direction_less_event {
1844 if (!THIS->lexer_->is_lyric_state ())
1845 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
1846 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1849 if (!THIS->lexer_->is_lyric_state ())
1850 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
1851 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1853 | script_dir direction_reqd_event {
1855 $2->set_property ("direction", scm_int2num ($1));
1858 | script_dir direction_less_event {
1860 $2->set_property ("direction", scm_int2num ($1));
1863 | string_number_event
1866 string_number_event:
1868 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1869 s->set_property ("string-number", scm_int2num ($1));
1875 direction_less_char:
1877 $$ = ly_symbol2scm ("bracketOpenSymbol");
1880 $$ = ly_symbol2scm ("bracketCloseSymbol");
1883 $$ = ly_symbol2scm ("tildeSymbol");
1886 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1889 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1892 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1895 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1898 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1901 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1904 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1908 direction_less_event:
1909 direction_less_char {
1910 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1912 if (unsmob_music (predefd))
1914 m = unsmob_music (predefd)->clone ();
1918 m = MY_MAKE_MUSIC ("Music");
1923 | EVENT_IDENTIFIER {
1924 $$ = unsmob_music ($1);
1927 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1929 a->set_property ("tremolo-type", scm_int2num ($1));
1934 direction_reqd_event:
1938 | script_abbreviation {
1939 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1940 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1941 if (scm_is_string (s))
1942 a->set_property ("articulation-type", s);
1943 else THIS->parser_error (@1, _ ("expecting string as script definition"));
1949 /**/ { $$ = SCM_EOL; }
1950 | '=' { $$ = scm_int2num (0); }
1951 | '=' sub_quotes { $$ = scm_int2num ($2); }
1952 | '=' sup_quotes { $$ = scm_int2num ($2); }
1977 | NOTENAME_PITCH sup_quotes {
1978 Pitch p = *unsmob_pitch ($1);
1979 p = p.transposed (Pitch ($2,0,0));
1980 $$ = p.smobbed_copy ();
1982 | NOTENAME_PITCH sub_quotes {
1983 Pitch p =* unsmob_pitch ($1);
1984 p = p.transposed (Pitch (-$2,0,0));
1985 $$ = p.smobbed_copy ();
1997 | TONICNAME_PITCH sup_quotes {
1998 Pitch p = *unsmob_pitch ($1);
1999 p = p.transposed (Pitch ($2,0,0));
2000 $$ = p.smobbed_copy ();
2002 | TONICNAME_PITCH sub_quotes {
2003 Pitch p =* unsmob_pitch ($1);
2005 p = p.transposed (Pitch (-$2,0,0));
2006 $$ = p.smobbed_copy ();
2016 pitch_also_in_chords:
2023 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
2024 t->set_property ("text", $1);
2029 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
2030 t->set_property ("text",
2031 make_simple_markup ($1));
2037 Music *t = MY_MAKE_MUSIC ("FingerEvent");
2038 t->set_property ("digit", scm_int2num ($1));
2044 script_abbreviation:
2046 $$ = scm_makfrom0str ("Hat");
2049 $$ = scm_makfrom0str ("Plus");
2052 $$ = scm_makfrom0str ("Dash");
2055 $$ = scm_makfrom0str ("Bar");
2058 $$ = scm_makfrom0str ("Larger");
2061 $$ = scm_makfrom0str ("Dot");
2064 $$ = scm_makfrom0str ("Underscore");
2071 | '-' { $$ = CENTER; }
2082 multiplied_duration {
2087 optional_notemode_duration:
2089 Duration dd = THIS->default_duration_;
2090 $$ = dd.smobbed_copy ();
2092 THIS->beam_check ($$);
2094 | multiplied_duration {
2096 THIS->default_duration_ = *unsmob_duration ($$);
2098 THIS->beam_check ($$);
2103 bare_unsigned dots {
2105 if (!is_duration ($1))
2106 THIS->parser_error (@1, _f ("not a duration: %d", $1));
2110 $$ = Duration (len, $2).smobbed_copy ();
2112 | DURATION_IDENTIFIER dots {
2113 Duration *d = unsmob_duration ($1);
2114 Duration k (d->duration_log (), d->dot_count () + $2);
2120 multiplied_duration:
2124 | multiplied_duration '*' bare_unsigned {
2125 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2127 | multiplied_duration '*' FRACTION {
2128 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2130 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2135 FRACTION { $$ = $1; }
2136 | UNSIGNED '/' UNSIGNED {
2137 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2154 | ':' bare_unsigned {
2155 if (!is_duration ($2))
2156 THIS->parser_error (@2, _f ("not a duration: %d", $2));
2163 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2164 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2168 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2169 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2172 | STRING { $$ = $1; }
2173 | full_markup { $$ = $1; }
2184 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2185 $$ = bfr->self_scm ();
2186 scm_gc_unprotect_object ($$);
2189 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2190 $$ = bfr->self_scm ();
2192 bfr->set_property ("figure", $1);
2194 scm_gc_unprotect_object ($$);
2196 | bass_figure bass_mod {
2197 Music *m = unsmob_music ($1);
2199 SCM salter = m->get_property ("alteration");
2200 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2201 m->set_property ("alteration",
2202 scm_int2num (alter + $2));
2204 m->set_property ("alteration", scm_int2num (0));
2212 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2217 | br_bass_figure ']' {
2219 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2227 | figure_list br_bass_figure {
2228 $$ = scm_cons ($2, $1);
2233 FIGURE_OPEN figure_list FIGURE_CLOSE {
2234 Music *m = MY_MAKE_MUSIC ("EventChord");
2235 $2 = scm_reverse_x ($2, SCM_EOL);
2236 m->set_property ("elements", $2);
2237 $$ = m->self_scm ();
2248 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2249 if (!THIS->lexer_->is_note_state ())
2250 THIS->parser_error (@1, _ ("have to be in Note mode for notes"));
2254 n = MY_MAKE_MUSIC ("RestEvent");
2256 n = MY_MAKE_MUSIC ("NoteEvent");
2258 n->set_property ("pitch", $1);
2259 n->set_property ("duration", $5);
2261 if (scm_is_number ($4))
2263 int q = scm_to_int ($4);
2264 n->set_property ("absolute-octave", scm_int2num (q-1));
2268 n->set_property ("cautionary", SCM_BOOL_T);
2269 if ($2 % 2 || $3 % 2)
2270 n->set_property ("force-accidental", SCM_BOOL_T);
2272 Music *v = MY_MAKE_MUSIC ("EventChord");
2273 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2274 scm_gc_unprotect_object (n->self_scm ());
2280 | DRUM_PITCH optional_notemode_duration {
2281 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2282 n->set_property ("duration", $2);
2283 n->set_property ("drum-type", $1);
2285 Music *v = MY_MAKE_MUSIC ("EventChord");
2286 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2287 scm_gc_unprotect_object (n->self_scm ());
2293 | figure_spec optional_notemode_duration {
2294 Music *m = unsmob_music ($1);
2296 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2298 unsmob_music (scm_car (s))->set_property ("duration", $2);
2302 | RESTNAME optional_notemode_duration {
2304 if (ly_scm2string ($1) == "s") {
2306 ev = MY_MAKE_MUSIC ("SkipEvent");
2309 ev = MY_MAKE_MUSIC ("RestEvent");
2312 ev->set_property ("duration", $2);
2314 Music *velt = MY_MAKE_MUSIC ("EventChord");
2315 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2316 velt->set_spot (@$);
2318 scm_gc_unprotect_object (ev->self_scm ());
2322 | MULTI_MEASURE_REST optional_notemode_duration {
2323 SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
2324 SCM mus = scm_call_2 (proc, $2, make_input (@$));
2325 scm_gc_protect_object (mus);
2326 $$ = unsmob_music (mus);
2329 | lyric_element optional_notemode_duration {
2330 if (!THIS->lexer_->is_lyric_state ())
2331 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2333 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2334 lreq->set_property ("text", $1);
2335 lreq->set_property ("duration",$2);
2336 lreq->set_spot (@$);
2337 Music *velt = MY_MAKE_MUSIC ("EventChord");
2338 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2343 if (!THIS->lexer_->is_chord_state ())
2344 THIS->parser_error (@1, _ ("have to be in Chord mode for chords"));
2345 $$ = unsmob_music ($1);
2354 $$ = make_simple_markup ($1);
2359 steno_tonic_pitch optional_notemode_duration {
2360 $$ = make_chord ($1, $2, SCM_EOL);
2362 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2363 SCM its = scm_reverse_x ($4, SCM_EOL);
2364 $$ = make_chord ($1, $2, scm_cons ($3, its));
2372 | chord_items chord_item {
2373 $$ = scm_cons ($2, $$);
2379 $$ = ly_symbol2scm ("chord-colon");
2382 $$ = ly_symbol2scm ("chord-caret");
2384 | CHORD_SLASH steno_tonic_pitch {
2385 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2387 | CHORD_BASS steno_tonic_pitch {
2388 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2397 $$ = scm_reverse_x ($1, SCM_EOL);
2405 step_number { $$ = scm_cons ($1, SCM_EOL); }
2406 | step_numbers '.' step_number {
2407 $$ = scm_cons ($3, $$);
2413 $$ = make_chord_step ($1, 0);
2415 | bare_unsigned '+' {
2416 $$ = make_chord_step ($1, SHARP);
2418 | bare_unsigned CHORD_MINUS {
2419 $$ = make_chord_step ($1, FLAT);
2426 TODO: should deprecate in favor of Scheme?
2430 number_expression '+' number_term {
2431 $$ = scm_sum ($1, $3);
2433 | number_expression '-' number_term {
2434 $$ = scm_difference ($1, $3);
2443 | number_factor '*' number_factor {
2444 $$ = scm_product ($1, $3);
2446 | number_factor '/' number_factor {
2447 $$ = scm_divide ($1, $3);
2452 '-' number_factor { /* %prec UNARY_MINUS */
2453 $$ = scm_difference ($2, SCM_UNDEFINED);
2461 $$ = scm_int2num ($1);
2466 | NUMBER_IDENTIFIER {
2469 | REAL NUMBER_IDENTIFIER {
2470 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2472 | UNSIGNED NUMBER_IDENTIFIER {
2473 $$ = scm_make_real ($1 *scm_to_double ($2));
2489 if (scm_integer_p ($1) == SCM_BOOL_T)
2491 int k = scm_to_int ($1);
2495 THIS->parser_error (@1, _ ("need integer number arg"));
2506 | exclamations '!' { $$ ++; }
2511 | questions '?' { $$ ++; }
2515 This should be done more dynamically if possible.
2519 LYRIC_MARKUP_IDENTIFIER {
2523 { THIS->lexer_->push_markup_state (); }
2526 THIS->lexer_->pop_state ();
2535 { THIS->lexer_->push_markup_state (); }
2538 THIS->lexer_->pop_state ();
2544 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
2546 | markup_head_1_list simple_markup {
2547 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2555 markup_composed_list {
2558 | markup_braced_list {
2563 markup_composed_list:
2564 markup_head_1_list markup_braced_list {
2565 $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
2571 '{' markup_braced_list_body '}' {
2572 $$ = scm_reverse_x ($2, SCM_EOL);
2576 markup_braced_list_body:
2577 /* empty */ { $$ = scm_list (SCM_EOL); }
2578 | markup_braced_list_body markup {
2579 $$ = scm_cons ($2, $1);
2581 | markup_braced_list_body markup_list {
2582 $$ = scm_append_x (scm_list_2 (scm_reverse_x ($2, SCM_EOL), $1));
2587 MARKUP_HEAD_MARKUP0 {
2588 $$ = scm_list_1 ($1);
2590 | MARKUP_HEAD_SCM0_MARKUP1 embedded_scm {
2591 $$ = scm_list_2 ($1, $2);
2593 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm {
2594 $$ = scm_list_3 ($1, $2, $3);
2599 markup_head_1_item {
2600 $$ = scm_list_1 ($1);
2602 | markup_head_1_list markup_head_1_item {
2603 $$ = scm_cons ($2, $1);
2609 $$ = make_simple_markup ($1);
2611 | MARKUP_IDENTIFIER {
2614 | LYRIC_MARKUP_IDENTIFIER {
2617 | STRING_IDENTIFIER {
2621 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2622 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2623 } '{' score_body '}' {
2625 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());
2626 scm_gc_unprotect_object (sc->self_scm ());
2627 THIS->lexer_->pop_state ();
2629 | MARKUP_HEAD_SCM0 embedded_scm {
2630 $$ = scm_list_2 ($1, $2);
2632 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2633 $$ = scm_list_4 ($1, $2, $3, $4);
2635 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2636 $$ = scm_list_3 ($1, $2, $3);
2638 | MARKUP_HEAD_EMPTY {
2639 $$ = scm_list_1 ($1);
2641 | MARKUP_HEAD_LIST0 markup_list {
2642 $$ = scm_list_2 ($1,$2);
2644 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2645 $$ = scm_list_3 ($1, $2, $3);
2650 markup_head_1_list simple_markup {
2651 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2661 Lily_parser::set_yydebug (bool )
2669 Lily_parser::do_yyparse ()
2671 yyparse ((void*)this);
2676 Should make this optional? It will also complain when you do
2680 which is entirely legitimate.
2682 Or we can scrap it. Barchecks should detect wrong durations, and
2683 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);