1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for LilyPond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
16 * The rules for who is protecting what are very shady. Uniformise
19 * There are too many lexical modes?
29 #include "context-def.hh"
30 #include "dimensions.hh"
32 #include "file-path.hh"
33 #include "input-smob.hh"
35 #include "lily-guile.hh"
36 #include "lilypond-input-version.hh"
39 #include "lily-lexer.hh"
40 #include "lily-parser.hh"
41 #include "paper-book.hh"
42 #include "output-def.hh"
43 #include "scm-hash.hh"
44 #include "scm-option.hh"
46 #include "text-item.hh"
49 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
51 Music *property_op_to_music (SCM op);
52 Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops);
53 SCM get_next_unique_context_id ();
54 SCM get_next_unique_lyrics_context_id ();
56 #define YYERROR_VERBOSE 1
58 #define YYPARSE_PARAM my_lily_parser
59 #define YYLEX_PARAM my_lily_parser
61 ((Lily_parser *) my_lily_parser)
63 #define yyerror THIS->parser_error
65 /* We use custom location type: Input objects */
67 #define YYLLOC_DEFAULT(Current,Rhs,N) \
68 ((Current).set_location ((Rhs)[1], (Rhs)[N]))
71 /* Add symbols to the TAGS field of a music object. */
74 tag_music (Music *m, SCM tag, Input ip)
76 SCM tags = m->get_property ("tags");
77 if (scm_is_symbol (tag))
78 tags = scm_cons (tag, tags);
79 else if (ly_c_list_p (tag))
80 tags = ly_append2 (tag, tags);
82 ip.warning (_ ("Tag must be symbol or list of symbols."));
84 m->set_property ("tags", tags);
88 is_regular_identifier (SCM id)
90 String str = ly_scm2string (id);
91 char const *s = str.to_str0 ();
100 v = v && isalnum (*s);
108 get_first_context_id (SCM type, Music *m)
110 SCM id = m->get_property ("context-id");
111 if (SCM_BOOL_T == scm_equal_p (m->get_property ("context-type"), type)
112 && scm_is_string (m->get_property ("context-id"))
113 && scm_c_string_length (id) > 0)
121 make_simple_markup (SCM a)
123 SCM simple = ly_lily_module_constant ("simple-markup");
124 return scm_list_2 (simple, a);
130 return t && t == 1 << intlog2 (t);
134 set_music_properties (Music *p, SCM a)
136 for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
137 p->internal_set_property (scm_caar (k), scm_cdar (k));
141 make_chord_step (int step, int alter)
148 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
149 return m.smobbed_copy ();
154 make_chord (SCM pitch, SCM dur, SCM modification_list)
156 SCM chord_ctor = ly_lily_module_constant ("construct-chord");
157 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
158 scm_gc_protect_object (ch);
162 /* Todo: actually also use apply iso. call too ... */
164 ly_input_procedure_p (SCM x)
166 return ly_c_procedure_p (x)
167 || (scm_is_pair (x) && ly_c_procedure_p (scm_car (x)));
171 set_property_music (SCM sym, SCM value)
173 Music *p = MY_MAKE_MUSIC ("PropertySet");
174 p->set_property ("symbol", sym);
175 p->set_property ("value", value);
180 make_music_relative (Pitch start, Music *music)
182 Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
183 relative->set_property ("element", music->self_scm ());
185 Pitch last = music->to_relative_octave (start);
186 if (lily_1_8_relative)
187 music->set_property ("last-pitch", last.smobbed_copy ());
192 make_lyric_combine_music (SCM name, Music *music)
194 Music *combine = MY_MAKE_MUSIC ("NewLyricCombineMusic");
195 combine->set_property ("element", music->self_scm ());
196 combine->set_property ("associated-context", name);
202 /* We use SCMs to do strings, because it saves us the trouble of
203 deleting them. Let's hope that a stack overflow doesnt trigger a move
204 of the parse stack onto the heap. */
210 Output_def *outputdef;
220 yylex (YYSTYPE *s, YYLTYPE *l, void *v)
222 Lily_parser *pars = (Lily_parser*) v;
223 Lily_lexer *lex = pars->lexer_;
225 lex->lexval = (void*) s;
227 lex->prepare_for_next_token ();
228 return lex->yylex ();
237 Three shift/reduce problems:
239 2. \markup identifier.
249 \repeat .. \alternative
252 \repeat { \repeat .. \alternative }
256 \repeat { \repeat } \alternative
273 %token CHORDMODIFIERS
276 %token DOUBLE_ANGLE_OPEN
277 %token DOUBLE_ANGLE_CLOSE
279 %token COMMANDSPANREQUEST
288 %token FIGURE_OPEN FIGURE_CLOSE
289 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
290 %token GROBDESCRIPTIONS
300 %token MULTI_MEASURE_REST
307 %token OVERRIDE SET REVERT
334 /* FIXME: this sucks. The user will get to see these names:
335 syntax error, unexpected E_CHAR:
340 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
341 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
343 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
348 %token <i> E_UNSIGNED
349 %token <id> IDENTIFIER
350 %token <scm> CHORDMODIFIER_PITCH
351 %token <scm> DRUM_PITCH
352 %token <scm> DURATION_IDENTIFIER
353 %token <scm> EVENT_IDENTIFIER
354 %token <scm> MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
355 %token <scm> NOTENAME_PITCH
356 %token <scm> NUMBER_IDENTIFIER
357 %token <scm> OUTPUT_DEF_IDENTIFIER
358 %token <scm> RESTNAME
359 %token <scm> LYRICS_STRING
361 %token <scm> SCORE_IDENTIFIER
363 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
364 %token <scm> TONICNAME_PITCH
365 %token <scm> CHORD_MODIFIER
366 %token <scm> FRACTION
368 %token <scm> MARKUP_HEAD_EMPTY
369 %token <scm> MARKUP_HEAD_MARKUP0
370 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
371 %token <scm> MARKUP_HEAD_SCM0
372 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
373 %token <scm> MARKUP_HEAD_SCM0_SCM1
374 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
375 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
376 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
377 %token <scm> MUSIC_FUNCTION
378 %token <scm> MUSIC_FUNCTION_MUSIC
379 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
380 %token <scm> MUSIC_FUNCTION_SCM
381 %token <scm> MUSIC_FUNCTION_SCM_SCM
382 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
383 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
384 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
385 %token <scm> MUSIC_FUNCTION_MARKUP
386 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
387 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
388 %token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
389 %token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
395 %type <book> book_block book_body
396 %type <i> bare_int bare_unsigned
397 %type <i> exclamations questions dots optional_rest
399 %type <i> sub_quotes sup_quotes
400 %type <i> tremolo_type
403 %type <music> Composite_music Simple_music Prefix_composite_music Generic_prefix_music
404 %type <music> Grouped_music_list
405 %type <music> Music Sequential_music Simultaneous_music
406 %type <music> Repeated_music
407 %type <music> command_req
408 %type <music> gen_text_def direction_less_event direction_reqd_event
409 %type <music> music_property_def context_change
410 %type <music> note_chord_element chord_body chord_body_element
411 %type <music> post_event tagged_post_event
412 %type <music> relative_music re_rhythmed_music
413 %type <music> simple_element event_chord command_element
414 %type <music> string_number_event
415 %type <music> toplevel_music
416 %type <music> tempo_event
418 %type <outputdef> output_def_body output_def_head
419 %type <outputdef> output_def paper_block
421 %type <scm> Music_list
422 %type <scm> chord_body_elements
423 %type <scm> chord_item chord_items chord_separator new_chord
424 %type <scm> context_def_spec_block context_def_spec_body
425 %type <scm> context_mod context_def_mod optional_context_mod
426 %type <scm> context_prop_spec
427 %type <scm> direction_less_char
428 %type <scm> duration_length fraction
429 %type <scm> embedded_scm scalar
430 %type <scm> identifier_init
431 %type <scm> lilypond_header lilypond_header_body
432 %type <scm> new_lyrics
433 %type <scm> post_events
434 %type <scm> property_operation
435 %type <scm> script_abbreviation
436 %type <scm> simple_string
437 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
438 %type <scm> steno_tonic_pitch
439 %type <scm> step_number step_numbers
440 %type <scm> string bare_number number_expression number_term number_factor
441 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
442 %type <scm> context_mod_list
443 %type <scm> octave_check
444 %type <scm> steno_duration optional_notemode_duration multiplied_duration
445 %type <scm> Generic_prefix_music_scm
446 %type <scm> lyric_element
447 %type <scm> Alternative_music
448 %type <scm> full_markup markup_list markup_composed_list markup_braced_list markup_braced_list_body
449 %type <scm> markup_head_1_item markup_head_1_list markup simple_markup markup_top
450 %type <scm> mode_changing_head
451 %type <scm> mode_changing_head_with_context
452 %type <scm> object_id_setting
454 %type <score> score_block score_body
459 /* We don't assign precedence to / and *, because we might need varied
460 prec levels in different prods */
466 lilypond: /* empty */
467 | lilypond toplevel_expression {
469 | lilypond assignment {
472 THIS->error_level_ = 1;
475 THIS->error_level_ = 1;
481 OBJECTID STRING { $$ = $2; }
486 THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1);
493 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
494 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
495 scm_gc_unprotect_object (book->self_scm ());
500 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
501 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
502 scm_gc_unprotect_object (score->self_scm ());
506 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
507 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
508 scm_gc_unprotect_object (music->self_scm ());
512 Output_def * od = $1;
514 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
515 id = ly_symbol2scm ("$defaultpaper");
516 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
517 id = ly_symbol2scm ("$defaultmidi");
518 else if ($1->c_variable ("is-layout") == SCM_BOOL_T)
519 id = ly_symbol2scm ("$defaultlayout");
521 THIS->lexer_->set_identifier (id, od->self_scm ());
522 scm_gc_unprotect_object (od->self_scm ());
537 lilypond_header_body:
539 $$ = ly_make_anonymous_module (be_safe_global);
540 THIS->lexer_->add_scope ($$);
542 | lilypond_header_body assignment {
548 HEADER '{' lilypond_header_body '}' {
549 $$ = THIS->lexer_->remove_scope ();
558 STRING '=' identifier_init {
559 if (! is_regular_identifier ($1))
561 @1.warning (_ ("Identifier should have alphabetic characters only"));
564 THIS->lexer_->set_identifier ($1, $3);
567 TODO: devise standard for protection in parser.
569 The parser stack lives on the C-stack, which means that
570 all objects can be unprotected as soon as they're here.
580 $$ = $1->self_scm ();
581 scm_gc_unprotect_object ($$);
584 $$ = $1->self_scm ();
585 scm_gc_unprotect_object ($$);
587 | context_def_spec_block {
591 $$ = $1->self_scm ();
592 scm_gc_unprotect_object ($$);
595 $$ = $1->self_scm ();
596 scm_gc_unprotect_object ($$);
598 | number_expression {
611 $$ = scm_int2num ($1);
615 context_def_spec_block:
616 CONTEXT '{' context_def_spec_body '}'
622 context_def_spec_body:
624 $$ = Context_def::make_scm ();
625 unsmob_context_def ($$)->set_spot (@$);
627 | CONTEXT_DEF_IDENTIFIER {
629 unsmob_context_def ($$)->set_spot (@$);
631 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
632 Context_def*td = unsmob_context_def ($$);
634 for (SCM p = $3; scm_is_pair (p); p = scm_cdr (p)) {
635 SCM tag = scm_caar (p);
637 /* TODO: should make new tag "grob-definition" ? */
638 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
639 tag, scm_cons (scm_cdar (p), SCM_EOL)));
642 | context_def_spec_body context_mod {
643 unsmob_context_def ($$)->add_context_mod ($2);
650 BOOK '{' book_body '}' {
656 * Use 'handlers' like for toplevel-* stuff?
657 * grok \layout and \midi? */
662 $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
663 scm_gc_unprotect_object ($$->paper_->self_scm ());
664 $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader");
666 | book_body paper_block {
668 scm_gc_unprotect_object ($2->self_scm ());
670 | book_body score_block {
672 $$->add_score (score);
674 | book_body lilypond_header {
681 | book_body object_id_setting {
682 $$->user_key_ = ly_scm2string ($2);
687 SCORE '{' score_body '}' {
698 $$ = new Score ( *unsmob_score ($1));
701 | score_body object_id_setting {
702 $$->user_key_ = ly_scm2string ($2);
705 SCM m = $2->self_scm ();
706 scm_gc_unprotect_object (m);
707 $$->set_music (m, THIS->self_scm ());
709 | score_body lilypond_header {
712 | score_body output_def {
713 if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
715 THIS->parser_error (@2, _("\\paper cannot be in \\score. Use \\layout instead"));
722 scm_gc_unprotect_object ($2->self_scm ());
725 $$->error_found_ = true;
737 if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
739 THIS->parser_error (@1, _("Need \\paper for paper block."));
740 $$ = get_paper (THIS);
747 output_def_body '}' {
750 THIS->lexer_->remove_scope ();
751 THIS->lexer_->pop_state ();
757 $$ = get_paper (THIS);
758 $$->input_origin_ = @$;
759 THIS->lexer_->add_scope ($$->scope_);
762 Output_def *p = get_midi (THIS);
764 THIS->lexer_->add_scope (p->scope_);
767 Output_def *p = get_layout (THIS);
769 THIS->lexer_->add_scope (p->scope_);
776 output_def_head '{' {
778 $$->input_origin_.set_spot (@$);
779 THIS->lexer_->push_initial_state ();
781 | output_def_head '{' OUTPUT_DEF_IDENTIFIER {
782 scm_gc_unprotect_object ($1->self_scm ());
783 Output_def *o = unsmob_output_def ($3);
784 o->input_origin_.set_spot (@$);
786 THIS->lexer_->remove_scope ();
787 THIS->lexer_->add_scope (o->scope_);
788 THIS->lexer_->push_initial_state ();
790 | output_def_body assignment {
793 | output_def_body context_def_spec_block {
794 assign_context_def ($$, $2);
796 | output_def_body tempo_event {
798 junk this ? there already is tempo stuff in
801 int m = scm_to_int ($2->get_property ("metronome-count"));
802 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
803 set_tempo ($$, d->get_length (), m);
804 scm_gc_unprotect_object ($2->self_scm ());
806 | output_def_body error {
812 TEMPO steno_duration '=' bare_unsigned {
813 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
814 $$->set_property ("tempo-unit", $2);
815 $$->set_property ("metronome-count", scm_int2num ( $4));
820 The representation of a list is the
824 to have efficient append. */
828 $$ = scm_cons (SCM_EOL, SCM_EOL);
832 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
833 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
835 if (scm_is_pair (scm_cdr (s)))
836 scm_set_cdr_x (scm_cdr (s), c); /* append */
838 scm_set_car_x (s, c); /* set first cons */
839 scm_set_cdr_x (s, c); /* remember last cell */
841 | Music_list embedded_scm {
845 Music * m = MY_MAKE_MUSIC("Music");
847 m->set_property ("error-found", SCM_BOOL_T);
849 SCM c = scm_cons (m->self_scm (), SCM_EOL);
850 scm_gc_unprotect_object (m->self_scm ()); /* UGH */
852 if (scm_is_pair (scm_cdr (s)))
853 scm_set_cdr_x (scm_cdr (s), c); /* append */
855 scm_set_car_x (s, c); /* set first cons */
856 scm_set_cdr_x (s, c); /* remember last cell */
869 | ALTERNATIVE '{' Music_list '}' {
876 REPEAT simple_string bare_unsigned Music Alternative_music
880 SCM alts = scm_is_pair ($5) ? scm_car ($5) : SCM_EOL;
881 if (times < scm_ilength (alts)) {
882 unsmob_music (scm_car (alts))
883 ->origin ()->warning (
884 _ ("More alternatives than repeats. Junking excess alternatives."));
885 alts = ly_truncate_list (times, alts);
889 SCM proc = ly_lily_module_constant ("make-repeated-music");
891 SCM mus = scm_call_1 (proc, $2);
892 scm_gc_protect_object (mus); // UGH.
893 Music *r = unsmob_music (mus);
896 r-> set_property ("element", beg->self_scm ());
897 scm_gc_unprotect_object (beg->self_scm ());
899 r->set_property ("repeat-count", scm_int2num (times >? 1));
901 r-> set_property ("elements",alts);
902 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
904 TODO: move this code to Scheme.
908 we can not get durations and other stuff correct down the line, so we have to
909 add to the duration log here.
911 SCM func = ly_lily_module_constant ("shift-duration-log");
913 int dots = ($3 % 3) ? 0 : 1;
914 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
917 if ($4->is_mus_type ("sequential-music"))
919 int list_len = scm_ilength ($4->get_property ("elements"));
921 $4->origin ()->warning ("Chord tremolo must have 2 elements.");
923 r->compress (Moment (Rational (1, list_len)));
925 scm_call_3 (func, r->self_scm (), scm_int2num (shift), scm_int2num (dots));
928 r->set_spot (*$4->origin ());
935 SEQUENTIAL '{' Music_list '}' {
936 $$ = MY_MAKE_MUSIC ("SequentialMusic");
937 $$->set_property ("elements", scm_car ($3));
940 | '{' Music_list '}' {
941 $$ = MY_MAKE_MUSIC ("SequentialMusic");
942 $$->set_property ("elements", scm_car ($2));
948 SIMULTANEOUS '{' Music_list '}'{
949 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
950 $$->set_property ("elements", scm_car ($3));
954 | simul_open Music_list simul_close {
955 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
956 $$->set_property ("elements", scm_car ($2));
962 event_chord { $$ = $1; }
964 $$ = unsmob_music ($1);
971 optional_context_mod:
972 /**/ { $$ = SCM_EOL; }
973 | WITH { THIS->lexer_->push_initial_state (); }
974 '{' context_mod_list '}'
976 THIS->lexer_->pop_state ();
982 /* */ { $$ = SCM_EOL; }
983 | context_mod_list context_mod {
984 $$ = scm_cons ($2, $1);
990 Prefix_composite_music { $$ = $1; }
991 | Grouped_music_list { $$ = $1; }
995 Simultaneous_music { $$ = $1; }
996 | Sequential_music { $$ = $1; }
999 Generic_prefix_music_scm:
1001 $$ = scm_list_2 ($1, make_input (@$));
1003 | MUSIC_FUNCTION_SCM embedded_scm {
1004 $$ = scm_list_3 ($1, make_input (@$), $2);
1006 | MUSIC_FUNCTION_MARKUP full_markup {
1007 $$ = scm_list_3 ($1, make_input (@$), $2);
1009 | MUSIC_FUNCTION_MUSIC Music {
1010 $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
1011 scm_gc_unprotect_object ($2->self_scm ());
1013 | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
1014 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1015 scm_gc_unprotect_object ($3->self_scm ());
1017 | MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
1018 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1020 | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
1021 $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
1023 | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
1024 $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
1025 scm_gc_unprotect_object ($3->self_scm ());
1027 | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
1028 $$ = scm_list_4 ($1, make_input (@$), $2, $3);
1030 | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
1031 $$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
1032 scm_gc_unprotect_object ($2->self_scm ());
1033 scm_gc_unprotect_object ($3->self_scm ());
1035 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
1036 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1037 scm_gc_unprotect_object ($4->self_scm ());
1038 scm_gc_unprotect_object ($3->self_scm ());
1040 | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
1041 $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
1042 scm_gc_unprotect_object ($3->self_scm ());
1043 scm_gc_unprotect_object ($4->self_scm ());
1047 Generic_prefix_music:
1048 Generic_prefix_music_scm {
1049 SCM func = scm_car ($1);
1050 Input *loc = unsmob_input (scm_cadr ($1));
1051 SCM args = scm_cddr ($1);
1052 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1054 SCM type_check_proc = ly_lily_module_constant ("type-check-list");
1057 if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr ($1), sig, args)))
1059 THIS->error_level_ = 1;
1065 m = scm_apply_0 (func, scm_cons (THIS->self_scm(),
1068 if (unsmob_music (m))
1070 $$ = unsmob_music (m);
1071 scm_gc_protect_object (m);
1076 loc->error (_ ("Music head function should return Music object."));
1077 $$ = MY_MAKE_MUSIC ("Music");
1079 $$->set_spot (*loc);
1084 Prefix_composite_music:
1085 Generic_prefix_music {
1088 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1089 $$ = context_spec_music ($2, $4, $6, $5);
1092 | CONTEXT simple_string optional_context_mod Music {
1093 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1095 | NEWCONTEXT simple_string optional_context_mod Music {
1096 $$ = context_spec_music ($2, get_next_unique_context_id (), $4,
1100 | TIMES fraction Music
1103 int n = scm_to_int (scm_car ($2)); int d = scm_to_int (scm_cdr ($2));
1106 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1109 $$->set_property ("element", mp->self_scm ());
1110 scm_gc_unprotect_object (mp->self_scm ());
1111 $$->set_property ("numerator", scm_int2num (n));
1112 $$->set_property ("denominator", scm_int2num (d));
1113 $$->compress (Moment (Rational (n,d)));
1116 | Repeated_music { $$ = $1; }
1117 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1118 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1120 Pitch from = *unsmob_pitch ($2);
1121 Pitch to = *unsmob_pitch ($3);
1123 p->transpose (pitch_interval (from, to));
1124 $$->set_property ("element", p->self_scm ());
1125 scm_gc_unprotect_object (p->self_scm ());
1127 | mode_changing_head Grouped_music_list {
1128 if ($1 == ly_symbol2scm ("chords"))
1130 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1131 chm->set_property ("element", $2->self_scm ());
1133 scm_gc_unprotect_object ($2->self_scm ());
1139 THIS->lexer_->pop_state ();
1141 | mode_changing_head_with_context optional_context_mod Grouped_music_list {
1142 $$ = context_spec_music ($1, get_next_unique_context_id (),
1144 if ($1 == ly_symbol2scm ("ChordNames"))
1146 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1147 chm->set_property ("element", $$->self_scm ());
1148 scm_gc_unprotect_object ($$->self_scm ());
1151 THIS->lexer_->pop_state ();
1153 | relative_music { $$ = $1; }
1154 | re_rhythmed_music { $$ = $1; }
1155 | TAG embedded_scm Music {
1156 tag_music ($3, $2, @$);
1163 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1164 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1166 $$ = ly_symbol2scm ("notes");
1170 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1171 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1173 $$ = ly_symbol2scm ("drums");
1176 THIS->lexer_->push_figuredbass_state ();
1178 $$ = ly_symbol2scm ("figures");
1181 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1182 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1183 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1184 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1185 $$ = ly_symbol2scm ("chords");
1189 { THIS->lexer_->push_lyric_state ();
1190 $$ = ly_symbol2scm ("lyrics");
1194 mode_changing_head_with_context:
1196 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1197 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1199 $$ = ly_symbol2scm ("DrumStaff");
1202 THIS->lexer_->push_figuredbass_state ();
1204 $$ = ly_symbol2scm ("FiguredBass");
1207 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1208 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1209 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1210 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1211 $$ = ly_symbol2scm ("ChordNames");
1214 { THIS->lexer_->push_lyric_state ();
1215 $$ = ly_symbol2scm ("Lyrics");
1221 RELATIVE absolute_pitch Music {
1223 Pitch start = *unsmob_pitch ($2);
1224 $$ = make_music_relative (start, m);
1225 scm_gc_unprotect_object (m->self_scm ());
1227 | RELATIVE Composite_music {
1230 Pitch middle_c (0, 0, 0);
1231 $$ = make_music_relative (middle_c, m);
1232 scm_gc_unprotect_object (m->self_scm ());
1237 ADDLYRICS { THIS->lexer_->push_lyric_state (); }
1239 Grouped_music_list {
1240 /* Can also use Music at the expensive of two S/Rs similar to
1241 \repeat \alternative */
1242 THIS->lexer_->pop_state ();
1244 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1246 | new_lyrics ADDLYRICS {
1247 THIS->lexer_->push_lyric_state ();
1248 } Grouped_music_list {
1249 THIS->lexer_->pop_state ();
1250 $$ = scm_cons ($4->self_scm (), $1);
1255 Grouped_music_list new_lyrics {
1257 SCM name = get_first_context_id (scm_makfrom0str ("Voice"), voice);
1258 if (!scm_is_string (name))
1260 name = get_next_unique_lyrics_context_id ();
1261 voice = context_spec_music (scm_makfrom0str ("Voice"),
1266 SCM context = scm_makfrom0str ("Lyrics");
1267 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1270 for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
1272 Music *music = unsmob_music (scm_car (s));
1273 Music *com = make_lyric_combine_music (name, music);
1274 Music *csm = context_spec_music (context,
1275 get_next_unique_context_id (), com, SCM_EOL);
1276 lst = scm_cons (csm->self_scm (), lst);
1278 all->set_property ("elements", scm_cons (voice->self_scm (),
1281 scm_gc_unprotect_object (voice->self_scm ());
1284 THIS->lexer_->push_lyric_state ();
1285 } simple_string Music {
1286 THIS->lexer_->pop_state ();
1289 $$ = make_lyric_combine_music (name, music);
1290 scm_gc_unprotect_object (music->self_scm ());
1295 CHANGE STRING '=' STRING {
1296 Music*t = MY_MAKE_MUSIC ("ContextChange");
1297 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1298 t-> set_property ("change-to-id", $4);
1307 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1308 scm_string_to_symbol ($1), $3);
1310 | UNSET simple_string {
1311 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1312 scm_string_to_symbol ($2));
1314 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1315 $$ = scm_list_4 (ly_symbol2scm ("push"),
1316 scm_string_to_symbol ($2), $3, $5);
1318 | REVERT simple_string embedded_scm {
1319 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1320 scm_string_to_symbol ($2), $3);
1325 CONSISTS { $$ = ly_symbol2scm ("consists"); }
1326 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1328 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1329 | DENIES { $$ = ly_symbol2scm ("denies"); }
1331 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1332 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1333 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1334 | NAME { $$ = ly_symbol2scm ("context-name"); }
1338 property_operation { $$ = $1; }
1339 | context_def_mod STRING {
1340 $$ = scm_list_2 ($1, $2);
1346 if (!is_regular_identifier ($1))
1348 @$.error (_("Grob name should be alphanumeric"));
1351 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1352 scm_string_to_symbol ($1));
1354 | simple_string '.' simple_string {
1355 $$ = scm_list_2 (scm_string_to_symbol ($1),
1356 scm_string_to_symbol ($3));
1361 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1362 $$ = property_op_to_music (scm_list_4 (
1363 ly_symbol2scm ("poppush"),
1366 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1368 | REVERT context_prop_spec embedded_scm {
1369 $$ = property_op_to_music (scm_list_3 (
1370 ly_symbol2scm ("pop"),
1374 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1376 | SET context_prop_spec '=' scalar {
1377 $$ = property_op_to_music (scm_list_3 (
1378 ly_symbol2scm ("assign"),
1381 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1383 | UNSET context_prop_spec {
1384 $$ = property_op_to_music (scm_list_2 (
1385 ly_symbol2scm ("unset"),
1387 $$= context_spec_music (scm_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1389 | ONCE music_property_def {
1390 SCM e = $2->get_property ("element");
1391 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1402 | STRING_IDENTIFIER {
1405 | string '+' string {
1406 $$ = scm_string_append (scm_list_2 ($1, $3));
1410 simple_string: STRING {
1425 $$ = scm_int2num ($1);
1434 $$ = scm_int2num ($1);
1440 pre_events doesn't contain anything. It is a trick:
1442 Adding pre_events to the simple_element
1443 makes the choice between
1449 simple_element: STRING
1451 a single shift/reduction conflict.
1453 nevertheless, this is not very clean, and we should find a different
1457 pre_events: /* empty */
1461 pre_events simple_element post_events {
1462 SCM elts = $2-> get_property ("elements");
1464 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1466 $2->set_property ("elements", elts);
1467 /* why is this giving wrong start location? -ns
1468 * $2->set_spot (@$); */
1470 i.set_location (@2, @3);
1475 | note_chord_element
1480 chord_body optional_notemode_duration post_events
1482 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1483 SCM es = $1->get_property ("elements");
1484 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1486 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
1487 unsmob_music (scm_car (s))->set_property ("duration", dur);
1488 es = ly_append2 (es, postevs);
1490 $1-> set_property ("elements", es);
1502 simul_open: DOUBLE_ANGLE_OPEN
1505 simul_close: DOUBLE_ANGLE_CLOSE
1509 chord_open chord_body_elements chord_close
1511 $$ = MY_MAKE_MUSIC ("EventChord");
1513 $$->set_property ("elements",
1514 scm_reverse_x ($2, SCM_EOL));
1518 chord_body_elements:
1519 /* empty */ { $$ = SCM_EOL; }
1520 | chord_body_elements chord_body_element {
1521 $$ = scm_cons ($2->self_scm (), $1);
1522 scm_gc_unprotect_object ($2->self_scm ());
1527 pitch exclamations questions octave_check post_events
1534 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1535 n->set_property ("pitch", $1);
1538 n->set_property ("cautionary", SCM_BOOL_T);
1539 if (ex % 2 || q % 2)
1540 n->set_property ("force-accidental", SCM_BOOL_T);
1542 if (scm_is_pair (post)) {
1543 SCM arts = scm_reverse_x (post, SCM_EOL);
1544 n->set_property ("articulations", arts);
1546 if (scm_is_number (check))
1548 int q = scm_to_int (check);
1549 n->set_property ("absolute-octave", scm_int2num (q-1));
1555 | DRUM_PITCH post_events {
1556 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1557 n->set_property ("duration", $2);
1558 n->set_property ("drum-type", $1);
1561 if (scm_is_pair ($2)) {
1562 SCM arts = scm_reverse_x ($2, SCM_EOL);
1563 n->set_property ("articulations", arts);
1570 ADDQUOTE string Music {
1571 SCM adder = ly_lily_module_constant ("add-quotable");
1573 scm_call_2 (adder, $2, $3->self_scm ());
1574 scm_gc_unprotect_object ($3->self_scm ());
1580 $$ = MY_MAKE_MUSIC ("EventChord");
1581 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1582 scm_gc_unprotect_object ($1->self_scm ());
1587 | SKIP duration_length {
1588 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1589 skip->set_property ("duration", $2);
1590 skip->set_spot (@$);
1594 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1597 $$->set_property ("pitch", $2);
1600 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1601 m->set_property ("span-direction", scm_int2num (START));
1604 $$ = MY_MAKE_MUSIC ("EventChord");
1605 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1606 scm_gc_unprotect_object (m->self_scm ());
1610 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1611 m->set_property ("span-direction", scm_int2num (STOP));
1614 $$ = MY_MAKE_MUSIC ("EventChord");
1615 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1617 scm_gc_unprotect_object (m->self_scm ());
1620 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1624 SCM pipe = THIS->lexer_->lookup_identifier ("pipeSymbol");
1626 if (Music * m = unsmob_music (pipe))
1629 $$ = MY_MAKE_MUSIC ("BarCheck");
1633 | TRANSPOSITION pitch {
1635 Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
1636 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1637 sounds_as_c.smobbed_copy());
1639 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1643 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1645 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1647 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1651 | PARTIAL duration_length {
1652 Moment m = - unsmob_duration ($2)->get_length ();
1653 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1655 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1657 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1662 SCM proc = ly_lily_module_constant ("make-clef-set");
1664 SCM result = scm_call_1 (proc, $2);
1665 scm_gc_protect_object (result);
1666 $$ = unsmob_music (result);
1669 SCM proc = ly_lily_module_constant ("make-time-signature-set");
1671 SCM result = scm_apply_2 (proc, scm_car ($2), scm_cdr ($2), SCM_EOL);
1672 scm_gc_protect_object (result);
1673 $$ = unsmob_music (result);
1676 SCM proc = ly_lily_module_constant ("make-mark-set");
1678 SCM result = scm_call_1 (proc, $2);
1679 scm_gc_protect_object (result);
1680 $$ = unsmob_music (result);
1686 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1689 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1696 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1699 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1701 Music *key = MY_MAKE_MUSIC ("KeyChangeEvent");
1702 if (scm_ilength ($3) > 0)
1704 key->set_property ("pitch-alist", $3);
1705 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1706 key->transpose (* unsmob_pitch ($2));
1708 THIS->parser_error (@3, _ ("Second argument must be pitch list."));
1720 | post_events post_event {
1722 $$ = scm_cons ($2->self_scm (), $$);
1723 scm_gc_unprotect_object ($2->self_scm ());
1725 | post_events tagged_post_event {
1726 $2 -> set_spot (@2);
1727 $$ = scm_cons ($2->self_scm (), $$);
1728 scm_gc_unprotect_object ($2->self_scm ());
1734 '-' TAG embedded_scm post_event {
1735 tag_music ($4, $3, @$);
1742 direction_less_event {
1746 if (!THIS->lexer_->is_lyric_state ())
1747 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
1748 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1751 if (!THIS->lexer_->is_lyric_state ())
1752 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
1753 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1755 | script_dir direction_reqd_event {
1757 $2->set_property ("direction", scm_int2num ($1));
1760 | script_dir direction_less_event {
1762 $2->set_property ("direction", scm_int2num ($1));
1765 | string_number_event
1768 string_number_event:
1770 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1771 s->set_property ("string-number", scm_int2num ($1));
1777 direction_less_char:
1779 $$ = ly_symbol2scm ("bracketOpenSymbol");
1782 $$ = ly_symbol2scm ("bracketCloseSymbol");
1785 $$ = ly_symbol2scm ("tildeSymbol");
1788 $$ = ly_symbol2scm ("parenthesisOpenSymbol");
1791 $$ = ly_symbol2scm ("parenthesisCloseSymbol");
1794 $$ = ly_symbol2scm ("escapedExclamationSymbol");
1797 $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
1800 $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
1803 $$ = ly_symbol2scm ("escapedBiggerSymbol");
1806 $$ = ly_symbol2scm ("escapedSmallerSymbol");
1810 direction_less_event:
1811 direction_less_char {
1812 SCM predefd = THIS->lexer_->lookup_identifier_symbol ($1);
1814 if (unsmob_music (predefd))
1816 m = unsmob_music (predefd)->clone ();
1820 m = MY_MAKE_MUSIC ("Music");
1825 | EVENT_IDENTIFIER {
1826 $$ = unsmob_music ($1);
1829 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1831 a->set_property ("tremolo-type", scm_int2num ($1));
1836 direction_reqd_event:
1840 | script_abbreviation {
1841 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1842 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1843 if (scm_is_string (s))
1844 a->set_property ("articulation-type", s);
1845 else THIS->parser_error (@1, _ ("Expecting string as script definition"));
1851 /**/ { $$ = SCM_EOL; }
1852 | '=' { $$ = scm_int2num (0); }
1853 | '=' sub_quotes { $$ = scm_int2num ($2); }
1854 | '=' sup_quotes { $$ = scm_int2num ($2); }
1879 | NOTENAME_PITCH sup_quotes {
1880 Pitch p = *unsmob_pitch ($1);
1881 p = p.transposed (Pitch ($2,0,0));
1882 $$ = p.smobbed_copy ();
1884 | NOTENAME_PITCH sub_quotes {
1885 Pitch p =* unsmob_pitch ($1);
1886 p = p.transposed (Pitch (-$2,0,0));
1887 $$ = p.smobbed_copy ();
1899 | TONICNAME_PITCH sup_quotes {
1900 Pitch p = *unsmob_pitch ($1);
1901 p = p.transposed (Pitch ($2,0,0));
1902 $$ = p.smobbed_copy ();
1904 | TONICNAME_PITCH sub_quotes {
1905 Pitch p =* unsmob_pitch ($1);
1907 p = p.transposed (Pitch (-$2,0,0));
1908 $$ = p.smobbed_copy ();
1918 pitch_also_in_chords:
1925 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1926 t->set_property ("text", $1);
1931 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1932 t->set_property ("text",
1933 make_simple_markup ($1));
1939 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1940 t->set_property ("digit", scm_int2num ($1));
1946 script_abbreviation:
1948 $$ = scm_makfrom0str ("Hat");
1951 $$ = scm_makfrom0str ("Plus");
1954 $$ = scm_makfrom0str ("Dash");
1957 $$ = scm_makfrom0str ("Bar");
1960 $$ = scm_makfrom0str ("Larger");
1963 $$ = scm_makfrom0str ("Dot");
1966 $$ = scm_makfrom0str ("Underscore");
1973 | '-' { $$ = CENTER; }
1984 multiplied_duration {
1989 optional_notemode_duration:
1991 Duration dd = THIS->default_duration_;
1992 $$ = dd.smobbed_copy ();
1994 THIS->beam_check ($$);
1996 | multiplied_duration {
1998 THIS->default_duration_ = *unsmob_duration ($$);
2000 THIS->beam_check ($$);
2005 bare_unsigned dots {
2007 if (!is_duration ($1))
2008 THIS->parser_error (@1, _f ("not a duration: %d", $1));
2012 $$ = Duration (len, $2).smobbed_copy ();
2014 | DURATION_IDENTIFIER dots {
2015 Duration *d = unsmob_duration ($1);
2016 Duration k (d->duration_log (), d->dot_count () + $2);
2022 multiplied_duration:
2026 | multiplied_duration '*' bare_unsigned {
2027 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2029 | multiplied_duration '*' FRACTION {
2030 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2032 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2037 FRACTION { $$ = $1; }
2038 | UNSIGNED '/' UNSIGNED {
2039 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2056 | ':' bare_unsigned {
2057 if (!is_duration ($2))
2058 THIS->parser_error (@2, _f ("not a duration: %d", $2));
2065 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2066 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2070 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2071 $$ = scm_list_2 (ly_lily_module_constant ("number-markup"),
2074 | STRING { $$ = $1; }
2085 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2086 $$ = bfr->self_scm ();
2087 scm_gc_unprotect_object ($$);
2090 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2091 $$ = bfr->self_scm ();
2093 bfr->set_property ("figure", $1);
2095 scm_gc_unprotect_object ($$);
2097 | bass_figure bass_mod {
2098 Music *m = unsmob_music ($1);
2100 SCM salter = m->get_property ("alteration");
2101 int alter = scm_is_number (salter) ? scm_to_int (salter) : 0;
2102 m->set_property ("alteration",
2103 scm_int2num (alter + $2));
2105 m->set_property ("alteration", scm_int2num (0));
2113 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2118 | br_bass_figure ']' {
2120 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2128 | figure_list br_bass_figure {
2129 $$ = scm_cons ($2, $1);
2134 FIGURE_OPEN figure_list FIGURE_CLOSE {
2135 Music *m = MY_MAKE_MUSIC ("EventChord");
2136 $2 = scm_reverse_x ($2, SCM_EOL);
2137 m->set_property ("elements", $2);
2138 $$ = m->self_scm ();
2149 pitch exclamations questions octave_check optional_notemode_duration optional_rest {
2150 if (!THIS->lexer_->is_note_state ())
2151 THIS->parser_error (@1, _ ("Have to be in Note mode for notes"));
2155 n = MY_MAKE_MUSIC ("RestEvent");
2157 n = MY_MAKE_MUSIC ("NoteEvent");
2159 n->set_property ("pitch", $1);
2160 n->set_property ("duration", $5);
2162 if (scm_is_number ($4))
2164 int q = scm_to_int ($4);
2165 n->set_property ("absolute-octave", scm_int2num (q-1));
2169 n->set_property ("cautionary", SCM_BOOL_T);
2170 if ($2 % 2 || $3 % 2)
2171 n->set_property ("force-accidental", SCM_BOOL_T);
2173 Music *v = MY_MAKE_MUSIC ("EventChord");
2174 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2175 scm_gc_unprotect_object (n->self_scm ());
2181 | DRUM_PITCH optional_notemode_duration {
2182 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2183 n->set_property ("duration", $2);
2184 n->set_property ("drum-type", $1);
2186 Music *v = MY_MAKE_MUSIC ("EventChord");
2187 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2188 scm_gc_unprotect_object (n->self_scm ());
2194 | figure_spec optional_notemode_duration {
2195 Music *m = unsmob_music ($1);
2197 for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
2199 unsmob_music (scm_car (s))->set_property ("duration", $2);
2203 | RESTNAME optional_notemode_duration {
2205 if (ly_scm2string ($1) == "s") {
2207 ev = MY_MAKE_MUSIC ("SkipEvent");
2210 ev = MY_MAKE_MUSIC ("RestEvent");
2213 ev->set_property ("duration", $2);
2215 Music *velt = MY_MAKE_MUSIC ("EventChord");
2216 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2217 velt->set_spot (@$);
2219 scm_gc_unprotect_object (ev->self_scm ());
2223 | MULTI_MEASURE_REST optional_notemode_duration {
2224 SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
2225 SCM mus = scm_call_2 (proc, $2, make_input (@$));
2226 scm_gc_protect_object (mus);
2227 $$ = unsmob_music (mus);
2230 | lyric_element optional_notemode_duration {
2231 if (!THIS->lexer_->is_lyric_state ())
2232 THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
2234 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2235 lreq->set_property ("text", $1);
2236 lreq->set_property ("duration",$2);
2237 lreq->set_spot (@$);
2238 Music *velt = MY_MAKE_MUSIC ("EventChord");
2239 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2244 if (!THIS->lexer_->is_chord_state ())
2245 THIS->parser_error (@1, _ ("Have to be in Chord mode for chords"));
2246 $$ = unsmob_music ($1);
2251 /* FIXME: lyric flavoured markup would be better */
2256 $$ = make_simple_markup ($1);
2261 steno_tonic_pitch optional_notemode_duration {
2262 $$ = make_chord ($1, $2, SCM_EOL);
2264 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2265 SCM its = scm_reverse_x ($4, SCM_EOL);
2266 $$ = make_chord ($1, $2, scm_cons ($3, its));
2274 | chord_items chord_item {
2275 $$ = scm_cons ($2, $$);
2281 $$ = ly_symbol2scm ("chord-colon");
2284 $$ = ly_symbol2scm ("chord-caret");
2286 | CHORD_SLASH steno_tonic_pitch {
2287 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2289 | CHORD_BASS steno_tonic_pitch {
2290 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2299 $$ = scm_reverse_x ($1, SCM_EOL);
2307 step_number { $$ = scm_cons ($1, SCM_EOL); }
2308 | step_numbers '.' step_number {
2309 $$ = scm_cons ($3, $$);
2315 $$ = make_chord_step ($1, 0);
2317 | bare_unsigned '+' {
2318 $$ = make_chord_step ($1, SHARP);
2320 | bare_unsigned CHORD_MINUS {
2321 $$ = make_chord_step ($1, FLAT);
2328 TODO: should deprecate in favor of Scheme?
2332 number_expression '+' number_term {
2333 $$ = scm_sum ($1, $3);
2335 | number_expression '-' number_term {
2336 $$ = scm_difference ($1, $3);
2345 | number_factor '*' number_factor {
2346 $$ = scm_product ($1, $3);
2348 | number_factor '/' number_factor {
2349 $$ = scm_divide ($1, $3);
2354 '-' number_factor { /* %prec UNARY_MINUS */
2355 $$ = scm_difference ($2, SCM_UNDEFINED);
2363 $$ = scm_int2num ($1);
2368 | NUMBER_IDENTIFIER {
2371 | REAL NUMBER_IDENTIFIER {
2372 $$ = scm_make_real (scm_to_double ($1) *scm_to_double ($2));
2374 | UNSIGNED NUMBER_IDENTIFIER {
2375 $$ = scm_make_real ($1 *scm_to_double ($2));
2391 if (scm_integer_p ($1) == SCM_BOOL_T)
2393 int k = scm_to_int ($1);
2397 THIS->parser_error (@1, _ ("need integer number arg"));
2408 | exclamations '!' { $$ ++; }
2413 | questions '?' { $$ ++; }
2417 This should be done more dynamically if possible.
2425 { THIS->lexer_->push_markup_state (); }
2428 THIS->lexer_->pop_state ();
2434 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
2436 | markup_head_1_list simple_markup {
2437 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2445 markup_composed_list {
2448 | markup_braced_list {
2453 markup_composed_list:
2454 markup_head_1_list markup_braced_list {
2455 $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
2461 '{' markup_braced_list_body '}' {
2462 $$ = scm_reverse_x ($2, SCM_EOL);
2466 markup_braced_list_body:
2467 /* empty */ { $$ = scm_list (SCM_EOL); }
2468 | markup_braced_list_body markup {
2469 $$ = scm_cons ($2, $1);
2471 | markup_braced_list_body markup_list {
2472 $$ = scm_append_x (scm_list_2 (scm_reverse_x ($2, SCM_EOL), $1));
2477 MARKUP_HEAD_MARKUP0 {
2478 $$ = scm_list_1 ($1);
2480 | MARKUP_HEAD_SCM0_MARKUP1 embedded_scm {
2481 $$ = scm_list_2 ($1, $2);
2483 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm {
2484 $$ = scm_list_3 ($1, $2, $3);
2489 markup_head_1_item {
2490 $$ = scm_list_1 ($1);
2492 | markup_head_1_list markup_head_1_item {
2493 $$ = scm_cons ($2, $1);
2499 $$ = make_simple_markup ($1);
2501 | MARKUP_IDENTIFIER {
2504 | STRING_IDENTIFIER {
2508 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2509 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2510 } '{' score_body '}' {
2512 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());
2513 scm_gc_unprotect_object (sc->self_scm ());
2514 THIS->lexer_->pop_state ();
2516 | MARKUP_HEAD_SCM0 embedded_scm {
2517 $$ = scm_list_2 ($1, $2);
2519 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2520 $$ = scm_list_4 ($1, $2, $3, $4);
2522 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2523 $$ = scm_list_3 ($1, $2, $3);
2525 | MARKUP_HEAD_EMPTY {
2526 $$ = scm_list_1 ($1);
2528 | MARKUP_HEAD_LIST0 markup_list {
2529 $$ = scm_list_2 ($1,$2);
2531 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2532 $$ = scm_list_3 ($1, $2, $3);
2537 markup_head_1_list simple_markup {
2538 $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
2548 Lily_parser::set_yydebug (bool )
2556 Lily_parser::do_yyparse ()
2558 yyparse ((void*)this);
2563 Should make this optional? It will also complain when you do
2567 which is entirely legitimate.
2569 Or we can scrap it. Barchecks should detect wrong durations, and
2570 skipTypesetting speeds it up a lot.
2574 Lily_parser::beam_check (SCM dur)
2576 Duration *d = unsmob_duration (dur);
2577 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2579 Music *m = unsmob_music (last_beam_start_);
2580 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2582 last_beam_start_ = SCM_EOL;
2590 It is a little strange to have this function in this file, but
2591 otherwise, we have to import music classes into the lexer.
2595 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2597 if (scm_is_string (sid)) {
2599 return STRING_IDENTIFIER;
2600 } else if (scm_is_number (sid)) {
2602 return NUMBER_IDENTIFIER;
2603 } else if (unsmob_context_def (sid)) {
2604 *destination = unsmob_context_def (sid)->clone_scm ();
2605 return CONTEXT_DEF_IDENTIFIER;
2606 } else if (unsmob_score (sid)) {
2607 Score *score = new Score (*unsmob_score (sid));
2608 *destination = score->self_scm ();
2609 return SCORE_IDENTIFIER;
2610 } else if (Music *mus = unsmob_music (sid)) {
2611 mus = mus->clone ();
2612 *destination = mus->self_scm ();
2613 unsmob_music (*destination)->
2614 set_property ("origin", make_input (last_input_));
2615 return dynamic_cast<Event*> (mus)
2616 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2617 } else if (unsmob_duration (sid)) {
2618 *destination = unsmob_duration (sid)->smobbed_copy ();
2619 return DURATION_IDENTIFIER;
2620 } else if (unsmob_output_def (sid)) {
2621 Output_def *p = unsmob_output_def (sid);
2624 *destination = p->self_scm ();
2625 return OUTPUT_DEF_IDENTIFIER;
2626 } else if (Text_interface::markup_p (sid)) {
2628 return MARKUP_IDENTIFIER;
2635 property_op_to_music (SCM op)
2638 SCM tag = scm_car (op);
2639 SCM symbol = scm_cadr (op);
2640 SCM args = scm_cddr (op);
2641 SCM grob_val = SCM_UNDEFINED;
2642 SCM grob_sym = SCM_UNDEFINED;
2643 SCM val = SCM_UNDEFINED;
2645 if (tag == ly_symbol2scm ("assign"))
2647 m = MY_MAKE_MUSIC ("PropertySet");
2648 val = scm_car (args);
2650 else if (tag == ly_symbol2scm ("unset"))
2651 m = MY_MAKE_MUSIC ("PropertyUnset");
2652 else if (tag == ly_symbol2scm ("poppush")
2653 || tag == ly_symbol2scm ("push"))
2655 m = MY_MAKE_MUSIC ("OverrideProperty");
2656 grob_sym = scm_car (args);
2657 grob_val = scm_cadr (args);
2659 else if (tag == ly_symbol2scm ("pop")) {
2660 m = MY_MAKE_MUSIC ("RevertProperty");
2661 grob_sym = scm_car (args);
2664 m->set_property ("symbol", symbol);
2666 if (val != SCM_UNDEFINED)
2667 m->set_property ("value", val);
2668 if (grob_val != SCM_UNDEFINED)
2669 m->set_property ("grob-value", grob_val);
2671 if (grob_sym != SCM_UNDEFINED)
2673 bool itc = do_internal_type_checking_global;
2676 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2678 do_internal_type_checking_global = false;
2679 m->set_property ("grob-property", grob_sym);
2681 do_internal_type_checking_global = itc;
2684 if (tag == ly_symbol2scm ("poppush"))
2685 m->set_property ("pop-first", SCM_BOOL_T);
2692 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2694 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2696 csm->set_property ("element", m->self_scm ());
2697 scm_gc_unprotect_object (m->self_scm ());
2699 csm->set_property ("context-type",
2700 scm_is_symbol (type) ? type : scm_string_to_symbol (type));
2701 csm->set_property ("property-operations", ops);
2703 if (scm_is_string (id))
2704 csm->set_property ("context-id", id);
2709 get_next_unique_context_id ()
2711 return scm_makfrom0str ("$uniqueContextId");
2716 get_next_unique_lyrics_context_id ()
2718 static int new_context_count;
2720 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2721 return scm_makfrom0str (s);