1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for LilyPond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2004 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 "music-list.hh"
40 #include "music-sequence.hh"
41 #include "lily-lexer.hh"
42 #include "lily-parser.hh"
43 #include "paper-book.hh"
44 #include "output-def.hh"
45 #include "scm-hash.hh"
46 #include "scm-option.hh"
48 #include "text-item.hh"
51 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
53 Music *property_op_to_music (SCM op);
54 Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
55 SCM get_next_unique_context_id ();
56 SCM get_next_unique_lyrics_context_id ();
58 #define YYERROR_VERBOSE 1
60 #define YYPARSE_PARAM my_lily_parser
61 #define YYLEX_PARAM my_lily_parser
63 ((Lily_parser *) my_lily_parser)
65 #define yyerror THIS->parser_error
67 /* We use custom location type: Input objects */
69 #define YYLLOC_DEFAULT(Current,Rhs,N) \
70 ((Current).set_location ((Rhs)[1], (Rhs)[N]))
73 /* Add symbols to the TAGS field of a music object. */
76 tag_music (Music *m, SCM tag, Input ip)
78 SCM tags = m->get_property ("tags");
79 if (scm_is_symbol (tag))
80 tags = scm_cons (tag, tags);
81 else if (ly_c_list_p (tag))
82 tags = ly_append2 (tag, tags);
84 ip.warning (_ ("Tag must be symbol or list of symbols."));
86 m->set_property ("tags", tags);
90 is_regular_identifier (SCM id)
92 String str = ly_scm2string (id);
93 char const *s = str.to_str0 ();
102 v = v && isalnum (*s);
110 get_first_context_id (SCM type, Music *m)
112 SCM id = m->get_property ("context-id");
113 if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
114 && scm_is_string (m->get_property ("context-id"))
115 && scm_c_string_length (id) > 0)
123 make_simple_markup (SCM a)
125 SCM simple = ly_lily_module_constant ("simple-markup");
126 return scm_list_2 (simple, a);
132 return t && t == 1 << intlog2 (t);
136 set_music_properties (Music *p, SCM a)
138 for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
139 p->internal_set_property (scm_caar (k), scm_cdar (k));
143 make_chord_step (int step, int alter)
150 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
151 return m.smobbed_copy ();
156 make_chord (SCM pitch, SCM dur, SCM modification_list)
158 SCM chord_ctor = ly_lily_module_constant ("construct-chord");
159 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
160 scm_gc_protect_object (ch);
164 /* Todo: actually also use apply iso. call too ... */
166 ly_input_procedure_p (SCM x)
168 return ly_c_procedure_p (x)
169 || (scm_is_pair (x) && ly_c_procedure_p (scm_car (x)));
173 set_property_music (SCM sym, SCM value)
175 Music *p = MY_MAKE_MUSIC ("PropertySet");
176 p->set_property ("symbol", sym);
177 p->set_property ("value", value);
182 make_music_relative (Pitch start, Music *music)
184 Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
185 relative->set_property ("element", music->self_scm ());
187 Pitch last = music->to_relative_octave (start);
188 if (lily_1_8_relative)
189 music->set_property ("last-pitch", last.smobbed_copy ());
194 make_lyric_combine_music (SCM name, Music *music)
196 Music *combine = MY_MAKE_MUSIC ("NewLyricCombineMusic");
197 combine->set_property ("element", music->self_scm ());
198 combine->set_property ("associated-context", name);
204 /* We use SCMs to do strings, because it saves us the trouble of
205 deleting them. Let's hope that a stack overflow doesnt trigger a move
206 of the parse stack onto the heap. */
212 Output_def *outputdef;
222 yylex (YYSTYPE *s, YYLTYPE *l, void *v)
224 Lily_parser *pars = (Lily_parser*) v;
225 Lily_lexer *lex = pars->lexer_;
227 lex->lexval = (void*) s;
229 lex->prepare_for_next_token ();
230 return lex->yylex ();
239 Three shift/reduce problems:
241 2. \markup identifier.
251 \repeat .. \alternative
254 \repeat { \repeat .. \alternative }
258 \repeat { \repeat } \alternative
275 %token CHORDMODIFIERS
278 %token DOUBLE_ANGLE_OPEN
279 %token DOUBLE_ANGLE_CLOSE
281 %token COMMANDSPANREQUEST
290 %token FIGURE_OPEN FIGURE_CLOSE
291 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
292 %token GROBDESCRIPTIONS
302 %token MULTI_MEASURE_REST
309 %token OVERRIDE SET REVERT
336 /* FIXME: this sucks. The user will get to see these names:
337 syntax error, unexpected E_CHAR:
342 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
343 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
345 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
350 %token <i> E_UNSIGNED
351 %token <id> IDENTIFIER
352 %token <scm> CHORDMODIFIER_PITCH
353 %token <scm> DRUM_PITCH
354 %token <scm> DURATION_IDENTIFIER
355 %token <scm> EVENT_IDENTIFIER
356 %token <scm> MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
357 %token <scm> NOTENAME_PITCH
358 %token <scm> NUMBER_IDENTIFIER
359 %token <scm> OUTPUT_DEF_IDENTIFIER
360 %token <scm> RESTNAME
361 %token <scm> LYRICS_STRING
363 %token <scm> SCORE_IDENTIFIER
365 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
366 %token <scm> TONICNAME_PITCH
367 %token <scm> CHORD_MODIFIER
368 %token <scm> FRACTION
370 %token <scm> MARKUP_HEAD_EMPTY
371 %token <scm> MARKUP_HEAD_MARKUP0
372 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
373 %token <scm> MARKUP_HEAD_SCM0
374 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
375 %token <scm> MARKUP_HEAD_SCM0_SCM1
376 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
377 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
378 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
379 %token <scm> MUSIC_FUNCTION
380 %token <scm> MUSIC_FUNCTION_MUSIC
381 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
382 %token <scm> MUSIC_FUNCTION_SCM
383 %token <scm> MUSIC_FUNCTION_SCM_SCM
384 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
385 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
386 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
387 %token <scm> MUSIC_FUNCTION_MARKUP
388 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
389 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
390 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
391 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
397 %type <book> book_block book_body
398 %type <i> bare_int bare_unsigned
399 %type <i> exclamations questions dots optional_rest
401 %type <i> sub_quotes sup_quotes
402 %type <i> tremolo_type
405 %type <music> Composite_music Simple_music Prefix_composite_music Generic_prefix_music
406 %type <music> Grouped_music_list
407 %type <music> Music Sequential_music Simultaneous_music
408 %type <music> Repeated_music
409 %type <music> command_req
410 %type <music> gen_text_def direction_less_event direction_reqd_event
411 %type <music> music_property_def context_change
412 %type <music> note_chord_element chord_body chord_body_element
413 %type <music> post_event tagged_post_event
414 %type <music> relative_music re_rhythmed_music
415 %type <music> simple_element event_chord command_element
416 %type <music> string_number_event
417 %type <music> toplevel_music
418 %type <music> tempo_event
420 %type <outputdef> output_def_body output_def_head
421 %type <outputdef> output_def paper_block
423 %type <scm> Music_list
424 %type <scm> chord_body_elements
425 %type <scm> chord_item chord_items chord_separator new_chord
426 %type <scm> context_def_spec_block context_def_spec_body
427 %type <scm> context_mod context_def_mod optional_context_mod
428 %type <scm> context_prop_spec
429 %type <scm> direction_less_char
430 %type <scm> duration_length fraction
431 %type <scm> embedded_scm scalar
432 %type <scm> identifier_init
433 %type <scm> lilypond_header lilypond_header_body
434 %type <scm> new_lyrics
435 %type <scm> post_events
436 %type <scm> property_operation
437 %type <scm> script_abbreviation
438 %type <scm> simple_string
439 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
440 %type <scm> steno_tonic_pitch
441 %type <scm> step_number step_numbers
442 %type <scm> string bare_number number_expression number_term number_factor
443 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
444 %type <scm> context_mod_list
445 %type <scm> octave_check
446 %type <scm> steno_duration optional_notemode_duration multiplied_duration
447 %type <scm> Generic_prefix_music_scm
448 %type <scm> lyric_element
449 %type <scm> Alternative_music
450 %type <scm> full_markup markup_list markup_composed_list markup_braced_list markup_braced_list_body
451 %type <scm> markup_head_1_item markup_head_1_list markup simple_markup markup_top
452 %type <scm> mode_changing_head
453 %type <scm> mode_changing_head_with_context
454 %type <scm> object_id_setting
456 %type <score> score_block score_body
461 /* We don't assign precedence to / and *, because we might need varied
462 prec levels in different prods */
468 lilypond: /* empty */
469 | lilypond toplevel_expression {
471 | lilypond assignment {
474 THIS->error_level_ = 1;
477 THIS->error_level_ = 1;
483 OBJECTID STRING { $$ = $2; }
488 THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1);
495 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
496 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
497 scm_gc_unprotect_object (book->self_scm ());
502 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
503 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
504 scm_gc_unprotect_object (score->self_scm ());
508 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
509 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
510 scm_gc_unprotect_object (music->self_scm ());
514 Output_def * od = $1;
516 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
517 id = ly_symbol2scm ("$defaultpaper");
518 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
519 id = ly_symbol2scm ("$defaultmidi");
520 else if ($1->c_variable ("is-layout") == SCM_BOOL_T)
521 id = ly_symbol2scm ("$defaultlayout");
523 THIS->lexer_->set_identifier (id, od->self_scm ());
524 scm_gc_unprotect_object (od->self_scm ());
539 lilypond_header_body:
541 $$ = ly_make_anonymous_module (be_safe_global);
542 THIS->lexer_->add_scope ($$);
544 | lilypond_header_body assignment {
550 HEADER '{' lilypond_header_body '}' {
551 $$ = THIS->lexer_->remove_scope ();
560 STRING '=' identifier_init {
561 if (! is_regular_identifier ($1))
563 @1.warning (_ ("Identifier should have alphabetic characters only"));
566 THIS->lexer_->set_identifier ($1, $3);
569 TODO: devise standard for protection in parser.
571 The parser stack lives on the C-stack, which means that
572 all objects can be unprotected as soon as they're here.
582 $$ = $1->self_scm ();
583 scm_gc_unprotect_object ($$);
586 $$ = $1->self_scm ();
587 scm_gc_unprotect_object ($$);
589 | context_def_spec_block {
593 $$ = $1->self_scm ();
594 scm_gc_unprotect_object ($$);
597 $$ = $1->self_scm ();
598 scm_gc_unprotect_object ($$);
600 | number_expression {
613 $$ = scm_int2num ($1);
617 context_def_spec_block:
618 CONTEXT '{' context_def_spec_body '}'
624 context_def_spec_body:
626 $$ = Context_def::make_scm ();
627 unsmob_context_def ($$)->set_spot (@$);
629 | CONTEXT_DEF_IDENTIFIER {
631 unsmob_context_def ($$)->set_spot (@$);
633 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
634 Context_def*td = unsmob_context_def ($$);
636 for (SCM p = $3; scm_is_pair (p); p = scm_cdr (p)) {
637 SCM tag = scm_caar (p);
639 /* TODO: should make new tag "grob-definition" ? */
640 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
641 tag, scm_cons (scm_cdar (p), SCM_EOL)));
644 | context_def_spec_body context_mod {
645 unsmob_context_def ($$)->add_context_mod ($2);
652 BOOK '{' book_body '}' {
658 * Use 'handlers' like for toplevel-* stuff?
659 * grok \layout and \midi? */
664 $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
665 scm_gc_unprotect_object ($$->paper_->self_scm ());
666 $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader");
668 | book_body paper_block {
670 scm_gc_unprotect_object ($2->self_scm ());
672 | book_body score_block {
674 $$->add_score (score);
676 | book_body lilypond_header {
683 | book_body object_id_setting {
684 $$->user_key_ = ly_scm2string ($2);
689 SCORE '{' score_body '}' {
700 $$ = new Score ( *unsmob_score ($1));
703 | score_body object_id_setting {
704 $$->user_key_ = ly_scm2string ($2);
707 SCM m = $2->self_scm ();
708 scm_gc_unprotect_object (m);
709 $$->set_music (m, THIS->self_scm ());
711 | score_body lilypond_header {
714 | score_body output_def {
715 if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
717 THIS->parser_error (@2, _("\\paper cannot be in \\score. Use \\layout instead"));
724 scm_gc_unprotect_object ($2->self_scm ());
727 $$->error_found_ = true;
739 if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
741 THIS->parser_error (@1, _("Need \\paper for paper block."));
742 $$ = get_paper (THIS);
749 output_def_body '}' {
752 THIS->lexer_->remove_scope ();
753 THIS->lexer_->pop_state ();
759 $$ = get_paper (THIS);
760 $$->input_origin_ = @$;
761 THIS->lexer_->add_scope ($$->scope_);
764 Output_def *p = get_midi (THIS);
766 THIS->lexer_->add_scope (p->scope_);
769 Output_def *p = get_layout (THIS);
771 THIS->lexer_->add_scope (p->scope_);
778 output_def_head '{' {
780 $$->input_origin_.set_spot (@$);
781 THIS->lexer_->push_initial_state ();
783 | output_def_head '{' OUTPUT_DEF_IDENTIFIER {
784 scm_gc_unprotect_object ($1->self_scm ());
785 Output_def *o = unsmob_output_def ($3);
786 o->input_origin_.set_spot (@$);
788 THIS->lexer_->remove_scope ();
789 THIS->lexer_->add_scope (o->scope_);
790 THIS->lexer_->push_initial_state ();
792 | output_def_body assignment {
795 | output_def_body context_def_spec_block {
796 assign_context_def ($$, $2);
798 | output_def_body tempo_event {
800 junk this ? there already is tempo stuff in
803 int m = scm_to_int ($2->get_property ("metronome-count"));
804 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
805 set_tempo ($$, d->get_length (), m);
806 scm_gc_unprotect_object ($2->self_scm ());
808 | output_def_body error {
814 TEMPO steno_duration '=' bare_unsigned {
815 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
816 $$->set_property ("tempo-unit", $2);
817 $$->set_property ("metronome-count", scm_int2num ( $4));
822 The representation of a list is the
826 to have efficient append. */
830 $$ = scm_cons (SCM_EOL, SCM_EOL);
834 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
835 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
837 if (scm_is_pair (scm_cdr (s)))
838 scm_set_cdr_x (scm_cdr (s), c); /* append */
840 scm_set_car_x (s, c); /* set first cons */
841 scm_set_cdr_x (s, c); /* remember last cell */
843 | Music_list embedded_scm {
847 Music * m = MY_MAKE_MUSIC("Music");
849 m->set_property ("error-found", SCM_BOOL_T);
851 SCM c = scm_cons (m->self_scm (), SCM_EOL);
852 scm_gc_unprotect_object (m->self_scm ()); /* UGH */
854 if (scm_is_pair (scm_cdr (s)))
855 scm_set_cdr_x (scm_cdr (s), c); /* append */
857 scm_set_car_x (s, c); /* set first cons */
858 scm_set_cdr_x (s, c); /* remember last cell */
871 | ALTERNATIVE '{' Music_list '}' {
878 REPEAT simple_string bare_unsigned Music Alternative_music
882 SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
883 if (times < scm_ilength (alts)) {
884 unsmob_music (scm_car (alts))
885 ->origin ()->warning (
886 _ ("More alternatives than repeats. Junking excess alternatives."));
887 alts = ly_truncate_list (times, alts);
891 SCM proc = ly_lily_module_constant ("make-repeated-music");
893 SCM mus = scm_call_1 (proc, $2);
894 scm_gc_protect_object (mus); // UGH.
895 Music *r = unsmob_music (mus);
898 r-> set_property ("element", beg->self_scm ());
899 scm_gc_unprotect_object (beg->self_scm ());
901 r->set_property ("repeat-count", scm_int2num (times >? 1));
903 r-> set_property ("elements",alts);
904 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
906 TODO: move this code to Scheme.
910 we can not get durations and other stuff correct down the line, so we have to
911 add to the duration log here.
913 SCM func = ly_lily_module_constant ("shift-duration-log");
915 int dots = ($3 % 3) ? 0 : 1;
916 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
919 if ($4->is_mus_type ("sequential-music"))
921 int list_len = scm_ilength ($4->get_property ("elements"));
923 seq->origin ()->warning ("Chord tremolo must have 2 elements.");
925 r->compress (Moment (Rational (1, list_len)));
927 scm_call_3 (func, r->self_scm (), scm_int2num (shift), scm_int2num (dots));
930 r->set_spot (*$4->origin ());
937 SEQUENTIAL '{' Music_list '}' {
938 $$ = MY_MAKE_MUSIC ("SequentialMusic");
939 $$->set_property ("elements", scm_car ($3));
942 | '{' Music_list '}' {
943 $$ = MY_MAKE_MUSIC ("SequentialMusic");
944 $$->set_property ("elements", scm_car ($2));
950 SIMULTANEOUS '{' Music_list '}'{
951 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
952 $$->set_property ("elements", scm_car ($3));
956 | simul_open Music_list simul_close {
957 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
958 $$->set_property ("elements", scm_car ($2));
964 event_chord { $$ = $1; }
966 $$ = unsmob_music ($1);
973 optional_context_mod:
974 /**/ { $$ = SCM_EOL; }
975 | WITH { THIS->lexer_->push_initial_state (); }
976 '{' context_mod_list '}'
978 THIS->lexer_->pop_state ();
984 /* */ { $$ = SCM_EOL; }
985 | context_mod_list context_mod {
986 $$ = scm_cons ($2, $1);
992 Prefix_composite_music { $$ = $1; }
993 | Grouped_music_list { $$ = $1; }
997 Simultaneous_music { $$ = $1; }
998 | Sequential_music { $$ = $1; }
1001 Generic_prefix_music_scm:
1003 $$ = scm_list_2 ($1, make_input (@$));
1005 | MUSIC_FUNCTION_SCM embedded_scm {
1006 $$ = scm_list_3 ($1, make_input (@$), $2);
1008 | MUSIC_FUNCTION_MARKUP full_markup {
1009 $$ = scm_list_3 ($1, make_input (@$), $2);
1011 | MUSIC_FUNCTION_MUSIC Music {
1012 $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
1013 scm_gc_unprotect_object ($2->self_scm ());
1015 | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
1016 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1017 scm_gc_unprotect_object ($3->self_scm ());
1019 | MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
1020 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1022 | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
1023 $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
1025 | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
1026 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1027 scm_gc_unprotect_object ($3->self_scm ());
1029 | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
1030 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1032 | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
1033 $$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
1034 scm_gc_unprotect_object ($2->self_scm ());
1035 scm_gc_unprotect_object ($3->self_scm ());
1037 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
1038 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1039 scm_gc_unprotect_object ($4->self_scm ());
1040 scm_gc_unprotect_object ($3->self_scm ());
1042 | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
1043 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1044 scm_gc_unprotect_object ($3->self_scm ());
1045 scm_gc_unprotect_object ($4->self_scm ());
1049 Generic_prefix_music:
1050 Generic_prefix_music_scm {
1051 SCM func = scm_car ($1);
1052 Input *loc = unsmob_input (scm_cadr ($1));
1053 SCM args = scm_cddr ($1);
1054 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1056 SCM type_check_proc = ly_lily_module_constant ("type-check-list");
1059 if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr ($1), sig, args)))
1061 THIS->error_level_ = 1;
1067 m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
1070 if (unsmob_music (m))
1072 $$ = unsmob_music (m);
1073 scm_gc_protect_object (m);
1078 loc->error (_ ("Music head function should return Music object."));
1079 $$ = MY_MAKE_MUSIC ("Music");
1081 $$->set_spot (*loc);
1086 Prefix_composite_music:
1087 Generic_prefix_music {
1090 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1091 $$ = context_spec_music ($2, $4, $6, $5);
1094 | CONTEXT simple_string optional_context_mod Music {
1095 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1097 | NEWCONTEXT simple_string optional_context_mod Music {
1098 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1102 | TIMES fraction Music
1105 int n = scm_to_int (scm_car ($2)); int d = scm_to_int (scm_cdr ($2));
1108 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1111 $$->set_property ("element", mp->self_scm ());
1112 scm_gc_unprotect_object (mp->self_scm ());
1113 $$->set_property ("numerator", scm_int2num (n));
1114 $$->set_property ("denominator", scm_int2num (d));
1115 $$->compress (Moment (Rational (n,d)));
1118 | Repeated_music { $$ = $1; }
1119 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1120 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1122 Pitch from = *unsmob_pitch ($2);
1123 Pitch to = *unsmob_pitch ($3);
1125 p->transpose (pitch_interval (from, to));
1126 $$->set_property ("element", p->self_scm ());
1127 scm_gc_unprotect_object (p->self_scm ());
1129 | mode_changing_head Grouped_music_list {
1130 if ($1 == ly_symbol2scm ("chords"))
1132 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1133 chm->set_property ("element", $2->self_scm ());
1135 scm_gc_unprotect_object ($2->self_scm ());
1141 THIS->lexer_->pop_state ();
1143 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1144 $$ = context_spec_music ($1, get_next_unique_context_id (),
1146 if ($1 == ly_symbol2scm ("ChordNames"))
1148 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1149 chm->set_property ("element", $$->self_scm ());
1150 scm_gc_unprotect_object ($$->self_scm ());
1153 THIS->lexer_->pop_state ();
1155 | relative_music { $$ = $1; }
1156 | re_rhythmed_music { $$ = $1; }
1157 | TAG embedded_scm Music {
1158 tag_music ($3, $2, @$);
1165 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1166 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1168 $$ = ly_symbol2scm ("notes");
1172 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1173 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1175 $$ = ly_symbol2scm ("drums");
1178 THIS->lexer_->push_figuredbass_state ();
1180 $$ = ly_symbol2scm ("figures");
1183 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1184 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1185 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1186 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1187 $$ = ly_symbol2scm ("chords");
1191 { THIS->lexer_->push_lyric_state ();
1192 $$ = ly_symbol2scm ("lyrics");
1196 mode_changing_head_with_context:
1198 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1199 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1201 $$ = ly_symbol2scm ("DrumStaff");
1204 THIS->lexer_->push_figuredbass_state ();
1206 $$ = ly_symbol2scm ("FiguredBass");
1209 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1210 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1211 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1212 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1213 $$ = ly_symbol2scm ("ChordNames");
1216 { THIS->lexer_->push_lyric_state ();
1217 $$ = ly_symbol2scm ("Lyrics");
1223 RELATIVE absolute_pitch Music {
1225 Pitch start = *unsmob_pitch ($2);
1226 $$ = make_music_relative (start, m);
1227 scm_gc_unprotect_object (m->self_scm ());
1229 | RELATIVE Composite_music {
1232 Pitch middle_c (0, 0, 0);
1233 $$ = make_music_relative (middle_c, m);
1234 scm_gc_unprotect_object (m->self_scm ());
1239 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1241 Grouped_music_list {
1242 /* Can also use Music at the expensive of two S/Rs similar to
1243 \repeat \alternative */
1244 THIS->lexer_->pop_state ();
1246 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1248 | new_lyrics ADDLYRICS {
1249 THIS->lexer_->push_lyric_state ();
1250 } Grouped_music_list {
1251 THIS->lexer_->pop_state ();
1252 $$ = scm_cons ($4->self_scm (), $1);
1257 Grouped_music_list new_lyrics {
1259 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1260 if (!scm_is_string (name))
1262 name = get_next_unique_lyrics_context_id ();
1263 voice = context_spec_music (scm_makfrom0str ("Voice"),
1268 SCM context = scm_makfrom0str ("Lyrics");
1269 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1272 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1274 Music *music = unsmob_music (scm_car (s));
1275 Music *com = make_lyric_combine_music (name, music);
1276 Music *csm = context_spec_music (context,
1277 get_next_unique_context_id (), com, SCM_EOL);
1278 lst = scm_cons (csm->self_scm (), lst);
1280 all->set_property ("elements", scm_cons (voice->self_scm (),
1283 scm_gc_unprotect_object (voice->self_scm ());
1286 THIS->lexer_->push_lyric_state ();
1287 } simple_string Music {
1288 THIS->lexer_->pop_state ();
1291 $$ = make_lyric_combine_music (name, music);
1292 scm_gc_unprotect_object (music->self_scm ());
1297 CHANGE STRING '=' STRING {
1298 Music*t = MY_MAKE_MUSIC ("ContextChange");
1299 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1300 t-> set_property ("change-to-id", $4);
1309 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1310 scm_string_to_symbol ($1), $3);
1312 | UNSET simple_string {
1313 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1314 scm_string_to_symbol ($2));
1316 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1317 $$ = scm_list_4 (ly_symbol2scm ("push"),
1318 scm_string_to_symbol ($2), $3, $5);
1320 | REVERT simple_string embedded_scm {
1321 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1322 scm_string_to_symbol ($2), $3);
1327 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1328 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1330 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1331 | DENIES { $$ = ly_symbol2scm ("denies"); }
1333 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1334 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1335 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1336 | NAME { $$ = ly_symbol2scm ("context-name"); }
1340 property_operation { $$ = $1; }
1341 | context_def_mod STRING {
1342 $$ = scm_list_2 ($1, $2);
1348 if (!is_regular_identifier ($1))
1350 @$.error (_("Grob name should be alphanumeric"));
1353 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1354 scm_string_to_symbol ($1));
1356 | simple_string '.' simple_string {
1357 $$ = scm_list_2 (scm_string_to_symbol ($1),
1358 scm_string_to_symbol ($3));
1363 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1364 $$ = property_op_to_music (scm_list_4 (
1365 ly_symbol2scm ("poppush"),
1368 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1370 | REVERT context_prop_spec embedded_scm {
1371 $$ = property_op_to_music (scm_list_3 (
1372 ly_symbol2scm ("pop"),
1376 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1378 | SET context_prop_spec '=' scalar {
1379 $$ = property_op_to_music (scm_list_3 (
1380 ly_symbol2scm ("assign"),
1383 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1385 | UNSET context_prop_spec {
1386 $$ = property_op_to_music (scm_list_2 (
1387 ly_symbol2scm ("unset"),
1389 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1391 | ONCE music_property_def {
1392 SCM e = $2->get_property ("element");
1393 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1404 | STRING_IDENTIFIER {
1407 | string '+' string {
1408 $$ = scm_string_append (scm_list_2 ($1, $3));
1412 simple_string: STRING {
1427 $$ = scm_int2num ($1);
1436 $$ = scm_int2num ($1);
1442 pre_events doesn't contain anything. It is a trick:
1444 Adding pre_events to the simple_element
1445 makes the choice between
1451 simple_element: STRING
1453 a single shift/reduction conflict.
1455 nevertheless, this is not very clean, and we should find a different
1459 pre_events: /* empty */
1463 pre_events simple_element post_events {
1464 SCM elts = $2-> get_property ("elements");
1466 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1468 $2->set_property ("elements", elts);
1469 /* why is this giving wrong start location? -ns
1470 * $2->set_spot (@$); */
1472 i.set_location (@2, @3);
1477 | note_chord_element
1482 chord_body optional_notemode_duration post_events
1484 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1485 SCM es = $1->get_property ("elements");
1486 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1488 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1489 unsmob_music (scm_car (s))->set_property ("duration", dur);
1490 es = ly_append2 (es, postevs);
1492 $1-> set_property ("elements", es);
1504 simul_open: DOUBLE_ANGLE_OPEN
1507 simul_close: DOUBLE_ANGLE_CLOSE
1511 chord_open chord_body_elements chord_close
1513 $$ = MY_MAKE_MUSIC ("EventChord");
1515 $$->set_property ("elements",
1516 scm_reverse_x ($2, SCM_EOL));
1520 chord_body_elements:
1521 /* empty */ { $$ = SCM_EOL; }
1522 | chord_body_elements chord_body_element {
1523 $$ = scm_cons ($2->self_scm (), $1);
1524 scm_gc_unprotect_object ($2->self_scm ());
1529 pitch exclamations questions octave_check post_events
1536 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1537 n->set_property ("pitch", $1);
1540 n->set_property ("cautionary", SCM_BOOL_T);
1541 if (ex % 2 || q % 2)
1542 n->set_property ("force-accidental", SCM_BOOL_T);
1544 if (scm_is_pair (post)) {
1545 SCM arts = scm_reverse_x (post, SCM_EOL);
1546 n->set_property ("articulations", arts);
1548 if (scm_is_number (check))
1550 int q = scm_to_int (check);
1551 n->set_property ("absolute-octave", scm_int2num (q-1));
1557 | DRUM_PITCH post_events {
1558 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1559 n->set_property ("duration", $2);
1560 n->set_property ("drum-type", $1);
1563 if (scm_is_pair ($2)) {
1564 SCM arts = scm_reverse_x ($2, SCM_EOL);
1565 n->set_property ("articulations", arts);
1572 ADDQUOTE string Music {
1573 SCM adder = ly_lily_module_constant ("add-quotable");
1575 scm_call_2 (adder, $2, $3->self_scm ());
1576 scm_gc_unprotect_object ($3->self_scm ());
1582 $$ = MY_MAKE_MUSIC ("EventChord");
1583 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1584 scm_gc_unprotect_object ($1->self_scm ());
1589 | SKIP duration_length {
1590 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1591 skip->set_property ("duration", $2);
1592 skip->set_spot (@$);
1596 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1599 $$->set_property ("pitch", $2);
1602 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1603 m->set_property ("span-direction", scm_int2num (START));
1606 $$ = MY_MAKE_MUSIC ("EventChord");
1607 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1608 scm_gc_unprotect_object (m->self_scm ());
1612 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1613 m->set_property ("span-direction", scm_int2num (STOP));
1616 $$ = MY_MAKE_MUSIC ("EventChord");
1617 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1619 scm_gc_unprotect_object (m->self_scm ());
1622 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1626 SCM pipe = THIS->lexer_->lookup_identifier ("pipeSymbol");
1628 if (Music * m = unsmob_music (pipe))
1631 $$ = MY_MAKE_MUSIC ("BarCheck");
1635 | TRANSPOSITION pitch {
1637 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1638 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1639 sounds_as_c.smobbed_copy());
1641 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1645 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1647 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1649 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1653 | PARTIAL duration_length {
1654 Moment m = - unsmob_duration ($2)->get_length ();
1655 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1657 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1659 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1664 SCM proc = ly_lily_module_constant ("make-clef-set");
1666 SCM result = scm_call_1 (proc, $2);
1667 scm_gc_protect_object (result);
1668 $$ = unsmob_music (result);
1671 SCM proc = ly_lily_module_constant ("make-time-signature-set");
1673 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1674 scm_gc_protect_object (result);
1675 $$ = unsmob_music (result);
1678 SCM proc = ly_lily_module_constant ("make-mark-set");
1680 SCM result = scm_call_1 (proc, $2);
1681 scm_gc_protect_object (result);
1682 $$ = unsmob_music (result);
1688 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1691 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1698 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1701 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1703 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1704 if (scm_ilength ($3) > 0)
1706 key->set_property ("pitch-alist", $3);
1707 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1708 key->transpose (* unsmob_pitch ($2));
1710 THIS->parser_error (@3, _ ("Second argument must be pitch list."));
1722 | post_events post_event {
1724 $$ = scm_cons ($2->self_scm (), $$);
1725 scm_gc_unprotect_object ($2->self_scm ());
1727 | post_events tagged_post_event {
1728 $2 -> set_spot (@2);
1729 $$ = scm_cons ($2->self_scm (), $$);
1730 scm_gc_unprotect_object ($2->self_scm ());
1736 '-' TAG embedded_scm post_event {
1737 tag_music ($4, $3, @$);
1744 direction_less_event {
1748 if (!THIS->lexer_->is_lyric_state ())
1749 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
1750 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1753 if (!THIS->lexer_->is_lyric_state ())
1754 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
1755 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1757 | script_dir direction_reqd_event {
1759 $2->set_property ("direction", scm_int2num ($1));
1762 | script_dir direction_less_event {
1764 $2->set_property ("direction", scm_int2num ($1));
1767 | string_number_event
1770 string_number_event:
1772 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1773 s->set_property ("string-number", scm_int2num ($1));
1779 direction_less_char:
1781 $$ = ly_symbol2scm ("bracketOpenSymbol");
1784 $$ = ly_symbol2scm ("bracketCloseSymbol");
1787 $$ = ly_symbol2scm ("tildeSymbol");
1790 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1793 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1796 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1799 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1802 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1805 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1808 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1812 direction_less_event:
1813 direction_less_char {
1814 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1816 if (unsmob_music (predefd))
1818 m = unsmob_music (predefd)->clone ();
1822 m = MY_MAKE_MUSIC ("Music");
1827 | EVENT_IDENTIFIER {
1828 $$ = unsmob_music ($1);
1831 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1833 a->set_property ("tremolo-type", scm_int2num ($1));
1838 direction_reqd_event:
1842 | script_abbreviation {
1843 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1844 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1845 if (scm_is_string (s))
1846 a->set_property ("articulation-type", s);
1847 else THIS->parser_error (@1, _ ("Expecting string as script definition"));
1853 /**/ { $$ = SCM_EOL; }
1854 | '=' { $$ = scm_int2num (0); }
1855 | '=' sub_quotes { $$ = scm_int2num ($2); }
1856 | '=' sup_quotes { $$ = scm_int2num ($2); }
1881 | NOTENAME_PITCH sup_quotes {
1882 Pitch p = *unsmob_pitch ($1);
1883 p = p.transposed (Pitch ($2,0,0));
1884 $$ = p.smobbed_copy ();
1886 | NOTENAME_PITCH sub_quotes {
1887 Pitch p =* unsmob_pitch ($1);
1888 p = p.transposed (Pitch (-$2,0,0));
1889 $$ = p.smobbed_copy ();
1901 | TONICNAME_PITCH sup_quotes {
1902 Pitch p = *unsmob_pitch ($1);
1903 p = p.transposed (Pitch ($2,0,0));
1904 $$ = p.smobbed_copy ();
1906 | TONICNAME_PITCH sub_quotes {
1907 Pitch p =* unsmob_pitch ($1);
1909 p = p.transposed (Pitch (-$2,0,0));
1910 $$ = p.smobbed_copy ();
1920 pitch_also_in_chords:
1927 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1928 t->set_property ("text", $1);
1933 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1934 t->set_property ("text",
1935 make_simple_markup ($1));
1941 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1942 t->set_property ("digit", scm_int2num ($1));
1948 script_abbreviation:
1950 $$ = scm_makfrom0str ("Hat");
1953 $$ = scm_makfrom0str ("Plus");
1956 $$ = scm_makfrom0str ("Dash");
1959 $$ = scm_makfrom0str ("Bar");
1962 $$ = scm_makfrom0str ("Larger");
1965 $$ = scm_makfrom0str ("Dot");
1968 $$ = scm_makfrom0str ("Underscore");
1975 | '-' { $$ = CENTER; }
1986 multiplied_duration {
1991 optional_notemode_duration:
1993 Duration dd = THIS->default_duration_;
1994 $$ = dd.smobbed_copy ();
1996 THIS->beam_check ($$);
1998 | multiplied_duration {
2000 THIS->default_duration_ = *unsmob_duration ($$);
2002 THIS->beam_check ($$);
2007 bare_unsigned dots {
2009 if (!is_duration ($1))
2010 THIS->parser_error (@1, _f ("not a duration: %d", $1));
2014 $$ = Duration (len, $2).smobbed_copy ();
2016 | DURATION_IDENTIFIER dots {
2017 Duration *d = unsmob_duration ($1);
2018 Duration k (d->duration_log (), d->dot_count () + $2);
2024 multiplied_duration:
2028 | multiplied_duration '*' bare_unsigned {
2029 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2031 | multiplied_duration '*' FRACTION {
2032 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2034 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2039 FRACTION { $$ = $1; }
2040 | UNSIGNED '/' UNSIGNED {
2041 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2058 | ':' bare_unsigned {
2059 if (!is_duration ($2))
2060 THIS->parser_error (@2, _f ("not a duration: %d", $2));
2067 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2068 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2072 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2073 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2076 | STRING { $$ = $1; }
2087 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2088 $$ = bfr->self_scm ();
2089 scm_gc_unprotect_object ($$);
2092 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2093 $$ = bfr->self_scm ();
2095 bfr->set_property ("figure", $1);
2097 scm_gc_unprotect_object ($$);
2099 | bass_figure bass_mod {
2100 Music *m = unsmob_music ($1);
2102 SCM salter = m->get_property ("alteration");
2103 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2104 m->set_property ("alteration",
2105 scm_int2num (alter + $2));
2107 m->set_property ("alteration", scm_int2num (0));
2115 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2120 | br_bass_figure ']' {
2122 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2130 | figure_list br_bass_figure {
2131 $$ = scm_cons ($2, $1);
2136 FIGURE_OPEN figure_list FIGURE_CLOSE {
2137 Music *m = MY_MAKE_MUSIC ("EventChord");
2138 $2 = scm_reverse_x ($2, SCM_EOL);
2139 m->set_property ("elements", $2);
2140 $$ = m->self_scm ();
2151 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2152 if (!THIS->lexer_->is_note_state ())
2153 THIS->parser_error (@1, _ ("Have to be in Note mode for notes"));
2157 n = MY_MAKE_MUSIC ("RestEvent");
2159 n = MY_MAKE_MUSIC ("NoteEvent");
2161 n->set_property ("pitch", $1);
2162 n->set_property ("duration", $5);
2164 if (scm_is_number ($4))
2166 int q = scm_to_int ($4);
2167 n->set_property ("absolute-octave", scm_int2num (q-1));
2171 n->set_property ("cautionary", SCM_BOOL_T);
2172 if ($2 % 2 || $3 % 2)
2173 n->set_property ("force-accidental", SCM_BOOL_T);
2175 Music *v = MY_MAKE_MUSIC ("EventChord");
2176 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2177 scm_gc_unprotect_object (n->self_scm ());
2183 | DRUM_PITCH optional_notemode_duration {
2184 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2185 n->set_property ("duration", $2);
2186 n->set_property ("drum-type", $1);
2188 Music *v = MY_MAKE_MUSIC ("EventChord");
2189 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2190 scm_gc_unprotect_object (n->self_scm ());
2196 | figure_spec optional_notemode_duration {
2197 Music *m = unsmob_music ($1);
2199 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2201 unsmob_music (scm_car (s))->set_property ("duration", $2);
2205 | RESTNAME optional_notemode_duration {
2207 if (ly_scm2string ($1) == "s") {
2209 ev = MY_MAKE_MUSIC ("SkipEvent");
2212 ev = MY_MAKE_MUSIC ("RestEvent");
2215 ev->set_property ("duration", $2);
2217 Music *velt = MY_MAKE_MUSIC ("EventChord");
2218 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2219 velt->set_spot (@$);
2221 scm_gc_unprotect_object (ev->self_scm ());
2225 | MULTI_MEASURE_REST optional_notemode_duration {
2226 SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
2227 SCM mus = scm_call_2 (proc, $2, make_input (@$));
2228 scm_gc_protect_object (mus);
2229 $$ = unsmob_music (mus);
2232 | lyric_element optional_notemode_duration {
2233 if (!THIS->lexer_->is_lyric_state ())
2234 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
2236 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2237 lreq->set_property ("text", $1);
2238 lreq->set_property ("duration",$2);
2239 lreq->set_spot (@$);
2240 Music *velt = MY_MAKE_MUSIC ("EventChord");
2241 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2246 if (!THIS->lexer_->is_chord_state ())
2247 THIS->parser_error (@1, _ ("Have to be in Chord mode for chords"));
2248 $$ = unsmob_music ($1);
2253 /* FIXME: lyric flavoured markup would be better */
2258 $$ = make_simple_markup ($1);
2263 steno_tonic_pitch optional_notemode_duration {
2264 $$ = make_chord ($1, $2, SCM_EOL);
2266 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2267 SCM its = scm_reverse_x ($4, SCM_EOL);
2268 $$ = make_chord ($1, $2, scm_cons ($3, its));
2276 | chord_items chord_item {
2277 $$ = scm_cons ($2, $$);
2283 $$ = ly_symbol2scm ("chord-colon");
2286 $$ = ly_symbol2scm ("chord-caret");
2288 | CHORD_SLASH steno_tonic_pitch {
2289 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2291 | CHORD_BASS steno_tonic_pitch {
2292 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2301 $$ = scm_reverse_x ($1, SCM_EOL);
2309 step_number { $$ = scm_cons ($1, SCM_EOL); }
2310 | step_numbers '.' step_number {
2311 $$ = scm_cons ($3, $$);
2317 $$ = make_chord_step ($1, 0);
2319 | bare_unsigned '+' {
2320 $$ = make_chord_step ($1, SHARP);
2322 | bare_unsigned CHORD_MINUS {
2323 $$ = make_chord_step ($1, FLAT);
2330 TODO: should deprecate in favor of Scheme?
2334 number_expression '+' number_term {
2335 $$ = scm_sum ($1, $3);
2337 | number_expression '-' number_term {
2338 $$ = scm_difference ($1, $3);
2347 | number_factor '*' number_factor {
2348 $$ = scm_product ($1, $3);
2350 | number_factor '/' number_factor {
2351 $$ = scm_divide ($1, $3);
2356 '-' number_factor { /* %prec UNARY_MINUS */
2357 $$ = scm_difference ($2, SCM_UNDEFINED);
2365 $$ = scm_int2num ($1);
2370 | NUMBER_IDENTIFIER {
2373 | REAL NUMBER_IDENTIFIER {
2374 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2376 | UNSIGNED NUMBER_IDENTIFIER {
2377 $$ = scm_make_real ($1 *scm_to_double ($2));
2393 if (scm_integer_p ($1) == SCM_BOOL_T)
2395 int k = scm_to_int ($1);
2399 THIS->parser_error (@1, _ ("need integer number arg"));
2410 | exclamations '!' { $$ ++; }
2415 | questions '?' { $$ ++; }
2419 This should be done more dynamically if possible.
2427 { THIS->lexer_->push_markup_state (); }
2430 THIS->lexer_->pop_state ();
2436 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
2438 | markup_head_1_list simple_markup {
2439 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2447 markup_composed_list {
2450 | markup_braced_list {
2455 markup_composed_list:
2456 markup_head_1_list markup_braced_list {
2457 $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
2463 '{' markup_braced_list_body '}' {
2464 $$ = scm_reverse_x ($2, SCM_EOL);
2468 markup_braced_list_body:
2469 /* empty */ { $$ = scm_list (SCM_EOL); }
2470 | markup_braced_list_body markup {
2471 $$ = scm_cons ($2, $1);
2473 | markup_braced_list_body markup_list {
2474 $$ = scm_append_x (scm_list_2 (scm_reverse_x ($2, SCM_EOL), $1));
2479 MARKUP_HEAD_MARKUP0 {
2480 $$ = scm_list_1 ($1);
2482 | MARKUP_HEAD_SCM0_MARKUP1 embedded_scm {
2483 $$ = scm_list_2 ($1, $2);
2485 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm {
2486 $$ = scm_list_3 ($1, $2, $3);
2491 markup_head_1_item {
2492 $$ = scm_list_1 ($1);
2494 | markup_head_1_list markup_head_1_item {
2495 $$ = scm_cons ($2, $1);
2501 $$ = make_simple_markup ($1);
2503 | MARKUP_IDENTIFIER {
2506 | STRING_IDENTIFIER {
2510 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2511 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2512 } '{' score_body '}' {
2514 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());
2515 scm_gc_unprotect_object (sc->self_scm ());
2516 THIS->lexer_->pop_state ();
2518 | MARKUP_HEAD_SCM0 embedded_scm {
2519 $$ = scm_list_2 ($1, $2);
2521 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2522 $$ = scm_list_4 ($1, $2, $3, $4);
2524 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2525 $$ = scm_list_3 ($1, $2, $3);
2527 | MARKUP_HEAD_EMPTY {
2528 $$ = scm_list_1 ($1);
2530 | MARKUP_HEAD_LIST0 markup_list {
2531 $$ = scm_list_2 ($1,$2);
2533 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2534 $$ = scm_list_3 ($1, $2, $3);
2539 markup_head_1_list simple_markup {
2540 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2550 Lily_parser::set_yydebug (bool )
2558 Lily_parser::do_yyparse ()
2560 yyparse ((void*)this);
2565 Should make this optional? It will also complain when you do
2569 which is entirely legitimate.
2571 Or we can scrap it. Barchecks should detect wrong durations, and
2572 skipTypesetting speeds it up a lot.
2576 Lily_parser::beam_check (SCM dur)
2578 Duration *d = unsmob_duration (dur);
2579 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2581 Music *m = unsmob_music (last_beam_start_);
2582 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2584 last_beam_start_ = SCM_EOL;
2592 It is a little strange to have this function in this file, but
2593 otherwise, we have to import music classes into the lexer.
2597 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2599 if (scm_is_string (sid)) {
2601 return STRING_IDENTIFIER;
2602 } else if (scm_is_number (sid)) {
2604 return NUMBER_IDENTIFIER;
2605 } else if (unsmob_context_def (sid)) {
2606 *destination = unsmob_context_def (sid)->clone_scm ();
2607 return CONTEXT_DEF_IDENTIFIER;
2608 } else if (unsmob_score (sid)) {
2609 Score *score = new Score (*unsmob_score (sid));
2610 *destination = score->self_scm ();
2611 return SCORE_IDENTIFIER;
2612 } else if (Music *mus = unsmob_music (sid)) {
2613 mus = mus->clone ();
2614 *destination = mus->self_scm ();
2615 unsmob_music (*destination)->
2616 set_property ("origin", make_input (last_input_));
2617 return dynamic_cast<Event*> (mus)
2618 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2619 } else if (unsmob_duration (sid)) {
2620 *destination = unsmob_duration (sid)->smobbed_copy ();
2621 return DURATION_IDENTIFIER;
2622 } else if (unsmob_output_def (sid)) {
2623 Output_def *p = unsmob_output_def (sid);
2626 *destination = p->self_scm ();
2627 return OUTPUT_DEF_IDENTIFIER;
2628 } else if (Text_interface::markup_p (sid)) {
2630 return MARKUP_IDENTIFIER;
2637 property_op_to_music (SCM op)
2640 SCM tag = scm_car (op);
2641 SCM symbol = scm_cadr (op);
2642 SCM args = scm_cddr (op);
2643 SCM grob_val = SCM_UNDEFINED;
2644 SCM grob_sym = SCM_UNDEFINED;
2645 SCM val = SCM_UNDEFINED;
2647 if (tag == ly_symbol2scm ("assign"))
2649 m = MY_MAKE_MUSIC ("PropertySet");
2650 val = scm_car (args);
2652 else if (tag == ly_symbol2scm ("unset"))
2653 m = MY_MAKE_MUSIC ("PropertyUnset");
2654 else if (tag == ly_symbol2scm ("poppush")
2655 || tag == ly_symbol2scm ("push"))
2657 m = MY_MAKE_MUSIC ("OverrideProperty");
2658 grob_sym = scm_car (args);
2659 grob_val = scm_cadr (args);
2661 else if (tag == ly_symbol2scm ("pop")) {
2662 m = MY_MAKE_MUSIC ("RevertProperty");
2663 grob_sym = scm_car (args);
2666 m->set_property ("symbol", symbol);
2668 if (val != SCM_UNDEFINED)
2669 m->set_property ("value", val);
2670 if (grob_val != SCM_UNDEFINED)
2671 m->set_property ("grob-value", grob_val);
2673 if (grob_sym != SCM_UNDEFINED)
2675 bool itc = do_internal_type_checking_global;
2678 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2680 do_internal_type_checking_global = false;
2681 m->set_property ("grob-property", grob_sym);
2683 do_internal_type_checking_global = itc;
2686 if (tag == ly_symbol2scm ("poppush"))
2687 m->set_property ("pop-first", SCM_BOOL_T);
2694 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2696 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2698 csm->set_property ("element", m->self_scm ());
2699 scm_gc_unprotect_object (m->self_scm ());
2701 csm->set_property ("context-type",
2702 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2703 csm->set_property ("property-operations", ops);
2705 if (scm_is_string (id))
2706 csm->set_property ("context-id", id);
2711 get_next_unique_context_id ()
2713 return scm_makfrom0str ("$uniqueContextId");
2718 get_next_unique_lyrics_context_id ()
2720 static int new_context_count;
2722 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2723 return scm_makfrom0str (s);