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 = ly_cdr (k))
104 p->set_mus_property (ly_caar (k), ly_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 GROBDESCRIPTIONS
197 %token FIGURES FIGURE_OPEN FIGURE_CLOSE
207 %token MULTI_MEASURE_REST
219 %token OVERRIDE SET REVERT
232 %token COMMANDSPANREQUEST
234 %token OUTPUTPROPERTY
244 %token E_CHAR E_EXCLAMATION E_SMALLER E_BIGGER E_OPEN E_CLOSE E_TILDE
245 %token CHORD_BASS CHORD_COLON CHORD_MINUS CHORD_CARET
247 %type <i> exclamations questions dots
248 %type <i> bass_number bass_mod
249 %type <scm> bass_figure figure_list figure_spec
251 %token <scm> NOTENAME_PITCH
252 %token <scm> TONICNAME_PITCH
253 %token <scm> CHORDMODIFIER_PITCH
254 %token <scm> DURATION_IDENTIFIER
255 %token <scm> FRACTION
256 %token <id> IDENTIFIER
259 %token <scm> SCORE_IDENTIFIER
260 %token <scm> MUSIC_OUTPUT_DEF_IDENTIFIER
262 %token <scm> NUMBER_IDENTIFIER
263 %token <scm> REQUEST_IDENTIFIER
264 %token <scm> MUSIC_IDENTIFIER TRANSLATOR_IDENTIFIER
265 %token <scm> STRING_IDENTIFIER SCM_IDENTIFIER
266 %token <scm> RESTNAME
272 %type <outputdef> output_def
273 %type <scmhash> lilypond_header lilypond_header_body
274 %type <request> open_request_parens close_request_parens open_request close_request
275 %type <request> request_with_dir request_that_take_dir verbose_request
276 %type <i> sub_quotes sup_quotes
277 %type <music> simple_element request_chord command_element Simple_music Composite_music
278 %type <music> Repeated_music
279 %type <scm> Alternative_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
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 = ly_cdr (s)) {
387 SCM pt = ly_cdar (s);
388 if (!unsmob_pitch (pt))
389 THIS->parser_error ("Need pitch object.");
391 scm_hashq_set_x (tab, ly_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 GROBDESCRIPTIONS embedded_scm {
525 Translator_def*td = unsmob_translator_def($$);
526 // td->add_property_assign (ly_symbol2scm ("allGrobDescriptions"), $3);
527 for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p))
528 td->add_property_assign (scm_symbol_to_string (ly_caar (p)), ly_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));
668 The representation of a list is the
672 to have efficient append.
674 Music_list: /* empty */ {
675 $$ = gh_cons (SCM_EOL, SCM_EOL);
679 SCM c = gh_cons ($2->self_scm (), SCM_EOL);
680 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
681 if (gh_pair_p (ly_cdr (s)))
682 gh_set_cdr_x (ly_cdr (s), c); /* append */
684 gh_set_car_x (s, c); /* set first cons */
685 gh_set_cdr_x (s, c) ; /* remember last cell */
701 | ALTERNATIVE '{' Music_list '}' {
707 REPEAT string bare_unsigned Music Alternative_music
711 SCM alts = gh_pair_p ($5) ? gh_car ($5) : SCM_EOL;
712 if (times < scm_ilength (alts)) {
713 unsmob_music (gh_car (alts))
714 ->origin ()->warning (
715 _("More alternatives than repeats. Junking excess alternatives."));
716 alts = ly_truncate_list (times, alts);
719 Repeated_music * r = new Repeated_music (SCM_EOL);
722 r-> set_mus_property ("element", beg->self_scm ());
723 scm_gc_unprotect_object (beg->self_scm ());
725 r->set_mus_property ("repeat-count", gh_int2scm (times >? 1));
727 r-> set_mus_property ("elements",alts);
728 SCM func = scm_primitive_eval (ly_symbol2scm ("repeat-name-to-ctor"));
729 SCM result = gh_call1 (func, $2);
731 set_music_properties (r, result);
733 r->set_spot (*$4->origin ());
739 SEQUENTIAL '{' Music_list '}' {
740 $$ = new Sequential_music (SCM_EOL);
741 $$->set_mus_property ("elements", ly_car ($3));
743 | '{' Music_list '}' {
744 $$ = new Sequential_music (SCM_EOL);
745 $$->set_mus_property ("elements", ly_car ($2));
750 SIMULTANEOUS '{' Music_list '}'{
751 $$ = new Simultaneous_music (SCM_EOL);
752 $$->set_mus_property ("elements", ly_car ($3));
755 | '<' Music_list '>' {
756 $$ = new Simultaneous_music (SCM_EOL);
757 $$->set_mus_property ("elements", ly_car ($2));
762 request_chord { $$ = $1; }
763 | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm {
765 if (!gh_symbol_p ($3))
767 THIS->parser_error (_ ("Second argument must be a symbol"));
769 /*hould check # args */
770 if (!gh_procedure_p (pred))
772 THIS->parser_error (_ ("First argument must be a procedure taking 1 argument"));
775 Music *m = new Music (SCM_EOL);
776 m->set_mus_property ("predicate", pred);
777 m->set_mus_property ("grob-property", $3);
778 m->set_mus_property ("grob-value", $5);
779 m->set_mus_property ("iterator-ctor",
780 Output_property_music_iterator::constructor_cxx_function);
785 $$ = unsmob_music ($1)->clone ();
793 CONTEXT STRING Music {
794 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
795 csm->set_mus_property ("element", $3->self_scm ());
796 scm_gc_unprotect_object ($3->self_scm ());
798 csm->set_mus_property ("context-type",$2);
799 csm->set_mus_property ("context-id", ly_str02scm (""));
803 | AUTOCHANGE STRING Music {
804 Music * chm = new Music_wrapper (SCM_EOL);
805 chm->set_mus_property ("element", $3->self_scm ());
806 chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_cxx_function);
808 scm_gc_unprotect_object ($3->self_scm ());
809 chm->set_mus_property ("what", $2);
812 chm->set_spot (*$3->origin ());
817 The other version is for easier debugging of
818 Sequential_music_iterator in combination with grace notes.
821 SCM start = THIS->lexer_p_->lookup_identifier ("startGraceMusic");
822 SCM stop = THIS->lexer_p_->lookup_identifier ("stopGraceMusic");
823 Music *startm = unsmob_music (start);
824 Music *stopm = unsmob_music (stop);
828 stopm = stopm->clone ();
829 ms = gh_cons (stopm->self_scm (), ms);
830 scm_gc_unprotect_object (stopm->self_scm ());
832 ms = gh_cons ($2->self_scm (), ms);
833 scm_gc_unprotect_object ($2->self_scm());
835 startm = startm->clone ();
836 ms = gh_cons (startm->self_scm () , ms);
837 scm_gc_unprotect_object (startm->self_scm ());
840 Music* seq = new Sequential_music (SCM_EOL);
841 seq->set_mus_property ("elements", ms);
843 $$ = new Grace_music (SCM_EOL);
844 $$->set_mus_property ("element", seq->self_scm ());
845 scm_gc_unprotect_object (seq->self_scm ());
847 $$ = new Grace_music (SCM_EOL);
848 $$->set_mus_property ("element", $2->self_scm ());
849 scm_gc_unprotect_object ($2->self_scm ());
852 | CONTEXT string '=' string Music {
853 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
854 csm->set_mus_property ("element", $5->self_scm ());
855 scm_gc_unprotect_object ($5->self_scm ());
857 csm->set_mus_property ("context-type", $2);
858 csm->set_mus_property ("context-id", $4);
869 int n = gh_scm2int (ly_car ($3)); int d = gh_scm2int (ly_cdr ($3));
871 $$ = new Time_scaled_music (SCM_EOL);
872 $$->set_spot (THIS->pop_spot ());
875 $$->set_mus_property ("element", mp->self_scm ());
876 scm_gc_unprotect_object (mp->self_scm ());
877 $$->set_mus_property ("numerator", gh_int2scm (n));
878 $$->set_mus_property ("denominator", gh_int2scm (d));
879 $$->compress (Moment (Rational (n,d)));
882 | Repeated_music { $$ = $1; }
883 | Simultaneous_music { $$ = $1; }
884 | Sequential_music { $$ = $1; }
885 | TRANSPOSE pitch Music {
886 $$ = new Transposed_music (SCM_EOL);
888 Pitch pit = *unsmob_pitch ($2);
891 $$->set_mus_property ("element", p->self_scm ());
892 scm_gc_unprotect_object (p->self_scm ());
894 | TRANSPOSE steno_tonic_pitch Music {
895 $$ = new Transposed_music (SCM_EOL);
897 Pitch pit = *unsmob_pitch ($2);
900 $$->set_mus_property ("element", p->self_scm ());
901 scm_gc_unprotect_object (p->self_scm ());
904 | APPLY embedded_scm Music {
905 SCM ret = gh_call1 ($2, $3->self_scm ());
906 Music *m = unsmob_music (ret);
908 THIS->parser_error ("\\apply must return a Music");
909 m = new Music (SCM_EOL);
914 { THIS->lexer_p_->push_note_state (); }
917 THIS->lexer_p_->pop_state ();
920 { THIS->lexer_p_->push_figuredbass_state (); }
923 Music * chm = new Untransposable_music () ;
924 chm->set_mus_property ("element", $3->self_scm ());
927 THIS->lexer_p_->pop_state ();
930 { THIS->lexer_p_->push_chord_state (); }
933 Music * chm = new Un_relativable_music ;
934 chm->set_mus_property ("element", $3->self_scm ());
937 THIS->lexer_p_->pop_state ();
940 { THIS->lexer_p_->push_lyric_state (); }
944 THIS->lexer_p_->pop_state ();
946 | relative_music { $$ = $1; }
947 | re_rhythmed_music { $$ = $1; }
948 | part_combined_music { $$ = $1; }
952 RELATIVE absolute_pitch Music {
954 Pitch pit = *unsmob_pitch ($2);
955 $$ = new Relative_octave_music (SCM_EOL);
957 $$->set_mus_property ("element", p->self_scm ());
958 scm_gc_unprotect_object (p->self_scm ());
960 $$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ());
966 ADDLYRICS Music Music {
967 Lyric_combine_music * l = new Lyric_combine_music (SCM_EOL);
968 l->set_mus_property ("elements", gh_list ($2->self_scm (), $3->self_scm (), SCM_UNDEFINED));
969 scm_gc_unprotect_object ($3->self_scm ());
970 scm_gc_unprotect_object ($2->self_scm ());
976 PARTCOMBINE STRING Music Music {
977 Part_combine_music * p = new Part_combine_music (SCM_EOL);
979 p->set_mus_property ("what", $2);
980 p->set_mus_property ("elements", gh_list ($3->self_scm (),$4->self_scm (), SCM_UNDEFINED));
982 scm_gc_unprotect_object ($3->self_scm ());
983 scm_gc_unprotect_object ($4->self_scm ());
990 TRANSLATOR STRING '=' STRING {
991 Music * t = new Music (SCM_EOL);
992 t->set_mus_property ("iterator-ctor",
993 Change_iterator::constructor_cxx_function);
994 t-> set_mus_property ("change-to-type", $2);
995 t-> set_mus_property ("change-to-id", $4);
998 $$->set_spot (THIS->here_input ());
1003 PROPERTY STRING '.' STRING '=' scalar {
1005 Music *t = set_property_music (scm_string_to_symbol ($4), $6);
1006 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1008 csm->set_mus_property ("element", t->self_scm ());
1009 scm_gc_unprotect_object (t->self_scm ());
1012 $$->set_spot (THIS->here_input ());
1014 csm-> set_mus_property ("context-type", $2);
1016 | PROPERTY STRING '.' STRING UNSET {
1017 Music *t = new Music (SCM_EOL);
1019 t->set_mus_property ("iterator-ctor",
1020 Property_unset_iterator::constructor_cxx_function);
1021 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1023 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1024 csm->set_mus_property ("element", t->self_scm ());
1025 scm_gc_unprotect_object (t->self_scm ());
1028 $$->set_spot (THIS->here_input ());
1030 csm-> set_mus_property ("context-type", $2);
1032 | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm {
1033 Music *t = new Music (SCM_EOL);
1034 t->set_mus_property ("iterator-ctor",
1035 Push_property_iterator::constructor_cxx_function);
1036 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1037 t->set_mus_property ("pop-first", SCM_BOOL_T);
1038 t->set_mus_property ("grob-property", $6);
1039 t->set_mus_property ("grob-value", $8);
1040 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1041 csm->set_mus_property ("element", t->self_scm ());
1042 scm_gc_unprotect_object (t->self_scm ());
1044 $$->set_spot (THIS->here_input ());
1046 csm-> set_mus_property ("context-type", $2);
1048 | PROPERTY STRING '.' STRING OVERRIDE embedded_scm '=' embedded_scm {
1049 Music *t = new Music (SCM_EOL);
1050 t->set_mus_property ("iterator-ctor",
1051 Push_property_iterator::constructor_cxx_function);
1052 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1053 t->set_mus_property ("grob-property", $6);
1054 t->set_mus_property ("grob-value", $8);
1055 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1056 csm->set_mus_property ("element", t->self_scm ());
1057 scm_gc_unprotect_object (t->self_scm ());
1060 $$->set_spot (THIS->here_input ());
1062 csm-> set_mus_property ("context-type", $2);
1064 | PROPERTY STRING '.' STRING REVERT embedded_scm {
1065 Music *t = new Music (SCM_EOL);
1066 t->set_mus_property ("iterator-ctor",
1067 Pop_property_iterator::constructor_cxx_function);
1068 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1069 t->set_mus_property ("grob-property", $6);
1071 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1072 csm->set_mus_property ("element", t->self_scm ());
1073 scm_gc_unprotect_object (t->self_scm ());
1076 $$->set_spot (THIS->here_input ());
1078 csm-> set_mus_property ("context-type", $2);
1084 | bare_int { $$ = gh_int2scm ($1); }
1085 | embedded_scm { $$ = $1; }
1092 } /*cont */ simple_element post_requests {
1093 Music_sequence *l = dynamic_cast<Music_sequence*> ($3);
1095 for (int i=0; i < $1->size (); i++)
1096 l->append_music ($1->elem (i));
1097 for (int i=0; i < $4->size (); i++)
1098 l->append_music ($4->elem (i));
1101 programming_error ("Need Sequence to add music to");
1109 $$ = new Request_chord (SCM_EOL);
1110 $$->set_mus_property ("elements", gh_cons ($1->self_scm (), SCM_EOL));
1111 $$-> set_spot (THIS->here_input ());
1112 $1-> set_spot (THIS->here_input ());
1115 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1117 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1118 csm->set_mus_property ("element", t->self_scm ());
1119 scm_gc_unprotect_object (t->self_scm ());
1122 $$->set_spot (THIS->here_input ());
1124 csm->set_mus_property ("context-type", ly_str02scm ("Score"));
1126 | PARTIAL duration_length {
1127 Moment m = - unsmob_duration ($2)->length_mom ();
1128 Music * p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1130 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1131 sp->set_mus_property ("element", p->self_scm ());
1132 scm_gc_unprotect_object (p->self_scm ());
1135 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1138 SCM func = scm_primitive_eval (ly_symbol2scm ("clef-name-to-properties"));
1139 SCM result = gh_call1 (func, $2);
1142 for (SCM s = result ; gh_pair_p (s); s = ly_cdr (s)) {
1143 Music * p = new Music (SCM_EOL);
1144 set_music_properties (p, ly_car (s));
1145 l = gh_cons (p->self_scm (), l);
1146 scm_gc_unprotect_object (p->self_scm ());
1148 Sequential_music * seq = new Sequential_music (SCM_EOL);
1149 seq->set_mus_property ("elements", l);
1151 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1152 sp->set_mus_property ("element", seq->self_scm ());
1153 scm_gc_unprotect_object (seq->self_scm ());
1156 sp-> set_mus_property ("context-type", ly_str02scm ("Staff"));
1159 Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2);
1161 int l = gh_scm2int (ly_car ($2));
1162 int o = gh_scm2int (ly_cdr ($2));
1164 Moment one_beat = Moment (1)/Moment (o);
1165 Moment len = Moment (l) * one_beat;
1168 Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ());
1169 Music *p3 = set_property_music (ly_symbol2scm ("beatLength"), one_beat.smobbed_copy ());
1171 SCM list = scm_list_n (p1->self_scm (), p2->self_scm (), p3->self_scm(), SCM_UNDEFINED);
1172 Sequential_music *seq = new Sequential_music (SCM_EOL);
1173 seq->set_mus_property ("elements", list);
1176 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1177 sp->set_mus_property ("element", seq->self_scm ());
1181 scm_gc_unprotect_object (p3->self_scm ());
1182 scm_gc_unprotect_object (p2->self_scm ());
1183 scm_gc_unprotect_object (p1->self_scm ());
1184 scm_gc_unprotect_object (seq->self_scm ());
1189 TODO: should make alias TimingContext for Score
1192 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1197 shorthand_command_req { $$ = $1; }
1198 | verbose_command_req { $$ = $1; }
1201 shorthand_command_req:
1209 $$ = new Barcheck_req;
1215 Span_req*b= new Span_req;
1216 b->set_span_dir (START);
1217 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1221 Span_req*b= new Span_req;
1222 b->set_span_dir ( STOP);
1223 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1227 $$ = new Breathing_sign_req;
1230 $$ = new Porrectus_req;
1234 verbose_command_req:
1235 COMMANDSPANREQUEST bare_int STRING { /*TODO: junkme */
1236 Span_req * sp_p = new Span_req;
1237 sp_p-> set_span_dir ( Direction ($2));
1238 sp_p->set_mus_property ("span-type",$3);
1239 sp_p->set_spot (THIS->here_input ());
1243 Mark_req * m = new Mark_req;
1247 Mark_req *m = new Mark_req;
1248 m->set_mus_property ("label", $2);
1255 Break_req * b = new Break_req;
1257 if (!gh_number_p (s))
1260 b->set_mus_property ("penalty", s);
1261 b->set_spot (THIS->here_input ());
1264 | SKIP duration_length {
1265 Skip_req * skip_p = new Skip_req;
1266 skip_p->set_mus_property ("duration", $2);
1274 Key_change_req *key_p= new Key_change_req;
1277 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1278 Key_change_req *key_p= new Key_change_req;
1280 key_p->set_mus_property ("pitch-alist", $3);
1281 ((Music* )key_p)->transpose (* unsmob_pitch ($2));
1288 $$ = new Link_array<Request>;
1290 | post_requests post_request {
1291 $2->set_spot (THIS->here_input ());
1303 request_that_take_dir:
1306 | script_abbreviation {
1307 SCM s = THIS->lexer_p_->lookup_identifier ("dash" + ly_scm2string ($1));
1308 Articulation_req *a = new Articulation_req;
1309 if (gh_string_p (s))
1310 a->set_mus_property ("articulation-type", s);
1311 else THIS->parser_error (_ ("Expecting string as script definition"));
1317 script_dir request_that_take_dir {
1318 if (Script_req * gs = dynamic_cast<Script_req*> ($2))
1319 gs->set_direction (Direction ($1));
1321 $2->origin ()->warning (_ ("Can't specify direction for this request"));
1327 REQUEST_IDENTIFIER {
1328 $$ = dynamic_cast<Request*> (unsmob_music ($1)->clone ());
1329 $$->set_spot (THIS->here_input ());
1331 | DYNAMICSCRIPT embedded_scm {
1333 TODO: junkme, use text-type == dynamic
1335 Text_script_req *d = new Text_script_req;
1336 d->set_mus_property ("text-type" , ly_symbol2scm ("dynamic"));
1337 d->set_mus_property ("text", $2);
1338 d->set_spot (THIS->here_input ());
1341 | SPANREQUEST bare_int STRING {
1342 Span_req * sp_p = new Span_req;
1343 sp_p->set_span_dir ( Direction ($2));
1344 sp_p->set_mus_property ("span-type", $3);
1345 sp_p->set_spot (THIS->here_input ());
1349 Tremolo_req* a = new Tremolo_req;
1350 a->set_spot (THIS->here_input ());
1351 a->set_mus_property ("tremolo-type", gh_int2scm ($1));
1355 Articulation_req * a = new Articulation_req;
1356 a->set_mus_property ("articulation-type", $2);
1357 a->set_spot (THIS->here_input ());
1361 duh, junk this syntax from the parser, if possible.
1364 Arpeggio_req *a = new Arpeggio_req;
1365 a->set_spot (THIS->here_input ());
1369 Glissando_req *g = new Glissando_req;
1370 g->set_spot /* No pun intended */ (THIS->here_input ());
1397 | NOTENAME_PITCH sup_quotes {
1398 Pitch p = *unsmob_pitch ($1);
1400 $$ = p.smobbed_copy ();
1402 | NOTENAME_PITCH sub_quotes {
1403 Pitch p =* unsmob_pitch ($1);
1406 $$ = p.smobbed_copy ();
1419 | TONICNAME_PITCH sup_quotes {
1420 Pitch p = *unsmob_pitch ($1);
1422 $$ = p.smobbed_copy ();
1424 | TONICNAME_PITCH sub_quotes {
1425 Pitch p =* unsmob_pitch ($1);
1428 $$ = p.smobbed_copy ();
1443 PITCH embedded_scm {
1445 if (!unsmob_pitch ($2)) {
1446 THIS->parser_error (_f ("Expecting musical-pitch value", 3));
1447 $$ = Pitch ().smobbed_copy ();
1453 DURATION embedded_scm {
1455 if (!unsmob_duration ($2))
1457 THIS->parser_error (_ ("Must have duration object"));
1458 $$ = Duration ().smobbed_copy ();
1465 if (!THIS->lexer_p_->lyric_state_b ())
1466 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1467 $$ = new Extender_req;
1473 if (!THIS->lexer_p_->lyric_state_b ())
1474 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1475 $$ = new Hyphen_req;
1480 close_request_parens {
1482 dynamic_cast<Span_req*> ($$)->set_span_dir ( START);
1485 close_request_parens:
1487 Span_req* s= new Span_req;
1489 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1492 Span_req* s= new Span_req;
1494 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1497 Span_req*s =new Span_req;
1499 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1502 Span_req*s =new Span_req;
1504 s->set_mus_property ("span-type", ly_str02scm ("decrescendo"));
1510 open_request_parens {
1512 dynamic_cast<Span_req*> ($$)->set_span_dir (STOP);
1516 open_request_parens:
1518 Span_req *s = new Span_req;
1519 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1524 Span_req* s= new Span_req;
1526 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1529 Span_req* s= new Span_req;
1531 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1537 Text_script_req *t = new Text_script_req;
1538 t->set_mus_property ("text", $1);
1539 t->set_spot (THIS->here_input ());
1543 Text_script_req *t = new Text_script_req;
1544 t->set_mus_property ("text", $1);
1545 t->set_spot (THIS->here_input ());
1549 String ds = to_str ($1);
1550 Text_script_req* t = new Text_script_req;
1552 t->set_mus_property ("text", ly_str02scm (ds.ch_C ()));
1553 t->set_mus_property ("text-type" , ly_symbol2scm ("finger"));
1554 t->set_spot (THIS->here_input ());
1559 script_abbreviation:
1561 $$ = gh_str02scm ("Hat");
1564 $$ = gh_str02scm ("Plus");
1567 $$ = gh_str02scm ("Dash");
1570 $$ = gh_str02scm ("Bar");
1573 $$ = gh_str02scm ("Larger");
1576 $$ = gh_str02scm ("Dot");
1584 | '-' { $$ = CENTER; }
1589 $$ = new Link_array<Request>;
1591 | pre_requests open_request {
1603 multiplied_duration {
1606 | explicit_duration {
1611 optional_notemode_duration:
1613 $$ = THIS->default_duration_.smobbed_copy ();
1615 | multiplied_duration {
1618 | explicit_duration {
1624 bare_unsigned dots {
1626 if (!is_duration_b ($1))
1627 THIS->parser_error (_f ("not a duration: %d", $1));
1631 $$ = Duration (l, $2).smobbed_copy ();
1633 THIS->set_last_duration (unsmob_duration ($$));
1635 | DURATION_IDENTIFIER dots {
1636 Duration *d =unsmob_duration ($1);
1637 Duration k (d->duration_log (),d->dot_count () + $2);
1638 $$ = k.smobbed_copy ();
1640 THIS->set_last_duration (unsmob_duration ($$));
1647 multiplied_duration:
1651 | multiplied_duration '*' bare_unsigned {
1652 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1654 | multiplied_duration '*' FRACTION {
1655 Rational m (gh_scm2int (ly_car ($3)), gh_scm2int (ly_cdr ($3)));
1657 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
1662 FRACTION { $$ = $1; }
1663 | UNSIGNED '/' UNSIGNED {
1664 $$ = gh_cons (gh_int2scm ($1), gh_int2scm ($3));
1682 | ':' bare_unsigned {
1683 if (!is_duration_b ($2))
1684 THIS->parser_error (_f ("not a duration: %d", $2));
1704 p .notename_i_ = $1 - 1;
1707 Note_req * nr = new Note_req;
1708 $$ = nr->self_scm ();
1709 nr->set_mus_property ("pitch", p.smobbed_copy ());
1710 scm_gc_unprotect_object ($$);
1712 | bass_figure bass_mod {
1714 SCM sp = unsmob_music ($1)->get_mus_property ("pitch");
1715 unsmob_pitch (sp)->alteration_i_ += $2;
1717 unsmob_music ($1)->set_mus_property ("force-accidental", SCM_BOOL_T);
1726 | figure_list bass_figure {
1727 $$ = gh_cons ($2, $1);
1732 FIGURE_OPEN figure_list FIGURE_CLOSE {
1733 Music * m = new Request_chord (SCM_EOL);
1734 $2 = scm_reverse_x ($2, SCM_EOL);
1735 m->set_mus_property ("elements", $2);
1736 $$ = m->self_scm ();
1741 pitch exclamations questions optional_notemode_duration {
1743 Input i = THIS->pop_spot ();
1744 if (!THIS->lexer_p_->note_state_b ())
1745 THIS->parser_error (_ ("Have to be in Note mode for notes"));
1747 Note_req *n = new Note_req;
1749 n->set_mus_property ("pitch", $1);
1750 n->set_mus_property ("duration", $4);
1753 n->set_mus_property ("cautionary", SCM_BOOL_T);
1754 if ($2 % 2 || $3 % 2)
1755 n->set_mus_property ("force-accidental", SCM_BOOL_T);
1757 Simultaneous_music*v = new Request_chord (SCM_EOL);
1758 v->set_mus_property ("elements", scm_list_n (n->self_scm (), SCM_UNDEFINED));
1764 | figure_spec optional_notemode_duration {
1765 Music * m = unsmob_music ($1);
1766 Input i = THIS->pop_spot ();
1768 for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = ly_cdr (s))
1770 unsmob_music (ly_car (s))->set_mus_property ("duration", $2);
1774 | RESTNAME optional_notemode_duration {
1776 Input i = THIS->pop_spot ();
1777 SCM e = SCM_UNDEFINED;
1778 if (ly_scm2string ($1) =="s") {
1780 Skip_req * skip_p = new Skip_req;
1781 skip_p->set_mus_property ("duration" ,$2);
1782 skip_p->set_spot (i);
1783 e = skip_p->self_scm ();
1786 Rest_req * rest_req_p = new Rest_req;
1787 rest_req_p->set_mus_property ("duration", $2);
1788 rest_req_p->set_spot (i);
1789 e = rest_req_p->self_scm ();
1791 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1792 velt_p-> set_mus_property ("elements", scm_list_n (e,SCM_UNDEFINED));
1793 velt_p->set_spot (i);
1797 | MULTI_MEASURE_REST optional_notemode_duration {
1798 Input i = THIS->pop_spot ();
1800 Skip_req * sk = new Skip_req;
1801 sk->set_mus_property ("duration", $2);
1802 Span_req *sp1 = new Span_req;
1803 Span_req *sp2 = new Span_req;
1804 sp1-> set_span_dir ( START);
1805 sp2-> set_span_dir ( STOP);
1806 SCM r = ly_str02scm ("rest");
1807 sp1->set_mus_property ("span-type", r);
1808 sp2->set_mus_property ("span-type", r);
1810 Request_chord * rqc1 = new Request_chord (SCM_EOL);
1811 rqc1->set_mus_property ("elements", scm_list_n (sp1->self_scm (), SCM_UNDEFINED));
1812 Request_chord * rqc2 = new Request_chord (SCM_EOL);
1813 rqc2->set_mus_property ("elements", scm_list_n (sk->self_scm (), SCM_UNDEFINED));;
1814 Request_chord * rqc3 = new Request_chord (SCM_EOL);
1815 rqc3->set_mus_property ("elements", scm_list_n (sp2->self_scm (), SCM_UNDEFINED));;
1817 SCM ms = scm_list_n (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED);
1819 $$ = new Sequential_music (SCM_EOL);
1820 $$->set_mus_property ("elements", ms);
1822 | STRING optional_notemode_duration {
1823 Input i = THIS->pop_spot ();
1825 Lyric_req* lreq_p = new Lyric_req;
1826 lreq_p->set_mus_property ("text", $1);
1827 lreq_p->set_mus_property ("duration",$2);
1828 lreq_p->set_spot (i);
1829 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1830 velt_p->set_mus_property ("elements", scm_list_n (lreq_p->self_scm (), SCM_UNDEFINED));
1835 Input i = THIS->pop_spot ();
1837 if (!THIS->lexer_p_->chord_state_b ())
1838 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
1845 steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
1846 $$ = Chord::get_chord ($1, $3, $4, $5, $6, $2);
1847 $$->set_spot (THIS->here_input ());
1854 | CHORD_COLON chord_notes {
1863 | chord_notes '.' chord_step {
1864 $$ = gh_append2 ($$, $3);
1872 | CHORD_CARET chord_notes {
1882 | '/' steno_tonic_pitch {
1891 | CHORD_BASS steno_tonic_pitch {
1898 $$ = gh_cons ($1, SCM_EOL);
1900 | CHORDMODIFIER_PITCH {
1901 $$ = gh_cons (unsmob_pitch ($1)->smobbed_copy (), SCM_EOL);
1903 | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
1904 $$ = scm_list_n (unsmob_pitch ($1)->smobbed_copy (),
1912 m.notename_i_ = ($1 - 1) % 7;
1913 m.octave_i_ = $1 > 7 ? 1 : 0;
1914 m.alteration_i_ = 0;
1916 $$ = m.smobbed_copy ();
1918 | bare_unsigned '+' {
1920 m.notename_i_ = ($1 - 1) % 7;
1921 m.octave_i_ = $1 > 7 ? 1 : 0;
1922 m.alteration_i_ = 1;
1925 $$ = m.smobbed_copy ();
1927 | bare_unsigned CHORD_MINUS {
1929 m.notename_i_ = ($1 - 1) % 7;
1930 m.octave_i_ = $1 > 7 ? 1 : 0;
1931 m.alteration_i_ = -1;
1933 $$ = m.smobbed_copy ();
1941 number_expression '+' number_term {
1942 $$ = scm_sum ($1, $3);
1944 | number_expression '-' number_term {
1945 $$ = scm_difference ($1, $3);
1954 | number_factor '*' number_factor {
1955 $$ = scm_product ($1, $3);
1957 | number_factor '/' number_factor {
1958 $$ = scm_divide ($1, $3);
1963 '(' number_expression ')' {
1966 | '-' number_factor { /* %prec UNARY_MINUS */
1967 $$ = scm_difference ($2, SCM_UNDEFINED);
1975 $$ = gh_int2scm ($1);
1980 | NUMBER_IDENTIFIER {
1984 $$ = gh_double2scm (gh_scm2double ($1) CM );
1987 $$ = gh_double2scm (gh_scm2double ($1) PT);
1990 $$ = gh_double2scm (gh_scm2double ($1) INCH);
1993 $$ = gh_double2scm (gh_scm2double ($1) MM);
1996 $$ = gh_double2scm (gh_scm2double ($1) CHAR);
2012 if (scm_integer_p ($1) == SCM_BOOL_T)
2014 int k = gh_scm2int ($1);
2018 THIS->parser_error (_ ("need integer number arg"));
2032 | STRING_IDENTIFIER {
2035 | string '+' string {
2036 $$ = scm_string_append (scm_list_n ($1, $3, SCM_UNDEFINED));
2043 | exclamations '!' { $$ ++; }
2048 | questions '?' { $$ ++; }
2055 My_lily_parser::set_yydebug (bool b)
2062 extern My_lily_parser * current_parser;
2065 My_lily_parser::do_yyparse ()
2068 current_parser = this;;
2069 yyparse ((void*)this);