1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for LilyPond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
15 * The rules for who is protecting what are very shady. Uniformise
18 * There are too many lexical modes?
29 #include "context-def.hh"
30 #include "dimensions.hh"
32 #include "file-path.hh"
33 #include "input-smob.hh"
35 #include "lily-guile.hh"
36 #include "lilypond-input-version.hh"
39 #include "lily-lexer.hh"
40 #include "lily-parser.hh"
41 #include "paper-book.hh"
42 #include "output-def.hh"
43 #include "scm-hash.hh"
44 #include "scm-option.hh"
46 #include "text-item.hh"
49 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
51 Music *property_op_to_music (SCM op);
52 Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
53 SCM get_next_unique_context_id ();
54 SCM get_next_unique_lyrics_context_id ();
61 #define _(x) gettext (x)
64 #define YYERROR_VERBOSE 1
66 #define YYPARSE_PARAM my_lily_parser
67 #define YYLEX_PARAM my_lily_parser
69 ((Lily_parser *) my_lily_parser)
71 #define yyerror THIS->parser_error
73 /* We use custom location type: Input objects */
75 #define YYLLOC_DEFAULT(Current,Rhs,N) \
76 ((Current).set_location ((Rhs)[1], (Rhs)[N]))
79 /* Add symbols to the TAGS field of a music object. */
82 tag_music (Music *m, SCM tag, Input ip)
84 SCM tags = m->get_property ("tags");
85 if (scm_is_symbol (tag))
86 tags = scm_cons (tag, tags);
87 else if (ly_c_list_p (tag))
88 tags = ly_append2 (tag, tags);
90 ip.warning (_ ("tag must be symbol or list of symbols"));
92 m->set_property ("tags", tags);
96 is_regular_identifier (SCM id)
98 String str = ly_scm2string (id);
99 char const *s = str.to_str0 ();
108 v = v && isalnum (*s);
116 get_first_context_id (SCM type, Music *m)
118 SCM id = m->get_property ("context-id");
119 if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
120 && scm_is_string (m->get_property ("context-id"))
121 && scm_c_string_length (id) > 0)
129 make_simple_markup (SCM a)
131 SCM simple = ly_lily_module_constant ("simple-markup");
132 return scm_list_2 (simple, a);
138 return t && t == 1 << intlog2 (t);
142 set_music_properties (Music *p, SCM a)
144 for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
145 p->internal_set_property (scm_caar (k), scm_cdar (k));
149 make_chord_step (int step, int alter)
156 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
157 return m.smobbed_copy ();
162 make_chord (SCM pitch, SCM dur, SCM modification_list)
164 SCM chord_ctor = ly_lily_module_constant ("construct-chord");
165 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
166 scm_gc_protect_object (ch);
170 /* Todo: actually also use apply iso. call too ... */
172 ly_input_procedure_p (SCM x)
174 return ly_c_procedure_p (x)
175 || (scm_is_pair (x) && ly_c_procedure_p (scm_car (x)));
179 set_property_music (SCM sym, SCM value)
181 Music *p = MY_MAKE_MUSIC ("PropertySet");
182 p->set_property ("symbol", sym);
183 p->set_property ("value", value);
188 make_music_relative (Pitch start, Music *music)
190 Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
191 relative->set_property ("element", music->self_scm ());
193 Pitch last = music->to_relative_octave (start);
194 if (lily_1_8_relative)
195 music->set_property ("last-pitch", last.smobbed_copy ());
200 make_lyric_combine_music (SCM name, Music *music)
202 Music *combine = MY_MAKE_MUSIC ("NewLyricCombineMusic");
203 combine->set_property ("element", music->self_scm ());
204 combine->set_property ("associated-context", name);
210 /* We use SCMs to do strings, because it saves us the trouble of
211 deleting them. Let's hope that a stack overflow doesnt trigger a move
212 of the parse stack onto the heap. */
218 Output_def *outputdef;
228 yylex (YYSTYPE *s, YYLTYPE *loc, void *v)
230 Lily_parser *pars = (Lily_parser*) v;
231 Lily_lexer *lex = pars->lexer_;
233 lex->lexval = (void*) s;
235 lex->prepare_for_next_token ();
236 return lex->yylex ();
244 /* One shift/reduce problem
247 \repeat .. \alternative
249 \repeat { \repeat .. \alternative }
253 \repeat { \repeat } \alternative
260 /* The third option is an alias that will be used to display the
261 syntax error. Bison CVS now correctly handles backslash escapes.
263 FIXME: Bison needs to translate some of these, eg, STRING.
267 /* Keyword tokens with plain escaped name. */
268 %token ACCEPTS "\\accepts"
269 %token ADDLYRICS "\\addlyrics"
270 %token ADDQUOTE "\\addquote"
271 %token ALIAS "\\alias"
272 %token ALTERNATIVE "\\alternative"
275 %token CHANGE "\\change"
276 %token CHORDMODE "\\chordmode"
277 %token CHORDS "\\chords"
279 %token CONSISTS "\\consists"
280 %token CONTEXT "\\context"
281 %token DEFAULT "\\default"
282 %token DENIES "\\denies"
283 %token DESCRIPTION "\\description"
284 %token DRUMMODE "\\drummode"
285 %token DRUMS "\\drums"
286 %token FIGUREMODE "\\figuremode"
287 %token FIGURES "\\figures"
288 %token GROBDESCRIPTIONS "\\grobdescriptions"
289 %token HEADER "\\header"
290 %token INVALID "\\invalid"
292 %token LAYOUT "\\layout"
293 %token LYRICMODE "\\lyricmode"
294 %token LYRICS "\\lyrics"
295 %token LYRICSTO "\\lyricsto"
297 %token MARKUP "\\markup"
300 %token NOTEMODE "\\notemode"
301 %token OBJECTID "\\objectid"
302 %token OCTAVE "\\octave"
304 %token OVERRIDE "\\override"
305 %token PAPER "\\paper"
306 %token PARTIAL "\\partial"
307 %token RELATIVE "\\relative"
308 %token REMOVE "\\remove"
309 %token REPEAT "\\repeat"
311 %token REVERT "\\revert"
312 %token SCORE "\\score"
313 %token SEQUENTIAL "\\sequential"
315 %token SIMULTANEOUS "\\simultaneous"
318 %token TEMPO "\\tempo"
319 %token TIMES "\\times"
320 %token TRANSPOSE "\\transpose"
321 %token TRANSPOSITION "\\transposition"
323 %token UNSET "\\unset"
326 /* Keyword token exceptions. */
327 %token TIME_T "\\time"
328 %token NEWCONTEXT "\\new"
331 /* Other string tokens. */
333 %token CHORD_BASS "/+"
334 %token CHORD_CARET "^"
335 %token CHORD_COLON ":"
336 %token CHORD_MINUS "-"
337 %token CHORD_SLASH "/"
338 %token DOUBLE_ANGLE_CLOSE ">>"
339 %token DOUBLE_ANGLE_OPEN "<<"
340 %token E_BACKSLASH "\\"
341 %token E_ANGLE_CLOSE "\\>"
342 %token E_CHAR "\\C[haracter]"
344 %token E_EXCLAMATION "\\!"
345 %token E_BRACKET_OPEN "\\["
347 %token E_BRACKET_CLOSE "\\]"
348 %token E_ANGLE_OPEN "\\<"
351 /* These used at all?
352 %token FIGURE_BRACKET_CLOSE
353 %token FIGURE_BRACKET_OPEN
355 parser.yy:348.8-25: warning: symbol `"\\>"' used more than once as a literal string
356 parser.yy:352.8-24: warning: symbol `"\\<"' used more than once as a literal string
359 %token FIGURE_CLOSE /* "\\>" */
360 %token FIGURE_OPEN /* "\\<" */
361 %token FIGURE_SPACE "_"
364 %token CHORDMODIFIERS
365 %token COMMANDSPANREQUEST
367 %token MULTI_MEASURE_REST
372 %token <i> E_UNSIGNED
375 %token <id> IDENTIFIER
377 %token <scm> CHORDMODIFIER_PITCH
378 %token <scm> CHORD_MODIFIER
379 %token <scm> CONTEXT_DEF_IDENTIFIER
380 %token <scm> DRUM_PITCH
381 %token <scm> DURATION_IDENTIFIER
382 %token <scm> EVENT_IDENTIFIER
383 %token <scm> FRACTION
384 %token <scm> LYRICS_STRING
385 %token <scm> LYRIC_MARKUP_IDENTIFIER
386 %token <scm> MARKUP_HEAD_EMPTY
387 %token <scm> MARKUP_HEAD_LIST0
388 %token <scm> MARKUP_HEAD_MARKUP0
389 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
390 %token <scm> MARKUP_HEAD_SCM0
391 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
392 %token <scm> MARKUP_HEAD_SCM0_SCM1
393 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
394 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
395 %token <scm> MARKUP_IDENTIFIER
396 %token <scm> MUSIC_FUNCTION
397 %token <scm> MUSIC_FUNCTION_MARKUP
398 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
399 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
400 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
401 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
402 %token <scm> MUSIC_FUNCTION_MUSIC
403 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
404 %token <scm> MUSIC_FUNCTION_SCM
405 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
406 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
407 %token <scm> MUSIC_FUNCTION_SCM_SCM
408 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
409 %token <scm> MUSIC_IDENTIFIER
410 %token <scm> NOTENAME_PITCH
411 %token <scm> NUMBER_IDENTIFIER
412 %token <scm> OUTPUT_DEF_IDENTIFIER
414 %token <scm> RESTNAME
415 %token <scm> SCM_IDENTIFIER
417 %token <scm> SCORE_IDENTIFIER
419 %token <scm> STRING_IDENTIFIER
420 %token <scm> TONICNAME_PITCH
423 %type <book> book_block
424 %type <book> book_body
427 %type <i> bare_unsigned
430 %type <i> exclamations
431 %type <i> optional_rest
436 %type <i> tremolo_type
438 %type <music> Composite_music
439 %type <music> Generic_prefix_music
440 %type <music> Grouped_music_list
442 %type <music> Prefix_composite_music
443 %type <music> Repeated_music
444 %type <music> Sequential_music
445 %type <music> Simple_music
446 %type <music> Simultaneous_music
447 %type <music> chord_body
448 %type <music> chord_body_element
449 %type <music> command_element
450 %type <music> command_req
451 %type <music> context_change
452 %type <music> direction_less_event
453 %type <music> direction_reqd_event
454 %type <music> event_chord
455 %type <music> gen_text_def
456 %type <music> music_property_def
457 %type <music> note_chord_element
458 %type <music> post_event
459 %type <music> re_rhythmed_music
460 %type <music> relative_music
461 %type <music> simple_element
462 %type <music> string_number_event
463 %type <music> tagged_post_event
464 %type <music> tempo_event
465 %type <music> toplevel_music
467 %type <outputdef> output_def_body
468 %type <outputdef> output_def_head
469 %type <outputdef> output_def
470 %type <outputdef> paper_block
472 %type <scm> Alternative_music
473 %type <scm> Generic_prefix_music_scm
474 %type <scm> Music_list
475 %type <scm> absolute_pitch
476 %type <scm> assignment_id
477 %type <scm> bare_number
478 %type <scm> bass_figure
479 %type <scm> bass_number
480 %type <scm> br_bass_figure
481 %type <scm> chord_body_elements
482 %type <scm> chord_item
483 %type <scm> chord_items
484 %type <scm> chord_separator
485 %type <scm> context_def_mod
486 %type <scm> context_def_spec_block
487 %type <scm> context_def_spec_body
488 %type <scm> context_mod
489 %type <scm> context_mod_list
490 %type <scm> context_prop_spec
491 %type <scm> direction_less_char
492 %type <scm> duration_length
493 %type <scm> embedded_scm
494 %type <scm> figure_list
495 %type <scm> figure_spec
497 %type <scm> full_markup
498 %type <scm> identifier_init
499 %type <scm> lilypond_header
500 %type <scm> lilypond_header_body
501 %type <scm> lyric_element
502 %type <scm> lyric_markup
504 %type <scm> markup_braced_list
505 %type <scm> markup_braced_list_body
506 %type <scm> markup_composed_list
507 %type <scm> markup_head_1_item
508 %type <scm> markup_head_1_list
509 %type <scm> markup_list
510 %type <scm> markup_top
511 %type <scm> mode_changing_head
512 %type <scm> mode_changing_head_with_context
513 %type <scm> multiplied_duration
514 %type <scm> new_chord
515 %type <scm> new_lyrics
516 %type <scm> number_expression
517 %type <scm> number_factor
518 %type <scm> number_term
519 %type <scm> object_id_setting
520 %type <scm> octave_check
521 %type <scm> optional_context_mod
522 %type <scm> optional_notemode_duration
524 %type <scm> pitch_also_in_chords
525 %type <scm> post_events
526 %type <scm> property_operation
528 %type <scm> script_abbreviation
529 %type <scm> simple_markup
530 %type <scm> simple_string
531 %type <scm> steno_duration
532 %type <scm> steno_pitch
533 %type <scm> steno_tonic_pitch
534 %type <scm> step_number
535 %type <scm> step_numbers
538 %type <score> score_block
539 %type <score> score_body
544 /* We don't assign precedence to / and *, because we might need varied
545 prec levels in different prods */
551 lilypond: /* empty */
552 | lilypond toplevel_expression {
554 | lilypond assignment {
557 THIS->error_level_ = 1;
560 THIS->error_level_ = 1;
566 OBJECTID STRING { $$ = $2; }
571 THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1);
578 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
579 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
580 scm_gc_unprotect_object (book->self_scm ());
585 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
586 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
587 scm_gc_unprotect_object (score->self_scm ());
591 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
592 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
593 scm_gc_unprotect_object (music->self_scm ());
596 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-text-handler");
597 scm_call_2 (proc, THIS->self_scm (), $1);
601 Output_def * od = $1;
603 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
604 id = ly_symbol2scm ("$defaultpaper");
605 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
606 id = ly_symbol2scm ("$defaultmidi");
607 else if ($1->c_variable ("is-layout") == SCM_BOOL_T)
608 id = ly_symbol2scm ("$defaultlayout");
610 THIS->lexer_->set_identifier (id, od->self_scm ());
611 scm_gc_unprotect_object (od->self_scm ());
626 lilypond_header_body:
628 $$ = ly_make_anonymous_module (be_safe_global);
629 THIS->lexer_->add_scope ($$);
631 | lilypond_header_body assignment {
637 HEADER '{' lilypond_header_body '}' {
638 $$ = THIS->lexer_->remove_scope ();
647 | LYRICS_STRING { $$ = $1; }
651 assignment_id '=' identifier_init {
652 if (! is_regular_identifier ($1))
654 @1.warning (_ ("identifier should have alphabetic characters only"));
657 THIS->lexer_->set_identifier ($1, $3);
660 TODO: devise standard for protection in parser.
662 The parser stack lives on the C-stack, which means that
663 all objects can be unprotected as soon as they're here.
673 $$ = $1->self_scm ();
674 scm_gc_unprotect_object ($$);
677 $$ = $1->self_scm ();
678 scm_gc_unprotect_object ($$);
680 | context_def_spec_block {
684 $$ = $1->self_scm ();
685 scm_gc_unprotect_object ($$);
688 $$ = $1->self_scm ();
689 scm_gc_unprotect_object ($$);
691 | number_expression {
704 $$ = scm_int2num ($1);
708 context_def_spec_block:
709 CONTEXT '{' context_def_spec_body '}'
715 context_def_spec_body:
717 $$ = Context_def::make_scm ();
718 unsmob_context_def ($$)->set_spot (@$);
720 | CONTEXT_DEF_IDENTIFIER {
722 unsmob_context_def ($$)->set_spot (@$);
724 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
725 Context_def*td = unsmob_context_def ($$);
727 for (SCM p = $3; scm_is_pair (p); p = scm_cdr (p)) {
728 SCM tag = scm_caar (p);
730 /* TODO: should make new tag "grob-definition" ? */
731 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
732 tag, scm_cons (scm_cdar (p), SCM_EOL)));
735 | context_def_spec_body context_mod {
736 unsmob_context_def ($$)->add_context_mod ($2);
743 BOOK '{' book_body '}' {
749 * Use 'handlers' like for toplevel-* stuff?
750 * grok \layout and \midi? */
755 $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
756 scm_gc_unprotect_object ($$->paper_->self_scm ());
757 $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader");
759 | book_body paper_block {
761 scm_gc_unprotect_object ($2->self_scm ());
763 | book_body score_block {
764 SCM s = $2->self_scm ();
766 scm_gc_unprotect_object (s);
768 | book_body full_markup {
771 | book_body lilypond_header {
776 $$->scores_ = SCM_EOL;
778 | book_body object_id_setting {
779 $$->user_key_ = ly_scm2string ($2);
784 SCORE '{' score_body '}' {
795 $$ = new Score ( *unsmob_score ($1));
798 | score_body object_id_setting {
799 $$->user_key_ = ly_scm2string ($2);
802 SCM m = $2->self_scm ();
803 scm_gc_unprotect_object (m);
804 $$->set_music (m, THIS->self_scm ());
806 | score_body lilypond_header {
809 | score_body output_def {
810 if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
812 THIS->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
819 scm_gc_unprotect_object ($2->self_scm ());
822 $$->error_found_ = true;
834 if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
836 THIS->parser_error (@1, _ ("need \\paper for paper block"));
837 $$ = get_paper (THIS);
844 output_def_body '}' {
847 THIS->lexer_->remove_scope ();
848 THIS->lexer_->pop_state ();
854 $$ = get_paper (THIS);
855 $$->input_origin_ = @$;
856 THIS->lexer_->add_scope ($$->scope_);
859 Output_def *p = get_midi (THIS);
861 THIS->lexer_->add_scope (p->scope_);
864 Output_def *p = get_layout (THIS);
866 THIS->lexer_->add_scope (p->scope_);
873 output_def_head '{' {
875 $$->input_origin_.set_spot (@$);
876 THIS->lexer_->push_initial_state ();
878 | output_def_head '{' OUTPUT_DEF_IDENTIFIER {
879 scm_gc_unprotect_object ($1->self_scm ());
880 Output_def *o = unsmob_output_def ($3);
881 o->input_origin_.set_spot (@$);
883 THIS->lexer_->remove_scope ();
884 THIS->lexer_->add_scope (o->scope_);
885 THIS->lexer_->push_initial_state ();
887 | output_def_body assignment {
890 | output_def_body context_def_spec_block {
891 assign_context_def ($$, $2);
893 | output_def_body tempo_event {
895 junk this ? there already is tempo stuff in
898 int m = scm_to_int ($2->get_property ("metronome-count"));
899 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
900 set_tempo ($$, d->get_length (), m);
901 scm_gc_unprotect_object ($2->self_scm ());
903 | output_def_body error {
909 TEMPO steno_duration '=' bare_unsigned {
910 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
911 $$->set_property ("tempo-unit", $2);
912 $$->set_property ("metronome-count", scm_int2num ( $4));
917 The representation of a list is the
921 to have efficient append. */
925 $$ = scm_cons (SCM_EOL, SCM_EOL);
929 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
930 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
932 if (scm_is_pair (scm_cdr (s)))
933 scm_set_cdr_x (scm_cdr (s), c); /* append */
935 scm_set_car_x (s, c); /* set first cons */
936 scm_set_cdr_x (s, c); /* remember last cell */
938 | Music_list embedded_scm {
942 Music * m = MY_MAKE_MUSIC("Music");
944 m->set_property ("error-found", SCM_BOOL_T);
946 SCM c = scm_cons (m->self_scm (), SCM_EOL);
947 scm_gc_unprotect_object (m->self_scm ()); /* UGH */
949 if (scm_is_pair (scm_cdr (s)))
950 scm_set_cdr_x (scm_cdr (s), c); /* append */
952 scm_set_car_x (s, c); /* set first cons */
953 scm_set_cdr_x (s, c); /* remember last cell */
966 | ALTERNATIVE '{' Music_list '}' {
973 REPEAT simple_string bare_unsigned Music Alternative_music
977 SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
978 if (times < scm_ilength (alts)) {
979 unsmob_music (scm_car (alts))
980 ->origin ()->warning (
981 _ ("more alternatives than repeats"));
982 warning ("junking excess alternatives");
983 alts = ly_truncate_list (times, alts);
987 SCM proc = ly_lily_module_constant ("make-repeated-music");
989 SCM mus = scm_call_1 (proc, $2);
990 scm_gc_protect_object (mus); // UGH.
991 Music *r = unsmob_music (mus);
994 r-> set_property ("element", beg->self_scm ());
995 scm_gc_unprotect_object (beg->self_scm ());
997 r->set_property ("repeat-count", scm_int2num (times >? 1));
999 r-> set_property ("elements",alts);
1000 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
1002 TODO: move this code to Scheme.
1005 /* we cannot get durations and other stuff
1006 correct down the line,
1007 so we have to add to the duration log here. */
1008 SCM func = ly_lily_module_constant ("shift-duration-log");
1010 int dots = ($3 % 3) ? 0 : 1;
1011 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
1014 if ($4->is_mus_type ("sequential-music"))
1016 int list_len = scm_ilength ($4->get_property ("elements"));
1018 $4->origin ()->warning (_f ("expect 2 elements for Chord tremolo, found %d", list_len));
1020 r->compress (Moment (Rational (1, list_len)));
1022 scm_call_3 (func, r->self_scm (), scm_int2num (shift), scm_int2num (dots));
1025 r->set_spot (*$4->origin ());
1032 SEQUENTIAL '{' Music_list '}' {
1033 $$ = MY_MAKE_MUSIC ("SequentialMusic");
1034 $$->set_property ("elements", scm_car ($3));
1037 | '{' Music_list '}' {
1038 $$ = MY_MAKE_MUSIC ("SequentialMusic");
1039 $$->set_property ("elements", scm_car ($2));
1045 SIMULTANEOUS '{' Music_list '}'{
1046 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
1047 $$->set_property ("elements", scm_car ($3));
1051 | simul_open Music_list simul_close {
1052 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
1053 $$->set_property ("elements", scm_car ($2));
1059 event_chord { $$ = $1; }
1060 | MUSIC_IDENTIFIER {
1061 $$ = unsmob_music ($1);
1063 | music_property_def
1068 optional_context_mod:
1069 /**/ { $$ = SCM_EOL; }
1070 | WITH { THIS->lexer_->push_initial_state (); }
1071 '{' context_mod_list '}'
1073 THIS->lexer_->pop_state ();
1079 /* */ { $$ = SCM_EOL; }
1080 | context_mod_list context_mod {
1081 $$ = scm_cons ($2, $1);
1087 Prefix_composite_music { $$ = $1; }
1088 | Grouped_music_list { $$ = $1; }
1092 Simultaneous_music { $$ = $1; }
1093 | Sequential_music { $$ = $1; }
1096 Generic_prefix_music_scm:
1098 $$ = scm_list_2 ($1, make_input (@$));
1100 | MUSIC_FUNCTION_SCM embedded_scm {
1101 $$ = scm_list_3 ($1, make_input (@$), $2);
1103 | MUSIC_FUNCTION_MARKUP full_markup {
1104 $$ = scm_list_3 ($1, make_input (@$), $2);
1106 | MUSIC_FUNCTION_MUSIC Music {
1107 $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
1108 scm_gc_unprotect_object ($2->self_scm ());
1110 | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
1111 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1112 scm_gc_unprotect_object ($3->self_scm ());
1114 | MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
1115 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1117 | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
1118 $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
1120 | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
1121 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1122 scm_gc_unprotect_object ($3->self_scm ());
1124 | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
1125 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1127 | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
1128 $$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
1129 scm_gc_unprotect_object ($2->self_scm ());
1130 scm_gc_unprotect_object ($3->self_scm ());
1132 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
1133 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1134 scm_gc_unprotect_object ($4->self_scm ());
1135 scm_gc_unprotect_object ($3->self_scm ());
1137 | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
1138 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1139 scm_gc_unprotect_object ($3->self_scm ());
1140 scm_gc_unprotect_object ($4->self_scm ());
1144 Generic_prefix_music:
1145 Generic_prefix_music_scm {
1146 SCM func = scm_car ($1);
1147 Input *loc = unsmob_input (scm_cadr ($1));
1148 SCM args = scm_cddr ($1);
1149 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1151 SCM type_check_proc = ly_lily_module_constant ("type-check-list");
1154 if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr ($1), sig, args)))
1156 THIS->error_level_ = 1;
1162 m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
1165 if (unsmob_music (m))
1167 $$ = unsmob_music (m);
1168 scm_gc_protect_object (m);
1173 loc->error (_ ("music head function must return Music object"));
1174 $$ = MY_MAKE_MUSIC ("Music");
1176 $$->set_spot (*loc);
1181 Prefix_composite_music:
1182 Generic_prefix_music {
1185 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1186 $$ = context_spec_music ($2, $4, $6, $5);
1189 | CONTEXT simple_string optional_context_mod Music {
1190 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1192 | NEWCONTEXT simple_string optional_context_mod Music {
1193 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1197 | TIMES fraction Music
1200 int n = scm_to_int (scm_car ($2)); int d = scm_to_int (scm_cdr ($2));
1203 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1206 $$->set_property ("element", mp->self_scm ());
1207 scm_gc_unprotect_object (mp->self_scm ());
1208 $$->set_property ("numerator", scm_int2num (n));
1209 $$->set_property ("denominator", scm_int2num (d));
1210 $$->compress (Moment (Rational (n,d)));
1213 | Repeated_music { $$ = $1; }
1214 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1215 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1217 Pitch from = *unsmob_pitch ($2);
1218 Pitch to = *unsmob_pitch ($3);
1220 p->transpose (pitch_interval (from, to));
1221 $$->set_property ("element", p->self_scm ());
1222 scm_gc_unprotect_object (p->self_scm ());
1224 | mode_changing_head Grouped_music_list {
1225 if ($1 == ly_symbol2scm ("chords"))
1227 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1228 chm->set_property ("element", $2->self_scm ());
1230 scm_gc_unprotect_object ($2->self_scm ());
1236 THIS->lexer_->pop_state ();
1238 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1239 $$ = context_spec_music ($1, get_next_unique_context_id (),
1241 if ($1 == ly_symbol2scm ("ChordNames"))
1243 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1244 chm->set_property ("element", $$->self_scm ());
1245 scm_gc_unprotect_object ($$->self_scm ());
1248 THIS->lexer_->pop_state ();
1250 | relative_music { $$ = $1; }
1251 | re_rhythmed_music { $$ = $1; }
1252 | TAG embedded_scm Music {
1253 tag_music ($3, $2, @$);
1260 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1261 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1263 $$ = ly_symbol2scm ("notes");
1267 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1268 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1270 $$ = ly_symbol2scm ("drums");
1273 THIS->lexer_->push_figuredbass_state ();
1275 $$ = ly_symbol2scm ("figures");
1278 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1279 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1280 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1281 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1282 $$ = ly_symbol2scm ("chords");
1286 { THIS->lexer_->push_lyric_state ();
1287 $$ = ly_symbol2scm ("lyrics");
1291 mode_changing_head_with_context:
1293 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1294 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1296 $$ = ly_symbol2scm ("DrumStaff");
1299 THIS->lexer_->push_figuredbass_state ();
1301 $$ = ly_symbol2scm ("FiguredBass");
1304 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1305 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1306 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1307 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1308 $$ = ly_symbol2scm ("ChordNames");
1311 { THIS->lexer_->push_lyric_state ();
1312 $$ = ly_symbol2scm ("Lyrics");
1318 RELATIVE absolute_pitch Music {
1320 Pitch start = *unsmob_pitch ($2);
1321 $$ = make_music_relative (start, m);
1322 scm_gc_unprotect_object (m->self_scm ());
1324 | RELATIVE Composite_music {
1327 Pitch middle_c (0, 0, 0);
1328 $$ = make_music_relative (middle_c, m);
1329 scm_gc_unprotect_object (m->self_scm ());
1334 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1336 Grouped_music_list {
1337 /* Can also use Music at the expensive of two S/Rs similar to
1338 \repeat \alternative */
1339 THIS->lexer_->pop_state ();
1341 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1343 | new_lyrics ADDLYRICS {
1344 THIS->lexer_->push_lyric_state ();
1345 } Grouped_music_list {
1346 THIS->lexer_->pop_state ();
1347 $$ = scm_cons ($4->self_scm (), $1);
1352 Grouped_music_list new_lyrics {
1354 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1355 if (!scm_is_string (name))
1357 name = get_next_unique_lyrics_context_id ();
1358 voice = context_spec_music (scm_makfrom0str ("Voice"),
1363 SCM context = scm_makfrom0str ("Lyrics");
1364 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1367 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1369 Music *music = unsmob_music (scm_car (s));
1370 Music *com = make_lyric_combine_music (name, music);
1371 Music *csm = context_spec_music (context,
1372 get_next_unique_context_id (), com, SCM_EOL);
1373 lst = scm_cons (csm->self_scm (), lst);
1375 all->set_property ("elements", scm_cons (voice->self_scm (),
1378 scm_gc_unprotect_object (voice->self_scm ());
1380 | LYRICSTO simple_string {
1381 THIS->lexer_->push_lyric_state ();
1383 THIS->lexer_->pop_state ();
1386 $$ = make_lyric_combine_music (name, music);
1387 scm_gc_unprotect_object (music->self_scm ());
1392 CHANGE STRING '=' STRING {
1393 Music*t = MY_MAKE_MUSIC ("ContextChange");
1394 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1395 t-> set_property ("change-to-id", $4);
1404 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1405 scm_string_to_symbol ($1), $3);
1407 | UNSET simple_string {
1408 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1409 scm_string_to_symbol ($2));
1411 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1412 $$ = scm_list_4 (ly_symbol2scm ("push"),
1413 scm_string_to_symbol ($2), $3, $5);
1415 | REVERT simple_string embedded_scm {
1416 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1417 scm_string_to_symbol ($2), $3);
1422 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1423 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1425 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1426 | DENIES { $$ = ly_symbol2scm ("denies"); }
1428 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1429 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1430 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1431 | NAME { $$ = ly_symbol2scm ("context-name"); }
1435 property_operation { $$ = $1; }
1436 | context_def_mod STRING {
1437 $$ = scm_list_2 ($1, $2);
1443 if (!is_regular_identifier ($1))
1445 @$.error (_("Grob name should be alphanumeric"));
1448 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1449 scm_string_to_symbol ($1));
1451 | simple_string '.' simple_string {
1452 $$ = scm_list_2 (scm_string_to_symbol ($1),
1453 scm_string_to_symbol ($3));
1458 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1459 $$ = property_op_to_music (scm_list_4 (
1460 ly_symbol2scm ("poppush"),
1463 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1465 | REVERT context_prop_spec embedded_scm {
1466 $$ = property_op_to_music (scm_list_3 (
1467 ly_symbol2scm ("pop"),
1471 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1473 | SET context_prop_spec '=' scalar {
1474 $$ = property_op_to_music (scm_list_3 (
1475 ly_symbol2scm ("assign"),
1478 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1480 | UNSET context_prop_spec {
1481 $$ = property_op_to_music (scm_list_2 (
1482 ly_symbol2scm ("unset"),
1484 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1486 | ONCE music_property_def {
1487 SCM e = $2->get_property ("element");
1488 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1499 | STRING_IDENTIFIER {
1502 | string '+' string {
1503 $$ = scm_string_append (scm_list_2 ($1, $3));
1507 simple_string: STRING {
1522 $$ = scm_int2num ($1);
1531 $$ = scm_int2num ($1);
1537 pre_events doesn't contain anything. It is a trick:
1539 Adding pre_events to the simple_element
1540 makes the choice between
1546 simple_element: STRING
1548 a single shift/reduction conflict.
1550 nevertheless, this is not very clean, and we should find a different
1554 pre_events: /* empty */
1558 pre_events simple_element post_events {
1559 SCM elts = $2-> get_property ("elements");
1561 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1563 $2->set_property ("elements", elts);
1564 /* why is this giving wrong start location? -ns
1565 * $2->set_spot (@$); */
1567 i.set_location (@2, @3);
1572 | note_chord_element
1577 chord_body optional_notemode_duration post_events
1579 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1580 SCM es = $1->get_property ("elements");
1581 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1583 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1584 unsmob_music (scm_car (s))->set_property ("duration", dur);
1585 es = ly_append2 (es, postevs);
1587 $1-> set_property ("elements", es);
1599 simul_open: DOUBLE_ANGLE_OPEN
1602 simul_close: DOUBLE_ANGLE_CLOSE
1606 chord_open chord_body_elements chord_close
1608 $$ = MY_MAKE_MUSIC ("EventChord");
1610 $$->set_property ("elements",
1611 scm_reverse_x ($2, SCM_EOL));
1615 chord_body_elements:
1616 /* empty */ { $$ = SCM_EOL; }
1617 | chord_body_elements chord_body_element {
1618 $$ = scm_cons ($2->self_scm (), $1);
1619 scm_gc_unprotect_object ($2->self_scm ());
1624 pitch exclamations questions octave_check post_events
1631 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1632 n->set_property ("pitch", $1);
1635 n->set_property ("cautionary", SCM_BOOL_T);
1636 if (ex % 2 || q % 2)
1637 n->set_property ("force-accidental", SCM_BOOL_T);
1639 if (scm_is_pair (post)) {
1640 SCM arts = scm_reverse_x (post, SCM_EOL);
1641 n->set_property ("articulations", arts);
1643 if (scm_is_number (check))
1645 int q = scm_to_int (check);
1646 n->set_property ("absolute-octave", scm_int2num (q-1));
1652 | DRUM_PITCH post_events {
1653 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1654 n->set_property ("duration", $2);
1655 n->set_property ("drum-type", $1);
1658 if (scm_is_pair ($2)) {
1659 SCM arts = scm_reverse_x ($2, SCM_EOL);
1660 n->set_property ("articulations", arts);
1667 ADDQUOTE string Music {
1668 SCM adder = ly_lily_module_constant ("add-quotable");
1670 scm_call_2 (adder, $2, $3->self_scm ());
1671 scm_gc_unprotect_object ($3->self_scm ());
1677 $$ = MY_MAKE_MUSIC ("EventChord");
1678 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1679 scm_gc_unprotect_object ($1->self_scm ());
1684 | SKIP duration_length {
1685 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1686 skip->set_property ("duration", $2);
1687 skip->set_spot (@$);
1691 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1694 $$->set_property ("pitch", $2);
1697 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1698 m->set_property ("span-direction", scm_int2num (START));
1701 $$ = MY_MAKE_MUSIC ("EventChord");
1702 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1703 scm_gc_unprotect_object (m->self_scm ());
1707 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1708 m->set_property ("span-direction", scm_int2num (STOP));
1711 $$ = MY_MAKE_MUSIC ("EventChord");
1712 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1714 scm_gc_unprotect_object (m->self_scm ());
1717 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1721 SCM pipe = THIS->lexer_->lookup_identifier ("pipeSymbol");
1723 if (Music * m = unsmob_music (pipe))
1726 $$ = MY_MAKE_MUSIC ("BarCheck");
1730 | TRANSPOSITION pitch {
1732 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1733 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1734 sounds_as_c.smobbed_copy());
1736 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1740 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1742 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1744 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1748 | PARTIAL duration_length {
1749 Moment m = - unsmob_duration ($2)->get_length ();
1750 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1752 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1754 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1759 SCM proc = ly_lily_module_constant ("make-clef-set");
1761 SCM result = scm_call_1 (proc, $2);
1762 scm_gc_protect_object (result);
1763 $$ = unsmob_music (result);
1766 SCM proc = ly_lily_module_constant ("make-time-signature-set");
1768 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1769 scm_gc_protect_object (result);
1770 $$ = unsmob_music (result);
1773 SCM proc = ly_lily_module_constant ("make-mark-set");
1775 SCM result = scm_call_1 (proc, $2);
1776 scm_gc_protect_object (result);
1777 $$ = unsmob_music (result);
1783 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1786 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1793 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1796 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1798 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1799 if (scm_ilength ($3) > 0)
1801 key->set_property ("pitch-alist", $3);
1802 key->set_property ("tonic", Pitch (0, 0, 0).smobbed_copy ());
1803 key->transpose (* unsmob_pitch ($2));
1805 THIS->parser_error (@3, _ ("second argument must be pitch list"));
1817 | post_events post_event {
1819 $$ = scm_cons ($2->self_scm (), $$);
1820 scm_gc_unprotect_object ($2->self_scm ());
1822 | post_events tagged_post_event {
1823 $2 -> set_spot (@2);
1824 $$ = scm_cons ($2->self_scm (), $$);
1825 scm_gc_unprotect_object ($2->self_scm ());
1831 '-' TAG embedded_scm post_event {
1832 tag_music ($4, $3, @$);
1839 direction_less_event {
1843 if (!THIS->lexer_->is_lyric_state ())
1844 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
1845 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1848 if (!THIS->lexer_->is_lyric_state ())
1849 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
1850 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1852 | script_dir direction_reqd_event {
1854 $2->set_property ("direction", scm_int2num ($1));
1857 | script_dir direction_less_event {
1859 $2->set_property ("direction", scm_int2num ($1));
1862 | string_number_event
1865 string_number_event:
1867 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1868 s->set_property ("string-number", scm_int2num ($1));
1874 direction_less_char:
1876 $$ = ly_symbol2scm ("bracketOpenSymbol");
1879 $$ = ly_symbol2scm ("bracketCloseSymbol");
1882 $$ = ly_symbol2scm ("tildeSymbol");
1885 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1888 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1891 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1894 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1897 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1900 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1903 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1907 direction_less_event:
1908 direction_less_char {
1909 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1911 if (unsmob_music (predefd))
1913 m = unsmob_music (predefd)->clone ();
1917 m = MY_MAKE_MUSIC ("Music");
1922 | EVENT_IDENTIFIER {
1923 $$ = unsmob_music ($1);
1926 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1928 a->set_property ("tremolo-type", scm_int2num ($1));
1933 direction_reqd_event:
1937 | script_abbreviation {
1938 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1939 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1940 if (scm_is_string (s))
1941 a->set_property ("articulation-type", s);
1942 else THIS->parser_error (@1, _ ("expecting string as script definition"));
1948 /**/ { $$ = SCM_EOL; }
1949 | '=' { $$ = scm_int2num (0); }
1950 | '=' sub_quotes { $$ = scm_int2num ($2); }
1951 | '=' sup_quotes { $$ = scm_int2num ($2); }
1976 | NOTENAME_PITCH sup_quotes {
1977 Pitch p = *unsmob_pitch ($1);
1978 p = p.transposed (Pitch ($2,0,0));
1979 $$ = p.smobbed_copy ();
1981 | NOTENAME_PITCH sub_quotes {
1982 Pitch p =* unsmob_pitch ($1);
1983 p = p.transposed (Pitch (-$2,0,0));
1984 $$ = p.smobbed_copy ();
1996 | TONICNAME_PITCH sup_quotes {
1997 Pitch p = *unsmob_pitch ($1);
1998 p = p.transposed (Pitch ($2,0,0));
1999 $$ = p.smobbed_copy ();
2001 | TONICNAME_PITCH sub_quotes {
2002 Pitch p =* unsmob_pitch ($1);
2004 p = p.transposed (Pitch (-$2,0,0));
2005 $$ = p.smobbed_copy ();
2015 pitch_also_in_chords:
2022 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
2023 t->set_property ("text", $1);
2028 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
2029 t->set_property ("text",
2030 make_simple_markup ($1));
2036 Music *t = MY_MAKE_MUSIC ("FingerEvent");
2037 t->set_property ("digit", scm_int2num ($1));
2043 script_abbreviation:
2045 $$ = scm_makfrom0str ("Hat");
2048 $$ = scm_makfrom0str ("Plus");
2051 $$ = scm_makfrom0str ("Dash");
2054 $$ = scm_makfrom0str ("Bar");
2057 $$ = scm_makfrom0str ("Larger");
2060 $$ = scm_makfrom0str ("Dot");
2063 $$ = scm_makfrom0str ("Underscore");
2070 | '-' { $$ = CENTER; }
2081 multiplied_duration {
2086 optional_notemode_duration:
2088 Duration dd = THIS->default_duration_;
2089 $$ = dd.smobbed_copy ();
2091 THIS->beam_check ($$);
2093 | multiplied_duration {
2095 THIS->default_duration_ = *unsmob_duration ($$);
2097 THIS->beam_check ($$);
2102 bare_unsigned dots {
2104 if (!is_duration ($1))
2105 THIS->parser_error (@1, _f ("not a duration: %d", $1));
2109 $$ = Duration (len, $2).smobbed_copy ();
2111 | DURATION_IDENTIFIER dots {
2112 Duration *d = unsmob_duration ($1);
2113 Duration k (d->duration_log (), d->dot_count () + $2);
2119 multiplied_duration:
2123 | multiplied_duration '*' bare_unsigned {
2124 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2126 | multiplied_duration '*' FRACTION {
2127 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2129 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2134 FRACTION { $$ = $1; }
2135 | UNSIGNED '/' UNSIGNED {
2136 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2153 | ':' bare_unsigned {
2154 if (!is_duration ($2))
2155 THIS->parser_error (@2, _f ("not a duration: %d", $2));
2162 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2163 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2167 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2168 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2171 | STRING { $$ = $1; }
2172 | full_markup { $$ = $1; }
2183 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2184 $$ = bfr->self_scm ();
2185 scm_gc_unprotect_object ($$);
2188 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2189 $$ = bfr->self_scm ();
2191 bfr->set_property ("figure", $1);
2193 scm_gc_unprotect_object ($$);
2195 | bass_figure bass_mod {
2196 Music *m = unsmob_music ($1);
2198 SCM salter = m->get_property ("alteration");
2199 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2200 m->set_property ("alteration",
2201 scm_int2num (alter + $2));
2203 m->set_property ("alteration", scm_int2num (0));
2211 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2216 | br_bass_figure ']' {
2218 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2226 | figure_list br_bass_figure {
2227 $$ = scm_cons ($2, $1);
2232 FIGURE_OPEN figure_list FIGURE_CLOSE {
2233 Music *m = MY_MAKE_MUSIC ("EventChord");
2234 $2 = scm_reverse_x ($2, SCM_EOL);
2235 m->set_property ("elements", $2);
2236 $$ = m->self_scm ();
2247 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2248 if (!THIS->lexer_->is_note_state ())
2249 THIS->parser_error (@1, _ ("have to be in Note mode for notes"));
2253 n = MY_MAKE_MUSIC ("RestEvent");
2255 n = MY_MAKE_MUSIC ("NoteEvent");
2257 n->set_property ("pitch", $1);
2258 n->set_property ("duration", $5);
2260 if (scm_is_number ($4))
2262 int q = scm_to_int ($4);
2263 n->set_property ("absolute-octave", scm_int2num (q-1));
2267 n->set_property ("cautionary", SCM_BOOL_T);
2268 if ($2 % 2 || $3 % 2)
2269 n->set_property ("force-accidental", SCM_BOOL_T);
2271 Music *v = MY_MAKE_MUSIC ("EventChord");
2272 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2273 scm_gc_unprotect_object (n->self_scm ());
2279 | DRUM_PITCH optional_notemode_duration {
2280 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2281 n->set_property ("duration", $2);
2282 n->set_property ("drum-type", $1);
2284 Music *v = MY_MAKE_MUSIC ("EventChord");
2285 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2286 scm_gc_unprotect_object (n->self_scm ());
2292 | figure_spec optional_notemode_duration {
2293 Music *m = unsmob_music ($1);
2295 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2297 unsmob_music (scm_car (s))->set_property ("duration", $2);
2301 | RESTNAME optional_notemode_duration {
2303 if (ly_scm2string ($1) == "s") {
2305 ev = MY_MAKE_MUSIC ("SkipEvent");
2308 ev = MY_MAKE_MUSIC ("RestEvent");
2311 ev->set_property ("duration", $2);
2313 Music *velt = MY_MAKE_MUSIC ("EventChord");
2314 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2315 velt->set_spot (@$);
2317 scm_gc_unprotect_object (ev->self_scm ());
2321 | MULTI_MEASURE_REST optional_notemode_duration {
2322 SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
2323 SCM mus = scm_call_2 (proc, $2, make_input (@$));
2324 scm_gc_protect_object (mus);
2325 $$ = unsmob_music (mus);
2328 | lyric_element optional_notemode_duration {
2329 if (!THIS->lexer_->is_lyric_state ())
2330 THIS->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2332 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2333 lreq->set_property ("text", $1);
2334 lreq->set_property ("duration",$2);
2335 lreq->set_spot (@$);
2336 Music *velt = MY_MAKE_MUSIC ("EventChord");
2337 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2342 if (!THIS->lexer_->is_chord_state ())
2343 THIS->parser_error (@1, _ ("have to be in Chord mode for chords"));
2344 $$ = unsmob_music ($1);
2353 $$ = make_simple_markup ($1);
2358 steno_tonic_pitch optional_notemode_duration {
2359 $$ = make_chord ($1, $2, SCM_EOL);
2361 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2362 SCM its = scm_reverse_x ($4, SCM_EOL);
2363 $$ = make_chord ($1, $2, scm_cons ($3, its));
2371 | chord_items chord_item {
2372 $$ = scm_cons ($2, $$);
2378 $$ = ly_symbol2scm ("chord-colon");
2381 $$ = ly_symbol2scm ("chord-caret");
2383 | CHORD_SLASH steno_tonic_pitch {
2384 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2386 | CHORD_BASS steno_tonic_pitch {
2387 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2396 $$ = scm_reverse_x ($1, SCM_EOL);
2404 step_number { $$ = scm_cons ($1, SCM_EOL); }
2405 | step_numbers '.' step_number {
2406 $$ = scm_cons ($3, $$);
2412 $$ = make_chord_step ($1, 0);
2414 | bare_unsigned '+' {
2415 $$ = make_chord_step ($1, SHARP);
2417 | bare_unsigned CHORD_MINUS {
2418 $$ = make_chord_step ($1, FLAT);
2425 TODO: should deprecate in favor of Scheme?
2429 number_expression '+' number_term {
2430 $$ = scm_sum ($1, $3);
2432 | number_expression '-' number_term {
2433 $$ = scm_difference ($1, $3);
2442 | number_factor '*' number_factor {
2443 $$ = scm_product ($1, $3);
2445 | number_factor '/' number_factor {
2446 $$ = scm_divide ($1, $3);
2451 '-' number_factor { /* %prec UNARY_MINUS */
2452 $$ = scm_difference ($2, SCM_UNDEFINED);
2460 $$ = scm_int2num ($1);
2465 | NUMBER_IDENTIFIER {
2468 | REAL NUMBER_IDENTIFIER {
2469 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2471 | UNSIGNED NUMBER_IDENTIFIER {
2472 $$ = scm_make_real ($1 *scm_to_double ($2));
2488 if (scm_integer_p ($1) == SCM_BOOL_T)
2490 int k = scm_to_int ($1);
2494 THIS->parser_error (@1, _ ("need integer number arg"));
2505 | exclamations '!' { $$ ++; }
2510 | questions '?' { $$ ++; }
2514 This should be done more dynamically if possible.
2518 LYRIC_MARKUP_IDENTIFIER {
2522 { THIS->lexer_->push_markup_state (); }
2525 THIS->lexer_->pop_state ();
2534 { THIS->lexer_->push_markup_state (); }
2537 THIS->lexer_->pop_state ();
2543 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
2545 | markup_head_1_list simple_markup {
2546 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2554 markup_composed_list {
2557 | markup_braced_list {
2562 markup_composed_list:
2563 markup_head_1_list markup_braced_list {
2564 $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
2570 '{' markup_braced_list_body '}' {
2571 $$ = scm_reverse_x ($2, SCM_EOL);
2575 markup_braced_list_body:
2576 /* empty */ { $$ = scm_list (SCM_EOL); }
2577 | markup_braced_list_body markup {
2578 $$ = scm_cons ($2, $1);
2580 | markup_braced_list_body markup_list {
2581 $$ = scm_append_x (scm_list_2 (scm_reverse_x ($2, SCM_EOL), $1));
2586 MARKUP_HEAD_MARKUP0 {
2587 $$ = scm_list_1 ($1);
2589 | MARKUP_HEAD_SCM0_MARKUP1 embedded_scm {
2590 $$ = scm_list_2 ($1, $2);
2592 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm {
2593 $$ = scm_list_3 ($1, $2, $3);
2598 markup_head_1_item {
2599 $$ = scm_list_1 ($1);
2601 | markup_head_1_list markup_head_1_item {
2602 $$ = scm_cons ($2, $1);
2608 $$ = make_simple_markup ($1);
2610 | MARKUP_IDENTIFIER {
2613 | LYRIC_MARKUP_IDENTIFIER {
2616 | STRING_IDENTIFIER {
2620 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2621 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2622 } '{' score_body '}' {
2624 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());
2625 scm_gc_unprotect_object (sc->self_scm ());
2626 THIS->lexer_->pop_state ();
2628 | MARKUP_HEAD_SCM0 embedded_scm {
2629 $$ = scm_list_2 ($1, $2);
2631 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2632 $$ = scm_list_4 ($1, $2, $3, $4);
2634 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2635 $$ = scm_list_3 ($1, $2, $3);
2637 | MARKUP_HEAD_EMPTY {
2638 $$ = scm_list_1 ($1);
2640 | MARKUP_HEAD_LIST0 markup_list {
2641 $$ = scm_list_2 ($1,$2);
2643 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2644 $$ = scm_list_3 ($1, $2, $3);
2649 markup_head_1_list simple_markup {
2650 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2660 Lily_parser::set_yydebug (bool )
2668 Lily_parser::do_yyparse ()
2670 yyparse ((void*)this);
2674 /* FIXME: Should make this optional? It will also complain at
2678 which is entirely legitimate.
2680 Or we can scrap it. Barchecks should detect wrong durations, and
2681 skipTypesetting speeds it up a lot. */
2684 Lily_parser::beam_check (SCM dur)
2686 Duration *d = unsmob_duration (dur);
2687 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2689 Music *m = unsmob_music (last_beam_start_);
2690 m->origin ()->warning (_f ("suspect duration in beam: %s",
2693 last_beam_start_ = SCM_EOL;
2701 It is a little strange to have this function in this file, but
2702 otherwise, we have to import music classes into the lexer.
2706 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2708 if (scm_is_string (sid)) {
2710 return STRING_IDENTIFIER;
2711 } else if (scm_is_number (sid)) {
2713 return NUMBER_IDENTIFIER;
2714 } else if (unsmob_context_def (sid)) {
2715 *destination = unsmob_context_def (sid)->clone_scm ();
2716 return CONTEXT_DEF_IDENTIFIER;
2717 } else if (unsmob_score (sid)) {
2718 Score *score = new Score (*unsmob_score (sid));
2719 *destination = score->self_scm ();
2720 return SCORE_IDENTIFIER;
2721 } else if (Music *mus = unsmob_music (sid)) {
2722 mus = mus->clone ();
2723 *destination = mus->self_scm ();
2724 unsmob_music (*destination)->
2725 set_property ("origin", make_input (last_input_));
2726 return dynamic_cast<Event*> (mus)
2727 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2728 } else if (unsmob_duration (sid)) {
2729 *destination = unsmob_duration (sid)->smobbed_copy ();
2730 return DURATION_IDENTIFIER;
2731 } else if (unsmob_output_def (sid)) {
2732 Output_def *p = unsmob_output_def (sid);
2735 *destination = p->self_scm ();
2736 return OUTPUT_DEF_IDENTIFIER;
2737 } else if (Text_interface::markup_p (sid)) {
2739 if (is_lyric_state ())
2740 return LYRIC_MARKUP_IDENTIFIER;
2741 return MARKUP_IDENTIFIER;
2748 property_op_to_music (SCM op)
2751 SCM tag = scm_car (op);
2752 SCM symbol = scm_cadr (op);
2753 SCM args = scm_cddr (op);
2754 SCM grob_val = SCM_UNDEFINED;
2755 SCM grob_sym = SCM_UNDEFINED;
2756 SCM val = SCM_UNDEFINED;
2758 if (tag == ly_symbol2scm ("assign"))
2760 m = MY_MAKE_MUSIC ("PropertySet");
2761 val = scm_car (args);
2763 else if (tag == ly_symbol2scm ("unset"))
2764 m = MY_MAKE_MUSIC ("PropertyUnset");
2765 else if (tag == ly_symbol2scm ("poppush")
2766 || tag == ly_symbol2scm ("push"))
2768 m = MY_MAKE_MUSIC ("OverrideProperty");
2769 grob_sym = scm_car (args);
2770 grob_val = scm_cadr (args);
2772 else if (tag == ly_symbol2scm ("pop")) {
2773 m = MY_MAKE_MUSIC ("RevertProperty");
2774 grob_sym = scm_car (args);
2777 m->set_property ("symbol", symbol);
2779 if (val != SCM_UNDEFINED)
2780 m->set_property ("value", val);
2781 if (grob_val != SCM_UNDEFINED)
2782 m->set_property ("grob-value", grob_val);
2784 if (grob_sym != SCM_UNDEFINED)
2786 bool itc = do_internal_type_checking_global;
2789 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2791 do_internal_type_checking_global = false;
2792 m->set_property ("grob-property", grob_sym);
2794 do_internal_type_checking_global = itc;
2797 if (tag == ly_symbol2scm ("poppush"))
2798 m->set_property ("pop-first", SCM_BOOL_T);
2805 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2807 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2809 csm->set_property ("element", m->self_scm ());
2810 scm_gc_unprotect_object (m->self_scm ());
2812 csm->set_property ("context-type",
2813 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2814 csm->set_property ("property-operations", ops);
2816 if (scm_is_string (id))
2817 csm->set_property ("context-id", id);
2822 get_next_unique_context_id ()
2824 return scm_makfrom0str ("$uniqueContextId");
2829 get_next_unique_lyrics_context_id ()
2831 static int new_context_count;
2833 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2834 return scm_makfrom0str (s);