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 "book-paper-def.hh"
30 #include "context-def.hh"
31 #include "dimensions.hh"
33 #include "file-path.hh"
34 #include "input-smob.hh"
36 #include "lily-guile.hh"
37 #include "lilypond-input-version.hh"
38 #include "ly-module.hh"
41 #include "music-list.hh"
42 #include "music-sequence.hh"
43 #include "my-lily-lexer.hh"
44 #include "my-lily-parser.hh"
45 #include "paper-book.hh"
46 #include "output-def.hh"
47 #include "scm-hash.hh"
48 #include "scm-option.hh"
50 #include "text-item.hh"
53 #define MY_MAKE_MUSIC(x) make_music_by_name (ly_symbol2scm (x))
55 Music *property_op_to_music (SCM op);
56 Music *context_spec_music (SCM type, SCM id, Music *m, SCM ops_);
57 SCM get_next_unique_context ();
59 #define YYERROR_VERBOSE 1
61 #define YYPARSE_PARAM my_lily_parser
62 #define YYLEX_PARAM my_lily_parser
64 ((My_lily_parser *) my_lily_parser)
66 #define yyerror THIS->parser_error
68 /* Add symbols to the TAGS field of a music object. */
71 tag_music (Music *m, SCM tag, Input ip)
73 SCM tags = m->get_property ("tags");
74 if (ly_c_symbol_p (tag))
75 tags = scm_cons (tag, tags);
76 else if (ly_c_list_p (tag))
77 tags = ly_append2 (tag, tags);
79 ip.warning (_ ("Tag must be symbol or list of symbols."));
81 m->set_property ("tags", tags);
85 is_regular_identifier (SCM id)
87 String str = ly_scm2string (id);
88 char const *s = str.to_str0 ();
97 v = v && isalnum (*s);
104 make_simple_markup (SCM encoding, SCM a)
106 SCM simple = ly_scheme_function ("simple-markup");
107 if (ly_c_symbol_p (encoding))
108 return scm_list_3 (ly_scheme_function ("encoded-simple-markup"),
110 return scm_list_2 (simple, a);
116 return t && t == 1 << intlog2 (t);
120 set_music_properties (Music *p, SCM a)
122 for (SCM k = a; ly_c_pair_p (k); k = ly_cdr (k))
123 p->internal_set_property (ly_caar (k), ly_cdar (k));
127 make_chord_step (int step, int alter)
134 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
135 return m.smobbed_copy ();
140 make_chord (SCM pitch, SCM dur, SCM modification_list)
142 SCM chord_ctor = ly_scheme_function ("construct-chord");
143 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
144 scm_gc_protect_object (ch);
148 /* Todo: actually also use apply iso. call too ... */
150 ly_input_procedure_p (SCM x)
152 return ly_c_procedure_p (x)
153 || (ly_c_pair_p (x) && ly_c_procedure_p (ly_car (x)));
157 set_property_music (SCM sym, SCM value)
159 Music *p = MY_MAKE_MUSIC ("PropertySet");
160 p->set_property ("symbol", sym);
161 p->set_property ("value", value);
166 make_music_relative (Pitch start, Music *music)
168 Music *relative = MY_MAKE_MUSIC ("RelativeOctaveMusic");
169 relative->set_property ("element", music->self_scm ());
171 Pitch last = music->to_relative_octave (start);
172 if (lily_1_8_relative)
173 music->set_property ("last-pitch", last.smobbed_copy ());
178 make_lyric_combine_music (SCM name, Music *music)
180 Music *combine = MY_MAKE_MUSIC ("NewLyricCombineMusic");
181 combine->set_property ("element", music->self_scm ());
182 combine->set_property ("associated-context", name);
188 /* We use SCMs to do strings, because it saves us the trouble of
189 deleting them. Let's hope that a stack overflow doesnt trigger a move
190 of the parse stack onto the heap. */
196 Book_output_def *bookpaper;
197 Output_def *outputdef;
207 yylex (YYSTYPE *s, void *v)
209 My_lily_parser *pars = (My_lily_parser*) v;
210 My_lily_lexer *lex = pars->lexer_;
212 lex->lexval = (void*) s;
213 lex->prepare_for_next_token ();
214 return lex->yylex ();
223 Three shift/reduce problems:
225 2. \markup identifier.
230 \repeat .. \alternative
233 \repeat { \repeat .. \alternative }
237 \repeat { \repeat } \alternative
254 %token CHORDMODIFIERS
256 %token DOUBLE_ANGLE_OPEN
257 %token DOUBLE_ANGLE_CLOSE
259 %token COMMANDSPANREQUEST
267 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
268 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
269 %token GROBDESCRIPTIONS
278 %token MULTI_MEASURE_REST
284 %token OVERRIDE SET REVERT
310 /* FIXME: this sucks. The user will get to see these names:
311 syntax error, unexpected E_CHAR:
315 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
316 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
318 %token <i> E_UNSIGNED
319 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
323 %token <scm> NOTENAME_PITCH
324 %token <scm> TONICNAME_PITCH
325 %token <scm> CHORDMODIFIER_PITCH
326 %token <scm> DURATION_IDENTIFIER
327 %token <scm> FRACTION
328 %token <id> IDENTIFIER
330 %token <scm> DRUM_PITCH
331 %token <scm> CHORD_MODIFIER
332 %token <scm> SCORE_IDENTIFIER
333 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
334 %token <scm> NUMBER_IDENTIFIER
335 %token <scm> EVENT_IDENTIFIER
336 %token <scm> MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
337 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
338 %token <scm> RESTNAME
345 %token <scm> MARKUP_HEAD_MARKUP0
346 %token <scm> MARKUP_HEAD_EMPTY
347 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
348 %token <scm> MARKUP_HEAD_SCM0
349 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
350 %token <scm> MARKUP_HEAD_SCM0_SCM1
351 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
352 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
354 %token <scm> MUSIC_FUNCTION
355 %token <scm> MUSIC_FUNCTION_SCM
356 %token <scm> MUSIC_FUNCTION_MUSIC
357 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
358 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
359 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
360 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
362 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
363 %type <scm> markup markup_line markup_list markup_list_body full_markup
365 %type <book> book_block book_body
366 %type <bookpaper> book_paper_head book_paper_block book_paper_body
368 %type <i> exclamations questions dots optional_rest
370 %type <scm> oct_check
371 %type <scm> context_mod_list
372 %type <scm> lyric_element
373 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
374 %type <scm> new_lyrics
375 %type <outputdef> output_def
376 %type <scm> lilypond_header lilypond_header_body
377 %type <music> open_event close_event
378 %type <i> sub_quotes sup_quotes
379 %type <music> toplevel_music
380 %type <music> simple_element event_chord command_element
381 %type <music> Composite_music Simple_music Prefix_composite_music Generic_prefix_music
382 %type <scm> Generic_prefix_music_scm
383 %type <music> Grouped_music_list
384 %type <music> Repeated_music
385 %type <scm> Alternative_music
386 %type <i> tremolo_type
387 %type <i> bare_int bare_unsigned
389 %type <scm> identifier_init
390 %type <scm> simple_string
392 %type <music> note_chord_element chord_body chord_body_element
393 %type <scm> chord_body_elements
394 %type <scm> steno_duration optional_notemode_duration multiplied_duration
396 %type <scm> post_events
397 %type <music> gen_text_def direction_less_event direction_reqd_event
398 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
399 %type <scm> steno_tonic_pitch
400 %type <scm> duration_length fraction
402 %type <scm> chord_item chord_items chord_separator new_chord
403 %type <scm> step_number step_numbers
405 %type <scm> embedded_scm scalar
406 %type <music> Music Sequential_music Simultaneous_music
407 %type <music> relative_music re_rhythmed_music
408 %type <music> music_property_def context_change
409 %type <scm> context_prop_spec
410 %type <scm> Music_list
411 %type <scm> property_operation
412 %type <scm> context_mod context_def_mod optional_context_mod
413 %type <outputdef> music_output_def_body music_output_def_head
414 %type <music> post_event tagged_post_event
415 %type <music> command_req
416 %type <music> string_number_event
417 %type <scm> string bare_number number_expression number_term number_factor
418 %type <score> score_block score_body
420 %type <scm> context_def_spec_block context_def_spec_body
421 %type <music> tempo_event
422 %type <scm> script_abbreviation
428 /* We don't assign precedence to / and *, because we might need varied
429 prec levels in different prods */
435 lilypond: /* empty */
436 | lilypond toplevel_expression {
438 | lilypond assignment {
441 THIS->error_level_ = 1;
444 THIS->error_level_ = 1;
457 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
458 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
459 scm_gc_unprotect_object (book->self_scm ());
464 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
465 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
466 scm_gc_unprotect_object (score->self_scm ());
470 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
471 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
472 scm_gc_unprotect_object (music->self_scm ());
476 if ($1->c_variable ("is-paper") == SCM_BOOL_T)
477 id = ly_symbol2scm ("$defaultpaper");
478 else if ($1->c_variable ("is-midi") == SCM_BOOL_T)
479 id = ly_symbol2scm ("$defaultmidi");
480 else if ($1->c_variable ("is-book-paper") == SCM_BOOL_T)
481 id = ly_symbol2scm ("$defaultbookpaper");
483 THIS->lexer_->set_identifier (id, $1->self_scm ());
484 scm_gc_unprotect_object ($1->self_scm ());
487 THIS->lexer_->set_identifier (ly_symbol2scm ("$defaultbookpaper"), $1->self_scm ());
488 scm_gc_unprotect_object ($1->self_scm ());
503 lilypond_header_body:
505 $$ = ly_make_anonymous_module (safe_global_b);
506 THIS->lexer_->add_scope ($$);
508 | lilypond_header_body assignment {
514 HEADER '{' lilypond_header_body '}' {
515 $$ = THIS->lexer_->remove_scope ();
527 /* cont */ '=' identifier_init {
530 Should find generic way of associating input with objects.
532 Input ip = THIS->pop_spot ();
534 if (! is_regular_identifier ($1))
536 ip.warning (_ ("Identifier should have alphabetic characters only"));
539 THIS->lexer_->set_identifier ($1, $4);
542 TODO: devise standard for protection in parser.
544 The parser stack lives on the C-stack, which means that
545 all objects can be unprotected as soon as they're here.
555 $$ = $1->self_scm ();
556 scm_gc_unprotect_object ($$);
562 $$ = $1->self_scm ();
563 scm_gc_unprotect_object ($$);
565 | context_def_spec_block {
569 $$ = $1->self_scm ();
570 scm_gc_unprotect_object ($$);
573 $$ = $1->self_scm ();
574 scm_gc_unprotect_object ($$);
576 | number_expression {
587 context_def_spec_block:
588 CONTEXT '{' context_def_spec_body '}'
594 context_def_spec_body:
596 $$ = Context_def::make_scm ();
597 unsmob_context_def ($$)->set_spot (THIS->here_input ());
599 | CONTEXT_DEF_IDENTIFIER {
601 unsmob_context_def ($$)->set_spot (THIS->here_input ());
603 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
604 Context_def*td = unsmob_context_def ($$);
606 for (SCM p = $3; ly_c_pair_p (p); p = ly_cdr (p)) {
607 SCM tag = ly_caar (p);
609 /* TODO: should make new tag "grob-definition" ? */
610 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
611 tag, scm_cons (ly_cdar (p), SCM_EOL)));
614 | context_def_spec_body context_mod {
615 unsmob_context_def ($$)->add_context_mod ($2);
621 book_paper_body '}' {
627 $$ = get_bookpaper (THIS);
628 THIS->lexer_->add_scope ($$->scope_);
634 | book_paper_body assignment { }
643 /*cont*/ '{' book_body '}' {
650 * Use 'handlers' like for toplevel-* stuff?
651 * grok \paper and \midi? */
655 $$->set_spot (THIS->here_input ());
656 $$->bookpaper_ = dynamic_cast<Book_output_def*> (unsmob_book_output_def (THIS->lexer_->lookup_identifier ("$defaultbookpaper"))->clone ());
657 scm_gc_unprotect_object ($$->bookpaper_->self_scm ());
659 | book_body book_paper_block {
661 scm_gc_unprotect_object ($2->self_scm ());
663 | book_body score_block {
665 $$->scores_.push (score);
666 scm_gc_unprotect_object (score->self_scm ());
668 | book_body Composite_music {
671 = unsmob_score (ly_music_scorify (music->self_scm ()));
672 $$->scores_.push (score);
673 scm_gc_unprotect_object (music->self_scm ());
687 /*cont*/ '{' score_body '}' {
697 $$->set_spot (THIS->here_input ());
698 SCM m = $1->self_scm ();
699 scm_gc_unprotect_object (m);
704 SCM check_funcs = ly_scheme_function ("toplevel-music-functions");
705 for (; ly_c_pair_p (check_funcs); check_funcs = ly_cdr (check_funcs))
706 m = scm_call_1 (ly_car (check_funcs), m);
711 $$ = new Score ( *unsmob_score ($1));
712 $$->set_spot (THIS->here_input ());
714 | score_body lilypond_header {
717 | score_body output_def {
719 scm_gc_unprotect_object ($2->self_scm ());
731 music_output_def_body '}' {
733 THIS->lexer_->remove_scope ();
734 THIS->lexer_->pop_state ();
738 music_output_def_head:
740 Output_def *p = get_midi (THIS);
742 THIS->lexer_->add_scope (p->scope_);
745 Output_def* p = get_paper (THIS);
748 THIS->lexer_->add_scope (p->scope_);
754 music_output_def_body:
755 music_output_def_head '{' {
757 $$->input_origin_. set_spot (THIS->here_input ());
758 THIS->lexer_->push_initial_state ();
760 | music_output_def_head '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
761 scm_gc_unprotect_object ($1->self_scm ());
762 Output_def *o = unsmob_output_def ($3);
763 o->input_origin_.set_spot (THIS->here_input ());
765 THIS->lexer_->remove_scope ();
766 THIS->lexer_->add_scope (o->scope_);
767 THIS->lexer_->push_initial_state ();
769 | music_output_def_body assignment {
772 | music_output_def_body context_def_spec_block {
773 assign_context_def ($$, $2);
775 | music_output_def_body tempo_event {
777 junk this ? there already is tempo stuff in
780 int m = ly_scm2int ($2->get_property ("metronome-count"));
781 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
782 set_tempo ($$, d->get_length (), m);
783 scm_gc_unprotect_object ($2->self_scm ());
785 | music_output_def_body error {
791 TEMPO steno_duration '=' bare_unsigned {
792 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
793 $$->set_property ("tempo-unit", $2);
794 $$->set_property ("metronome-count", scm_int2num ( $4));
799 The representation of a list is the
803 to have efficient append.
807 $$ = scm_cons (SCM_EOL, SCM_EOL);
811 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
812 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
813 if (ly_c_pair_p (ly_cdr (s)))
814 scm_set_cdr_x (ly_cdr (s), c); /* append */
816 scm_set_car_x (s, c); /* set first cons */
817 scm_set_cdr_x (s, c); /* remember last cell */
819 | Music_list embedded_scm {
835 | ALTERNATIVE '{' Music_list '}' {
842 REPEAT simple_string bare_unsigned Music Alternative_music
846 SCM alts = ly_c_pair_p ($5) ? ly_car ($5) : SCM_EOL;
847 if (times < scm_ilength (alts)) {
848 unsmob_music (ly_car (alts))
849 ->origin ()->warning (
850 _ ("More alternatives than repeats. Junking excess alternatives."));
851 alts = ly_truncate_list (times, alts);
855 SCM proc = ly_scheme_function ("make-repeated-music");
857 SCM mus = scm_call_1 (proc, $2);
858 scm_gc_protect_object (mus); // UGH.
859 Music *r = unsmob_music (mus);
862 r-> set_property ("element", beg->self_scm ());
863 scm_gc_unprotect_object (beg->self_scm ());
865 r->set_property ("repeat-count", scm_int2num (times >? 1));
867 r-> set_property ("elements",alts);
868 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
870 TODO: move this code to Scheme.
874 we can not get durations and other stuff correct down the line, so we have to
875 add to the duration log here.
877 SCM func = ly_scheme_function ("shift-duration-log");
879 int dots = ($3 % 3) ? 0 : 1;
880 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
882 Sequential_music *seq = dynamic_cast<Sequential_music*> ($4);
885 int list_len = scm_ilength (seq->music_list ());
887 seq->origin ()->warning ("Chord tremolo must have 2 elements.");
889 r->compress (Moment (Rational (1, list_len)));
891 scm_call_3 (func, r->self_scm (), scm_int2num (shift),scm_int2num (dots));
894 r->set_spot (*$4->origin ());
901 SEQUENTIAL '{' Music_list '}' {
902 $$ = MY_MAKE_MUSIC ("SequentialMusic");
903 $$->set_property ("elements", ly_car ($3));
904 $$->set_spot (THIS->here_input ());
906 | '{' Music_list '}' {
907 $$ = MY_MAKE_MUSIC ("SequentialMusic");
908 $$->set_property ("elements", ly_car ($2));
909 $$->set_spot (THIS->here_input ());
914 SIMULTANEOUS '{' Music_list '}'{
915 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
916 $$->set_property ("elements", ly_car ($3));
917 $$->set_spot (THIS->here_input ());
920 | simul_open Music_list simul_close {
921 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
922 $$->set_property ("elements", ly_car ($2));
923 $$->set_spot (THIS->here_input ());
928 event_chord { $$ = $1; }
930 $$ = unsmob_music ($1);
937 optional_context_mod:
938 /**/ { $$ = SCM_EOL; }
939 | WITH { THIS->lexer_->push_initial_state (); }
940 '{' context_mod_list '}'
942 THIS->lexer_->pop_state ();
948 /* */ { $$ = SCM_EOL; }
949 | context_mod_list context_mod {
950 $$ = scm_cons ($2, $1);
956 Prefix_composite_music { $$ = $1; }
957 | Grouped_music_list { $$ = $1; }
961 Simultaneous_music { $$ = $1; }
962 | Sequential_music { $$ = $1; }
965 Generic_prefix_music_scm:
967 $$ = scm_list_2 ($1, make_input (THIS->here_input ()));
969 | MUSIC_FUNCTION_SCM {
972 $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3);
974 | MUSIC_FUNCTION_MUSIC {
977 $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3->self_scm ());
978 scm_gc_unprotect_object ($3->self_scm ());
980 | MUSIC_FUNCTION_SCM_MUSIC {
982 } embedded_scm Music {
983 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4->self_scm ());
984 scm_gc_unprotect_object ($4->self_scm ());
986 | MUSIC_FUNCTION_MUSIC_MUSIC {
989 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3->self_scm (), $4->self_scm ());
990 scm_gc_unprotect_object ($3->self_scm ());
991 scm_gc_unprotect_object ($4->self_scm ());
993 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC {
995 } embedded_scm Music Music {
996 $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()),
997 $3, $4->self_scm (), $5->self_scm ());
998 scm_gc_unprotect_object ($5->self_scm ());
999 scm_gc_unprotect_object ($4->self_scm ());
1003 Generic_prefix_music:
1004 Generic_prefix_music_scm {
1005 SCM func = ly_car ($1);
1006 Input *loc = unsmob_input (ly_cadr ($1));
1007 SCM args = ly_cddr ($1);
1008 SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
1011 for (SCM s = sig, t = args;
1012 ok && ly_c_pair_p (s) && ly_c_pair_p (t);
1013 s = ly_cdr (s), t = ly_cdr (t)) {
1015 if (scm_call_1 (ly_car (s), ly_car (t)) != SCM_BOOL_T)
1017 loc->error (_f ("Argument %d failed typecheck", k));
1018 THIS->error_level_ = 1;
1024 m = scm_apply_0 (func, ly_cdr ($1));
1025 if (unsmob_music (m))
1027 $$ = unsmob_music (m);
1028 scm_gc_protect_object (m);
1033 loc->error (_ ("Music head function should return Music object."));
1034 $$ = MY_MAKE_MUSIC ("Music");
1036 $$->set_spot (*loc);
1041 Prefix_composite_music:
1042 Generic_prefix_music {
1045 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1046 $$ = context_spec_music ($2, $4, $6, $5);
1049 | CONTEXT simple_string optional_context_mod Music {
1050 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1052 | NEWCONTEXT simple_string optional_context_mod Music {
1053 $$ = context_spec_music ($2, get_next_unique_context (), $4,
1064 int n = ly_scm2int (ly_car ($3)); int d = ly_scm2int (ly_cdr ($3));
1067 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1068 $$->set_spot (THIS->pop_spot ());
1070 $$->set_property ("element", mp->self_scm ());
1071 scm_gc_unprotect_object (mp->self_scm ());
1072 $$->set_property ("numerator", scm_int2num (n));
1073 $$->set_property ("denominator", scm_int2num (d));
1074 $$->compress (Moment (Rational (n,d)));
1077 | Repeated_music { $$ = $1; }
1078 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1079 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1081 Pitch from = *unsmob_pitch ($2);
1082 Pitch to = *unsmob_pitch ($3);
1084 p->transpose (interval (from, to));
1085 $$->set_property ("element", p->self_scm ());
1086 scm_gc_unprotect_object (p->self_scm ());
1090 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1091 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1095 THIS->lexer_->pop_state ();
1099 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1100 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1102 /* FIXME: This used to be: */
1104 /* Grouped_music_list */
1106 THIS->lexer_->pop_state ();
1109 { THIS->lexer_->push_figuredbass_state (); }
1110 /* FIXME: This used to be:
1112 but that breaks web build
1116 Music *chm = MY_MAKE_MUSIC ("UntransposableMusic");
1117 chm->set_property ("element", $3->self_scm ());
1119 scm_gc_unprotect_object ($3->self_scm ());
1121 THIS->lexer_->pop_state ();
1124 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1125 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1126 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1127 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1135 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1136 chm->set_property ("element", $3->self_scm ());
1137 scm_gc_unprotect_object ($3->self_scm ());
1140 THIS->lexer_->pop_state ();
1143 { THIS->lexer_->push_lyric_state (); }
1150 THIS->lexer_->pop_state ();
1152 | relative_music { $$ = $1; }
1153 | re_rhythmed_music { $$ = $1; }
1154 | TAG embedded_scm Music {
1155 tag_music ($3, $2, THIS->here_input ());
1161 RELATIVE absolute_pitch Music {
1163 Pitch start = *unsmob_pitch ($2);
1164 $$ = make_music_relative (start, m);
1165 scm_gc_unprotect_object (m->self_scm ());
1167 | RELATIVE Composite_music {
1169 /* FIXME: why is octave==0 and default not middleC? */
1170 Pitch middle_c (-1, 0, 0);
1171 $$ = make_music_relative (middle_c, m);
1172 scm_gc_unprotect_object (m->self_scm ());
1177 NEWLYRICS { THIS->lexer_->push_lyric_state (); }
1179 Grouped_music_list {
1180 /* Can also use Music at the expensive of two S/Rs similar to
1181 \repeat \alternative */
1182 THIS->lexer_->pop_state ();
1184 Music *music = MY_MAKE_MUSIC ("SimultaneousMusic");
1185 music->set_property ("elements", scm_list_1 ($3->self_scm ()));
1188 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1191 | new_lyrics NEWLYRICS { THIS->lexer_->push_lyric_state (); }
1192 Grouped_music_list {
1193 THIS->lexer_->pop_state ();
1194 $$ = scm_cons ($4->self_scm (), $1);
1199 Grouped_music_list new_lyrics {
1201 /* FIXME: should find out uniqueXXX name from music */
1202 SCM name = $1->get_property ("context-id");
1203 //if (name == SCM_EOL)
1204 if (!ly_c_string_p (name))
1205 name = scm_makfrom0str ("");
1207 SCM context = scm_makfrom0str ("Lyrics");
1208 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1211 for (SCM s = $2; ly_c_pair_p (s); s = ly_cdr (s))
1213 Music *music = unsmob_music (ly_car (s));
1214 Music *com = make_lyric_combine_music (name, music);
1215 Music *csm = context_spec_music (context,
1216 get_next_unique_context (), com, SCM_EOL);
1217 lst = scm_cons (csm->self_scm (), lst);
1219 /* FIXME: only first lyric music is accepted,
1220 the rest is junked */
1221 all->set_property ("elements", scm_cons ($1->self_scm (),
1224 scm_gc_unprotect_object ($1->self_scm ());
1226 | LYRICSTO string Music {
1229 $$ = make_lyric_combine_music (name, music);
1230 scm_gc_unprotect_object (music->self_scm ());
1235 CHANGE STRING '=' STRING {
1236 Music*t= MY_MAKE_MUSIC ("ContextChange");
1237 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1238 t-> set_property ("change-to-id", $4);
1241 $$->set_spot (THIS->here_input ());
1247 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1248 scm_string_to_symbol ($1), $3);
1250 | UNSET simple_string {
1251 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1252 scm_string_to_symbol ($2));
1254 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1255 $$ = scm_list_4 (ly_symbol2scm ("push"),
1256 scm_string_to_symbol ($2), $3, $5);
1258 | REVERT simple_string embedded_scm {
1259 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1260 scm_string_to_symbol ($2), $3);
1265 CONSISTSEND { $$ = ly_symbol2scm ("consists-end"); }
1266 | CONSISTS { $$ = ly_symbol2scm ("consists"); }
1267 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1269 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1270 | DENIES { $$ = ly_symbol2scm ("denies"); }
1272 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1273 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1274 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1275 | NAME { $$ = ly_symbol2scm ("context-name"); }
1279 property_operation { $$ = $1; }
1280 | context_def_mod STRING {
1281 $$ = scm_list_2 ($1, $2);
1287 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1288 scm_string_to_symbol ($1));
1290 | simple_string '.' simple_string {
1291 $$ = scm_list_2 (scm_string_to_symbol ($1),
1292 scm_string_to_symbol ($3));
1297 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1298 $$ = property_op_to_music (scm_list_4 (
1299 ly_symbol2scm ("poppush"),
1302 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1304 | REVERT context_prop_spec embedded_scm {
1305 $$ = property_op_to_music (scm_list_3 (
1306 ly_symbol2scm ("pop"),
1310 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1312 | SET context_prop_spec '=' scalar {
1313 $$ = property_op_to_music (scm_list_3 (
1314 ly_symbol2scm ("assign"),
1317 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1319 | UNSET context_prop_spec {
1320 $$ = property_op_to_music (scm_list_2 (
1321 ly_symbol2scm ("unset"),
1323 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1325 | ONCE music_property_def {
1326 SCM e = $2->get_property ("element");
1327 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1338 | STRING_IDENTIFIER {
1341 | string '+' string {
1342 $$ = scm_string_append (scm_list_2 ($1, $3));
1346 simple_string: STRING {
1357 $$ = scm_int2num ($1);
1364 $$ = scm_int2num ($1);
1369 FIXME: remove or fix this comment. What is `This'?
1373 Adding pre_events to the simple_element
1374 makes the choice between
1380 simple_element: STRING
1382 a single shift/reduction conflict.
1384 nevertheless, this is not very clean, and we should find a different
1394 pre_events simple_element post_events {
1395 SCM elts = $2-> get_property ("elements");
1397 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1399 $2->set_property ("elements", elts);
1403 | note_chord_element
1408 chord_body optional_notemode_duration post_events
1410 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1411 SCM es = $1->get_property ("elements");
1412 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1414 for (SCM s = es; ly_c_pair_p (s); s = ly_cdr (s))
1415 unsmob_music (ly_car (s))->set_property ("duration", dur);
1416 es = ly_append2 (es, postevs);
1418 $1-> set_property ("elements", es);
1429 simul_open: DOUBLE_ANGLE_OPEN
1432 simul_close: DOUBLE_ANGLE_CLOSE
1436 chord_open chord_body_elements chord_close
1438 $$ = MY_MAKE_MUSIC ("EventChord");
1439 $$->set_property ("elements",
1440 scm_reverse_x ($2, SCM_EOL));
1444 chord_body_elements:
1445 /* empty */ { $$ = SCM_EOL; }
1446 | chord_body_elements chord_body_element {
1447 $$ = scm_cons ($2->self_scm (), $1);
1448 scm_gc_unprotect_object ($2->self_scm ());
1453 pitch exclamations questions post_events
1455 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1456 n->set_property ("pitch", $1);
1458 n->set_property ("cautionary", SCM_BOOL_T);
1459 if ($2 % 2 || $3 % 2)
1460 n->set_property ("force-accidental", SCM_BOOL_T);
1462 if (ly_c_pair_p ($4)) {
1463 SCM arts = scm_reverse_x ($4, SCM_EOL);
1464 n->set_property ("articulations", arts);
1468 | DRUM_PITCH post_events {
1469 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1470 n->set_property ("duration", $2);
1471 n->set_property ("drum-type", $1);
1472 n->set_spot (THIS->here_input ());
1474 if (ly_c_pair_p ($2)) {
1475 SCM arts = scm_reverse_x ($2, SCM_EOL);
1476 n->set_property ("articulations", arts);
1483 ADDQUOTE string Music {
1484 SCM adder = ly_scheme_function ("add-quotable");
1486 scm_call_2 (adder, $2, $3->self_scm ());
1487 scm_gc_unprotect_object ($3->self_scm ());
1493 $$ = MY_MAKE_MUSIC ("EventChord");
1494 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1495 scm_gc_unprotect_object ($1->self_scm ());
1497 $$-> set_spot (THIS->here_input ());
1498 $1-> set_spot (THIS->here_input ());
1500 | SKIP duration_length {
1501 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1502 skip->set_property ("duration", $2);
1506 | QUOTE STRING duration_length {
1507 SCM tab = THIS->lexer_->lookup_identifier ("musicQuotes");
1509 if (scm_hash_table_p (tab) == SCM_BOOL_T)
1511 SCM key = $2; // use symbol?
1512 evs = scm_hash_ref (tab, key, SCM_BOOL_F);
1515 if (ly_c_vector_p (evs))
1517 quote = MY_MAKE_MUSIC ("QuoteMusic");
1518 quote->set_property ("duration", $3);
1519 quote->set_property ("quoted-events", evs);
1521 THIS->here_input ().warning (_f ("Can\'t find music"));
1522 quote = MY_MAKE_MUSIC ("Event");
1524 quote->set_spot (THIS->here_input ());
1527 | OCTAVE { THIS->push_spot (); }
1529 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1531 $$->set_spot (THIS->pop_spot ());
1532 $$->set_property ("pitch", $3);
1535 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1536 m->set_property ("span-direction", scm_int2num (START));
1537 m->set_spot (THIS->here_input ());
1539 $$ = MY_MAKE_MUSIC ("EventChord");
1540 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1541 scm_gc_unprotect_object (m->self_scm ());
1542 $$->set_spot (THIS->here_input ());
1545 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1546 m->set_property ("span-direction", scm_int2num (STOP));
1547 m->set_spot (THIS->here_input ());
1549 $$ = MY_MAKE_MUSIC ("EventChord");
1550 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1551 $$->set_spot (THIS->here_input ());
1552 scm_gc_unprotect_object (m->self_scm ());
1555 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1556 $$->set_spot (THIS->here_input ());
1559 SCM pipe =THIS->lexer_->lookup_identifier ("pipeSymbol");
1561 if (Music * m = unsmob_music (pipe))
1564 $$ = MY_MAKE_MUSIC ("BarCheck");
1566 $$->set_spot (THIS->here_input ());
1568 | TRANSPOSITION pitch {
1569 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1571 $$->set_spot (THIS-> here_input ());
1572 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1576 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1578 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1580 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1581 $$->set_spot (THIS->here_input ());
1582 t->set_spot (THIS->here_input ());
1584 | PARTIAL duration_length {
1585 Moment m = - unsmob_duration ($2)->get_length ();
1586 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1587 p->set_spot (THIS->here_input ());
1588 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1590 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1595 SCM proc = ly_scheme_function ("make-clef-set");
1597 SCM result = scm_call_1 (proc, $2);
1598 scm_gc_protect_object (result);
1599 $$ = unsmob_music (result);
1602 SCM proc= ly_scheme_function ("make-time-signature-set");
1604 SCM result = scm_apply_2 (proc, ly_car ($2), ly_cdr ($2), SCM_EOL);
1605 scm_gc_protect_object (result);
1606 $$ = unsmob_music (result);
1609 SCM proc = ly_scheme_function ("make-mark-set");
1611 SCM result = scm_call_1 (proc, $2);
1612 scm_gc_protect_object (result);
1613 $$ = unsmob_music (result);
1619 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1622 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1629 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1632 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1634 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1635 if (scm_ilength ($3) > 0)
1637 key->set_property ("pitch-alist", $3);
1638 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1639 ((Music*)key)->transpose (* unsmob_pitch ($2));
1641 THIS->parser_error (_ ("Second argument must be pitch list."));
1652 | post_events post_event {
1653 $2->set_spot (THIS->here_input ());
1654 $$ = scm_cons ($2->self_scm (), $$);
1655 scm_gc_unprotect_object ($2->self_scm ());
1657 | post_events tagged_post_event {
1658 $2 -> set_spot (THIS->here_input ());
1659 $$ = scm_cons ($2->self_scm (), $$);
1660 scm_gc_unprotect_object ($2->self_scm ());
1666 '-' TAG embedded_scm post_event {
1667 tag_music ($4, $3, THIS->here_input ());
1673 direction_less_event {
1677 if (!THIS->lexer_->is_lyric_state ())
1678 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1679 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1682 if (!THIS->lexer_->is_lyric_state ())
1683 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1684 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1686 | script_dir direction_reqd_event {
1688 $2->set_property ("direction", scm_int2num ($1));
1691 | script_dir direction_less_event {
1693 $2->set_property ("direction", scm_int2num ($1));
1696 | string_number_event
1699 string_number_event:
1701 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1702 s->set_property ("string-number", scm_int2num ($1));
1703 s->set_spot (THIS->here_input ());
1709 direction_less_event:
1715 TODO: should take all these defs out of the parser, adn make use
1719 (set-articulation '~ "trill")
1722 Music *m = MY_MAKE_MUSIC ("BeamEvent");
1723 m->set_spot (THIS->here_input ());
1724 m->set_property ("span-direction", scm_int2num (START));
1728 Music *m = MY_MAKE_MUSIC ("BeamEvent");
1729 m->set_spot (THIS->here_input ());
1730 m->set_property ("span-direction", scm_int2num (STOP));
1734 Music *m = MY_MAKE_MUSIC ("TieEvent");
1735 m->set_spot (THIS->here_input ());
1740 dynamic_cast<Music *> ($$)->set_property ("span-direction",
1741 scm_int2num (START));
1745 dynamic_cast<Music *> ($$)->set_property ("span-direction",
1746 scm_int2num (STOP));
1748 | EVENT_IDENTIFIER {
1749 $$ = unsmob_music ($1);
1752 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1753 a->set_spot (THIS->here_input ());
1754 a->set_property ("tremolo-type", scm_int2num ($1));
1759 direction_reqd_event:
1763 | script_abbreviation {
1764 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1765 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1766 if (ly_c_string_p (s))
1767 a->set_property ("articulation-type", s);
1768 else THIS->parser_error (_ ("Expecting string as script definition"));
1774 /**/ { $$ = SCM_EOL; }
1775 | '=' { $$ = scm_int2num (0); }
1776 | '=' sub_quotes { $$ = scm_int2num ($2); }
1777 | '=' sup_quotes { $$ = scm_int2num ($2); }
1802 | NOTENAME_PITCH sup_quotes {
1803 Pitch p = *unsmob_pitch ($1);
1804 p = p.transposed (Pitch ($2,0,0));
1805 $$ = p.smobbed_copy ();
1807 | NOTENAME_PITCH sub_quotes {
1808 Pitch p =* unsmob_pitch ($1);
1809 p = p.transposed (Pitch (-$2,0,0));
1810 $$ = p.smobbed_copy ();
1822 | TONICNAME_PITCH sup_quotes {
1823 Pitch p = *unsmob_pitch ($1);
1824 p = p.transposed (Pitch ($2,0,0));
1825 $$ = p.smobbed_copy ();
1827 | TONICNAME_PITCH sub_quotes {
1828 Pitch p =* unsmob_pitch ($1);
1830 p = p.transposed (Pitch (-$2,0,0));
1831 $$ = p.smobbed_copy ();
1841 pitch_also_in_chords:
1848 Music *s = MY_MAKE_MUSIC ("SlurEvent");
1850 s->set_spot (THIS->here_input ());
1853 Music *s = MY_MAKE_MUSIC ("PhrasingSlurEvent");
1855 s->set_spot (THIS->here_input ());
1858 Music *s = MY_MAKE_MUSIC ("CrescendoEvent");
1860 s->set_spot (THIS->here_input ());
1863 Music *s = MY_MAKE_MUSIC ("DecrescendoEvent");
1865 s->set_spot (THIS->here_input ());
1872 Music *s = MY_MAKE_MUSIC ("CrescendoEvent");
1873 s->set_spot (THIS->here_input ());
1878 Music *s= MY_MAKE_MUSIC ("SlurEvent");
1880 s->set_spot (THIS->here_input ());
1884 Music *s= MY_MAKE_MUSIC ("PhrasingSlurEvent");
1886 s->set_property ("span-type",
1887 scm_makfrom0str ("phrasing-slur"));
1888 s->set_spot (THIS->here_input ());
1894 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1895 t->set_property ("text", $1);
1896 t->set_spot (THIS->here_input ());
1900 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1901 t->set_property ("text",
1902 make_simple_markup (THIS->lexer_->encoding (), $1));
1903 t->set_spot (THIS->here_input ());
1908 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1909 t->set_property ("digit", scm_int2num ($1));
1910 t->set_spot (THIS->here_input ());
1915 script_abbreviation:
1917 $$ = scm_makfrom0str ("Hat");
1920 $$ = scm_makfrom0str ("Plus");
1923 $$ = scm_makfrom0str ("Dash");
1926 $$ = scm_makfrom0str ("Bar");
1929 $$ = scm_makfrom0str ("Larger");
1932 $$ = scm_makfrom0str ("Dot");
1935 $$ = scm_makfrom0str ("Underscore");
1942 | '-' { $$ = CENTER; }
1953 multiplied_duration {
1958 optional_notemode_duration:
1960 Duration dd = THIS->default_duration_;
1961 $$ = dd.smobbed_copy ();
1963 THIS->beam_check ($$);
1965 | multiplied_duration {
1967 THIS->default_duration_ = *unsmob_duration ($$);
1969 THIS->beam_check ($$);
1974 bare_unsigned dots {
1976 if (!is_duration ($1))
1977 THIS->parser_error (_f ("not a duration: %d", $1));
1981 $$ = Duration (len, $2).smobbed_copy ();
1983 | DURATION_IDENTIFIER dots {
1984 Duration *d = unsmob_duration ($1);
1985 Duration k (d->duration_log (), d->dot_count () + $2);
1991 multiplied_duration:
1995 | multiplied_duration '*' bare_unsigned {
1996 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1998 | multiplied_duration '*' FRACTION {
1999 Rational m (ly_scm2int (ly_car ($3)), ly_scm2int (ly_cdr ($3)));
2001 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2006 FRACTION { $$ = $1; }
2007 | UNSIGNED '/' UNSIGNED {
2008 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2025 | ':' bare_unsigned {
2026 if (!is_duration ($2))
2027 THIS->parser_error (_f ("not a duration: %d", $2));
2034 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2035 $$ = scm_list_2 (ly_scheme_function ("number-markup"),
2039 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2040 $$ = scm_list_2 (ly_scheme_function ("number-markup"),
2043 | STRING { $$ = $1; }
2054 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2055 $$ = bfr->self_scm ();
2056 scm_gc_unprotect_object ($$);
2059 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2060 $$ = bfr->self_scm ();
2062 bfr->set_property ("figure", $1);
2064 scm_gc_unprotect_object ($$);
2066 | bass_figure bass_mod {
2067 Music *m = unsmob_music ($1);
2069 SCM salter = m->get_property ("alteration");
2070 int alter = ly_c_number_p (salter) ? ly_scm2int (salter) : 0;
2071 m->set_property ("alteration",
2072 scm_int2num (alter + $2));
2074 m->set_property ("alteration", scm_int2num (0));
2082 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2087 | br_bass_figure ']' {
2089 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2097 | figure_list br_bass_figure {
2098 $$ = scm_cons ($2, $1);
2103 FIGURE_OPEN figure_list FIGURE_CLOSE {
2104 Music *m = MY_MAKE_MUSIC ("EventChord");
2105 $2 = scm_reverse_x ($2, SCM_EOL);
2106 m->set_property ("elements", $2);
2107 $$ = m->self_scm ();
2118 pitch exclamations questions oct_check optional_notemode_duration optional_rest {
2120 Input i = THIS->pop_spot ();
2121 if (!THIS->lexer_->is_note_state ())
2122 THIS->parser_error (_ ("Have to be in Note mode for notes"));
2126 n = MY_MAKE_MUSIC ("RestEvent");
2128 n = MY_MAKE_MUSIC ("NoteEvent");
2130 n->set_property ("pitch", $1);
2131 n->set_property ("duration", $5);
2133 if (ly_c_number_p ($4))
2135 int q = ly_scm2int ($4);
2136 n->set_property ("absolute-octave", scm_int2num (q-1));
2140 n->set_property ("cautionary", SCM_BOOL_T);
2141 if ($2 % 2 || $3 % 2)
2142 n->set_property ("force-accidental", SCM_BOOL_T);
2144 Music *v = MY_MAKE_MUSIC ("EventChord");
2145 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2146 scm_gc_unprotect_object (n->self_scm ());
2152 | DRUM_PITCH optional_notemode_duration {
2153 Input i = THIS->pop_spot ();
2155 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2156 n->set_property ("duration", $2);
2157 n->set_property ("drum-type", $1);
2159 Music *v = MY_MAKE_MUSIC ("EventChord");
2160 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2161 scm_gc_unprotect_object (n->self_scm ());
2167 | figure_spec optional_notemode_duration {
2168 Music *m = unsmob_music ($1);
2169 Input i = THIS->pop_spot ();
2171 for (SCM s = m->get_property ("elements"); ly_c_pair_p (s); s = ly_cdr (s))
2173 unsmob_music (ly_car (s))->set_property ("duration", $2);
2177 | RESTNAME optional_notemode_duration {
2179 Input i = THIS->pop_spot ();
2181 if (ly_scm2string ($1) == "s") {
2183 ev = MY_MAKE_MUSIC ("SkipEvent");
2186 ev = MY_MAKE_MUSIC ("RestEvent");
2189 ev->set_property ("duration", $2);
2191 Music *velt = MY_MAKE_MUSIC ("EventChord");
2192 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2195 scm_gc_unprotect_object (ev->self_scm ());
2199 | MULTI_MEASURE_REST optional_notemode_duration {
2202 SCM proc = ly_scheme_function ("make-multi-measure-rest");
2203 SCM mus = scm_call_2 (proc, $2,
2204 make_input (THIS->here_input ()));
2205 scm_gc_protect_object (mus);
2206 $$ = unsmob_music (mus);
2209 | lyric_element optional_notemode_duration {
2210 Input i = THIS->pop_spot ();
2211 if (!THIS->lexer_->is_lyric_state ())
2212 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
2214 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2215 lreq->set_property ("text", $1);
2216 lreq->set_property ("duration",$2);
2218 Music *velt = MY_MAKE_MUSIC ("EventChord");
2219 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2226 if (!THIS->lexer_->is_chord_state ())
2227 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
2228 $$ = unsmob_music ($1);
2233 /* FIXME: lyric flavoured markup would be better */
2241 steno_tonic_pitch optional_notemode_duration {
2242 $$ = make_chord ($1, $2, SCM_EOL);
2244 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2245 SCM its = scm_reverse_x ($4, SCM_EOL);
2246 $$ = make_chord ($1, $2, scm_cons ($3, its));
2254 | chord_items chord_item {
2255 $$ = scm_cons ($2, $$);
2261 $$ = ly_symbol2scm ("chord-colon");
2264 $$ = ly_symbol2scm ("chord-caret");
2266 | CHORD_SLASH steno_tonic_pitch {
2267 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2269 | CHORD_BASS steno_tonic_pitch {
2270 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2279 $$ = scm_reverse_x ($1, SCM_EOL);
2287 step_number { $$ = scm_cons ($1, SCM_EOL); }
2288 | step_numbers '.' step_number {
2289 $$ = scm_cons ($3, $$);
2295 $$ = make_chord_step ($1, 0);
2297 | bare_unsigned '+' {
2298 $$ = make_chord_step ($1, SHARP);
2300 | bare_unsigned CHORD_MINUS {
2301 $$ = make_chord_step ($1, FLAT);
2308 TODO: should deprecate in favor of Scheme?
2312 number_expression '+' number_term {
2313 $$ = scm_sum ($1, $3);
2315 | number_expression '-' number_term {
2316 $$ = scm_difference ($1, $3);
2325 | number_factor '*' number_factor {
2326 $$ = scm_product ($1, $3);
2328 | number_factor '/' number_factor {
2329 $$ = scm_divide ($1, $3);
2334 '-' number_factor { /* %prec UNARY_MINUS */
2335 $$ = scm_difference ($2, SCM_UNDEFINED);
2343 $$ = scm_int2num ($1);
2348 | NUMBER_IDENTIFIER {
2351 | REAL NUMBER_IDENTIFIER {
2352 $$ = scm_make_real (ly_scm2double ($1) *ly_scm2double ($2));
2354 | UNSIGNED NUMBER_IDENTIFIER {
2355 $$ = scm_make_real ($1 *ly_scm2double ($2));
2371 if (scm_integer_p ($1) == SCM_BOOL_T)
2373 int k = ly_scm2int ($1);
2377 THIS->parser_error (_ ("need integer number arg"));
2388 | exclamations '!' { $$ ++; }
2393 | questions '?' { $$ ++; }
2403 { THIS->lexer_->push_markup_state (); }
2406 THIS->lexer_->pop_state ();
2412 This should be done more dynamically if possible.
2416 $$ = make_simple_markup (THIS->lexer_->encoding (), $1);
2418 | MARKUP_HEAD_EMPTY {
2419 $$ = scm_list_1 ($1);
2421 | MARKUP_HEAD_MARKUP0 markup {
2422 $$ = scm_list_2 ($1, $2);
2424 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2425 $$ = scm_list_3 ($1, $2, $3);
2427 | MARKUP_HEAD_SCM0_MARKUP1 SCM_T markup {
2428 $$ = scm_list_3 ($1, $2, $3);
2433 | MARKUP_HEAD_LIST0 markup_list {
2434 $$ = scm_list_2 ($1,$2);
2436 | MARKUP_HEAD_SCM0 embedded_scm {
2437 $$ = scm_list_2 ($1, $2);
2439 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup {
2440 $$ = scm_list_4 ($1, $2, $3, $4);
2442 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2443 $$ = scm_list_4 ($1, $2, $3, $4);
2445 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2446 $$ = scm_list_3 ($1, $2, $3);
2448 | MARKUP_IDENTIFIER {
2451 | STRING_IDENTIFIER {
2455 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
2456 THIS->lexer_->push_note_state (alist_to_hashq (nn));
2458 /* cont */ score_block {
2459 /* WIP this is a bit arbitrary,
2460 we should also allow \book or Composite_music.
2461 However, you'd typically want to change paper
2462 settings, and need a \score block anyway. */
2464 THIS->lexer_->pop_state ();
2466 Book *book = new Book;
2467 book->scores_.push (score);
2469 Output_def *paper = get_paper (THIS);
2470 book->bookpaper_ = get_bookpaper (THIS);
2472 SCM s = book->to_stencil (paper, THIS->header_);
2473 scm_gc_unprotect_object (score->self_scm ());
2474 scm_gc_unprotect_object (book->self_scm ());
2475 $$ = scm_list_2 (ly_scheme_function ("stencil-markup"), s);
2480 chord_open markup_list_body chord_close { $$ = scm_reverse_x ($2, SCM_EOL); }
2484 '{' markup_list_body '}' {
2485 SCM line = ly_scheme_function ("line-markup");
2487 $$ = scm_list_2 (line, scm_reverse_x ($2, SCM_EOL));
2492 /**/ { $$ = SCM_EOL; }
2493 | markup_list_body markup {
2494 $$ = scm_cons ($2, $1);
2502 My_lily_parser::set_yydebug (bool )
2510 My_lily_parser::do_yyparse ()
2512 yyparse ((void*)this);
2517 Should make this optional? It will also complain when you do
2521 which is entirely legitimate.
2523 Or we can scrap it. Barchecks should detect wrong durations, and
2524 skipTypesetting speeds it up a lot.
2528 My_lily_parser::beam_check (SCM dur)
2530 Duration *d = unsmob_duration (dur);
2531 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2533 Music *m = unsmob_music (last_beam_start_);
2534 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2536 last_beam_start_ = SCM_EOL;
2544 It is a little strange to have this function in this file, but
2545 otherwise, we have to import music classes into the lexer.
2549 My_lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2551 if (ly_c_string_p (sid)) {
2553 return STRING_IDENTIFIER;
2554 } else if (ly_c_number_p (sid)) {
2556 return NUMBER_IDENTIFIER;
2557 } else if (unsmob_context_def (sid)) {
2558 *destination = unsmob_context_def (sid)->clone_scm ();
2559 return CONTEXT_DEF_IDENTIFIER;
2560 } else if (unsmob_score (sid)) {
2561 Score *score = new Score (*unsmob_score (sid));
2562 *destination = score->self_scm ();
2563 return SCORE_IDENTIFIER;
2564 } else if (Music *mus = unsmob_music (sid)) {
2565 mus = mus->clone ();
2566 *destination = mus->self_scm ();
2567 unsmob_music (*destination)->
2568 set_property ("origin", make_input (last_input_));
2569 return dynamic_cast<Event*> (mus)
2570 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2571 } else if (unsmob_duration (sid)) {
2572 *destination = unsmob_duration (sid)->smobbed_copy ();
2573 return DURATION_IDENTIFIER;
2574 } else if (unsmob_output_def (sid)) {
2575 Output_def *p = unsmob_output_def (sid);
2578 *destination = p->self_scm ();
2579 return MUSIC_OUTPUT_DEF_IDENTIFIER;
2580 } else if (Text_item::markup_p (sid)) {
2582 return MARKUP_IDENTIFIER;
2589 property_op_to_music (SCM op)
2592 SCM tag = ly_car (op);
2593 SCM symbol = ly_cadr (op);
2594 SCM args = ly_cddr (op);
2595 SCM grob_val = SCM_UNDEFINED;
2596 SCM grob_sym = SCM_UNDEFINED;
2597 SCM val = SCM_UNDEFINED;
2599 if (tag == ly_symbol2scm ("assign"))
2601 m = MY_MAKE_MUSIC ("PropertySet");
2602 val = ly_car (args);
2604 else if (tag == ly_symbol2scm ("unset"))
2605 m = MY_MAKE_MUSIC ("PropertyUnset");
2606 else if (tag == ly_symbol2scm ("poppush")
2607 || tag == ly_symbol2scm ("push"))
2609 m = MY_MAKE_MUSIC ("OverrideProperty");
2610 grob_sym = ly_car (args);
2611 grob_val = ly_cadr (args);
2613 else if (tag == ly_symbol2scm ("pop")) {
2614 m = MY_MAKE_MUSIC ("RevertProperty");
2615 grob_sym = ly_car (args);
2618 m->set_property ("symbol", symbol);
2620 if (val != SCM_UNDEFINED)
2621 m->set_property ("value", val);
2622 if (grob_val != SCM_UNDEFINED)
2623 m->set_property ("grob-value", grob_val);
2625 if (grob_sym != SCM_UNDEFINED)
2627 bool itc = internal_type_checking_global_b;
2630 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2632 internal_type_checking_global_b = false;
2633 m->set_property ("grob-property", grob_sym);
2635 internal_type_checking_global_b = itc;
2638 if (tag == ly_symbol2scm ("poppush"))
2639 m->set_property ("pop-first", SCM_BOOL_T);
2646 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2648 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2650 csm->set_property ("element", m->self_scm ());
2651 scm_gc_unprotect_object (m->self_scm ());
2653 csm->set_property ("context-type",
2654 ly_c_symbol_p (type) ? type : scm_string_to_symbol (type));
2655 csm->set_property ("property-operations", ops);
2657 if (ly_c_string_p (id))
2658 csm->set_property ("context-id", id);
2663 get_next_unique_context ()
2665 static int new_context_count;
2667 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2668 return scm_makfrom0str (s);