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?
28 #include "scm-option.hh"
29 #include "context-def.hh"
30 #include "lily-guile.hh"
32 #include "my-lily-lexer.hh"
33 #include "paper-def.hh"
34 #include "midi-def.hh"
36 #include "file-path.hh"
38 #include "dimensions.hh"
39 #include "my-lily-parser.hh"
41 #include "input-file-results.hh"
43 #include "lilypond-input-version.hh"
44 #include "scm-hash.hh"
45 #include "ly-module.hh"
46 #include "music-sequence.hh"
47 #include "input-smob.hh"
49 #include "text-item.hh"
50 #include "music-list.hh"
51 #include "paper-book.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 My_lily_parser* my_lily_parser;
62 #define YYPARSE_PARAM my_lily_parser
63 #define YYLEX_PARAM my_lily_parser
65 ((My_lily_parser *) my_lily_parser)
67 #define yyerror THIS->parser_error
69 /* Add symbols to the TAGS field of a music object. */
72 tag_music (Music *m, SCM tag, Input ip)
74 SCM tags = m->get_property ("tags");
75 if (gh_symbol_p (tag))
76 tags = scm_cons (tag, tags);
77 else if (gh_list_p (tag))
78 tags = gh_append2 (tag, tags);
80 ip.warning (_ ("Tag must be symbol or list of symbols."));
82 m->set_property ("tags", tags);
88 is_regular_identifier (SCM id)
90 String str = ly_scm2string (id);
91 char const *s = str.to_str0 ();
100 v = v && isalnum (*s);
107 make_simple_markup (SCM a)
109 SCM simple = ly_scheme_function ("simple-markup");
111 return scm_list_2 (simple, a);
116 is_is_duration (int t)
118 return t && t == 1 << intlog2 (t);
122 set_music_properties (Music *p, SCM a)
124 for (SCM k = a; gh_pair_p (k); k = ly_cdr (k))
126 p->internal_set_property (ly_caar (k), ly_cdar (k));
131 make_chord_step (int step, int alter)
138 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
139 return m.smobbed_copy ();
144 make_chord (SCM pitch, SCM dur, SCM modification_list)
146 SCM chord_ctor = ly_scheme_function ("construct-chord");
147 SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
148 scm_gc_protect_object (ch);
152 /* Todo: actually also use apply iso. call too ... */
154 ly_input_procedure_p (SCM x)
156 return gh_procedure_p (x)
157 || (gh_pair_p (x) && gh_procedure_p (gh_car (x)));
161 set_property_music (SCM sym, SCM value)
163 Music *p = MY_MAKE_MUSIC ("PropertySet");
164 p->set_property ("symbol", sym);
165 p->set_property ("value", value);
171 /* We use SCMs to do strings, because it saves us the trouble of
172 deleting them. Let's hope that a stack overflow doesnt trigger a move
173 of the parse stack onto the heap. */
180 Music_output_def *outputdef;
187 yylex (YYSTYPE *s, void *v)
189 My_lily_parser *pars = (My_lily_parser*) v;
190 My_lily_lexer *lex = pars->lexer_;
192 lex->lexval = (void*) s;
193 lex->prepare_for_next_token ();
194 return lex->yylex ();
203 Four shift/reduce problems:
207 "bar" -> String -> Lyric -> Music -> music-assignment
209 "bar" -> String -> string-assignment
214 2. \markup identifier.
219 \repeat .. \alternative
222 \repeat { \repeat .. \alternative }
226 \repeat { \repeat } \alternative
251 %token CHORDMODIFIERS
256 %token COMMANDSPANREQUEST
264 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
265 %token FIGURE_BRACKET_CLOSE FIGURE_BRACKET_OPEN
269 %token GROBDESCRIPTIONS
277 %token MULTI_MEASURE_REST
283 %token OVERRIDE SET REVERT
309 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
310 %token E_LEFTSQUARE E_RIGHTSQUARE E_TILDE
312 %token <i> E_UNSIGNED
313 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET CHORD_SLASH
316 %type <i> exclamations questions dots optional_rest
318 %type <scm> grace_head
319 %type <scm> oct_check
320 %type <scm> context_mod_list
321 %type <scm> lyric_element
322 %type <scm> bass_number br_bass_figure bass_figure figure_list figure_spec
324 %token <scm> NOTENAME_PITCH
325 %token <scm> TONICNAME_PITCH
326 %token <scm> CHORDMODIFIER_PITCH
327 %token <scm> DURATION_IDENTIFIER
328 %token <scm> FRACTION
329 %token <id> IDENTIFIER
331 %token <scm> DRUM_PITCH
332 %token <scm> CHORD_MODIFIER
333 %token <scm> SCORE_IDENTIFIER
334 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
335 %token <scm> NUMBER_IDENTIFIER
336 %token <scm> EVENT_IDENTIFIER
337 %token <scm> MUSIC_IDENTIFIER CONTEXT_DEF_IDENTIFIER
338 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
339 %token <scm> RESTNAME
346 %token <scm> MARKUP_HEAD_MARKUP0
347 %token <scm> MARKUP_HEAD_EMPTY
348 %token <scm> MARKUP_HEAD_MARKUP0_MARKUP1
349 %token <scm> MARKUP_HEAD_SCM0
350 %token <scm> MARKUP_HEAD_SCM0_MARKUP1
351 %token <scm> MARKUP_HEAD_SCM0_SCM1
352 %token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
353 %token <scm> MARKUP_HEAD_SCM0_SCM1_MARKUP2
355 %token <scm> MARKUP_IDENTIFIER MARKUP_HEAD_LIST0
356 %type <scm> markup markup_line markup_list markup_list_body full_markup
358 %type <outputdef> output_def
359 %type <scm> lilypond_header lilypond_header_body
360 %type <music> open_event close_event
361 %type <i> sub_quotes sup_quotes
362 %type <music> simple_element event_chord command_element Simple_music Composite_music
363 %type <music> Repeated_music
364 %type <scm> Alternative_music
365 %type <i> tremolo_type
366 %type <i> bare_int bare_unsigned
368 %type <scm> identifier_init
370 %type <music> note_chord_element chord_body chord_body_element
371 %type <scm> chord_body_elements
372 %type <scm> steno_duration optional_notemode_duration multiplied_duration
374 %type <scm> post_events
375 %type <music> gen_text_def direction_less_event direction_reqd_event
376 %type <scm> steno_pitch pitch absolute_pitch pitch_also_in_chords
377 %type <scm> steno_tonic_pitch
378 %type <scm> duration_length fraction
380 %type <scm> new_chord step_number chord_items chord_item chord_separator step_numbers
382 %type <scm> embedded_scm scalar
383 %type <music> Music Sequential_music Simultaneous_music
384 %type <music> relative_music re_rhythmed_music
385 %type <music> music_property_def context_change
386 %type <scm> context_prop_spec
387 %type <scm> Music_list
388 %type <scm> property_operation context_mod context_def_mod optional_context_mod
389 %type <outputdef> music_output_def_body music_output_def_head
390 %type <music> post_event tagged_post_event
391 %type <music> command_req
392 %type <music> string_number_event
393 %type <scm> string bare_number number_expression number_term number_factor
394 %type <score> score_block score_body
396 %type <scm> context_def_spec_block context_def_spec_body
397 %type <music> tempo_event
398 %type <scm> script_abbreviation
404 /* We don't assign precedence to / and *, because we might need varied
405 prec levels in different prods */
411 lilypond: /* empty */
412 | lilypond toplevel_expression {}
413 | lilypond assignment { }
415 THIS->error_level_ = 1;
418 THIS->error_level_ = 1;
424 THIS->input_file_->header_ = $1;
431 SCM head = ly_module_p (sc->header_) ? sc->header_ : THIS->input_file_->header_.to_SCM ();
433 Path p = split_path (THIS->output_basename_);
434 int *c = &THIS->input_file_->score_count_;
437 p.base += "-" + to_string (*c);
441 SCM outname = scm_makfrom0str (p.to_string ().to_str0());
443 for (int i = 0; i < sc->defs_.size (); i++)
444 default_rendering (sc->music_, sc->defs_[i]->self_scm (), head, outname);
446 if (sc->defs_.is_empty ())
448 Music_output_def *id = unsmob_music_output_def
449 (THIS->lexer_->lookup_identifier ("$defaultpaper"));
450 id = id ? id->clone () : new Paper_def;
451 default_rendering (sc->music_, id->self_scm (), head,
453 scm_gc_unprotect_object (id->self_scm ());
455 scm_gc_unprotect_object (sc->self_scm ());
459 if (dynamic_cast<Paper_def*> ($1))
460 id = scm_makfrom0str ("$defaultpaper");
461 else if (dynamic_cast<Midi_def*> ($1))
462 id = scm_makfrom0str ("$defaultmidi");
463 THIS->lexer_->set_identifier (id, $1->self_scm ());
464 scm_gc_unprotect_object ($1->self_scm ());
477 lilypond_header_body:
479 $$ = ly_make_anonymous_module ();
480 THIS->lexer_->add_scope ($$);
482 | lilypond_header_body assignment {
488 HEADER '{' lilypond_header_body '}' {
489 $$ = THIS->lexer_->remove_scope ();
501 /* cont */ '=' identifier_init {
504 Should find generic way of associating input with objects.
506 Input ip = THIS->pop_spot ();
508 if (! is_regular_identifier ($1))
510 ip.warning (_ ("Identifier should have alphabetic characters only"));
513 THIS->lexer_->set_identifier ($1, $4);
516 TODO: devise standard for protection in parser.
518 The parser stack lives on the C-stack, which means that
519 all objects can be unprotected as soon as they're here.
529 $$ = $1->self_scm ();
530 scm_gc_unprotect_object ($$);
536 $$ = $1->self_scm ();
537 scm_gc_unprotect_object ($$);
539 | context_def_spec_block {
543 $$ = $1->self_scm ();
544 scm_gc_unprotect_object ($$);
547 $$ = $1->self_scm ();
548 scm_gc_unprotect_object ($$);
550 | number_expression {
561 context_def_spec_block:
562 CONTEXT '{' context_def_spec_body '}'
568 context_def_spec_body:
570 $$ = Context_def::make_scm ();
571 unsmob_context_def ($$)->set_spot (THIS->here_input ());
573 | CONTEXT_DEF_IDENTIFIER {
575 unsmob_context_def ($$)->set_spot (THIS->here_input ());
577 | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
578 Context_def*td = unsmob_context_def ($$);
580 for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p)) {
581 SCM tag = gh_caar (p);
583 /* TODO: should make new tag "grob-definition" ? */
584 td->add_context_mod (scm_list_3 (ly_symbol2scm ("assign"),
585 tag, gh_cons (ly_cdar (p), SCM_EOL)));
588 | context_def_spec_body context_mod {
589 unsmob_context_def ($$)->add_context_mod ($2);
600 /*cont*/ '{' score_body '}' {
611 $$->set_spot (THIS->here_input ());
612 SCM m = $1->self_scm ();
613 scm_gc_unprotect_object (m);
618 SCM check_funcs = ly_scheme_function ("toplevel-music-functions");
619 for (; gh_pair_p (check_funcs); check_funcs = gh_cdr (check_funcs))
620 m = gh_call1 (gh_car (check_funcs), m);
625 $$ = new Score ( *unsmob_score ($1));
626 $$->set_spot (THIS->here_input ());
628 | score_body lilypond_header {
631 | score_body output_def {
633 scm_gc_unprotect_object ($2->self_scm ());
645 music_output_def_body '}' {
647 THIS-> lexer_-> remove_scope ();
651 music_output_def_head:
653 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultmidi"));
658 p = dynamic_cast<Midi_def*> (id->clone ());
663 THIS->lexer_->add_scope (p->scope_);
666 Music_output_def *id = unsmob_music_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"));
669 p = dynamic_cast<Paper_def*> (id->clone ());
673 THIS->lexer_->add_scope (p->scope_);
679 music_output_def_body:
680 music_output_def_head '{' {
682 $$->input_origin_. set_spot (THIS->here_input ());
685 | music_output_def_head '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
686 scm_gc_unprotect_object ($1->self_scm ());
687 Music_output_def *o = unsmob_music_output_def ($3);
688 o->input_origin_.set_spot (THIS->here_input ());
690 THIS->lexer_->remove_scope ();
691 THIS->lexer_->add_scope (o->scope_);
693 | music_output_def_body assignment {
696 | music_output_def_body context_def_spec_block {
697 $$->assign_context_def ($2);
699 | music_output_def_body tempo_event {
701 junk this ? there already is tempo stuff in
704 int m = gh_scm2int ( $2->get_property ("metronome-count"));
705 Duration *d = unsmob_duration ($2->get_property ("tempo-unit"));
706 Midi_def *md = dynamic_cast<Midi_def*> ($$);
708 md->set_tempo (d->get_length (), m);
709 scm_gc_unprotect_object ($2->self_scm ());
711 | music_output_def_body error {
717 TEMPO steno_duration '=' bare_unsigned {
718 $$ = MY_MAKE_MUSIC ("MetronomeChangeEvent");
719 $$->set_property ("tempo-unit", $2);
720 $$->set_property ("metronome-count", gh_int2scm ( $4));
725 The representation of a list is the
729 to have efficient append.
733 $$ = scm_cons (SCM_EOL, SCM_EOL);
737 SCM c = scm_cons ($2->self_scm (), SCM_EOL);
738 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
739 if (gh_pair_p (ly_cdr (s)))
740 gh_set_cdr_x (ly_cdr (s), c); /* append */
742 gh_set_car_x (s, c); /* set first cons */
743 gh_set_cdr_x (s, c); /* remember last cell */
759 | ALTERNATIVE '{' Music_list '}' {
765 REPEAT string bare_unsigned Music Alternative_music
769 SCM alts = gh_pair_p ($5) ? gh_car ($5) : SCM_EOL;
770 if (times < scm_ilength (alts)) {
771 unsmob_music (gh_car (alts))
772 ->origin ()->warning (
773 _ ("More alternatives than repeats. Junking excess alternatives."));
774 alts = ly_truncate_list (times, alts);
778 SCM proc = ly_scheme_function ("make-repeated-music");
780 SCM mus = scm_call_1 (proc, $2);
781 scm_gc_protect_object (mus); // UGH.
782 Music *r = unsmob_music (mus);
785 r-> set_property ("element", beg->self_scm ());
786 scm_gc_unprotect_object (beg->self_scm ());
788 r->set_property ("repeat-count", gh_int2scm (times >? 1));
790 r-> set_property ("elements",alts);
791 if (gh_equal_p ($2, scm_makfrom0str ("tremolo"))) {
793 TODO: move this code to Scheme.
797 we can not get durations and other stuff correct down the line, so we have to
798 add to the duration log here.
800 SCM func = ly_scheme_function ("shift-duration-log");
802 int dots = ($3 % 3) ? 0 : 1;
803 int shift = -intlog2 ((dots) ? ($3*2/3) : $3);
805 Sequential_music *seq = dynamic_cast<Sequential_music*> ($4);
808 int list_len = scm_ilength (seq->music_list ());
810 seq->origin ()->warning ("Chord tremolo must have 2 elements.");
812 r->compress (Moment (Rational (1, list_len)));
814 gh_call3 (func, r->self_scm (), gh_int2scm (shift),gh_int2scm (dots));
817 r->set_spot (*$4->origin ());
824 SEQUENTIAL '{' Music_list '}' {
825 $$ = MY_MAKE_MUSIC ("SequentialMusic");
826 $$->set_property ("elements", ly_car ($3));
827 $$->set_spot (THIS->here_input ());
829 | '{' Music_list '}' {
830 $$ = MY_MAKE_MUSIC ("SequentialMusic");
831 $$->set_property ("elements", ly_car ($2));
832 $$->set_spot (THIS->here_input ());
837 SIMULTANEOUS '{' Music_list '}'{
838 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
839 $$->set_property ("elements", ly_car ($3));
840 $$->set_spot (THIS->here_input ());
843 | simul_open Music_list simul_close {
844 $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
845 $$->set_property ("elements", ly_car ($2));
846 $$->set_spot (THIS->here_input ());
851 event_chord { $$ = $1; }
852 | APPLYOUTPUT embedded_scm {
853 if (!ly_input_procedure_p ($2))
854 THIS->parser_error (_ ("\\applycontext takes function argument"));
855 $$ = MY_MAKE_MUSIC ("ApplyOutputEvent");
856 $$->set_property ("procedure", $2);
857 $$->set_spot (THIS->here_input ());
859 | APPLYCONTEXT embedded_scm {
860 if (!ly_input_procedure_p ($2))
861 THIS->parser_error (_ ("\\applycontext takes function argument"));
862 $$ = MY_MAKE_MUSIC ("ApplyContext");
863 $$->set_property ("procedure", $2);
864 $$->set_spot (THIS->here_input ());
867 $$ = unsmob_music ($1);
874 optional_context_mod:
875 /**/ { $$ = SCM_EOL; }
876 | WITH '{' context_mod_list '}' { $$ = $3; }
880 GRACE { $$ = scm_makfrom0str ("Grace"); }
881 | ACCIACCATURA { $$ = scm_makfrom0str ("Acciaccatura"); }
882 | APPOGGIATURA { $$ = scm_makfrom0str ("Appoggiatura"); }
886 /* */ { $$ = SCM_EOL; }
887 | context_mod_list context_mod {
888 $$ = gh_cons ($2, $1);
894 SCM proc = ly_scheme_function ("make-autochange-music");
896 SCM res = scm_call_1 (proc, $2->self_scm ());
897 scm_gc_unprotect_object ($2->self_scm ());
898 $$ = unsmob_music (res);
899 scm_gc_protect_object (res);
900 $$->set_spot (THIS->here_input ());
902 | PARTCOMBINE Music Music {
903 SCM proc = ly_scheme_function ("make-part-combine-music");
905 SCM res = scm_call_1 (proc, gh_list ($2->self_scm (),
906 $3->self_scm (), SCM_UNDEFINED));
907 scm_gc_unprotect_object ($3->self_scm ());
908 scm_gc_unprotect_object ($2->self_scm ());
909 $$ = unsmob_music (res);
910 scm_gc_protect_object (res);
911 $$->set_spot (THIS->here_input ());
916 The other version is for easier debugging of
917 Sequential_music_iterator in combination with grace notes.
922 TODO: should distinguish between both grace types in the
923 basic music objects too, since the meaning is different.
927 String start_str = "start" + ly_scm2string ($1) + "Music";
928 String stop_str = "stop" + ly_scm2string ($1) + "Music";
930 SCM start = THIS->lexer_->lookup_identifier (start_str);
931 SCM stop = THIS->lexer_->lookup_identifier (stop_str);
933 Music *startm = unsmob_music (start);
934 Music *stopm = unsmob_music (stop);
938 stopm = stopm->clone ();
939 ms = scm_cons (stopm->self_scm (), ms);
940 scm_gc_unprotect_object (stopm->self_scm ());
942 ms = scm_cons ($2->self_scm (), ms);
943 scm_gc_unprotect_object ($2->self_scm ());
945 startm = startm->clone ();
946 ms = scm_cons (startm->self_scm (), ms);
947 scm_gc_unprotect_object (startm->self_scm ());
950 Music* seq = MY_MAKE_MUSIC ("SequentialMusic");
951 seq->set_property ("elements", ms);
954 $$ = MY_MAKE_MUSIC ("GraceMusic");
955 $$->set_property ("element", seq->self_scm ());
956 scm_gc_unprotect_object (seq->self_scm ());
958 $$ = MY_MAKE_MUSIC ("GraceMusic");
959 $$->set_property ("element", $2->self_scm ());
960 scm_gc_unprotect_object ($2->self_scm ());
963 | CONTEXT string '=' string optional_context_mod Music {
964 $$ = context_spec_music ($2, $4, $6, $5);
967 | CONTEXT STRING optional_context_mod Music {
968 $$ = context_spec_music ($2, SCM_UNDEFINED, $4, $3);
970 | NEWCONTEXT string optional_context_mod Music {
971 $$ = context_spec_music ($2, get_next_unique_context (),
982 int n = gh_scm2int (ly_car ($3)); int d = gh_scm2int (ly_cdr ($3));
985 $$= MY_MAKE_MUSIC ("TimeScaledMusic");
986 $$->set_spot (THIS->pop_spot ());
988 $$->set_property ("element", mp->self_scm ());
989 scm_gc_unprotect_object (mp->self_scm ());
990 $$->set_property ("numerator", gh_int2scm (n));
991 $$->set_property ("denominator", gh_int2scm (d));
992 $$->compress (Moment (Rational (n,d)));
995 | Repeated_music { $$ = $1; }
996 | Simultaneous_music { $$ = $1; }
997 | Sequential_music { $$ = $1; }
998 | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
999 $$ = MY_MAKE_MUSIC ("TransposedMusic");
1001 Pitch from = *unsmob_pitch ($2);
1002 Pitch to = *unsmob_pitch ($3);
1004 p->transpose (interval (from, to));
1005 $$->set_property ("element", p->self_scm ());
1006 scm_gc_unprotect_object (p->self_scm ());
1008 | APPLY embedded_scm Music {
1009 if (!ly_input_procedure_p ($2))
1011 THIS->parser_error (_ ("\\apply takes function argument"));
1016 SCM ret = gh_call1 ($2, $3->self_scm ());
1017 Music *m = unsmob_music (ret);
1019 THIS->parser_error ("\\apply must return a Music");
1020 m = MY_MAKE_MUSIC ("Music");
1027 SCM nn = THIS->lexer_->lookup_identifier ("pitchnames");
1028 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1032 THIS->lexer_->pop_state ();
1036 SCM nn = THIS->lexer_->lookup_identifier ("drumPitchNames");
1037 THIS->lexer_->push_note_state (alist_to_hashq (nn));
1041 THIS->lexer_->pop_state ();
1044 { THIS->lexer_->push_figuredbass_state (); }
1047 Music *chm = MY_MAKE_MUSIC ("UntransposableMusic");
1048 chm->set_property ("element", $3->self_scm ());
1050 scm_gc_unprotect_object ($3->self_scm ());
1052 THIS->lexer_->pop_state ();
1055 SCM nn = THIS->lexer_->lookup_identifier ("chordmodifiers");
1056 THIS->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
1057 nn = THIS->lexer_->lookup_identifier ("pitchnames");
1058 THIS->lexer_->push_chord_state (alist_to_hashq (nn));
1061 Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
1062 chm->set_property ("element", $3->self_scm ());
1063 scm_gc_unprotect_object ($3->self_scm ());
1066 THIS->lexer_->pop_state ();
1069 { THIS->lexer_->push_lyric_state (); }
1073 THIS->lexer_->pop_state ();
1075 | relative_music { $$ = $1; }
1076 | re_rhythmed_music { $$ = $1; }
1077 | TAG embedded_scm Music {
1078 tag_music ($3, $2, THIS->here_input ());
1084 RELATIVE absolute_pitch Music {
1086 Pitch pit = *unsmob_pitch ($2);
1087 $$ = MY_MAKE_MUSIC ("RelativeOctaveMusic");
1089 $$->set_property ("element", p->self_scm ());
1090 scm_gc_unprotect_object (p->self_scm ());
1093 Pitch retpitch = p->to_relative_octave (pit);
1094 if (lily_1_8_relative)
1095 $$->set_property ("last-pitch", retpitch.smobbed_copy ());
1100 ADDLYRICS Music Music {
1101 Music *l = MY_MAKE_MUSIC ("LyricCombineMusic");
1102 l->set_property ("elements", gh_list ($2->self_scm (), $3->self_scm (), SCM_UNDEFINED));
1103 scm_gc_unprotect_object ($3->self_scm ());
1104 scm_gc_unprotect_object ($2->self_scm ());
1107 | NEWADDLYRICS string Music {
1108 Music *l = MY_MAKE_MUSIC ("NewLyricCombineMusic");
1109 l->set_property ("element", $3->self_scm ());
1110 scm_gc_unprotect_object ($3->self_scm ());
1112 l->set_property ("associated-context", $2);
1117 CHANGE STRING '=' STRING {
1118 Music*t= MY_MAKE_MUSIC ("ContextChange");
1119 t-> set_property ("change-to-type", scm_string_to_symbol ($2));
1120 t-> set_property ("change-to-id", $4);
1123 $$->set_spot (THIS->here_input ());
1129 $$ = scm_list_3 (ly_symbol2scm ("assign"),
1130 scm_string_to_symbol ($1), $3);
1133 $$ = scm_list_2 (ly_symbol2scm ("unset"),
1134 scm_string_to_symbol ($2));
1136 | OVERRIDE STRING embedded_scm '=' embedded_scm {
1137 $$ = scm_list_4 (ly_symbol2scm ("push"),
1138 scm_string_to_symbol ($2), $3, $5);
1140 | REVERT STRING embedded_scm {
1141 $$ = scm_list_3 (ly_symbol2scm ("pop"),
1142 scm_string_to_symbol ($2), $3);
1147 CONSISTSEND { $$ = ly_symbol2scm ("consists-end"); }
1148 | CONSISTS { $$ = ly_symbol2scm ("consists"); }
1149 | REMOVE { $$ = ly_symbol2scm ("remove"); }
1151 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
1152 | DENIES { $$ = ly_symbol2scm ("denies"); }
1154 | ALIAS { $$ = ly_symbol2scm ("alias"); }
1155 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
1156 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
1157 | NAME { $$ = ly_symbol2scm ("context-name"); }
1161 property_operation { $$ = $1; }
1162 | context_def_mod STRING {
1163 $$ = scm_list_2 ($1, $2);
1169 $$ = scm_list_2 (ly_symbol2scm ("Bottom"), scm_string_to_symbol ($1));
1171 | STRING '.' STRING {
1172 $$ = scm_list_2 (scm_string_to_symbol ($1), scm_string_to_symbol ($3));
1177 OVERRIDE context_prop_spec embedded_scm '=' scalar {
1178 $$ = property_op_to_music (scm_list_4 (
1179 ly_symbol2scm ("poppush"),
1182 $$= context_spec_music (gh_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1184 | REVERT context_prop_spec embedded_scm {
1185 $$ = property_op_to_music (scm_list_3 (
1186 ly_symbol2scm ("pop"),
1190 $$= context_spec_music (gh_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1192 | SET context_prop_spec '=' scalar {
1193 $$ = property_op_to_music (scm_list_3 (
1194 ly_symbol2scm ("assign"),
1197 $$= context_spec_music (gh_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1199 | UNSET context_prop_spec {
1200 $$ = property_op_to_music (scm_list_2 (
1201 ly_symbol2scm ("unset"),
1203 $$= context_spec_music (gh_car ($2), SCM_UNDEFINED, $$, SCM_EOL);
1205 | ONCE music_property_def {
1206 SCM e = $2->get_property ("element");
1207 unsmob_music (e)->set_property ("once", SCM_BOOL_T);
1217 | bare_int { $$ = gh_int2scm ($1); }
1218 | embedded_scm { $$ = $1; }
1219 | full_markup { $$ = $1; }
1220 | DIGIT { $$ = gh_int2scm ($1); }
1226 Adding pre_events to the simple_element
1227 makes the choice between
1233 simple_element: STRING
1235 a single shift/reduction conflict.
1237 nevertheless, this is not very clean, and we should find a different
1247 pre_events simple_element post_events {
1248 SCM elts = $2-> get_property ("elements");
1250 elts = gh_append2 (elts, scm_reverse_x ($3, SCM_EOL));
1252 $2->set_property ("elements", elts);
1256 | note_chord_element
1261 chord_body optional_notemode_duration post_events
1263 SCM dur = unsmob_duration ($2)->smobbed_copy ();
1264 SCM es = $1->get_property ("elements");
1265 SCM postevs = scm_reverse_x ($3, SCM_EOL);
1267 for (SCM s = es; gh_pair_p (s); s = gh_cdr (s))
1268 unsmob_music (gh_car (s))->set_property ("duration", dur);
1269 es = gh_append2 (es, postevs);
1271 $1-> set_property ("elements", es);
1282 simul_open: LESSLESS
1285 simul_close: MOREMORE
1289 chord_open chord_body_elements chord_close
1291 $$ = MY_MAKE_MUSIC ("EventChord");
1292 $$->set_property ("elements",
1293 scm_reverse_x ($2, SCM_EOL));
1297 chord_body_elements:
1298 /* empty */ { $$ = SCM_EOL; }
1299 | chord_body_elements chord_body_element {
1300 $$ = gh_cons ($2->self_scm (), $1);
1301 scm_gc_unprotect_object ($2->self_scm ());
1306 pitch exclamations questions post_events
1308 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1309 n->set_property ("pitch", $1);
1311 n->set_property ("cautionary", SCM_BOOL_T);
1312 if ($2 % 2 || $3 % 2)
1313 n->set_property ("force-accidental", SCM_BOOL_T);
1315 if (gh_pair_p ($4)) {
1316 SCM arts = scm_reverse_x ($4, SCM_EOL);
1317 n->set_property ("articulations", arts);
1321 | DRUM_PITCH post_events {
1322 Music *n = MY_MAKE_MUSIC ("NoteEvent");
1323 n->set_property ("duration", $2);
1324 n->set_property ("drum-type", $1);
1325 n->set_spot (THIS->here_input ());
1327 if (gh_pair_p ($2)) {
1328 SCM arts = scm_reverse_x ($2, SCM_EOL);
1329 n->set_property ("articulations", arts);
1336 ADDQUOTE string Music {
1337 SCM adder = ly_scheme_function ("add-quotable");
1339 scm_call_2 (adder, $2, $3->self_scm ());
1340 scm_gc_unprotect_object ($3->self_scm ());
1346 $$ = MY_MAKE_MUSIC ("EventChord");
1347 $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
1348 scm_gc_unprotect_object ($1->self_scm ());
1350 $$-> set_spot (THIS->here_input ());
1351 $1-> set_spot (THIS->here_input ());
1353 | SKIP duration_length {
1354 Music *skip = MY_MAKE_MUSIC ("SkipMusic");
1355 skip->set_property ("duration", $2);
1359 | QUOTE STRING duration_length {
1360 SCM tab = THIS->lexer_->lookup_identifier ("musicQuotes");
1362 if (scm_hash_table_p (tab) == SCM_BOOL_T)
1364 SCM key = $2; // use symbol?
1365 evs = scm_hash_ref (tab, key, SCM_BOOL_F);
1368 if (gh_vector_p (evs))
1370 quote = MY_MAKE_MUSIC ("QuoteMusic");
1371 quote->set_property ("duration", $3);
1372 quote->set_property ("quoted-events", evs);
1374 THIS->here_input ().warning (_f ("Can\'t find music"));
1375 quote = MY_MAKE_MUSIC ("Event");
1377 quote->set_spot (THIS->here_input ());
1380 | OCTAVE { THIS->push_spot (); }
1382 Music *l = MY_MAKE_MUSIC ("RelativeOctaveCheck");
1384 $$->set_spot (THIS->pop_spot ());
1385 $$->set_property ("pitch", $3);
1388 Music *l = MY_MAKE_MUSIC ("LigatureEvent");
1389 l->set_property ("span-direction", gh_int2scm (START));
1390 l->set_spot (THIS->here_input ());
1392 $$ = MY_MAKE_MUSIC ("EventChord");
1393 $$->set_property ("elements", scm_cons (l->self_scm (), SCM_EOL));
1394 scm_gc_unprotect_object (l->self_scm ());
1395 $$->set_spot (THIS->here_input ());
1398 Music *l = MY_MAKE_MUSIC ("LigatureEvent");
1399 l->set_property ("span-direction", gh_int2scm (STOP));
1400 l->set_spot (THIS->here_input ());
1402 $$ = MY_MAKE_MUSIC ("EventChord");
1403 $$->set_property ("elements", scm_cons (l->self_scm (), SCM_EOL));
1404 $$->set_spot (THIS->here_input ());
1405 scm_gc_unprotect_object (l->self_scm ());
1408 $$ = MY_MAKE_MUSIC ("VoiceSeparator");
1409 $$->set_spot (THIS->here_input ());
1412 SCM pipe =THIS->lexer_->lookup_identifier ("pipeSymbol");
1414 if (Music * m = unsmob_music (pipe))
1417 $$ = MY_MAKE_MUSIC ("BarCheck");
1419 $$->set_spot (THIS->here_input ());
1421 | TRANSPOSITION pitch {
1422 $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
1424 $$->set_spot (THIS-> here_input ());
1425 $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
1429 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1431 Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1433 $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
1434 $$->set_spot (THIS->here_input ());
1435 t->set_spot (THIS->here_input ());
1437 | PARTIAL duration_length {
1438 Moment m = - unsmob_duration ($2)->get_length ();
1439 Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1440 p->set_spot (THIS->here_input ());
1441 p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
1443 p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
1448 SCM proc = ly_scheme_function ("make-clef-set");
1450 SCM result = scm_call_1 (proc, $2);
1451 scm_gc_protect_object (result);
1452 $$ = unsmob_music (result);
1455 SCM proc= ly_scheme_function ("make-time-signature-set");
1457 SCM result = scm_apply_2 (proc, gh_car ($2), gh_cdr ($2), SCM_EOL);
1458 scm_gc_protect_object (result);
1459 $$ = unsmob_music (result);
1462 SCM proc = ly_scheme_function ("make-mark-set");
1464 SCM result = scm_call_1 (proc, $2);
1465 scm_gc_protect_object (result);
1466 $$ = unsmob_music (result);
1472 $$ = MY_MAKE_MUSIC ("BreathingSignEvent");
1475 $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent");
1478 Music *m = MY_MAKE_MUSIC ("MarkEvent");
1485 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1488 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1490 Music *key= MY_MAKE_MUSIC ("KeyChangeEvent");
1491 if (scm_ilength ($3) > 0)
1493 key->set_property ("pitch-alist", $3);
1494 key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
1495 ((Music*)key)->transpose (* unsmob_pitch ($2));
1497 THIS->parser_error (_ ("Second argument must be pitch list."));
1508 | post_events post_event {
1509 $2->set_spot (THIS->here_input ());
1510 $$ = gh_cons ($2->self_scm (), $$);
1511 scm_gc_unprotect_object ($2->self_scm ());
1513 | post_events tagged_post_event {
1514 $2 -> set_spot (THIS->here_input ());
1515 $$ = scm_cons ($2->self_scm (), $$);
1516 scm_gc_unprotect_object ($2->self_scm ());
1522 '-' TAG embedded_scm post_event {
1523 tag_music ($4, $3, THIS->here_input ());
1529 direction_less_event {
1533 if (!THIS->lexer_->is_lyric_state ())
1534 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1535 $$ = MY_MAKE_MUSIC ("HyphenEvent");
1538 if (!THIS->lexer_->is_lyric_state ())
1539 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1540 $$ = MY_MAKE_MUSIC ("ExtenderEvent");
1542 | script_dir direction_reqd_event {
1544 $2->set_property ("direction", gh_int2scm ($1));
1547 | script_dir direction_less_event {
1549 $2->set_property ("direction", gh_int2scm ($1));
1552 | string_number_event
1555 string_number_event:
1557 Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
1558 s->set_property ("string-number", gh_int2scm ($1));
1559 s->set_spot (THIS->here_input ());
1565 direction_less_event:
1571 TODO: should take all these defs out of the parser, adn make use
1575 (set-articulation '~ "trill")
1578 Music *m = MY_MAKE_MUSIC ("BeamEvent");
1579 m->set_spot (THIS->here_input ());
1580 m->set_property ("span-direction", gh_int2scm (START));
1584 Music *m = MY_MAKE_MUSIC ("BeamEvent");
1585 m->set_spot (THIS->here_input ());
1586 m->set_property ("span-direction", gh_int2scm (STOP));
1590 Music *m = MY_MAKE_MUSIC ("TieEvent");
1591 m->set_spot (THIS->here_input ());
1596 dynamic_cast<Music *> ($$)->set_property ("span-direction",
1597 gh_int2scm (START));
1601 dynamic_cast<Music *> ($$)->set_property ("span-direction",
1604 | EVENT_IDENTIFIER {
1605 $$ = unsmob_music ($1);
1608 Music *a = MY_MAKE_MUSIC ("TremoloEvent");
1609 a->set_spot (THIS->here_input ());
1610 a->set_property ("tremolo-type", gh_int2scm ($1));
1615 direction_reqd_event:
1619 | script_abbreviation {
1620 SCM s = THIS->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
1621 Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
1622 if (gh_string_p (s))
1623 a->set_property ("articulation-type", s);
1624 else THIS->parser_error (_ ("Expecting string as script definition"));
1630 /**/ { $$ = SCM_EOL; }
1631 | '=' { $$ = gh_int2scm (0); }
1632 | '=' sub_quotes { $$ = gh_int2scm ($2); }
1633 | '=' sup_quotes { $$ = gh_int2scm ($2); }
1658 | NOTENAME_PITCH sup_quotes {
1659 Pitch p = *unsmob_pitch ($1);
1660 p = p.transposed (Pitch ($2,0,0));
1661 $$ = p.smobbed_copy ();
1663 | NOTENAME_PITCH sub_quotes {
1664 Pitch p =* unsmob_pitch ($1);
1665 p = p.transposed (Pitch (-$2,0,0));
1666 $$ = p.smobbed_copy ();
1678 | TONICNAME_PITCH sup_quotes {
1679 Pitch p = *unsmob_pitch ($1);
1680 p = p.transposed (Pitch ($2,0,0));
1681 $$ = p.smobbed_copy ();
1683 | TONICNAME_PITCH sub_quotes {
1684 Pitch p =* unsmob_pitch ($1);
1686 p = p.transposed (Pitch (-$2,0,0));
1687 $$ = p.smobbed_copy ();
1697 pitch_also_in_chords:
1704 Music *s = MY_MAKE_MUSIC ("SlurEvent");
1706 s->set_spot (THIS->here_input ());
1709 Music *s = MY_MAKE_MUSIC ("PhrasingSlurEvent");
1711 s->set_spot (THIS->here_input ());
1714 Music *s = MY_MAKE_MUSIC ("CrescendoEvent");
1716 s->set_spot (THIS->here_input ());
1719 Music *s = MY_MAKE_MUSIC ("DecrescendoEvent");
1721 s->set_spot (THIS->here_input ());
1728 Music *s = MY_MAKE_MUSIC ("CrescendoEvent");
1729 s->set_spot (THIS->here_input ());
1734 Music *s= MY_MAKE_MUSIC ("SlurEvent");
1736 s->set_spot (THIS->here_input ());
1740 Music *s= MY_MAKE_MUSIC ("PhrasingSlurEvent");
1742 s->set_property ("span-type", scm_makfrom0str ( "phrasing-slur"));
1743 s->set_spot (THIS->here_input ());
1749 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1750 t->set_property ("text", $1);
1751 t->set_spot (THIS->here_input ());
1755 Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
1756 t->set_property ("text", make_simple_markup ($1));
1757 t->set_spot (THIS->here_input ());
1762 Music *t = MY_MAKE_MUSIC ("FingerEvent");
1763 t->set_property ("digit", gh_int2scm ($1));
1764 t->set_spot (THIS->here_input ());
1769 script_abbreviation:
1771 $$ = scm_makfrom0str ("Hat");
1774 $$ = scm_makfrom0str ("Plus");
1777 $$ = scm_makfrom0str ("Dash");
1780 $$ = scm_makfrom0str ("Bar");
1783 $$ = scm_makfrom0str ("Larger");
1786 $$ = scm_makfrom0str ("Dot");
1789 $$ = scm_makfrom0str ("Underscore");
1796 | '-' { $$ = CENTER; }
1807 multiplied_duration {
1812 optional_notemode_duration:
1814 Duration dd = THIS->default_duration_;
1815 $$ = dd.smobbed_copy ();
1817 THIS->beam_check ($$);
1819 | multiplied_duration {
1821 THIS->default_duration_ = *unsmob_duration ($$);
1823 THIS->beam_check ($$);
1828 bare_unsigned dots {
1830 if (!is_is_duration ($1))
1831 THIS->parser_error (_f ("not a duration: %d", $1));
1835 $$ = Duration (len, $2).smobbed_copy ();
1837 | DURATION_IDENTIFIER dots {
1838 Duration *d = unsmob_duration ($1);
1839 Duration k (d->duration_log (), d->dot_count () + $2);
1848 multiplied_duration:
1852 | multiplied_duration '*' bare_unsigned {
1853 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1855 | multiplied_duration '*' FRACTION {
1856 Rational m (gh_scm2int (ly_car ($3)), gh_scm2int (ly_cdr ($3)));
1858 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
1863 FRACTION { $$ = $1; }
1864 | UNSIGNED '/' UNSIGNED {
1865 $$ = scm_cons (gh_int2scm ($1), gh_int2scm ($3));
1883 | ':' bare_unsigned {
1884 if (!is_is_duration ($2))
1885 THIS->parser_error (_f ("not a duration: %d", $2));
1892 /*****************************************************************
1894 *****************************************************************/
1897 $$ = scm_number_to_string (gh_int2scm ($1), gh_int2scm (10));
1900 $$ = scm_number_to_string (gh_int2scm ($1), gh_int2scm (10));
1902 | STRING { $$ = $1; }
1913 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
1914 $$ = bfr->self_scm ();
1915 scm_gc_unprotect_object ($$);
1918 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent");
1919 $$ = bfr->self_scm ();
1921 bfr->set_property ("figure", $1);
1923 scm_gc_unprotect_object ($$);
1925 | bass_figure bass_mod {
1926 Music *m = unsmob_music ($1);
1928 SCM salter = m->get_property ("alteration");
1929 int alter = gh_number_p (salter) ? gh_scm2int (salter) : 0;
1930 m->set_property ("alteration",
1931 gh_int2scm (alter + $2));
1933 m->set_property ("alteration", gh_int2scm (0));
1941 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
1946 | br_bass_figure ']' {
1948 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
1956 | figure_list br_bass_figure {
1957 $$ = scm_cons ($2, $1);
1962 FIGURE_OPEN figure_list FIGURE_CLOSE {
1963 Music *m = MY_MAKE_MUSIC ("EventChord");
1964 $2 = scm_reverse_x ($2, SCM_EOL);
1965 m->set_property ("elements", $2);
1966 $$ = m->self_scm ();
1977 pitch exclamations questions oct_check optional_notemode_duration optional_rest {
1979 Input i = THIS->pop_spot ();
1980 if (!THIS->lexer_->is_note_state ())
1981 THIS->parser_error (_ ("Have to be in Note mode for notes"));
1985 n = MY_MAKE_MUSIC ("RestEvent");
1987 n = MY_MAKE_MUSIC ("NoteEvent");
1989 n->set_property ("pitch", $1);
1990 n->set_property ("duration", $5);
1992 if (gh_number_p ($4))
1994 int q = gh_scm2int ($4);
1995 n->set_property ("absolute-octave", gh_int2scm (q-1));
1999 n->set_property ("cautionary", SCM_BOOL_T);
2000 if ($2 % 2 || $3 % 2)
2001 n->set_property ("force-accidental", SCM_BOOL_T);
2003 Music *v = MY_MAKE_MUSIC ("EventChord");
2004 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2005 scm_gc_unprotect_object (n->self_scm ());
2011 | DRUM_PITCH optional_notemode_duration {
2012 Input i = THIS->pop_spot ();
2014 Music *n = MY_MAKE_MUSIC ("NoteEvent");
2015 n->set_property ("duration", $2);
2016 n->set_property ("drum-type", $1);
2018 Music *v = MY_MAKE_MUSIC ("EventChord");
2019 v->set_property ("elements", scm_list_1 (n->self_scm ()));
2020 scm_gc_unprotect_object (n->self_scm ());
2026 | figure_spec optional_notemode_duration {
2027 Music *m = unsmob_music ($1);
2028 Input i = THIS->pop_spot ();
2030 for (SCM s = m->get_property ("elements"); gh_pair_p (s); s = ly_cdr (s))
2032 unsmob_music (ly_car (s))->set_property ("duration", $2);
2036 | RESTNAME optional_notemode_duration {
2038 Input i = THIS->pop_spot ();
2040 if (ly_scm2string ($1) == "s") {
2042 ev = MY_MAKE_MUSIC ("SkipEvent");
2045 ev = MY_MAKE_MUSIC ("RestEvent");
2048 ev->set_property ("duration", $2);
2050 Music *velt = MY_MAKE_MUSIC ("EventChord");
2051 velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
2054 scm_gc_unprotect_object (ev->self_scm ());
2058 | MULTI_MEASURE_REST optional_notemode_duration {
2061 SCM proc = ly_scheme_function ("make-multi-measure-rest");
2062 SCM mus = scm_call_2 (proc, $2,
2063 make_input (THIS->here_input ()));
2064 scm_gc_protect_object (mus);
2065 $$ = unsmob_music (mus);
2068 | lyric_element optional_notemode_duration {
2069 Input i = THIS->pop_spot ();
2070 if (!THIS->lexer_->is_lyric_state ())
2071 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
2073 Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
2074 lreq->set_property ("text", $1);
2075 lreq->set_property ("duration",$2);
2077 Music *velt = MY_MAKE_MUSIC ("EventChord");
2078 velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
2085 if (!THIS->lexer_->is_chord_state ())
2086 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
2087 $$ = unsmob_music ($1);
2092 full_markup { $$ = $1; }
2093 | STRING { $$ = $1; }
2097 steno_tonic_pitch optional_notemode_duration {
2098 $$ = make_chord ($1, $2, SCM_EOL);
2100 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
2101 SCM its = scm_reverse_x ($4, SCM_EOL);
2102 $$ = make_chord ($1, $2, gh_cons ($3, its));
2110 | chord_items chord_item {
2111 $$ = gh_cons ($2, $$);
2117 $$ = ly_symbol2scm ("chord-colon");
2120 $$ = ly_symbol2scm ("chord-caret");
2122 | CHORD_SLASH steno_tonic_pitch {
2123 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
2125 | CHORD_BASS steno_tonic_pitch {
2126 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
2135 $$ = scm_reverse_x ($1, SCM_EOL);
2143 step_number { $$ = gh_cons ($1, SCM_EOL); }
2144 | step_numbers '.' step_number {
2145 $$ = gh_cons ($3, $$);
2151 $$ = make_chord_step ($1, 0);
2153 | bare_unsigned '+' {
2154 $$ = make_chord_step ($1, SHARP);
2156 | bare_unsigned CHORD_MINUS {
2157 $$ = make_chord_step ($1, FLAT);
2164 TODO: should deprecate in favor of Scheme?
2168 number_expression '+' number_term {
2169 $$ = scm_sum ($1, $3);
2171 | number_expression '-' number_term {
2172 $$ = scm_difference ($1, $3);
2181 | number_factor '*' number_factor {
2182 $$ = scm_product ($1, $3);
2184 | number_factor '/' number_factor {
2185 $$ = scm_divide ($1, $3);
2190 '-' number_factor { /* %prec UNARY_MINUS */
2191 $$ = scm_difference ($2, SCM_UNDEFINED);
2199 $$ = gh_int2scm ($1);
2204 | NUMBER_IDENTIFIER {
2207 | REAL NUMBER_IDENTIFIER {
2208 $$ = gh_double2scm (gh_scm2double ($1) *gh_scm2double ($2));
2210 | UNSIGNED NUMBER_IDENTIFIER {
2211 $$ = gh_double2scm ($1 *gh_scm2double ($2));
2227 if (scm_integer_p ($1) == SCM_BOOL_T)
2229 int k = gh_scm2int ($1);
2233 THIS->parser_error (_ ("need integer number arg"));
2247 | STRING_IDENTIFIER {
2250 | string '+' string {
2251 $$ = scm_string_append (scm_list_2 ($1, $3));
2258 | exclamations '!' { $$ ++; }
2263 | questions '?' { $$ ++; }
2273 { THIS->lexer_->push_markup_state (); }
2276 THIS->lexer_->pop_state ();
2282 This should be done more dynamically if possible.
2286 $$ = make_simple_markup ($1);
2288 | MARKUP_HEAD_EMPTY {
2289 $$ = scm_list_1 ($1);
2291 | MARKUP_HEAD_MARKUP0 markup {
2292 $$ = scm_list_2 ($1, $2);
2294 | MARKUP_HEAD_MARKUP0_MARKUP1 markup markup {
2295 $$ = scm_list_3 ($1, $2, $3);
2297 | MARKUP_HEAD_SCM0_MARKUP1 SCM_T markup {
2298 $$ = scm_list_3 ($1, $2, $3);
2303 | MARKUP_HEAD_LIST0 markup_list {
2304 $$ = scm_list_2 ($1,$2);
2306 | MARKUP_HEAD_SCM0 embedded_scm {
2307 $$ = scm_list_2 ($1, $2);
2309 | MARKUP_HEAD_SCM0_SCM1_MARKUP2 embedded_scm embedded_scm markup {
2310 $$ = scm_list_4 ($1, $2, $3, $4);
2312 | MARKUP_HEAD_SCM0_SCM1_SCM2 embedded_scm embedded_scm embedded_scm {
2313 $$ = scm_list_4 ($1, $2, $3, $4);
2315 | MARKUP_HEAD_SCM0_SCM1 embedded_scm embedded_scm {
2316 $$ = scm_list_3 ($1, $2, $3);
2318 | MARKUP_IDENTIFIER {
2321 | STRING_IDENTIFIER {
2327 chord_open markup_list_body chord_close { $$ = scm_reverse_x ($2, SCM_EOL); }
2331 '{' markup_list_body '}' {
2332 SCM line = ly_scheme_function ("line-markup");
2334 $$ = scm_list_2 (line, scm_reverse_x ($2, SCM_EOL));
2339 /**/ { $$ = SCM_EOL; }
2340 | markup_list_body markup {
2341 $$ = gh_cons ($2, $1);
2349 My_lily_parser::set_yydebug (bool )
2356 extern My_lily_parser *current_parser;
2359 My_lily_parser::do_yyparse ()
2361 current_parser = this;;
2362 yyparse ((void*)this);
2367 Should make this optional? It will also complain when you do
2371 which is entirely legitimate.
2373 Or we can scrap it. Barchecks should detect wrong durations, and
2374 skipTypesetting speeds it up a lot.
2378 My_lily_parser::beam_check (SCM dur)
2380 Duration *d = unsmob_duration (dur);
2381 if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
2383 Music *m = unsmob_music (last_beam_start_);
2384 m->origin ()->warning (_ ("Suspect duration found following this beam"));
2386 last_beam_start_ = SCM_EOL;
2394 It is a little strange to have this function in this file, but
2395 otherwise, we have to import music classes into the lexer.
2399 My_lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
2401 if (gh_string_p (sid)) {
2403 return STRING_IDENTIFIER;
2404 } else if (gh_number_p (sid)) {
2406 return NUMBER_IDENTIFIER;
2407 } else if (unsmob_context_def (sid)) {
2408 *destination = unsmob_context_def (sid)->clone_scm ();
2409 return CONTEXT_DEF_IDENTIFIER;
2410 } else if (unsmob_score (sid)) {
2411 Score *sc = new Score (*unsmob_score (sid));
2412 *destination = sc->self_scm ();
2413 return SCORE_IDENTIFIER;
2414 } else if (Music *mus = unsmob_music (sid)) {
2415 mus = mus->clone ();
2416 *destination = mus->self_scm ();
2417 unsmob_music (*destination)->
2418 set_property ("origin", make_input (last_input_));
2419 return dynamic_cast<Event*> (mus)
2420 ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
2421 } else if (unsmob_duration (sid)) {
2422 *destination = unsmob_duration (sid)->smobbed_copy ();
2423 return DURATION_IDENTIFIER;
2424 } else if (unsmob_music_output_def (sid)) {
2425 Music_output_def *p = unsmob_music_output_def (sid);
2428 *destination = p->self_scm ();
2429 return MUSIC_OUTPUT_DEF_IDENTIFIER;
2430 } else if (Text_item::markup_p (sid)) {
2432 return MARKUP_IDENTIFIER;
2439 property_op_to_music (SCM op)
2442 SCM tag = gh_car (op);
2443 SCM symbol = gh_cadr (op);
2444 SCM args = gh_cddr (op);
2445 SCM grob_val = SCM_UNDEFINED;
2446 SCM grob_sym = SCM_UNDEFINED;
2447 SCM val = SCM_UNDEFINED;
2449 if (tag == ly_symbol2scm ("assign"))
2451 m = MY_MAKE_MUSIC ("PropertySet");
2452 val = gh_car (args);
2454 else if (tag == ly_symbol2scm ("unset"))
2455 m = MY_MAKE_MUSIC ("PropertyUnset");
2456 else if (tag == ly_symbol2scm ("poppush")
2457 || tag == ly_symbol2scm ("push"))
2459 m = MY_MAKE_MUSIC ("OverrideProperty");
2460 grob_sym = gh_car (args);
2461 grob_val = gh_cadr (args);
2463 else if (tag == ly_symbol2scm ("pop")) {
2464 m = MY_MAKE_MUSIC ("RevertProperty");
2465 grob_sym = gh_car (args);
2468 m->set_property ("symbol", symbol);
2470 if (val != SCM_UNDEFINED)
2471 m->set_property ("value", val);
2472 if (grob_val != SCM_UNDEFINED)
2473 m->set_property ("grob-value", grob_val);
2475 if (grob_sym != SCM_UNDEFINED)
2477 bool itc = internal_type_checking_global_b;
2480 bool autobeam = gh_equal_p (symbol, ly_symbol2scm ("autoBeamSettings"));
2482 internal_type_checking_global_b = false;
2483 m->set_property ("grob-property", grob_sym);
2485 internal_type_checking_global_b = itc;
2488 if (op == ly_symbol2scm ("poppush"))
2489 m->set_property ("pop-first", SCM_BOOL_T);
2496 context_spec_music (SCM type, SCM id, Music *m, SCM ops)
2498 Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
2500 csm->set_property ("element", m->self_scm ());
2501 scm_gc_unprotect_object (m->self_scm ());
2503 csm->set_property ("context-type",
2504 gh_symbol_p (type) ? type : scm_string_to_symbol (type));
2505 csm->set_property ("property-operations", ops);
2507 if (gh_string_p (id))
2508 csm->set_property ("context-id", id);
2514 get_next_unique_context ()
2516 static int new_context_count;
2519 snprintf (s, 1024, "uniqueContext%d", new_context_count ++);
2521 return scm_makfrom0str (s);