1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for LilyPond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
16 * The rules for who is protecting what are very shady. Uniformise
19 * There are too many lexical modes?
29 #include "context-def.hh"
30 #include "dimensions.hh"
32 #include "file-path.hh"
33 #include "input-smob.hh"
35 #include "lily-guile.hh"
36 #include "lilypond-input-version.hh"
37 #include "ly-module.hh"
39 #include "midi-def.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 "paper-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 Music_output_def *outputdef;
206 yylex (YYSTYPE *s, void *v)
208 My_lily_parser *pars = (My_lily_parser*) v;
209 My_lily_lexer *lex = pars->lexer_;
211 lex->lexval = (void*) s;
212 lex->prepare_for_next_token ();
213 return lex->yylex ();
222 Three shift/reduce problems:
224 2. \markup identifier.
229 \repeat .. \alternative
232 \repeat { \repeat .. \alternative }
236 \repeat { \repeat } \alternative
258 %token CHORDMODIFIERS
260 %token DOUBLE_ANGLE_OPEN
261 %token DOUBLE_ANGLE_CLOSE
263 %token COMMANDSPANREQUEST
271 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
272 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
276 %token GROBDESCRIPTIONS
285 %token MULTI_MEASURE_REST
291 %token OVERRIDE SET REVERT
318 /* FIXME: this sucks. The user will get to see these names:
319 syntax error, unexpected E_CHAR:
323 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
324 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
326 %token <i> E_UNSIGNED
327 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
331 %token <scm> NOTENAME_PITCH
332 %token <scm> TONICNAME_PITCH
333 %token <scm> CHORDMODIFIER_PITCH
334 %token <scm> DURATION_IDENTIFIER
335 %token <scm> FRACTION
336 %token <id> IDENTIFIER
338 %token <scm> DRUM_PITCH
339 %token <scm> CHORD_MODIFIER
340 %token <scm> SCORE_IDENTIFIER
341 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
342 %token <scm> NUMBER_IDENTIFIER
343 %token <scm> EVENT_IDENTIFIER
344 %token <scm> MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
345 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
346 %token <scm> RESTNAME
353 %token <scm> MARKUP_HEAD_MARKUP0
354 %token <scm> MARKUP_HEAD_EMPTY
355 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
356 %token <scm> MARKUP_HEAD_SCM0
357 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
358 %token <scm> MARKUP_HEAD_SCM0_SCM1
359 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
360 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
362 %token <scm> MUSIC_FUNCTION_SCM
363 %token <scm> MUSIC_FUNCTION_MUSIC
364 %token <scm> MUSIC_FUNCTION_SCM_MUSIC
365 %token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
366 %token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
367 %token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
369 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
370 %type <scm> markup markup_line markup_list markup_list_body full_markup
372 %type <book> book_block book_body
373 %type <i> exclamations questions dots optional_rest
375 %type <scm> grace_head
376 %type <scm> oct_check
377 %type <scm> context_mod_list
378 %type <scm> lyric_element
379 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
380 %type <scm> new_lyrics
381 %type <outputdef> output_def
382 %type <scm> lilypond_header lilypond_header_body
383 %type <music> open_event close_event
384 %type <i> sub_quotes sup_quotes
385 %type <music> toplevel_music
386 %type <music> simple_element event_chord command_element
387 %type <music> Composite_music Simple_music Prefix_composite_music Generic_prefix_music
388 %type <scm> Generic_prefix_music_scm
389 %type <music> Grouped_music_list
390 %type <music> Repeated_music
391 %type <scm> Alternative_music
392 %type <i> tremolo_type
393 %type <i> bare_int bare_unsigned
395 %type <scm> identifier_init
396 %type <scm> simple_string
398 %type <music> note_chord_element chord_body chord_body_element
399 %type <scm> chord_body_elements
400 %type <scm> steno_duration optional_notemode_duration multiplied_duration
402 %type <scm> post_events
403 %type <music> gen_text_def direction_less_event direction_reqd_event
404 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
405 %type <scm> steno_tonic_pitch
406 %type <scm> duration_length fraction
408 %type <scm> chord_item chord_items chord_separator new_chord
409 %type <scm> step_number step_numbers
411 %type <scm> embedded_scm scalar
412 %type <music> Music Sequential_music Simultaneous_music
413 %type <music> relative_music re_rhythmed_music
414 %type <music> music_property_def context_change
415 %type <scm> context_prop_spec
416 %type <scm> Music_list
417 %type <scm> property_operation
418 %type <scm> context_mod context_def_mod optional_context_mod
419 %type <outputdef> music_output_def_body music_output_def_head
420 %type <music> post_event tagged_post_event
421 %type <music> command_req
422 %type <music> string_number_event
423 %type <scm> string bare_number number_expression number_term number_factor
424 %type <score> score_block score_body
426 %type <scm> context_def_spec_block context_def_spec_body
427 %type <music> tempo_event
428 %type <scm> script_abbreviation
434 /* We don't assign precedence to / and *, because we might need varied
435 prec levels in different prods */
441 lilypond: /* empty */
442 | lilypond toplevel_expression {
444 | lilypond assignment {
447 THIS->error_level_ = 1;
450 THIS->error_level_ = 1;
463 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-book-handler");
464 scm_call_2 (proc, THIS->self_scm (), book->self_scm ());
465 scm_gc_unprotect_object (book->self_scm ());
470 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-score-handler");
471 scm_call_2 (proc, THIS->self_scm (), score->self_scm ());
472 scm_gc_unprotect_object (score->self_scm ());
476 SCM proc = THIS->lexer_->lookup_identifier ("toplevel-music-handler");
477 scm_call_2 (proc, THIS->self_scm (), music->self_scm ());
478 scm_gc_unprotect_object (music->self_scm ());
482 if (dynamic_cast<Paper_def*> ($1))
483 id = scm_makfrom0str ("$defaultpaper");
484 else if (dynamic_cast<Midi_def*> ($1))
485 id = scm_makfrom0str ("$defaultmidi");
486 THIS->lexer_->set_identifier (id, $1->self_scm ());
487 scm_gc_unprotect_object ($1->self_scm ());
502 lilypond_header_body:
504 $$ = ly_make_anonymous_module ();
505 THIS->lexer_->add_scope ($$);
507 | lilypond_header_body assignment {
513 HEADER '{' lilypond_header_body '}' {
514 $$ = THIS->lexer_->remove_scope ();
526 /* cont */ '=' identifier_init {
529 Should find generic way of associating input with objects.
531 Input ip = THIS->pop_spot ();
533 if (! is_regular_identifier ($1))
535 ip.warning (_ ("Identifier should have alphabetic characters only"));
538 THIS->lexer_->set_identifier ($1, $4);
541 TODO: devise standard for protection in parser.
543 The parser stack lives on the C-stack, which means that
544 all objects can be unprotected as soon as they're here.
554 $$ = $1->self_scm ();
555 scm_gc_unprotect_object ($$);
561 $$ = $1->self_scm ();
562 scm_gc_unprotect_object ($$);
564 | context_def_spec_block {
568 $$ = $1->self_scm ();
569 scm_gc_unprotect_object ($$);
572 $$ = $1->self_scm ();
573 scm_gc_unprotect_object ($$);
575 | number_expression {
586 context_def_spec_block:
587 CONTEXT '{' context_def_spec_body '}'
593 context_def_spec_body:
595 $$ = Context_def::make_scm ();
596 unsmob_context_def ($$)->set_spot (THIS->here_input ());
598 | CONTEXT_DEF_IDENTIFIER {
600 unsmob_context_def ($$)->set_spot (THIS->here_input ());
602 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
603 Context_def*td = unsmob_context_def ($$);
605 for (SCM p = $3; ly_c_pair_p (p); p = ly_cdr (p)) {
606 SCM tag = ly_caar (p);
608 /* TODO: should make new tag "grob-definition" ? */
609 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
610 tag, scm_cons (ly_cdar (p), SCM_EOL)));
613 | context_def_spec_body context_mod {
614 unsmob_context_def ($$)->add_context_mod ($2);
622 /*cont*/ '{' book_body '}' {
631 $$->set_spot (THIS->here_input ());
633 | book_body score_block {
634 $$->scores_.push ($2);
635 scm_gc_unprotect_object ($2->self_scm ());
645 /*cont*/ '{' score_body '}' {
655 $$->set_spot (THIS->here_input ());
656 SCM m = $1->self_scm ();
657 scm_gc_unprotect_object (m);
662 SCM check_funcs = ly_scheme_function ("toplevel-music-functions");
663 for (; ly_c_pair_p (check_funcs); check_funcs = ly_cdr (check_funcs))
664 m = scm_call_1 (ly_car (check_funcs), m);
669 $$ = new Score ( *unsmob_score ($1));
670 $$->set_spot (THIS->here_input ());
672 | score_body lilypond_header {
675 | score_body output_def {
677 scm_gc_unprotect_object ($2->self_scm ());
689 music_output_def_body '}' {
691 THIS->lexer_->remove_scope ();
692 THIS->lexer_->pop_state ();
696 music_output_def_head:
698 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultmidi"));
703 p = dynamic_cast<Midi_def*> (id->clone ());
708 THIS->lexer_->add_scope (p->scope_);
711 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"));
714 p = dynamic_cast<Paper_def*> (id->clone ());
718 THIS->lexer_->add_scope (p->scope_);
724 music_output_def_body:
725 music_output_def_head '{' {
727 $$->input_origin_. set_spot (THIS->here_input ());
728 THIS->lexer_->push_initial_state ();
730 | music_output_def_head '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
731 scm_gc_unprotect_object ($1->self_scm ());
732 Music_output_def *o = unsmob_music_output_def ($3);
733 o->input_origin_.set_spot (THIS->here_input ());
735 THIS->lexer_->remove_scope ();
736 THIS->lexer_->add_scope (o->scope_);
737 THIS->lexer_->push_initial_state ();
739 | music_output_def_body assignment {
742 | music_output_def_body context_def_spec_block {
743 $$->assign_context_def ($2);
745 | music_output_def_body tempo_event {
747 junk this ? there already is tempo stuff in
750 int m = ly_scm2int ( $2->get_property ("metronome-count"));
751 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
752 Midi_def *md = dynamic_cast<Midi_def*> ($$);
754 md->set_tempo (d->get_length (), m);
755 scm_gc_unprotect_object ($2->self_scm ());
757 | music_output_def_body error {
763 TEMPO steno_duration '=' bare_unsigned {
764 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
765 $$->set_property ("tempo-unit", $2);
766 $$->set_property ("metronome-count", scm_int2num ( $4));
771 The representation of a list is the
775 to have efficient append.
779 $$ = scm_cons (SCM_EOL, SCM_EOL);
783 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
784 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
785 if (ly_c_pair_p (ly_cdr (s)))
786 scm_set_cdr_x (ly_cdr (s), c); /* append */
788 scm_set_car_x (s, c); /* set first cons */
789 scm_set_cdr_x (s, c); /* remember last cell */
791 | Music_list embedded_scm {
807 | ALTERNATIVE '{' Music_list '}' {
814 REPEAT simple_string bare_unsigned Music Alternative_music
818 SCM alts = ly_c_pair_p ($5) ? ly_car ($5) : SCM_EOL;
819 if (times < scm_ilength (alts)) {
820 unsmob_music (ly_car (alts))
821 ->origin ()->warning (
822 _ ("More alternatives than repeats. Junking excess alternatives."));
823 alts = ly_truncate_list (times, alts);
827 SCM proc = ly_scheme_function ("make-repeated-music");
829 SCM mus = scm_call_1 (proc, $2);
830 scm_gc_protect_object (mus); // UGH.
831 Music *r = unsmob_music (mus);
834 r-> set_property ("element", beg->self_scm ());
835 scm_gc_unprotect_object (beg->self_scm ());
837 r->set_property ("repeat-count", scm_int2num (times >? 1));
839 r-> set_property ("elements",alts);
840 if (ly_c_equal_p ($2, scm_makfrom0str ("tremolo"))) {
842 TODO: move this code to Scheme.
846 we can not get durations and other stuff correct down the line, so we have to
847 add to the duration log here.
849 SCM func = ly_scheme_function ("shift-duration-log");
851 int dots = ($3 % 3) ? 0 : 1;
852 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
854 Sequential_music *seq = dynamic_cast<Sequential_music*> ($4);
857 int list_len = scm_ilength (seq->music_list ());
859 seq->origin ()->warning ("Chord tremolo must have 2 elements.");
861 r->compress (Moment (Rational (1, list_len)));
863 scm_call_3 (func, r->self_scm (), scm_int2num (shift),scm_int2num (dots));
866 r->set_spot (*$4->origin ());
873 SEQUENTIAL '{' Music_list '}' {
874 $$ = MY_MAKE_MUSIC ("SequentialMusic");
875 $$->set_property ("elements", ly_car ($3));
876 $$->set_spot (THIS->here_input ());
878 | '{' Music_list '}' {
879 $$ = MY_MAKE_MUSIC ("SequentialMusic");
880 $$->set_property ("elements", ly_car ($2));
881 $$->set_spot (THIS->here_input ());
886 SIMULTANEOUS '{' Music_list '}'{
887 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
888 $$->set_property ("elements", ly_car ($3));
889 $$->set_spot (THIS->here_input ());
892 | simul_open Music_list simul_close {
893 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
894 $$->set_property ("elements", ly_car ($2));
895 $$->set_spot (THIS->here_input ());
900 event_chord { $$ = $1; }
901 | APPLYOUTPUT embedded_scm {
902 if (!ly_input_procedure_p ($2))
903 THIS->parser_error (_ ("\\applycontext takes function argument"));
904 $$ = MY_MAKE_MUSIC ("ApplyOutputEvent");
905 $$->set_property ("procedure", $2);
906 $$->set_spot (THIS->here_input ());
908 | APPLYCONTEXT embedded_scm {
909 if (!ly_input_procedure_p ($2))
910 THIS->parser_error (_ ("\\applycontext takes function argument"));
911 $$ = MY_MAKE_MUSIC ("ApplyContext");
912 $$->set_property ("procedure", $2);
913 $$->set_spot (THIS->here_input ());
916 $$ = unsmob_music ($1);
923 optional_context_mod:
924 /**/ { $$ = SCM_EOL; }
925 | WITH { THIS->lexer_->push_initial_state (); }
926 '{' context_mod_list '}'
928 THIS->lexer_->pop_state ();
934 GRACE { $$ = scm_makfrom0str ("Grace"); }
935 | ACCIACCATURA { $$ = scm_makfrom0str ("Acciaccatura"); }
936 | APPOGGIATURA { $$ = scm_makfrom0str ("Appoggiatura"); }
940 /* */ { $$ = SCM_EOL; }
941 | context_mod_list context_mod {
942 $$ = scm_cons ($2, $1);
948 Prefix_composite_music { $$ = $1; }
949 | Grouped_music_list { $$ = $1; }
953 Simultaneous_music { $$ = $1; }
954 | Sequential_music { $$ = $1; }
957 Generic_prefix_music_scm:
961 $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3);
963 | MUSIC_FUNCTION_MUSIC {
966 $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3->self_scm ());
967 scm_gc_unprotect_object ($3->self_scm ());
969 | MUSIC_FUNCTION_SCM_MUSIC {
971 } embedded_scm Music {
972 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4->self_scm ());
973 scm_gc_unprotect_object ($4->self_scm ());
975 | MUSIC_FUNCTION_MUSIC_MUSIC {
978 $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3->self_scm (), $4->self_scm ());
979 scm_gc_unprotect_object ($3->self_scm ());
980 scm_gc_unprotect_object ($4->self_scm ());
982 | MUSIC_FUNCTION_SCM_MUSIC_MUSIC {
984 } embedded_scm Music Music {
985 $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()),
986 $3, $4->self_scm (), $5->self_scm ());
987 scm_gc_unprotect_object ($5->self_scm ());
988 scm_gc_unprotect_object ($4->self_scm ());
992 Generic_prefix_music:
993 Generic_prefix_music_scm {
994 SCM func = ly_car ($1);
995 Input *loc = unsmob_input (ly_cadr ($1));
996 SCM args = ly_cddr ($1);
997 SCM sig = scm_object_property (func, ly_symbol2scm ("music-head-signature"));
1000 for (SCM s = sig, t = args;
1001 ok && ly_c_pair_p (s) && ly_c_pair_p (t);
1002 s = ly_cdr (s), t = ly_cdr (t)) {
1004 if (scm_call_1 (ly_car (s), ly_car (t)) != SCM_BOOL_T)
1006 loc->error (_f ("Argument %d failed typecheck", k));
1007 THIS->error_level_ = 1;
1013 m = scm_apply_0 (func, ly_cdr ($1));
1014 if (unsmob_music (m))
1016 $$ = unsmob_music (m);
1017 scm_gc_protect_object (m);
1021 loc->error (_ ("Music head function should return Music object."));
1022 $$ = MY_MAKE_MUSIC ("Music");
1029 Prefix_composite_music:
1030 Generic_prefix_music {
1034 SCM proc = ly_scheme_function ("make-autochange-music");
1036 SCM res = scm_call_1 (proc, $2->self_scm ());
1037 scm_gc_unprotect_object ($2->self_scm ());
1038 $$ = unsmob_music (res);
1039 scm_gc_protect_object (res);
1040 $$->set_spot (THIS->here_input ());
1042 | PARTCOMBINE Music Music {
1043 SCM proc = ly_scheme_function ("make-part-combine-music");
1045 SCM res = scm_call_1 (proc, scm_listify ($2->self_scm (),
1046 $3->self_scm (), SCM_UNDEFINED));
1047 scm_gc_unprotect_object ($3->self_scm ());
1048 scm_gc_unprotect_object ($2->self_scm ());
1049 $$ = unsmob_music (res);
1050 scm_gc_protect_object (res);
1051 $$->set_spot (THIS->here_input ());
1053 | grace_head Music {
1056 The other version is for easier debugging of
1057 Sequential_music_iterator in combination with grace notes.
1062 TODO: should distinguish between both grace types in the
1063 basic music objects too, since the meaning is different.
1067 String start_str = "start" + ly_scm2string ($1) + "Music";
1068 String stop_str = "stop" + ly_scm2string ($1) + "Music";
1070 SCM start = THIS->lexer_->lookup_identifier (start_str);
1071 SCM stop = THIS->lexer_->lookup_identifier (stop_str);
1073 Music *startm = unsmob_music (start);
1074 Music *stopm = unsmob_music (stop);
1078 stopm = stopm->clone ();
1079 ms = scm_cons (stopm->self_scm (), ms);
1080 scm_gc_unprotect_object (stopm->self_scm ());
1082 ms = scm_cons ($2->self_scm (), ms);
1083 scm_gc_unprotect_object ($2->self_scm ());
1085 startm = startm->clone ();
1086 ms = scm_cons (startm->self_scm (), ms);
1087 scm_gc_unprotect_object (startm->self_scm ());
1090 Music* seq = MY_MAKE_MUSIC ("SequentialMusic");
1091 seq->set_property ("elements", ms);
1094 $$ = MY_MAKE_MUSIC ("GraceMusic");
1095 $$->set_property ("element", seq->self_scm ());
1096 scm_gc_unprotect_object (seq->self_scm ());
1098 $$ = MY_MAKE_MUSIC ("GraceMusic");
1099 $$->set_property ("element", $2->self_scm ());
1100 scm_gc_unprotect_object ($2->self_scm ());
1103 | CONTEXT simple_string '=' simple_string optional_context_mod Music {
1104 $$ = context_spec_music ($2, $4, $6, $5);
1107 | CONTEXT simple_string optional_context_mod Music {
1108 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
1110 | NEWCONTEXT simple_string optional_context_mod Music {
1111 $$ = context_spec_music ($2, get_next_unique_context (), $4,
1122 int n = ly_scm2int (ly_car ($3)); int d = ly_scm2int (ly_cdr ($3));
1125 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
1126 $$->set_spot (THIS->pop_spot ());
1128 $$->set_property ("element", mp->self_scm ());
1129 scm_gc_unprotect_object (mp->self_scm ());
1130 $$->set_property ("numerator", scm_int2num (n));
1131 $$->set_property ("denominator", scm_int2num (d));
1132 $$->compress (Moment (Rational (n,d)));
1135 | Repeated_music { $$ = $1; }
1136 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
1137 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1139 Pitch from = *unsmob_pitch ($2);
1140 Pitch to = *unsmob_pitch ($3);
1142 p->transpose (interval (from, to));
1143 $$->set_property ("element", p->self_scm ());
1144 scm_gc_unprotect_object (p->self_scm ());
1146 | APPLY embedded_scm Music {
1147 if (!ly_input_procedure_p ($2))
1149 THIS->parser_error (_ ("\\apply takes function argument"));
1154 SCM ret = scm_call_1 ($2, $3->self_scm ());
1155 Music *m = unsmob_music (ret);
1157 THIS->parser_error ("\\apply must return a Music");
1158 m = MY_MAKE_MUSIC ("Music");
1165 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1166 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1170 THIS->lexer_->pop_state ();
1174 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1175 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1177 /* FIXME: This used to be: */
1179 /* Grouped_music_list */
1181 THIS->lexer_->pop_state ();
1184 { THIS->lexer_->push_figuredbass_state (); }
1185 /* FIXME: This used to be:
1187 but that breaks web build
1191 Music *chm = MY_MAKE_MUSIC ("UntransposableMusic");
1192 chm->set_property ("element", $3->self_scm ());
1194 scm_gc_unprotect_object ($3->self_scm ());
1196 THIS->lexer_->pop_state ();
1199 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1200 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1201 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1202 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1210 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1211 chm->set_property ("element", $3->self_scm ());
1212 scm_gc_unprotect_object ($3->self_scm ());
1215 THIS->lexer_->pop_state ();
1218 { THIS->lexer_->push_lyric_state (); }
1225 THIS->lexer_->pop_state ();
1227 | relative_music { $$ = $1; }
1228 | re_rhythmed_music { $$ = $1; }
1229 | TAG embedded_scm Music {
1230 tag_music ($3, $2, THIS->here_input ());
1236 RELATIVE absolute_pitch Music {
1238 Pitch start = *unsmob_pitch ($2);
1239 $$ = make_music_relative (start, m);
1240 scm_gc_unprotect_object (m->self_scm ());
1242 | RELATIVE Composite_music {
1244 /* FIXME: why is octave==0 and default not middleC? */
1245 Pitch middle_c (-1, 0, 0);
1246 $$ = make_music_relative (middle_c, m);
1247 scm_gc_unprotect_object (m->self_scm ());
1252 NEWLYRICS { THIS->lexer_->push_lyric_state (); }
1254 Grouped_music_list {
1255 /* Can also use Music at the expensive of two S/Rs similar to
1256 \repeat \alternative */
1257 THIS->lexer_->pop_state ();
1259 Music *music = MY_MAKE_MUSIC ("SimultaneousMusic");
1260 music->set_property ("elements", scm_list_1 ($3->self_scm ()));
1263 $$ = scm_cons ($3->self_scm (), SCM_EOL);
1266 | new_lyrics NEWLYRICS { THIS->lexer_->push_lyric_state (); }
1267 Grouped_music_list {
1268 THIS->lexer_->pop_state ();
1269 $$ = scm_cons ($4->self_scm (), $1);
1274 ADDLYRICS Music Music {
1275 Music *m = MY_MAKE_MUSIC ("LyricCombineMusic");
1276 m->set_property ("elements", scm_listify ($2->self_scm (),
1277 $3->self_scm (), SCM_UNDEFINED));
1278 scm_gc_unprotect_object ($3->self_scm ());
1279 scm_gc_unprotect_object ($2->self_scm ());
1282 | Grouped_music_list new_lyrics {
1284 /* FIXME: should find out uniqueXXX name from music */
1285 SCM name = $1->get_property ("context-id");
1286 //if (name == SCM_EOL)
1287 if (!ly_c_string_p (name))
1288 name = scm_makfrom0str ("");
1290 SCM context = scm_makfrom0str ("Lyrics");
1291 Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
1294 for (SCM s = $2; ly_c_pair_p (s); s = ly_cdr (s))
1296 Music *music = unsmob_music (ly_car (s));
1297 Music *com = make_lyric_combine_music (name, music);
1298 Music *csm = context_spec_music (context,
1299 get_next_unique_context (), com, SCM_EOL);
1300 lst = scm_cons (csm->self_scm (), lst);
1302 /* FIXME: only first lyric music is accepted,
1303 the rest is junked */
1304 all->set_property ("elements", scm_cons ($1->self_scm (),
1307 scm_gc_unprotect_object ($1->self_scm ());
1309 | LYRICSTO string Music {
1312 $$ = make_lyric_combine_music (name, music);
1313 scm_gc_unprotect_object (music->self_scm ());
1318 CHANGE STRING '=' STRING {
1319 Music*t= MY_MAKE_MUSIC ("ContextChange");
1320 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1321 t-> set_property ("change-to-id", $4);
1324 $$->set_spot (THIS->here_input ());
1330 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1331 scm_string_to_symbol ($1), $3);
1333 | UNSET simple_string {
1334 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1335 scm_string_to_symbol ($2));
1337 | OVERRIDE simple_string embedded_scm '=' embedded_scm {
1338 $$ = scm_list_4 (ly_symbol2scm ("push"),
1339 scm_string_to_symbol ($2), $3, $5);
1341 | REVERT simple_string embedded_scm {
1342 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1343 scm_string_to_symbol ($2), $3);
1348 CONSISTSEND { $$ = ly_symbol2scm ("consists-end"); }
1349 | CONSISTS { $$ = ly_symbol2scm ("consists"); }
1350 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1352 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1353 | DENIES { $$ = ly_symbol2scm ("denies"); }
1355 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1356 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1357 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1358 | NAME { $$ = ly_symbol2scm ("context-name"); }
1362 property_operation { $$ = $1; }
1363 | context_def_mod STRING {
1364 $$ = scm_list_2 ($1, $2);
1370 $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
1371 scm_string_to_symbol ($1));
1373 | simple_string '.' simple_string {
1374 $$ = scm_list_2 (scm_string_to_symbol ($1),
1375 scm_string_to_symbol ($3));
1380 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1381 $$ = property_op_to_music (scm_list_4 (
1382 ly_symbol2scm ("poppush"),
1385 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1387 | REVERT context_prop_spec embedded_scm {
1388 $$ = property_op_to_music (scm_list_3 (
1389 ly_symbol2scm ("pop"),
1393 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1395 | SET context_prop_spec '=' scalar {
1396 $$ = property_op_to_music (scm_list_3 (
1397 ly_symbol2scm ("assign"),
1400 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1402 | UNSET context_prop_spec {
1403 $$ = property_op_to_music (scm_list_2 (
1404 ly_symbol2scm ("unset"),
1406 $$= context_spec_music (ly_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1408 | ONCE music_property_def {
1409 SCM e = $2->get_property ("element");
1410 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1421 | STRING_IDENTIFIER {
1424 | string '+' string {
1425 $$ = scm_string_append (scm_list_2 ($1, $3));
1429 simple_string: STRING {
1440 $$ = scm_int2num ($1);
1447 $$ = scm_int2num ($1);
1452 FIXME: remove or fix this comment. What is `This'?
1456 Adding pre_events to the simple_element
1457 makes the choice between
1463 simple_element: STRING
1465 a single shift/reduction conflict.
1467 nevertheless, this is not very clean, and we should find a different
1477 pre_events simple_element post_events {
1478 SCM elts = $2-> get_property ("elements");
1480 elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1482 $2->set_property ("elements", elts);
1486 | note_chord_element
1491 chord_body optional_notemode_duration post_events
1493 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1494 SCM es = $1->get_property ("elements");
1495 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1497 for (SCM s = es; ly_c_pair_p (s); s = ly_cdr (s))
1498 unsmob_music (ly_car (s))->set_property ("duration", dur);
1499 es = ly_append2 (es, postevs);
1501 $1-> set_property ("elements", es);
1512 simul_open: DOUBLE_ANGLE_OPEN
1515 simul_close: DOUBLE_ANGLE_CLOSE
1519 chord_open chord_body_elements chord_close
1521 $$ = MY_MAKE_MUSIC ("EventChord");
1522 $$->set_property ("elements",
1523 scm_reverse_x ($2, SCM_EOL));
1527 chord_body_elements:
1528 /* empty */ { $$ = SCM_EOL; }
1529 | chord_body_elements chord_body_element {
1530 $$ = scm_cons ($2->self_scm (), $1);
1531 scm_gc_unprotect_object ($2->self_scm ());
1536 pitch exclamations questions post_events
1538 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1539 n->set_property ("pitch", $1);
1541 n->set_property ("cautionary", SCM_BOOL_T);
1542 if ($2 % 2 || $3 % 2)
1543 n->set_property ("force-accidental", SCM_BOOL_T);
1545 if (ly_c_pair_p ($4)) {
1546 SCM arts = scm_reverse_x ($4, SCM_EOL);
1547 n->set_property ("articulations", arts);
1551 | DRUM_PITCH post_events {
1552 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1553 n->set_property ("duration", $2);
1554 n->set_property ("drum-type", $1);
1555 n->set_spot (THIS->here_input ());
1557 if (ly_c_pair_p ($2)) {
1558 SCM arts = scm_reverse_x ($2, SCM_EOL);
1559 n->set_property ("articulations", arts);
1566 ADDQUOTE string Music {
1567 SCM adder = ly_scheme_function ("add-quotable");
1569 scm_call_2 (adder, $2, $3->self_scm ());
1570 scm_gc_unprotect_object ($3->self_scm ());
1576 $$ = MY_MAKE_MUSIC ("EventChord");
1577 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1578 scm_gc_unprotect_object ($1->self_scm ());
1580 $$-> set_spot (THIS->here_input ());
1581 $1-> set_spot (THIS->here_input ());
1583 | SKIP duration_length {
1584 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1585 skip->set_property ("duration", $2);
1589 | QUOTE STRING duration_length {
1590 SCM tab = THIS->lexer_->lookup_identifier ("musicQuotes");
1592 if (scm_hash_table_p (tab) == SCM_BOOL_T)
1594 SCM key = $2; // use symbol?
1595 evs = scm_hash_ref (tab, key, SCM_BOOL_F);
1598 if (ly_c_vector_p (evs))
1600 quote = MY_MAKE_MUSIC ("QuoteMusic");
1601 quote->set_property ("duration", $3);
1602 quote->set_property ("quoted-events", evs);
1604 THIS->here_input ().warning (_f ("Can\'t find music"));
1605 quote = MY_MAKE_MUSIC ("Event");
1607 quote->set_spot (THIS->here_input ());
1610 | OCTAVE { THIS->push_spot (); }
1612 Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1614 $$->set_spot (THIS->pop_spot ());
1615 $$->set_property ("pitch", $3);
1618 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1619 m->set_property ("span-direction", scm_int2num (START));
1620 m->set_spot (THIS->here_input ());
1622 $$ = MY_MAKE_MUSIC ("EventChord");
1623 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1624 scm_gc_unprotect_object (m->self_scm ());
1625 $$->set_spot (THIS->here_input ());
1628 Music *m = MY_MAKE_MUSIC ("LigatureEvent");
1629 m->set_property ("span-direction", scm_int2num (STOP));
1630 m->set_spot (THIS->here_input ());
1632 $$ = MY_MAKE_MUSIC ("EventChord");
1633 $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
1634 $$->set_spot (THIS->here_input ());
1635 scm_gc_unprotect_object (m->self_scm ());
1638 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1639 $$->set_spot (THIS->here_input ());
1642 SCM pipe =THIS->lexer_->lookup_identifier ("pipeSymbol");
1644 if (Music * m = unsmob_music (pipe))
1647 $$ = MY_MAKE_MUSIC ("BarCheck");
1649 $$->set_spot (THIS->here_input ());
1651 | TRANSPOSITION pitch {
1652 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1654 $$->set_spot (THIS-> here_input ());
1655 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1659 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1661 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1663 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1664 $$->set_spot (THIS->here_input ());
1665 t->set_spot (THIS->here_input ());
1667 | PARTIAL duration_length {
1668 Moment m = - unsmob_duration ($2)->get_length ();
1669 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1670 p->set_spot (THIS->here_input ());
1671 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1673 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1678 SCM proc = ly_scheme_function ("make-clef-set");
1680 SCM result = scm_call_1 (proc, $2);
1681 scm_gc_protect_object (result);
1682 $$ = unsmob_music (result);
1685 SCM proc= ly_scheme_function ("make-time-signature-set");
1687 SCM result = scm_apply_2 (proc, ly_car ($2), ly_cdr ($2), SCM_EOL);
1688 scm_gc_protect_object (result);
1689 $$ = unsmob_music (result);
1692 SCM proc = ly_scheme_function ("make-mark-set");
1694 SCM result = scm_call_1 (proc, $2);
1695 scm_gc_protect_object (result);
1696 $$ = unsmob_music (result);
1702 $$ = MY_MAKE_MUSIC ("BreathingSignEvent");
1705 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1708 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1715 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1718 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1720 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1721 if (scm_ilength ($3) > 0)
1723 key->set_property ("pitch-alist", $3);
1724 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1725 ((Music*)key)->transpose (* unsmob_pitch ($2));
1727 THIS->parser_error (_ ("Second argument must be pitch list."));
1738 | post_events post_event {
1739 $2->set_spot (THIS->here_input ());
1740 $$ = scm_cons ($2->self_scm (), $$);
1741 scm_gc_unprotect_object ($2->self_scm ());
1743 | post_events tagged_post_event {
1744 $2 -> set_spot (THIS->here_input ());
1745 $$ = scm_cons ($2->self_scm (), $$);
1746 scm_gc_unprotect_object ($2->self_scm ());
1752 '-' TAG embedded_scm post_event {
1753 tag_music ($4, $3, THIS->here_input ());
1759 direction_less_event {
1763 if (!THIS->lexer_->is_lyric_state ())
1764 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1765 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1768 if (!THIS->lexer_->is_lyric_state ())
1769 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1770 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1772 | script_dir direction_reqd_event {
1774 $2->set_property ("direction", scm_int2num ($1));
1777 | script_dir direction_less_event {
1779 $2->set_property ("direction", scm_int2num ($1));
1782 | string_number_event
1785 string_number_event:
1787 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1788 s->set_property ("string-number", scm_int2num ($1));
1789 s->set_spot (THIS->here_input ());
1795 direction_less_event:
1801 TODO: should take all these defs out of the parser, adn make use
1805 (set-articulation '~ "trill")
1808 Music *m = MY_MAKE_MUSIC ("BeamEvent");
1809 m->set_spot (THIS->here_input ());
1810 m->set_property ("span-direction", scm_int2num (START));
1814 Music *m = MY_MAKE_MUSIC ("BeamEvent");
1815 m->set_spot (THIS->here_input ());
1816 m->set_property ("span-direction", scm_int2num (STOP));
1820 Music *m = MY_MAKE_MUSIC ("TieEvent");
1821 m->set_spot (THIS->here_input ());
1826 dynamic_cast<Music *> ($$)->set_property ("span-direction",
1827 scm_int2num (START));
1831 dynamic_cast<Music *> ($$)->set_property ("span-direction",
1832 scm_int2num (STOP));
1834 | EVENT_IDENTIFIER {
1835 $$ = unsmob_music ($1);
1838 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1839 a->set_spot (THIS->here_input ());
1840 a->set_property ("tremolo-type", scm_int2num ($1));
1845 direction_reqd_event:
1849 | script_abbreviation {
1850 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1851 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1852 if (ly_c_string_p (s))
1853 a->set_property ("articulation-type", s);
1854 else THIS->parser_error (_ ("Expecting string as script definition"));
1860 /**/ { $$ = SCM_EOL; }
1861 | '=' { $$ = scm_int2num (0); }
1862 | '=' sub_quotes { $$ = scm_int2num ($2); }
1863 | '=' sup_quotes { $$ = scm_int2num ($2); }
1888 | NOTENAME_PITCH sup_quotes {
1889 Pitch p = *unsmob_pitch ($1);
1890 p = p.transposed (Pitch ($2,0,0));
1891 $$ = p.smobbed_copy ();
1893 | NOTENAME_PITCH sub_quotes {
1894 Pitch p =* unsmob_pitch ($1);
1895 p = p.transposed (Pitch (-$2,0,0));
1896 $$ = p.smobbed_copy ();
1908 | TONICNAME_PITCH sup_quotes {
1909 Pitch p = *unsmob_pitch ($1);
1910 p = p.transposed (Pitch ($2,0,0));
1911 $$ = p.smobbed_copy ();
1913 | TONICNAME_PITCH sub_quotes {
1914 Pitch p =* unsmob_pitch ($1);
1916 p = p.transposed (Pitch (-$2,0,0));
1917 $$ = p.smobbed_copy ();
1927 pitch_also_in_chords:
1934 Music *s = MY_MAKE_MUSIC ("SlurEvent");
1936 s->set_spot (THIS->here_input ());
1939 Music *s = MY_MAKE_MUSIC ("PhrasingSlurEvent");
1941 s->set_spot (THIS->here_input ());
1944 Music *s = MY_MAKE_MUSIC ("CrescendoEvent");
1946 s->set_spot (THIS->here_input ());
1949 Music *s = MY_MAKE_MUSIC ("DecrescendoEvent");
1951 s->set_spot (THIS->here_input ());
1958 Music *s = MY_MAKE_MUSIC ("CrescendoEvent");
1959 s->set_spot (THIS->here_input ());
1964 Music *s= MY_MAKE_MUSIC ("SlurEvent");
1966 s->set_spot (THIS->here_input ());
1970 Music *s= MY_MAKE_MUSIC ("PhrasingSlurEvent");
1972 s->set_property ("span-type",
1973 scm_makfrom0str ("phrasing-slur"));
1974 s->set_spot (THIS->here_input ());
1980 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1981 t->set_property ("text", $1);
1982 t->set_spot (THIS->here_input ());
1986 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1987 t->set_property ("text",
1988 make_simple_markup (THIS->lexer_->encoding (), $1));
1989 t->set_spot (THIS->here_input ());
1994 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1995 t->set_property ("digit", scm_int2num ($1));
1996 t->set_spot (THIS->here_input ());
2001 script_abbreviation:
2003 $$ = scm_makfrom0str ("Hat");
2006 $$ = scm_makfrom0str ("Plus");
2009 $$ = scm_makfrom0str ("Dash");
2012 $$ = scm_makfrom0str ("Bar");
2015 $$ = scm_makfrom0str ("Larger");
2018 $$ = scm_makfrom0str ("Dot");
2021 $$ = scm_makfrom0str ("Underscore");
2028 | '-' { $$ = CENTER; }
2039 multiplied_duration {
2044 optional_notemode_duration:
2046 Duration dd = THIS->default_duration_;
2047 $$ = dd.smobbed_copy ();
2049 THIS->beam_check ($$);
2051 | multiplied_duration {
2053 THIS->default_duration_ = *unsmob_duration ($$);
2055 THIS->beam_check ($$);
2060 bare_unsigned dots {
2062 if (!is_duration ($1))
2063 THIS->parser_error (_f ("not a duration: %d", $1));
2067 $$ = Duration (len, $2).smobbed_copy ();
2069 | DURATION_IDENTIFIER dots {
2070 Duration *d = unsmob_duration ($1);
2071 Duration k (d->duration_log (), d->dot_count () + $2);
2077 multiplied_duration:
2081 | multiplied_duration '*' bare_unsigned {
2082 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
2084 | multiplied_duration '*' FRACTION {
2085 Rational m (ly_scm2int (ly_car ($3)), ly_scm2int (ly_cdr ($3)));
2087 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2092 FRACTION { $$ = $1; }
2093 | UNSIGNED '/' UNSIGNED {
2094 $$ = scm_cons (scm_int2num ($1), scm_int2num ($3));
2111 | ':' bare_unsigned {
2112 if (!is_duration ($2))
2113 THIS->parser_error (_f ("not a duration: %d", $2));
2120 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2123 $$ = scm_number_to_string (scm_int2num ($1), scm_int2num (10));
2125 | STRING { $$ = $1; }
2136 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2137 $$ = bfr->self_scm ();
2138 scm_gc_unprotect_object ($$);
2141 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
2142 $$ = bfr->self_scm ();
2144 bfr->set_property ("figure", $1);
2146 scm_gc_unprotect_object ($$);
2148 | bass_figure bass_mod {
2149 Music *m = unsmob_music ($1);
2151 SCM salter = m->get_property ("alteration");
2152 int alter = ly_c_number_p (salter) ? ly_scm2int (salter) : 0;
2153 m->set_property ("alteration",
2154 scm_int2num (alter + $2));
2156 m->set_property ("alteration", scm_int2num (0));
2164 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
2169 | br_bass_figure ']' {
2171 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
2179 | figure_list br_bass_figure {
2180 $$ = scm_cons ($2, $1);
2185 FIGURE_OPEN figure_list FIGURE_CLOSE {
2186 Music *m = MY_MAKE_MUSIC ("EventChord");
2187 $2 = scm_reverse_x ($2, SCM_EOL);
2188 m->set_property ("elements", $2);
2189 $$ = m->self_scm ();
2200 pitch exclamations questions oct_check optional_notemode_duration optional_rest {
2202 Input i = THIS->pop_spot ();
2203 if (!THIS->lexer_->is_note_state ())
2204 THIS->parser_error (_ ("Have to be in Note mode for notes"));
2208 n = MY_MAKE_MUSIC ("RestEvent");
2210 n = MY_MAKE_MUSIC ("NoteEvent");
2212 n->set_property ("pitch", $1);
2213 n->set_property ("duration", $5);
2215 if (ly_c_number_p ($4))
2217 int q = ly_scm2int ($4);
2218 n->set_property ("absolute-octave", scm_int2num (q-1));
2222 n->set_property ("cautionary", SCM_BOOL_T);
2223 if ($2 % 2 || $3 % 2)
2224 n->set_property ("force-accidental", SCM_BOOL_T);
2226 Music *v = MY_MAKE_MUSIC ("EventChord");
2227 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2228 scm_gc_unprotect_object (n->self_scm ());
2234 | DRUM_PITCH optional_notemode_duration {
2235 Input i = THIS->pop_spot ();
2237 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2238 n->set_property ("duration", $2);
2239 n->set_property ("drum-type", $1);
2241 Music *v = MY_MAKE_MUSIC ("EventChord");
2242 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2243 scm_gc_unprotect_object (n->self_scm ());
2249 | figure_spec optional_notemode_duration {
2250 Music *m = unsmob_music ($1);
2251 Input i = THIS->pop_spot ();
2253 for (SCM s = m->get_property ("elements"); ly_c_pair_p (s); s = ly_cdr (s))
2255 unsmob_music (ly_car (s))->set_property ("duration", $2);
2259 | RESTNAME optional_notemode_duration {
2261 Input i = THIS->pop_spot ();
2263 if (ly_scm2string ($1) == "s") {
2265 ev = MY_MAKE_MUSIC ("SkipEvent");
2268 ev = MY_MAKE_MUSIC ("RestEvent");
2271 ev->set_property ("duration", $2);
2273 Music *velt = MY_MAKE_MUSIC ("EventChord");
2274 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2277 scm_gc_unprotect_object (ev->self_scm ());
2281 | MULTI_MEASURE_REST optional_notemode_duration {
2284 SCM proc = ly_scheme_function ("make-multi-measure-rest");
2285 SCM mus = scm_call_2 (proc, $2,
2286 make_input (THIS->here_input ()));
2287 scm_gc_protect_object (mus);
2288 $$ = unsmob_music (mus);
2291 | lyric_element optional_notemode_duration {
2292 Input i = THIS->pop_spot ();
2293 if (!THIS->lexer_->is_lyric_state ())
2294 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
2296 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2297 lreq->set_property ("text", $1);
2298 lreq->set_property ("duration",$2);
2300 Music *velt = MY_MAKE_MUSIC ("EventChord");
2301 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2308 if (!THIS->lexer_->is_chord_state ())
2309 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
2310 $$ = unsmob_music ($1);
2315 /* FIXME: lyric flavoured markup would be better */
2323 steno_tonic_pitch optional_notemode_duration {
2324 $$ = make_chord ($1, $2, SCM_EOL);
2326 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2327 SCM its = scm_reverse_x ($4, SCM_EOL);
2328 $$ = make_chord ($1, $2, scm_cons ($3, its));
2336 | chord_items chord_item {
2337 $$ = scm_cons ($2, $$);
2343 $$ = ly_symbol2scm ("chord-colon");
2346 $$ = ly_symbol2scm ("chord-caret");
2348 | CHORD_SLASH steno_tonic_pitch {
2349 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2351 | CHORD_BASS steno_tonic_pitch {
2352 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2361 $$ = scm_reverse_x ($1, SCM_EOL);
2369 step_number { $$ = scm_cons ($1, SCM_EOL); }
2370 | step_numbers '.' step_number {
2371 $$ = scm_cons ($3, $$);
2377 $$ = make_chord_step ($1, 0);
2379 | bare_unsigned '+' {
2380 $$ = make_chord_step ($1, SHARP);
2382 | bare_unsigned CHORD_MINUS {
2383 $$ = make_chord_step ($1, FLAT);
2390 TODO: should deprecate in favor of Scheme?
2394 number_expression '+' number_term {
2395 $$ = scm_sum ($1, $3);
2397 | number_expression '-' number_term {
2398 $$ = scm_difference ($1, $3);
2407 | number_factor '*' number_factor {
2408 $$ = scm_product ($1, $3);
2410 | number_factor '/' number_factor {
2411 $$ = scm_divide ($1, $3);
2416 '-' number_factor { /* %prec UNARY_MINUS */
2417 $$ = scm_difference ($2, SCM_UNDEFINED);
2425 $$ = scm_int2num ($1);
2430 | NUMBER_IDENTIFIER {
2433 | REAL NUMBER_IDENTIFIER {
2434 $$ = scm_make_real (ly_scm2double ($1) *ly_scm2double ($2));
2436 | UNSIGNED NUMBER_IDENTIFIER {
2437 $$ = scm_make_real ($1 *ly_scm2double ($2));
2453 if (scm_integer_p ($1) == SCM_BOOL_T)
2455 int k = ly_scm2int ($1);
2459 THIS->parser_error (_ ("need integer number arg"));
2470 | exclamations '!' { $$ ++; }
2475 | questions '?' { $$ ++; }
2485 { THIS->lexer_->push_markup_state (); }
2488 THIS->lexer_->pop_state ();
2494 This should be done more dynamically if possible.
2498 $$ = make_simple_markup (THIS->lexer_->encoding (), $1);
2500 | MARKUP_HEAD_EMPTY {
2501 $$ = scm_list_1 ($1);
2503 | MARKUP_HEAD_MARKUP0 markup {
2504 $$ = scm_list_2 ($1, $2);
2506 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2507 $$ = scm_list_3 ($1, $2, $3);
2509 | MARKUP_HEAD_SCM0_MARKUP1 SCM_T markup {
2510 $$ = scm_list_3 ($1, $2, $3);
2515 | MARKUP_HEAD_LIST0 markup_list {
2516 $$ = scm_list_2 ($1,$2);
2518 | MARKUP_HEAD_SCM0 embedded_scm {
2519 $$ = scm_list_2 ($1, $2);
2521 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup {
2522 $$ = scm_list_4 ($1, $2, $3, $4);
2524 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2525 $$ = scm_list_4 ($1, $2, $3, $4);
2527 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2528 $$ = scm_list_3 ($1, $2, $3);
2530 | MARKUP_IDENTIFIER {
2533 | STRING_IDENTIFIER {
2537 /* WIP this is a bit arbitrary,
2538 we should also allow \book or Composite_music.
2539 However, you'd typically want to change paper
2540 settings, and need a \score block anyway. */
2542 Book *book = new Book;
2543 book->scores_.push (score);
2544 extern Music_output_def* get_paper (My_lily_parser *parser);
2545 Music_output_def *paper = get_paper (THIS);
2546 SCM s = book->to_stencil (paper, THIS->header_);
2547 scm_gc_unprotect_object (score->self_scm ());
2548 scm_gc_unprotect_object (book->self_scm ());
2549 $$ = scm_list_2 (ly_scheme_function ("stencil-markup"), s);
2554 chord_open markup_list_body chord_close { $$ = scm_reverse_x ($2, SCM_EOL); }
2558 '{' markup_list_body '}' {
2559 SCM line = ly_scheme_function ("line-markup");
2561 $$ = scm_list_2 (line, scm_reverse_x ($2, SCM_EOL));
2566 /**/ { $$ = SCM_EOL; }
2567 | markup_list_body markup {
2568 $$ = scm_cons ($2, $1);
2576 My_lily_parser::set_yydebug (bool )
2584 My_lily_parser::do_yyparse ()
2586 yyparse ((void*)this);
2591 Should make this optional? It will also complain when you do
2595 which is entirely legitimate.
2597 Or we can scrap it. Barchecks should detect wrong durations, and
2598 skipTypesetting speeds it up a lot.
2602 My_lily_parser::beam_check (SCM dur)
2604 Duration *d = unsmob_duration (dur);
2605 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2607 Music *m = unsmob_music (last_beam_start_);
2608 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2610 last_beam_start_ = SCM_EOL;
2618 It is a little strange to have this function in this file, but
2619 otherwise, we have to import music classes into the lexer.
2623 My_lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2625 if (ly_c_string_p (sid)) {
2627 return STRING_IDENTIFIER;
2628 } else if (ly_c_number_p (sid)) {
2630 return NUMBER_IDENTIFIER;
2631 } else if (unsmob_context_def (sid)) {
2632 *destination = unsmob_context_def (sid)->clone_scm ();
2633 return CONTEXT_DEF_IDENTIFIER;
2634 } else if (unsmob_score (sid)) {
2635 Score *score = new Score (*unsmob_score (sid));
2636 *destination = score->self_scm ();
2637 return SCORE_IDENTIFIER;
2638 } else if (Music *mus = unsmob_music (sid)) {
2639 mus = mus->clone ();
2640 *destination = mus->self_scm ();
2641 unsmob_music (*destination)->
2642 set_property ("origin", make_input (last_input_));
2643 return dynamic_cast<Event*> (mus)
2644 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2645 } else if (unsmob_duration (sid)) {
2646 *destination = unsmob_duration (sid)->smobbed_copy ();
2647 return DURATION_IDENTIFIER;
2648 } else if (unsmob_music_output_def (sid)) {
2649 Music_output_def *p = unsmob_music_output_def (sid);
2652 *destination = p->self_scm ();
2653 return MUSIC_OUTPUT_DEF_IDENTIFIER;
2654 } else if (Text_item::markup_p (sid)) {
2656 return MARKUP_IDENTIFIER;
2663 property_op_to_music (SCM op)
2666 SCM tag = ly_car (op);
2667 SCM symbol = ly_cadr (op);
2668 SCM args = ly_cddr (op);
2669 SCM grob_val = SCM_UNDEFINED;
2670 SCM grob_sym = SCM_UNDEFINED;
2671 SCM val = SCM_UNDEFINED;
2673 if (tag == ly_symbol2scm ("assign"))
2675 m = MY_MAKE_MUSIC ("PropertySet");
2676 val = ly_car (args);
2678 else if (tag == ly_symbol2scm ("unset"))
2679 m = MY_MAKE_MUSIC ("PropertyUnset");
2680 else if (tag == ly_symbol2scm ("poppush")
2681 || tag == ly_symbol2scm ("push"))
2683 m = MY_MAKE_MUSIC ("OverrideProperty");
2684 grob_sym = ly_car (args);
2685 grob_val = ly_cadr (args);
2687 else if (tag == ly_symbol2scm ("pop")) {
2688 m = MY_MAKE_MUSIC ("RevertProperty");
2689 grob_sym = ly_car (args);
2692 m->set_property ("symbol", symbol);
2694 if (val != SCM_UNDEFINED)
2695 m->set_property ("value", val);
2696 if (grob_val != SCM_UNDEFINED)
2697 m->set_property ("grob-value", grob_val);
2699 if (grob_sym != SCM_UNDEFINED)
2701 bool itc = internal_type_checking_global_b;
2704 bool autobeam = ly_c_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2706 internal_type_checking_global_b = false;
2707 m->set_property ("grob-property", grob_sym);
2709 internal_type_checking_global_b = itc;
2712 if (op == ly_symbol2scm ("poppush"))
2713 m->set_property ("pop-first", SCM_BOOL_T);
2720 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2722 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2724 csm->set_property ("element", m->self_scm ());
2725 scm_gc_unprotect_object (m->self_scm ());
2727 csm->set_property ("context-type",
2728 ly_c_symbol_p (type) ? type : scm_string_to_symbol (type));
2729 csm->set_property ("property-operations", ops);
2731 if (ly_c_string_p (id))
2732 csm->set_property ("context-id", id);
2737 get_next_unique_context ()
2739 static int new_context_count;
2741 snprintf (s, 1024, "uniqueContext%d", new_context_count++);
2742 return scm_makfrom0str (s);