1 %{ // -*-Fundamental-*-
4 parser.yy -- Bison/C++ parser for lilypond
6 source file of the GNU LilyPond music typesetter
8 (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 Jan Nieuwenhuizen <janneke@gnu.org>
13 Two shift/reduce problems:
20 the rules for who is protecting what are very shady. TODO: uniformise
29 #include "translator-def.hh"
30 #include "lily-guile.hh"
31 #include "change-iterator.hh"
33 #include "my-lily-lexer.hh"
34 #include "paper-def.hh"
35 #include "midi-def.hh"
37 #include "file-path.hh"
39 #include "dimensions.hh"
40 #include "command-request.hh"
41 #include "musical-request.hh"
42 #include "my-lily-parser.hh"
43 #include "context-specced-music.hh"
45 #include "music-list.hh"
46 #include "output-property-music-iterator.hh"
47 #include "property-iterator.hh"
48 #include "file-results.hh"
51 #include "relative-music.hh"
52 #include "lyric-combine-music.hh"
53 #include "transposed-music.hh"
54 #include "time-scaled-music.hh"
55 #include "repeated-music.hh"
56 #include "untransposable-music.hh"
57 #include "lilypond-input-version.hh"
58 #include "grace-music.hh"
59 #include "part-combine-music.hh"
60 #include "scm-hash.hh"
61 #include "auto-change-iterator.hh"
62 #include "un-relativable-music.hh"
66 regular_identifier_b (SCM id)
68 String str = ly_scm2string (id);
69 char const *s = str.ch_C() ;
74 v = v && isalpha (*s);
82 set_property_music (SCM sym, SCM value)
84 Music * p = new Music (SCM_EOL);
85 p->set_mus_property ("symbol", sym);
86 p->set_mus_property ("iterator-ctor",
87 Property_iterator::constructor_cxx_function);
89 p->set_mus_property ("value", value);
96 return t && t == 1 << intlog2 (t);
100 set_music_properties (Music *p, SCM a)
102 for (SCM k = a; gh_pair_p (k); k = gh_cdr (k))
104 p->set_mus_property (gh_caar (k), gh_cdar (k));
114 // needed for bison.simple's malloc () and free ()
121 #define YYERROR_VERBOSE 1
123 #define YYPARSE_PARAM my_lily_parser_l
124 #define YYLEX_PARAM my_lily_parser_l
126 ((My_lily_parser *) my_lily_parser_l)
128 #define yyerror THIS->parser_error
129 #define ARRAY_SIZE(a,s) if (a.size () != s) THIS->parser_error (_f ("Expecting %d arguments", s))
136 Link_array<Request> *reqvec;
138 String *string; // needed by the lexer as temporary scratch area.
142 Scheme_hash_table *scmhash;
143 Music_output_def * outputdef;
147 /* We use SCMs to do strings, because it saves us the trouble of
148 deleting them. Let's hope that a stack overflow doesnt trigger a move
149 of the parse stack onto the heap. */
159 yylex (YYSTYPE *s, void * v_l)
161 My_lily_parser *pars_l = (My_lily_parser*) v_l;
162 My_lily_lexer * lex_l = pars_l->lexer_p_;
164 lex_l->lexval_l = (void*) s;
165 return lex_l->yylex ();
173 /* tokens which are not keywords */
183 %token CHORDMODIFIERS
191 %token ELEMENTDESCRIPTIONS
197 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
207 %token MULTI_MEASURE_REST
220 %token OVERRIDE SET REVERT
233 %token COMMANDSPANREQUEST
235 %token OUTPUTPROPERTY
245 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE
246 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET
248 %type <i> exclamations questions dots
249 %type <i> bass_number bass_mod
250 %type <scm> bass_figure figure_list figure_spec
252 %token <scm> NOTENAME_PITCH
253 %token <scm> TONICNAME_PITCH
254 %token <scm> CHORDMODIFIER_PITCH
255 %token <scm> DURATION_IDENTIFIER
256 %token <scm> FRACTION
257 %token <id> IDENTIFIER
260 %token <scm> SCORE_IDENTIFIER
261 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
263 %token <scm> NUMBER_IDENTIFIER
264 %token <scm> REQUEST_IDENTIFIER
265 %token <scm> MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
266 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
267 %token <scm> RESTNAME
273 %type <outputdef> output_def
274 %type <scmhash> lilypond_header lilypond_header_body
275 %type <request> open_request_parens close_request_parens open_request close_request
276 %type <request> request_with_dir request_that_take_dir verbose_request
277 %type <i> sub_quotes sup_quotes
278 %type <music> simple_element request_chord command_element Simple_music Composite_music
279 %type <music> Alternative_music Repeated_music
280 %type <i> tremolo_type
281 %type <i> bare_int bare_unsigned
284 %type <scm> identifier_init
286 %type <scm> steno_duration optional_notemode_duration multiplied_duration
287 %type <scm> explicit_duration
289 %type <reqvec> pre_requests post_requests
290 %type <request> gen_text_def
291 %type <scm> steno_pitch pitch absolute_pitch
292 %type <scm> explicit_pitch steno_tonic_pitch
294 %type <scm> chord_additions chord_subtractions chord_notes chord_step
296 %type <scm> chord_note chord_inversion chord_bass
297 %type <scm> duration_length fraction
299 %type <scm> embedded_scm scalar
300 %type <music> Music Sequential_music Simultaneous_music Music_sequence
301 %type <music> relative_music re_rhythmed_music part_combined_music
302 %type <music> property_def translator_change
303 %type <scm> Music_list
304 %type <outputdef> music_output_def_body
305 %type <request> shorthand_command_req
306 %type <request> post_request
307 %type <music> command_req verbose_command_req
308 %type <request> extender_req
309 %type <request> hyphen_req
310 %type <scm> string bare_number number_expression number_term number_factor
312 %type <score> score_block score_body
314 %type <scm> translator_spec_block translator_spec_body
315 %type <tempo> tempo_request
316 %type <scm> notenames_body notenames_block chordmodifiers_block
317 %type <scm> script_abbreviation
323 /* We don't assign precedence to / and *, because we might need varied
324 prec levels in different prods */
330 lilypond: /* empty */
331 | lilypond toplevel_expression {}
332 | lilypond assignment { }
334 THIS->error_level_i_ = 1;
337 THIS->error_level_i_ = 1;
343 THIS->lexer_p_->pitchname_tab_ = $1;
345 | chordmodifiers_block {
346 THIS->lexer_p_->chordmodifier_tab_ = $1;
350 scm_gc_unprotect_object (global_header_p->self_scm ());
351 global_header_p = $1;
354 score_global_array.push ($1);
357 if (dynamic_cast<Paper_def*> ($1))
358 THIS->lexer_p_->set_identifier ("$defaultpaper", $1->self_scm ());
359 else if (dynamic_cast<Midi_def*> ($1))
360 THIS->lexer_p_->set_identifier ("$defaultmidi", $1->self_scm ());
373 chordmodifiers_block:
374 CHORDMODIFIERS notenames_body { $$ = $2; }
378 PITCHNAMES notenames_body { $$ = $2; }
383 int i = scm_ilength ($1);
385 SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
386 for (SCM s = $1; gh_pair_p (s); s = gh_cdr (s)) {
387 SCM pt = gh_cdar (s);
388 if (!unsmob_pitch (pt))
389 THIS->parser_error ("Need pitch object.");
391 scm_hashq_set_x (tab, gh_caar (s), pt);
398 lilypond_header_body:
400 $$ = new Scheme_hash_table;
402 Scope *sc = new Scope ($$);
403 THIS->lexer_p_-> scope_l_arr_.push (sc);
405 | lilypond_header_body assignment {
411 HEADER '{' lilypond_header_body '}' {
413 delete THIS->lexer_p_-> scope_l_arr_.pop ();
425 /* cont */ '=' identifier_init {
428 Should find generic way of associating input with objects.
430 Input ip = THIS->pop_spot ();
432 if (! regular_identifier_b ($1))
434 ip.warning (_ ("Identifier should have alphabetic characters only"));
437 THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4);
440 TODO: devise standard for protection in parser.
442 The parser stack lives on the C-stack, which means that
443 all objects can be unprotected as soon as they're here.
453 $$ = $1->self_scm ();
454 scm_gc_unprotect_object ($$);
457 $$ = $1->self_scm ();
458 scm_gc_unprotect_object ($$);
460 | translator_spec_block {
464 $$ = $1->self_scm ();
465 scm_gc_unprotect_object ($$);
468 $$ = $1->self_scm ();
469 scm_gc_unprotect_object ($$);
471 | explicit_duration {
474 | number_expression {
485 translator_spec_block:
486 TRANSLATOR '{' translator_spec_body '}'
492 translator_spec_body:
493 TRANSLATOR_IDENTIFIER {
494 $$ = unsmob_translator_def ($1)->clone_scm ();
495 unsmob_translator_def ($$)-> set_spot (THIS->here_input ());
498 $$ = Translator_def::make_scm ();
499 Translator_def*td = unsmob_translator_def ($$);
500 td->translator_group_type_ = $2;
501 td->set_spot (THIS->here_input ());
503 | translator_spec_body STRING '=' embedded_scm {
504 unsmob_translator_def ($$)->add_property_assign ($2, $4);
506 | translator_spec_body STRING OVERRIDE embedded_scm '=' embedded_scm {
507 unsmob_translator_def ($$)
508 ->add_push_property (scm_string_to_symbol ($2), $4, $6);
510 | translator_spec_body STRING REVERT embedded_scm {
511 unsmob_translator_def ($$)->add_pop_property (
512 scm_string_to_symbol ($2), $4);
514 | translator_spec_body NAME STRING {
515 unsmob_translator_def ($$)->type_name_ = $3;
517 | translator_spec_body CONSISTS STRING {
518 unsmob_translator_def ($$)->add_element ($3);
520 | translator_spec_body ALIAS STRING {
521 Translator_def*td = unsmob_translator_def ($$);
522 td->type_aliases_ = gh_cons ($3, td->type_aliases_);
524 | translator_spec_body ELEMENTDESCRIPTIONS embedded_scm {
525 for (SCM p = $3; gh_pair_p (p); p = gh_cdr (p))
526 unsmob_translator_def ($$)
527 ->add_property_assign (scm_symbol_to_string (gh_caar (p)), gh_cdar (p));
530 | translator_spec_body CONSISTSEND STRING {
531 unsmob_translator_def ($$)->add_last_element ( $3);
533 | translator_spec_body ACCEPTS STRING {
534 unsmob_translator_def ($$)->set_acceptor ($3,true);
536 | translator_spec_body DENIES STRING {
537 unsmob_translator_def ($$)->set_acceptor ($3,false);
539 | translator_spec_body REMOVE STRING {
540 unsmob_translator_def ($$)->remove_element ($3);
551 /*cont*/ '{' score_body '}' {
554 if (!$$->def_p_arr_.size ())
556 Music_output_def *id =
557 unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
558 $$->add_output (id ? id->clone () : new Paper_def );
567 $$->set_spot (THIS->here_input ());
568 SCM m = $1->self_scm ();
569 scm_gc_unprotect_object (m);
573 $$ = new Score (*unsmob_score ($1));
574 $$->set_spot (THIS->here_input ());
576 | score_body lilypond_header {
577 scm_gc_unprotect_object ($2->self_scm ());
580 | score_body output_def {
593 music_output_def_body '}' {
595 THIS-> lexer_p_-> scope_l_arr_.pop ();
599 music_output_def_body:
601 Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultmidi"));
606 p = dynamic_cast<Midi_def*> (id->clone ());
611 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
614 Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
617 p = dynamic_cast<Paper_def*> (id->clone ());
620 THIS-> lexer_p_-> scope_l_arr_.push (p->scope_p_);
623 | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
624 Music_output_def *p = unsmob_music_output_def ($3);
626 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
629 | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
630 Music_output_def *p = unsmob_music_output_def ($3);
633 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
636 | music_output_def_body assignment {
639 | music_output_def_body translator_spec_block {
640 $$->assign_translator ($2);
642 | music_output_def_body STYLESHEET embedded_scm {
643 dynamic_cast<Paper_def*> ($$)-> style_sheet_ = $3;
645 | music_output_def_body tempo_request {
647 junk this ? there already is tempo stuff in
650 int m = gh_scm2int ( $2->get_mus_property ("metronome-count"));
651 Duration *d = unsmob_duration ($2->get_mus_property ("duration"));
652 dynamic_cast<Midi_def*> ($$)->set_tempo (d->length_mom (), m);
654 | music_output_def_body error {
660 TEMPO steno_duration '=' bare_unsigned {
662 $$->set_mus_property ("duration", $2);
663 $$->set_mus_property ("metronome-count", gh_int2scm ( $4));
667 Music_list: /* empty */ {
668 $$ = gh_cons (SCM_EOL, SCM_EOL);
672 SCM c = gh_cons ($2->self_scm (), SCM_EOL);
673 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
674 if (gh_pair_p (gh_cdr (s)))
675 gh_set_cdr_x (gh_cdr (s), c); /* append */
677 gh_set_car_x (s, c); /* set first cons */
678 gh_set_cdr_x (s, c) ; /* remember last cell */
694 | ALTERNATIVE Music_sequence {
696 $2->set_spot (THIS->here_input ());
704 REPEAT string bare_unsigned Music Alternative_music
706 Music_sequence* alts = dynamic_cast <Music_sequence*> ($5);
707 if (alts && $3 < alts->length_i ())
708 $5->origin ()->warning (_ ("More alternatives than repeats. Junking excess alternatives."));
712 Repeated_music * r = new Repeated_music (SCM_EOL);
716 r-> set_mus_property ("body", beg->self_scm ());
717 scm_gc_unprotect_object (beg->self_scm ());
719 r->set_mus_property ("repeat-count", gh_int2scm (times >? 1));
723 alts->truncate (times);
724 r-> set_mus_property ("alternatives", alts->self_scm ());
725 scm_gc_unprotect_object (alts->self_scm ());
727 SCM func = scm_primitive_eval (ly_symbol2scm ("repeat-name-to-ctor"));
728 SCM result = gh_call1 (func, $2);
730 set_music_properties (r, result);
732 r->set_spot (*$4->origin ());
737 Music_sequence: '{' Music_list '}' {
738 $$ = new Music_sequence (SCM_EOL);
739 $$->set_mus_property ("elements", gh_car ($2));
744 SEQUENTIAL '{' Music_list '}' {
745 $$ = new Sequential_music (SCM_EOL);
746 $$->set_mus_property ("elements", gh_car ($3));
748 | '{' Music_list '}' {
749 $$ = new Sequential_music (SCM_EOL);
750 $$->set_mus_property ("elements", gh_car ($2));
755 SIMULTANEOUS '{' Music_list '}'{
756 $$ = new Simultaneous_music (SCM_EOL);
757 $$->set_mus_property ("elements", gh_car ($3));
760 | '<' Music_list '>' {
761 $$ = new Simultaneous_music (SCM_EOL);
762 $$->set_mus_property ("elements", gh_car ($2));
767 request_chord { $$ = $1; }
768 | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm {
770 if (!gh_symbol_p ($3))
772 THIS->parser_error (_ ("Second argument must be a symbol"));
774 /*hould check # args */
775 if (!gh_procedure_p (pred))
777 THIS->parser_error (_ ("First argument must be a procedure taking 1 argument"));
780 Music *m = new Music (SCM_EOL);
781 m->set_mus_property ("predicate", pred);
782 m->set_mus_property ("grob-property", $3);
783 m->set_mus_property ("grob-value", $5);
784 m->set_mus_property ("iterator-ctor",
785 Output_property_music_iterator::constructor_cxx_function);
790 $$ = unsmob_music ($1)->clone ();
798 CONTEXT STRING Music {
799 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
800 csm->set_mus_property ("element", $3->self_scm ());
801 scm_gc_unprotect_object ($3->self_scm ());
803 csm->set_mus_property ("context-type",$2);
804 csm->set_mus_property ("context-id", ly_str02scm (""));
808 | AUTOCHANGE STRING Music {
809 Music * chm = new Music_wrapper (SCM_EOL);
810 chm->set_mus_property ("element", $3->self_scm ());
811 chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_cxx_function);
813 scm_gc_unprotect_object ($3->self_scm ());
814 chm->set_mus_property ("what", $2);
817 chm->set_spot (*$3->origin ());
822 The other version is for easier debugging of
823 Sequential_music_iterator in combination with grace notes.
826 SCM start = THIS->lexer_p_->lookup_identifier ("startGraceMusic");
827 SCM stop = THIS->lexer_p_->lookup_identifier ("stopGraceMusic");
828 Music *startm = unsmob_music (start);
829 Music *stopm = unsmob_music (stop);
833 stopm = stopm->clone ();
834 ms = gh_cons (stopm->self_scm (), ms);
835 scm_gc_unprotect_object (stopm->self_scm ());
837 ms = gh_cons ($2->self_scm (), ms);
838 scm_gc_unprotect_object ($2->self_scm());
840 startm = startm->clone ();
841 ms = gh_cons (startm->self_scm () , ms);
842 scm_gc_unprotect_object (startm->self_scm ());
845 Music* seq = new Sequential_music (SCM_EOL);
846 seq->set_mus_property ("elements", ms);
848 $$ = new Grace_music (SCM_EOL);
849 $$->set_mus_property ("element", seq->self_scm ());
850 scm_gc_unprotect_object (seq->self_scm ());
852 $$ = new Grace_music (SCM_EOL);
853 $$->set_mus_property ("element", $2->self_scm ());
854 scm_gc_unprotect_object ($2->self_scm ());
859 | CONTEXT string '=' string Music {
860 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
861 csm->set_mus_property ("element", $5->self_scm ());
862 scm_gc_unprotect_object ($5->self_scm ());
864 csm->set_mus_property ("context-type", $2);
865 csm->set_mus_property ("context-id", $4);
876 int n = gh_scm2int (gh_car ($3)); int d = gh_scm2int (gh_cdr ($3));
878 $$ = new Time_scaled_music (SCM_EOL);
879 $$->set_spot (THIS->pop_spot ());
882 $$->set_mus_property ("element", mp->self_scm ());
883 scm_gc_unprotect_object (mp->self_scm ());
884 $$->set_mus_property ("numerator", gh_int2scm (n));
885 $$->set_mus_property ("denominator", gh_int2scm (d));
886 $$->compress (Moment (Rational (n,d)));
889 | Repeated_music { $$ = $1; }
890 | Simultaneous_music { $$ = $1; }
891 | Sequential_music { $$ = $1; }
892 | TRANSPOSE pitch Music {
893 $$ = new Transposed_music (SCM_EOL);
895 Pitch pit = *unsmob_pitch ($2);
898 $$->set_mus_property ("element", p->self_scm ());
899 scm_gc_unprotect_object (p->self_scm ());
901 | TRANSPOSE steno_tonic_pitch Music {
902 $$ = new Transposed_music (SCM_EOL);
904 Pitch pit = *unsmob_pitch ($2);
907 $$->set_mus_property ("element", p->self_scm ());
908 scm_gc_unprotect_object (p->self_scm ());
911 | APPLY embedded_scm Music {
912 SCM ret = gh_call1 ($2, $3->self_scm ());
913 Music *m = unsmob_music (ret);
915 THIS->parser_error ("\\apply must return a Music");
916 m = new Music (SCM_EOL);
921 { THIS->lexer_p_->push_note_state (); }
924 THIS->lexer_p_->pop_state ();
927 { THIS->lexer_p_->push_figuredbass_state (); }
930 Music * chm = new Untransposable_music () ;
931 chm->set_mus_property ("element", $3->self_scm ());
934 THIS->lexer_p_->pop_state ();
937 { THIS->lexer_p_->push_chord_state (); }
940 Music * chm = new Un_relativable_music ;
941 chm->set_mus_property ("element", $3->self_scm ());
944 THIS->lexer_p_->pop_state ();
947 { THIS->lexer_p_->push_lyric_state (); }
951 THIS->lexer_p_->pop_state ();
953 | relative_music { $$ = $1; }
954 | re_rhythmed_music { $$ = $1; }
955 | part_combined_music { $$ = $1; }
959 RELATIVE absolute_pitch Music {
961 Pitch pit = *unsmob_pitch ($2);
962 $$ = new Relative_octave_music (SCM_EOL);
964 $$->set_mus_property ("element", p->self_scm ());
965 scm_gc_unprotect_object (p->self_scm ());
967 $$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ());
973 ADDLYRICS Music Music {
974 Lyric_combine_music * l = new Lyric_combine_music (SCM_EOL);
975 l->set_mus_property ("music", $2->self_scm ());
976 l->set_mus_property ("lyrics", $3->self_scm ());
977 scm_gc_unprotect_object ($3->self_scm ());
978 scm_gc_unprotect_object ($2->self_scm ());
984 PARTCOMBINE STRING Music Music {
985 Part_combine_music * p = new Part_combine_music (SCM_EOL);
987 p->set_mus_property ("what", $2);
988 p->set_mus_property ("one", $3->self_scm ());
989 p->set_mus_property ("two", $4->self_scm ());
991 scm_gc_unprotect_object ($3->self_scm ());
992 scm_gc_unprotect_object ($4->self_scm ());
1000 TRANSLATOR STRING '=' STRING {
1001 Music * t = new Music (SCM_EOL);
1002 t->set_mus_property ("iterator-ctor",
1003 Change_iterator::constructor_cxx_function);
1004 t-> set_mus_property ("change-to-type", $2);
1005 t-> set_mus_property ("change-to-id", $4);
1008 $$->set_spot (THIS->here_input ());
1013 PROPERTY STRING '.' STRING '=' scalar {
1015 Music *t = set_property_music (scm_string_to_symbol ($4), $6);
1016 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1018 csm->set_mus_property ("element", t->self_scm ());
1019 scm_gc_unprotect_object (t->self_scm ());
1022 $$->set_spot (THIS->here_input ());
1024 csm-> set_mus_property ("context-type", $2);
1026 | PROPERTY STRING '.' STRING UNSET {
1027 Music *t = new Music (SCM_EOL);
1029 t->set_mus_property ("iterator-ctor",
1030 Property_unset_iterator::constructor_cxx_function);
1031 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1033 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1034 csm->set_mus_property ("element", t->self_scm ());
1035 scm_gc_unprotect_object (t->self_scm ());
1038 $$->set_spot (THIS->here_input ());
1040 csm-> set_mus_property ("context-type", $2);
1042 | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm {
1043 Music *t = new Music (SCM_EOL);
1044 t->set_mus_property ("iterator-ctor",
1045 Push_property_iterator::constructor_cxx_function);
1046 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1047 t->set_mus_property ("pop-first", SCM_BOOL_T);
1048 t->set_mus_property ("grob-property", $6);
1049 t->set_mus_property ("grob-value", $8);
1050 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1051 csm->set_mus_property ("element", t->self_scm ());
1052 scm_gc_unprotect_object (t->self_scm ());
1054 $$->set_spot (THIS->here_input ());
1056 csm-> set_mus_property ("context-type", $2);
1058 | PROPERTY STRING '.' STRING OVERRIDE embedded_scm '=' embedded_scm {
1059 Music *t = new Music (SCM_EOL);
1060 t->set_mus_property ("iterator-ctor",
1061 Push_property_iterator::constructor_cxx_function);
1062 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1063 t->set_mus_property ("grob-property", $6);
1064 t->set_mus_property ("grob-value", $8);
1065 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1066 csm->set_mus_property ("element", t->self_scm ());
1067 scm_gc_unprotect_object (t->self_scm ());
1070 $$->set_spot (THIS->here_input ());
1072 csm-> set_mus_property ("context-type", $2);
1074 | PROPERTY STRING '.' STRING REVERT embedded_scm {
1075 Music *t = new Music (SCM_EOL);
1076 t->set_mus_property ("iterator-ctor",
1077 Pop_property_iterator::constructor_cxx_function);
1078 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1079 t->set_mus_property ("grob-property", $6);
1081 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1082 csm->set_mus_property ("element", t->self_scm ());
1083 scm_gc_unprotect_object (t->self_scm ());
1086 $$->set_spot (THIS->here_input ());
1088 csm-> set_mus_property ("context-type", $2);
1094 | bare_int { $$ = gh_int2scm ($1); }
1095 | embedded_scm { $$ = $1; }
1102 } /*cont */ simple_element post_requests {
1103 Music_sequence *l = dynamic_cast<Music_sequence*> ($3);
1105 for (int i=0; i < $1->size (); i++)
1106 l->append_music ($1->elem (i));
1107 for (int i=0; i < $4->size (); i++)
1108 l->append_music ($4->elem (i));
1111 programming_error ("Need Sequence to add music to");
1119 $$ = new Request_chord (SCM_EOL);
1120 $$->set_mus_property ("elements", gh_cons ($1->self_scm (), SCM_EOL));
1121 $$-> set_spot (THIS->here_input ());
1122 $1-> set_spot (THIS->here_input ());
1125 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1127 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1128 csm->set_mus_property ("element", t->self_scm ());
1129 scm_gc_unprotect_object (t->self_scm ());
1132 $$->set_spot (THIS->here_input ());
1134 csm->set_mus_property ("context-type", ly_str02scm ("Score"));
1136 | PARTIAL duration_length {
1137 Moment m = - unsmob_duration ($2)->length_mom ();
1138 Music * p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1140 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1141 sp->set_mus_property ("element", p->self_scm ());
1142 scm_gc_unprotect_object (p->self_scm ());
1145 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1148 SCM func = scm_primitive_eval (ly_symbol2scm ("clef-name-to-properties"));
1149 SCM result = gh_call1 (func, $2);
1152 for (SCM s = result ; gh_pair_p (s); s = gh_cdr (s)) {
1153 Music * p = new Music (SCM_EOL);
1154 set_music_properties (p, gh_car (s));
1155 l = gh_cons (p->self_scm (), l);
1156 scm_gc_unprotect_object (p->self_scm ());
1158 Sequential_music * seq = new Sequential_music (SCM_EOL);
1159 seq->set_mus_property ("elements", l);
1161 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1162 sp->set_mus_property ("element", seq->self_scm ());
1163 scm_gc_unprotect_object (seq->self_scm ());
1166 sp-> set_mus_property ("context-type", ly_str02scm ("Staff"));
1169 Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2);
1171 int l = gh_scm2int (gh_car ($2));
1172 int o = gh_scm2int (gh_cdr ($2));
1174 Moment one_beat = Moment (1)/Moment (o);
1175 Moment len = Moment (l) * one_beat;
1178 Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ());
1179 Music *p3 = set_property_music (ly_symbol2scm ("beatLength"), one_beat.smobbed_copy ());
1181 SCM list = gh_list (p1->self_scm (), p2->self_scm (), p3->self_scm(), SCM_UNDEFINED);
1182 Sequential_music *seq = new Sequential_music (SCM_EOL);
1183 seq->set_mus_property ("elements", list);
1186 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1187 sp->set_mus_property ("element", seq->self_scm ());
1191 scm_gc_unprotect_object (p3->self_scm ());
1192 scm_gc_unprotect_object (p2->self_scm ());
1193 scm_gc_unprotect_object (p1->self_scm ());
1194 scm_gc_unprotect_object (seq->self_scm ());
1199 TODO: should make alias TimingContext for Score
1202 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1207 shorthand_command_req { $$ = $1; }
1208 | verbose_command_req { $$ = $1; }
1211 shorthand_command_req:
1219 $$ = new Barcheck_req;
1225 Span_req*b= new Span_req;
1226 b->set_span_dir (START);
1227 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1231 Span_req*b= new Span_req;
1232 b->set_span_dir ( STOP);
1233 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1237 $$ = new Breathing_sign_req;
1240 $$ = new Porrectus_req;
1245 verbose_command_req:
1246 COMMANDSPANREQUEST bare_int STRING { /*TODO: junkme */
1247 Span_req * sp_p = new Span_req;
1248 sp_p-> set_span_dir ( Direction ($2));
1249 sp_p->set_mus_property ("span-type",$3);
1250 sp_p->set_spot (THIS->here_input ());
1254 Mark_req * m = new Mark_req;
1258 Mark_req *m = new Mark_req;
1259 m->set_mus_property ("label", $2);
1266 Break_req * b = new Break_req;
1268 if (!gh_number_p (s))
1271 b->set_mus_property ("penalty", s);
1272 b->set_spot (THIS->here_input ());
1275 | SKIP duration_length {
1276 Skip_req * skip_p = new Skip_req;
1277 skip_p->set_mus_property ("duration", $2);
1285 Key_change_req *key_p= new Key_change_req;
1288 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1289 Key_change_req *key_p= new Key_change_req;
1291 key_p->set_mus_property ("pitch-alist", $3);
1292 ((Music* )key_p)->transpose (* unsmob_pitch ($2));
1299 $$ = new Link_array<Request>;
1301 | post_requests post_request {
1302 $2->set_spot (THIS->here_input ());
1314 request_that_take_dir:
1317 | script_abbreviation {
1318 SCM s = THIS->lexer_p_->lookup_identifier ("dash" + ly_scm2string ($1));
1319 Articulation_req *a = new Articulation_req;
1320 if (gh_string_p (s))
1321 a->set_mus_property ("articulation-type", s);
1322 else THIS->parser_error (_ ("Expecting string as script definition"));
1328 script_dir request_that_take_dir {
1329 if (Script_req * gs = dynamic_cast<Script_req*> ($2))
1330 gs->set_direction (Direction ($1));
1332 $2->origin ()->warning (_ ("Can't specify direction for this request"));
1338 REQUEST_IDENTIFIER {
1339 $$ = dynamic_cast<Request*> (unsmob_music ($1)->clone ());
1340 $$->set_spot (THIS->here_input ());
1342 | DYNAMICSCRIPT embedded_scm {
1344 TODO: junkme, use text-type == dynamic
1346 Text_script_req *d = new Text_script_req;
1347 d->set_mus_property ("text-type" , ly_symbol2scm ("dynamic"));
1348 d->set_mus_property ("text", $2);
1349 d->set_spot (THIS->here_input ());
1352 | SPANREQUEST bare_int STRING {
1353 Span_req * sp_p = new Span_req;
1354 sp_p->set_span_dir ( Direction ($2));
1355 sp_p->set_mus_property ("span-type", $3);
1356 sp_p->set_spot (THIS->here_input ());
1360 Tremolo_req* a = new Tremolo_req;
1361 a->set_spot (THIS->here_input ());
1362 a->set_mus_property ("tremolo-type", gh_int2scm ($1));
1366 Articulation_req * a = new Articulation_req;
1367 a->set_mus_property ("articulation-type", $2);
1368 a->set_spot (THIS->here_input ());
1372 duh, junk this syntax from the parser, if possible.
1375 Arpeggio_req *a = new Arpeggio_req;
1376 a->set_spot (THIS->here_input ());
1380 Glissando_req *g = new Glissando_req;
1381 g->set_spot /* No pun intended */ (THIS->here_input ());
1408 | NOTENAME_PITCH sup_quotes {
1409 Pitch p = *unsmob_pitch ($1);
1411 $$ = p.smobbed_copy ();
1413 | NOTENAME_PITCH sub_quotes {
1414 Pitch p =* unsmob_pitch ($1);
1417 $$ = p.smobbed_copy ();
1430 | TONICNAME_PITCH sup_quotes {
1431 Pitch p = *unsmob_pitch ($1);
1433 $$ = p.smobbed_copy ();
1435 | TONICNAME_PITCH sub_quotes {
1436 Pitch p =* unsmob_pitch ($1);
1439 $$ = p.smobbed_copy ();
1454 PITCH embedded_scm {
1456 if (!unsmob_pitch ($2)) {
1457 THIS->parser_error (_f ("Expecting musical-pitch value", 3));
1458 $$ = Pitch ().smobbed_copy ();
1464 DURATION embedded_scm {
1466 if (!unsmob_duration ($2))
1468 THIS->parser_error (_ ("Must have duration object"));
1469 $$ = Duration ().smobbed_copy ();
1476 if (!THIS->lexer_p_->lyric_state_b ())
1477 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1478 $$ = new Extender_req;
1484 if (!THIS->lexer_p_->lyric_state_b ())
1485 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1486 $$ = new Hyphen_req;
1491 close_request_parens {
1493 dynamic_cast<Span_req*> ($$)->set_span_dir ( START);
1496 close_request_parens:
1498 Span_req* s= new Span_req;
1500 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1503 Span_req* s= new Span_req;
1505 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1508 Span_req*s =new Span_req;
1510 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1513 Span_req*s =new Span_req;
1515 s->set_mus_property ("span-type", ly_str02scm ("decrescendo"));
1521 open_request_parens {
1523 dynamic_cast<Span_req*> ($$)->set_span_dir (STOP);
1527 open_request_parens:
1529 Span_req *s = new Span_req;
1530 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1535 Span_req* s= new Span_req;
1537 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1540 Span_req* s= new Span_req;
1542 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1548 Text_script_req *t = new Text_script_req;
1549 t->set_mus_property ("text", $1);
1550 t->set_spot (THIS->here_input ());
1554 Text_script_req *t = new Text_script_req;
1555 t->set_mus_property ("text", $1);
1556 t->set_spot (THIS->here_input ());
1560 String ds = to_str ($1);
1561 Text_script_req* t = new Text_script_req;
1563 t->set_mus_property ("text", ly_str02scm (ds.ch_C ()));
1564 t->set_mus_property ("text-type" , ly_symbol2scm ("finger"));
1565 t->set_spot (THIS->here_input ());
1570 script_abbreviation:
1572 $$ = gh_str02scm ("Hat");
1575 $$ = gh_str02scm ("Plus");
1578 $$ = gh_str02scm ("Dash");
1581 $$ = gh_str02scm ("Bar");
1584 $$ = gh_str02scm ("Larger");
1587 $$ = gh_str02scm ("Dot");
1595 | '-' { $$ = CENTER; }
1600 $$ = new Link_array<Request>;
1602 | pre_requests open_request {
1614 multiplied_duration {
1617 | explicit_duration {
1622 optional_notemode_duration:
1624 $$ = THIS->default_duration_.smobbed_copy ();
1626 | multiplied_duration {
1629 | explicit_duration {
1635 bare_unsigned dots {
1637 if (!is_duration_b ($1))
1638 THIS->parser_error (_f ("not a duration: %d", $1));
1642 $$ = Duration (l, $2).smobbed_copy ();
1644 THIS->set_last_duration (unsmob_duration ($$));
1646 | DURATION_IDENTIFIER dots {
1647 Duration *d =unsmob_duration ($1);
1648 Duration k (d->duration_log (),d->dot_count () + $2);
1649 $$ = k.smobbed_copy ();
1651 THIS->set_last_duration (unsmob_duration ($$));
1658 multiplied_duration:
1662 | multiplied_duration '*' bare_unsigned {
1663 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1665 | multiplied_duration '*' FRACTION {
1666 Rational m (gh_scm2int (gh_car ($3)), gh_scm2int (gh_cdr ($3)));
1668 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
1673 FRACTION { $$ = $1; }
1674 | UNSIGNED '/' UNSIGNED {
1675 $$ = gh_cons (gh_int2scm ($1), gh_int2scm ($3));
1693 | ':' bare_unsigned {
1694 if (!is_duration_b ($2))
1695 THIS->parser_error (_f ("not a duration: %d", $2));
1715 p .notename_i_ = $1 - 1;
1718 Note_req * nr = new Note_req;
1719 $$ = nr->self_scm ();
1720 nr->set_mus_property ("pitch", p.smobbed_copy ());
1721 scm_unprotect_object ($$);
1723 | bass_figure bass_mod {
1725 SCM sp = unsmob_music ($1)->get_mus_property ("pitch");
1726 unsmob_pitch (sp)->alteration_i_ += $2;
1728 unsmob_music ($1)->set_mus_property ("force-accidental", SCM_BOOL_T);
1737 | figure_list bass_figure {
1738 $$ = gh_cons ($2, $1);
1743 FIGURE_OPEN figure_list FIGURE_CLOSE {
1744 Music * m = new Request_chord (SCM_EOL);
1745 $2 = scm_reverse_x ($2, SCM_EOL);
1746 m->set_mus_property ("elements", $2);
1747 $$ = m->self_scm ();
1752 pitch exclamations questions optional_notemode_duration {
1754 Input i = THIS->pop_spot ();
1755 if (!THIS->lexer_p_->note_state_b ())
1756 THIS->parser_error (_ ("Have to be in Note mode for notes"));
1758 Note_req *n = new Note_req;
1760 n->set_mus_property ("pitch", $1);
1761 n->set_mus_property ("duration", $4);
1764 n->set_mus_property ("cautionary", SCM_BOOL_T);
1765 if ($2 % 2 || $3 % 2)
1766 n->set_mus_property ("force-accidental", SCM_BOOL_T);
1768 Simultaneous_music*v = new Request_chord (SCM_EOL);
1769 v->set_mus_property ("elements", gh_list (n->self_scm (), SCM_UNDEFINED));
1775 | figure_spec optional_notemode_duration {
1776 Music * m = unsmob_music ($1);
1777 Input i = THIS->pop_spot ();
1779 for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = gh_cdr (s))
1781 unsmob_music (gh_car (s))->set_mus_property ("duration", $2);
1785 | RESTNAME optional_notemode_duration {
1787 Input i = THIS->pop_spot ();
1788 SCM e = SCM_UNDEFINED;
1789 if (ly_scm2string ($1) =="s") {
1791 Skip_req * skip_p = new Skip_req;
1792 skip_p->set_mus_property ("duration" ,$2);
1793 skip_p->set_spot (i);
1794 e = skip_p->self_scm ();
1797 Rest_req * rest_req_p = new Rest_req;
1798 rest_req_p->set_mus_property ("duration", $2);
1799 rest_req_p->set_spot (i);
1800 e = rest_req_p->self_scm ();
1802 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1803 velt_p-> set_mus_property ("elements", gh_list (e,SCM_UNDEFINED));
1804 velt_p->set_spot (i);
1808 | MULTI_MEASURE_REST optional_notemode_duration {
1809 Input i = THIS->pop_spot ();
1811 Skip_req * sk = new Skip_req;
1812 sk->set_mus_property ("duration", $2);
1813 Span_req *sp1 = new Span_req;
1814 Span_req *sp2 = new Span_req;
1815 sp1-> set_span_dir ( START);
1816 sp2-> set_span_dir ( STOP);
1817 SCM r = ly_str02scm ("rest");
1818 sp1->set_mus_property ("span-type", r);
1819 sp2->set_mus_property ("span-type", r);
1821 Request_chord * rqc1 = new Request_chord (SCM_EOL);
1822 rqc1->set_mus_property ("elements", gh_list (sp1->self_scm (), SCM_UNDEFINED));
1823 Request_chord * rqc2 = new Request_chord (SCM_EOL);
1824 rqc2->set_mus_property ("elements", gh_list (sk->self_scm (), SCM_UNDEFINED));;
1825 Request_chord * rqc3 = new Request_chord (SCM_EOL);
1826 rqc3->set_mus_property ("elements", gh_list (sp2->self_scm (), SCM_UNDEFINED));;
1828 SCM ms = gh_list (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED);
1830 $$ = new Sequential_music (SCM_EOL);
1831 $$->set_mus_property ("elements", ms);
1833 | STRING optional_notemode_duration {
1834 Input i = THIS->pop_spot ();
1836 Lyric_req* lreq_p = new Lyric_req;
1837 lreq_p->set_mus_property ("text", $1);
1838 lreq_p->set_mus_property ("duration",$2);
1839 lreq_p->set_spot (i);
1840 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1841 velt_p->set_mus_property ("elements", gh_list (lreq_p->self_scm (), SCM_UNDEFINED));
1846 Input i = THIS->pop_spot ();
1848 if (!THIS->lexer_p_->chord_state_b ())
1849 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
1856 steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
1857 $$ = Chord::get_chord ($1, $3, $4, $5, $6, $2);
1858 $$->set_spot (THIS->here_input ());
1865 | CHORD_COLON chord_notes {
1874 | chord_notes '.' chord_step {
1875 $$ = gh_append2 ($$, $3);
1883 | CHORD_CARET chord_notes {
1893 | '/' steno_tonic_pitch {
1902 | CHORD_BASS steno_tonic_pitch {
1909 $$ = gh_cons ($1, SCM_EOL);
1911 | CHORDMODIFIER_PITCH {
1912 $$ = gh_cons (unsmob_pitch ($1)->smobbed_copy (), SCM_EOL);
1914 | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
1915 $$ = gh_list (unsmob_pitch ($1)->smobbed_copy (),
1923 m.notename_i_ = ($1 - 1) % 7;
1924 m.octave_i_ = $1 > 7 ? 1 : 0;
1925 m.alteration_i_ = 0;
1927 $$ = m.smobbed_copy ();
1929 | bare_unsigned '+' {
1931 m.notename_i_ = ($1 - 1) % 7;
1932 m.octave_i_ = $1 > 7 ? 1 : 0;
1933 m.alteration_i_ = 1;
1936 $$ = m.smobbed_copy ();
1938 | bare_unsigned CHORD_MINUS {
1940 m.notename_i_ = ($1 - 1) % 7;
1941 m.octave_i_ = $1 > 7 ? 1 : 0;
1942 m.alteration_i_ = -1;
1944 $$ = m.smobbed_copy ();
1952 number_expression '+' number_term {
1953 $$ = scm_sum ($1, $3);
1955 | number_expression '-' number_term {
1956 $$ = scm_difference ($1, $3);
1965 | number_factor '*' number_factor {
1966 $$ = scm_product ($1, $3);
1968 | number_factor '/' number_factor {
1969 $$ = scm_divide ($1, $3);
1974 '(' number_expression ')' {
1977 | '-' number_factor { /* %prec UNARY_MINUS */
1978 $$ = scm_difference ($2, SCM_UNDEFINED);
1986 $$ = gh_int2scm ($1);
1991 | NUMBER_IDENTIFIER {
1995 $$ = gh_double2scm (gh_scm2double ($1) CM );
1998 $$ = gh_double2scm (gh_scm2double ($1) PT);
2001 $$ = gh_double2scm (gh_scm2double ($1) INCH);
2004 $$ = gh_double2scm (gh_scm2double ($1) MM);
2007 $$ = gh_double2scm (gh_scm2double ($1) CHAR);
2023 if (scm_integer_p ($1) == SCM_BOOL_T)
2025 int k = gh_scm2int ($1);
2029 THIS->parser_error (_ ("need integer number arg"));
2043 | STRING_IDENTIFIER {
2046 | string '+' string {
2047 $$ = scm_string_append (scm_list_n ($1, $3, SCM_UNDEFINED));
2054 | exclamations '!' { $$ ++; }
2059 | questions '?' { $$ ++; }
2066 My_lily_parser::set_yydebug (bool b)
2073 extern My_lily_parser * current_parser;
2076 My_lily_parser::do_yyparse ()
2079 current_parser = this;;
2080 yyparse ((void*)this);