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> Alternative_music Repeated_music
279 %type <i> tremolo_type
280 %type <i> bare_int bare_unsigned
283 %type <scm> identifier_init
285 %type <scm> steno_duration optional_notemode_duration multiplied_duration
286 %type <scm> explicit_duration
288 %type <reqvec> pre_requests post_requests
289 %type <request> gen_text_def
290 %type <scm> steno_pitch pitch absolute_pitch
291 %type <scm> explicit_pitch steno_tonic_pitch
293 %type <scm> chord_additions chord_subtractions chord_notes chord_step
295 %type <scm> chord_note chord_inversion chord_bass
296 %type <scm> duration_length fraction
298 %type <scm> embedded_scm scalar
299 %type <music> Music Sequential_music Simultaneous_music Music_sequence
300 %type <music> relative_music re_rhythmed_music part_combined_music
301 %type <music> property_def translator_change
302 %type <scm> Music_list
303 %type <outputdef> music_output_def_body
304 %type <request> shorthand_command_req
305 %type <request> post_request
306 %type <music> command_req verbose_command_req
307 %type <request> extender_req
308 %type <request> hyphen_req
309 %type <scm> string bare_number number_expression number_term number_factor
311 %type <score> score_block score_body
313 %type <scm> translator_spec_block translator_spec_body
314 %type <tempo> tempo_request
315 %type <scm> notenames_body notenames_block chordmodifiers_block
316 %type <scm> script_abbreviation
322 /* We don't assign precedence to / and *, because we might need varied
323 prec levels in different prods */
329 lilypond: /* empty */
330 | lilypond toplevel_expression {}
331 | lilypond assignment { }
333 THIS->error_level_i_ = 1;
336 THIS->error_level_i_ = 1;
342 THIS->lexer_p_->pitchname_tab_ = $1;
344 | chordmodifiers_block {
345 THIS->lexer_p_->chordmodifier_tab_ = $1;
349 scm_gc_unprotect_object (global_header_p->self_scm ());
350 global_header_p = $1;
353 score_global_array.push ($1);
356 if (dynamic_cast<Paper_def*> ($1))
357 THIS->lexer_p_->set_identifier ("$defaultpaper", $1->self_scm ());
358 else if (dynamic_cast<Midi_def*> ($1))
359 THIS->lexer_p_->set_identifier ("$defaultmidi", $1->self_scm ());
372 chordmodifiers_block:
373 CHORDMODIFIERS notenames_body { $$ = $2; }
377 PITCHNAMES notenames_body { $$ = $2; }
382 int i = scm_ilength ($1);
384 SCM tab = scm_make_vector (gh_int2scm (i), SCM_EOL);
385 for (SCM s = $1; gh_pair_p (s); s = ly_cdr (s)) {
386 SCM pt = ly_cdar (s);
387 if (!unsmob_pitch (pt))
388 THIS->parser_error ("Need pitch object.");
390 scm_hashq_set_x (tab, ly_caar (s), pt);
397 lilypond_header_body:
399 $$ = new Scheme_hash_table;
401 Scope *sc = new Scope ($$);
402 THIS->lexer_p_-> scope_l_arr_.push (sc);
404 | lilypond_header_body assignment {
410 HEADER '{' lilypond_header_body '}' {
412 delete THIS->lexer_p_-> scope_l_arr_.pop ();
424 /* cont */ '=' identifier_init {
427 Should find generic way of associating input with objects.
429 Input ip = THIS->pop_spot ();
431 if (! regular_identifier_b ($1))
433 ip.warning (_ ("Identifier should have alphabetic characters only"));
436 THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4);
439 TODO: devise standard for protection in parser.
441 The parser stack lives on the C-stack, which means that
442 all objects can be unprotected as soon as they're here.
452 $$ = $1->self_scm ();
453 scm_gc_unprotect_object ($$);
456 $$ = $1->self_scm ();
457 scm_gc_unprotect_object ($$);
459 | translator_spec_block {
463 $$ = $1->self_scm ();
464 scm_gc_unprotect_object ($$);
467 $$ = $1->self_scm ();
468 scm_gc_unprotect_object ($$);
470 | explicit_duration {
473 | number_expression {
484 translator_spec_block:
485 TRANSLATOR '{' translator_spec_body '}'
491 translator_spec_body:
492 TRANSLATOR_IDENTIFIER {
493 $$ = unsmob_translator_def ($1)->clone_scm ();
494 unsmob_translator_def ($$)-> set_spot (THIS->here_input ());
497 $$ = Translator_def::make_scm ();
498 Translator_def*td = unsmob_translator_def ($$);
499 td->translator_group_type_ = $2;
500 td->set_spot (THIS->here_input ());
502 | translator_spec_body STRING '=' embedded_scm {
503 unsmob_translator_def ($$)->add_property_assign ($2, $4);
505 | translator_spec_body STRING OVERRIDE embedded_scm '=' embedded_scm {
506 unsmob_translator_def ($$)
507 ->add_push_property (scm_string_to_symbol ($2), $4, $6);
509 | translator_spec_body STRING REVERT embedded_scm {
510 unsmob_translator_def ($$)->add_pop_property (
511 scm_string_to_symbol ($2), $4);
513 | translator_spec_body NAME STRING {
514 unsmob_translator_def ($$)->type_name_ = $3;
516 | translator_spec_body CONSISTS STRING {
517 unsmob_translator_def ($$)->add_element ($3);
519 | translator_spec_body ALIAS STRING {
520 Translator_def*td = unsmob_translator_def ($$);
521 td->type_aliases_ = gh_cons ($3, td->type_aliases_);
523 | translator_spec_body GROBDESCRIPTIONS embedded_scm {
524 Translator_def*td = unsmob_translator_def($$);
525 // td->add_property_assign (ly_symbol2scm ("allGrobDescriptions"), $3);
526 for (SCM p = $3; gh_pair_p (p); p = ly_cdr (p))
527 td->add_property_assign (scm_symbol_to_string (ly_caar (p)), ly_cdar (p));
529 | translator_spec_body CONSISTSEND STRING {
530 unsmob_translator_def ($$)->add_last_element ( $3);
532 | translator_spec_body ACCEPTS STRING {
533 unsmob_translator_def ($$)->set_acceptor ($3,true);
535 | translator_spec_body DENIES STRING {
536 unsmob_translator_def ($$)->set_acceptor ($3,false);
538 | translator_spec_body REMOVE STRING {
539 unsmob_translator_def ($$)->remove_element ($3);
550 /*cont*/ '{' score_body '}' {
553 if (!$$->def_p_arr_.size ())
555 Music_output_def *id =
556 unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
557 $$->add_output (id ? id->clone () : new Paper_def );
566 $$->set_spot (THIS->here_input ());
567 SCM m = $1->self_scm ();
568 scm_gc_unprotect_object (m);
572 $$ = new Score (*unsmob_score ($1));
573 $$->set_spot (THIS->here_input ());
575 | score_body lilypond_header {
576 scm_gc_unprotect_object ($2->self_scm ());
579 | score_body output_def {
592 music_output_def_body '}' {
594 THIS-> lexer_p_-> scope_l_arr_.pop ();
598 music_output_def_body:
600 Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultmidi"));
605 p = dynamic_cast<Midi_def*> (id->clone ());
610 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
613 Music_output_def *id = unsmob_music_output_def (THIS->lexer_p_->lookup_identifier ("$defaultpaper"));
616 p = dynamic_cast<Paper_def*> (id->clone ());
619 THIS-> lexer_p_-> scope_l_arr_.push (p->scope_p_);
622 | PAPER '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
623 Music_output_def *p = unsmob_music_output_def ($3);
625 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
628 | MIDI '{' MUSIC_OUTPUT_DEF_IDENTIFIER {
629 Music_output_def *p = unsmob_music_output_def ($3);
632 THIS->lexer_p_->scope_l_arr_.push (p->scope_p_);
635 | music_output_def_body assignment {
638 | music_output_def_body translator_spec_block {
639 $$->assign_translator ($2);
641 | music_output_def_body STYLESHEET embedded_scm {
642 dynamic_cast<Paper_def*> ($$)-> style_sheet_ = $3;
644 | music_output_def_body tempo_request {
646 junk this ? there already is tempo stuff in
649 int m = gh_scm2int ( $2->get_mus_property ("metronome-count"));
650 Duration *d = unsmob_duration ($2->get_mus_property ("duration"));
651 dynamic_cast<Midi_def*> ($$)->set_tempo (d->length_mom (), m);
653 | music_output_def_body error {
659 TEMPO steno_duration '=' bare_unsigned {
661 $$->set_mus_property ("duration", $2);
662 $$->set_mus_property ("metronome-count", gh_int2scm ( $4));
666 Music_list: /* empty */ {
667 $$ = gh_cons (SCM_EOL, SCM_EOL);
671 SCM c = gh_cons ($2->self_scm (), SCM_EOL);
672 scm_gc_unprotect_object ($2->self_scm ()); /* UGH */
673 if (gh_pair_p (ly_cdr (s)))
674 gh_set_cdr_x (ly_cdr (s), c); /* append */
676 gh_set_car_x (s, c); /* set first cons */
677 gh_set_cdr_x (s, c) ; /* remember last cell */
693 | ALTERNATIVE Music_sequence {
695 $2->set_spot (THIS->here_input ());
703 REPEAT string bare_unsigned Music Alternative_music
705 Music_sequence* alts = dynamic_cast <Music_sequence*> ($5);
706 if (alts && $3 < alts->length_i ())
707 $5->origin ()->warning (_ ("More alternatives than repeats. Junking excess alternatives."));
711 Repeated_music * r = new Repeated_music (SCM_EOL);
715 r-> set_mus_property ("body", beg->self_scm ());
716 scm_gc_unprotect_object (beg->self_scm ());
718 r->set_mus_property ("repeat-count", gh_int2scm (times >? 1));
722 alts->truncate (times);
723 r-> set_mus_property ("alternatives", alts->self_scm ());
724 scm_gc_unprotect_object (alts->self_scm ());
726 SCM func = scm_primitive_eval (ly_symbol2scm ("repeat-name-to-ctor"));
727 SCM result = gh_call1 (func, $2);
729 set_music_properties (r, result);
731 r->set_spot (*$4->origin ());
736 Music_sequence: '{' Music_list '}' {
737 $$ = new Music_sequence (SCM_EOL);
738 $$->set_mus_property ("elements", ly_car ($2));
743 SEQUENTIAL '{' Music_list '}' {
744 $$ = new Sequential_music (SCM_EOL);
745 $$->set_mus_property ("elements", ly_car ($3));
747 | '{' Music_list '}' {
748 $$ = new Sequential_music (SCM_EOL);
749 $$->set_mus_property ("elements", ly_car ($2));
754 SIMULTANEOUS '{' Music_list '}'{
755 $$ = new Simultaneous_music (SCM_EOL);
756 $$->set_mus_property ("elements", ly_car ($3));
759 | '<' Music_list '>' {
760 $$ = new Simultaneous_music (SCM_EOL);
761 $$->set_mus_property ("elements", ly_car ($2));
766 request_chord { $$ = $1; }
767 | OUTPUTPROPERTY embedded_scm embedded_scm '=' embedded_scm {
769 if (!gh_symbol_p ($3))
771 THIS->parser_error (_ ("Second argument must be a symbol"));
773 /*hould check # args */
774 if (!gh_procedure_p (pred))
776 THIS->parser_error (_ ("First argument must be a procedure taking 1 argument"));
779 Music *m = new Music (SCM_EOL);
780 m->set_mus_property ("predicate", pred);
781 m->set_mus_property ("grob-property", $3);
782 m->set_mus_property ("grob-value", $5);
783 m->set_mus_property ("iterator-ctor",
784 Output_property_music_iterator::constructor_cxx_function);
789 $$ = unsmob_music ($1)->clone ();
797 CONTEXT STRING Music {
798 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
799 csm->set_mus_property ("element", $3->self_scm ());
800 scm_gc_unprotect_object ($3->self_scm ());
802 csm->set_mus_property ("context-type",$2);
803 csm->set_mus_property ("context-id", ly_str02scm (""));
807 | AUTOCHANGE STRING Music {
808 Music * chm = new Music_wrapper (SCM_EOL);
809 chm->set_mus_property ("element", $3->self_scm ());
810 chm->set_mus_property ("iterator-ctor", Auto_change_iterator::constructor_cxx_function);
812 scm_gc_unprotect_object ($3->self_scm ());
813 chm->set_mus_property ("what", $2);
816 chm->set_spot (*$3->origin ());
821 The other version is for easier debugging of
822 Sequential_music_iterator in combination with grace notes.
825 SCM start = THIS->lexer_p_->lookup_identifier ("startGraceMusic");
826 SCM stop = THIS->lexer_p_->lookup_identifier ("stopGraceMusic");
827 Music *startm = unsmob_music (start);
828 Music *stopm = unsmob_music (stop);
832 stopm = stopm->clone ();
833 ms = gh_cons (stopm->self_scm (), ms);
834 scm_gc_unprotect_object (stopm->self_scm ());
836 ms = gh_cons ($2->self_scm (), ms);
837 scm_gc_unprotect_object ($2->self_scm());
839 startm = startm->clone ();
840 ms = gh_cons (startm->self_scm () , ms);
841 scm_gc_unprotect_object (startm->self_scm ());
844 Music* seq = new Sequential_music (SCM_EOL);
845 seq->set_mus_property ("elements", ms);
847 $$ = new Grace_music (SCM_EOL);
848 $$->set_mus_property ("element", seq->self_scm ());
849 scm_gc_unprotect_object (seq->self_scm ());
851 $$ = new Grace_music (SCM_EOL);
852 $$->set_mus_property ("element", $2->self_scm ());
853 scm_gc_unprotect_object ($2->self_scm ());
858 | CONTEXT string '=' string Music {
859 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
860 csm->set_mus_property ("element", $5->self_scm ());
861 scm_gc_unprotect_object ($5->self_scm ());
863 csm->set_mus_property ("context-type", $2);
864 csm->set_mus_property ("context-id", $4);
875 int n = gh_scm2int (ly_car ($3)); int d = gh_scm2int (ly_cdr ($3));
877 $$ = new Time_scaled_music (SCM_EOL);
878 $$->set_spot (THIS->pop_spot ());
881 $$->set_mus_property ("element", mp->self_scm ());
882 scm_gc_unprotect_object (mp->self_scm ());
883 $$->set_mus_property ("numerator", gh_int2scm (n));
884 $$->set_mus_property ("denominator", gh_int2scm (d));
885 $$->compress (Moment (Rational (n,d)));
888 | Repeated_music { $$ = $1; }
889 | Simultaneous_music { $$ = $1; }
890 | Sequential_music { $$ = $1; }
891 | TRANSPOSE pitch Music {
892 $$ = new Transposed_music (SCM_EOL);
894 Pitch pit = *unsmob_pitch ($2);
897 $$->set_mus_property ("element", p->self_scm ());
898 scm_gc_unprotect_object (p->self_scm ());
900 | TRANSPOSE steno_tonic_pitch Music {
901 $$ = new Transposed_music (SCM_EOL);
903 Pitch pit = *unsmob_pitch ($2);
906 $$->set_mus_property ("element", p->self_scm ());
907 scm_gc_unprotect_object (p->self_scm ());
910 | APPLY embedded_scm Music {
911 SCM ret = gh_call1 ($2, $3->self_scm ());
912 Music *m = unsmob_music (ret);
914 THIS->parser_error ("\\apply must return a Music");
915 m = new Music (SCM_EOL);
920 { THIS->lexer_p_->push_note_state (); }
923 THIS->lexer_p_->pop_state ();
926 { THIS->lexer_p_->push_figuredbass_state (); }
929 Music * chm = new Untransposable_music () ;
930 chm->set_mus_property ("element", $3->self_scm ());
933 THIS->lexer_p_->pop_state ();
936 { THIS->lexer_p_->push_chord_state (); }
939 Music * chm = new Un_relativable_music ;
940 chm->set_mus_property ("element", $3->self_scm ());
943 THIS->lexer_p_->pop_state ();
946 { THIS->lexer_p_->push_lyric_state (); }
950 THIS->lexer_p_->pop_state ();
952 | relative_music { $$ = $1; }
953 | re_rhythmed_music { $$ = $1; }
954 | part_combined_music { $$ = $1; }
958 RELATIVE absolute_pitch Music {
960 Pitch pit = *unsmob_pitch ($2);
961 $$ = new Relative_octave_music (SCM_EOL);
963 $$->set_mus_property ("element", p->self_scm ());
964 scm_gc_unprotect_object (p->self_scm ());
966 $$->set_mus_property ("last-pitch", p->to_relative_octave (pit).smobbed_copy ());
972 ADDLYRICS Music Music {
973 Lyric_combine_music * l = new Lyric_combine_music (SCM_EOL);
974 l->set_mus_property ("music", $2->self_scm ());
975 l->set_mus_property ("lyrics", $3->self_scm ());
976 scm_gc_unprotect_object ($3->self_scm ());
977 scm_gc_unprotect_object ($2->self_scm ());
983 PARTCOMBINE STRING Music Music {
984 Part_combine_music * p = new Part_combine_music (SCM_EOL);
986 p->set_mus_property ("what", $2);
987 p->set_mus_property ("one", $3->self_scm ());
988 p->set_mus_property ("two", $4->self_scm ());
990 scm_gc_unprotect_object ($3->self_scm ());
991 scm_gc_unprotect_object ($4->self_scm ());
999 TRANSLATOR STRING '=' STRING {
1000 Music * t = new Music (SCM_EOL);
1001 t->set_mus_property ("iterator-ctor",
1002 Change_iterator::constructor_cxx_function);
1003 t-> set_mus_property ("change-to-type", $2);
1004 t-> set_mus_property ("change-to-id", $4);
1007 $$->set_spot (THIS->here_input ());
1012 PROPERTY STRING '.' STRING '=' scalar {
1014 Music *t = set_property_music (scm_string_to_symbol ($4), $6);
1015 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1017 csm->set_mus_property ("element", t->self_scm ());
1018 scm_gc_unprotect_object (t->self_scm ());
1021 $$->set_spot (THIS->here_input ());
1023 csm-> set_mus_property ("context-type", $2);
1025 | PROPERTY STRING '.' STRING UNSET {
1026 Music *t = new Music (SCM_EOL);
1028 t->set_mus_property ("iterator-ctor",
1029 Property_unset_iterator::constructor_cxx_function);
1030 t->set_mus_property ("symbol", scm_string_to_symbol ($4));
1032 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1033 csm->set_mus_property ("element", t->self_scm ());
1034 scm_gc_unprotect_object (t->self_scm ());
1037 $$->set_spot (THIS->here_input ());
1039 csm-> set_mus_property ("context-type", $2);
1041 | PROPERTY STRING '.' STRING SET embedded_scm '=' embedded_scm {
1042 Music *t = new Music (SCM_EOL);
1043 t->set_mus_property ("iterator-ctor",
1044 Push_property_iterator::constructor_cxx_function);
1045 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1046 t->set_mus_property ("pop-first", SCM_BOOL_T);
1047 t->set_mus_property ("grob-property", $6);
1048 t->set_mus_property ("grob-value", $8);
1049 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1050 csm->set_mus_property ("element", t->self_scm ());
1051 scm_gc_unprotect_object (t->self_scm ());
1053 $$->set_spot (THIS->here_input ());
1055 csm-> set_mus_property ("context-type", $2);
1057 | PROPERTY STRING '.' STRING OVERRIDE embedded_scm '=' embedded_scm {
1058 Music *t = new Music (SCM_EOL);
1059 t->set_mus_property ("iterator-ctor",
1060 Push_property_iterator::constructor_cxx_function);
1061 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1062 t->set_mus_property ("grob-property", $6);
1063 t->set_mus_property ("grob-value", $8);
1064 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1065 csm->set_mus_property ("element", t->self_scm ());
1066 scm_gc_unprotect_object (t->self_scm ());
1069 $$->set_spot (THIS->here_input ());
1071 csm-> set_mus_property ("context-type", $2);
1073 | PROPERTY STRING '.' STRING REVERT embedded_scm {
1074 Music *t = new Music (SCM_EOL);
1075 t->set_mus_property ("iterator-ctor",
1076 Pop_property_iterator::constructor_cxx_function);
1077 t->set_mus_property ("symbols", scm_string_to_symbol ($4));
1078 t->set_mus_property ("grob-property", $6);
1080 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1081 csm->set_mus_property ("element", t->self_scm ());
1082 scm_gc_unprotect_object (t->self_scm ());
1085 $$->set_spot (THIS->here_input ());
1087 csm-> set_mus_property ("context-type", $2);
1093 | bare_int { $$ = gh_int2scm ($1); }
1094 | embedded_scm { $$ = $1; }
1101 } /*cont */ simple_element post_requests {
1102 Music_sequence *l = dynamic_cast<Music_sequence*> ($3);
1104 for (int i=0; i < $1->size (); i++)
1105 l->append_music ($1->elem (i));
1106 for (int i=0; i < $4->size (); i++)
1107 l->append_music ($4->elem (i));
1110 programming_error ("Need Sequence to add music to");
1118 $$ = new Request_chord (SCM_EOL);
1119 $$->set_mus_property ("elements", gh_cons ($1->self_scm (), SCM_EOL));
1120 $$-> set_spot (THIS->here_input ());
1121 $1-> set_spot (THIS->here_input ());
1124 Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
1126 Context_specced_music *csm = new Context_specced_music (SCM_EOL);
1127 csm->set_mus_property ("element", t->self_scm ());
1128 scm_gc_unprotect_object (t->self_scm ());
1131 $$->set_spot (THIS->here_input ());
1133 csm->set_mus_property ("context-type", ly_str02scm ("Score"));
1135 | PARTIAL duration_length {
1136 Moment m = - unsmob_duration ($2)->length_mom ();
1137 Music * p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
1139 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1140 sp->set_mus_property ("element", p->self_scm ());
1141 scm_gc_unprotect_object (p->self_scm ());
1144 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1147 SCM func = scm_primitive_eval (ly_symbol2scm ("clef-name-to-properties"));
1148 SCM result = gh_call1 (func, $2);
1151 for (SCM s = result ; gh_pair_p (s); s = ly_cdr (s)) {
1152 Music * p = new Music (SCM_EOL);
1153 set_music_properties (p, ly_car (s));
1154 l = gh_cons (p->self_scm (), l);
1155 scm_gc_unprotect_object (p->self_scm ());
1157 Sequential_music * seq = new Sequential_music (SCM_EOL);
1158 seq->set_mus_property ("elements", l);
1160 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1161 sp->set_mus_property ("element", seq->self_scm ());
1162 scm_gc_unprotect_object (seq->self_scm ());
1165 sp-> set_mus_property ("context-type", ly_str02scm ("Staff"));
1168 Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2);
1170 int l = gh_scm2int (ly_car ($2));
1171 int o = gh_scm2int (ly_cdr ($2));
1173 Moment one_beat = Moment (1)/Moment (o);
1174 Moment len = Moment (l) * one_beat;
1177 Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ());
1178 Music *p3 = set_property_music (ly_symbol2scm ("beatLength"), one_beat.smobbed_copy ());
1180 SCM list = scm_list_n (p1->self_scm (), p2->self_scm (), p3->self_scm(), SCM_UNDEFINED);
1181 Sequential_music *seq = new Sequential_music (SCM_EOL);
1182 seq->set_mus_property ("elements", list);
1185 Context_specced_music * sp = new Context_specced_music (SCM_EOL);
1186 sp->set_mus_property ("element", seq->self_scm ());
1190 scm_gc_unprotect_object (p3->self_scm ());
1191 scm_gc_unprotect_object (p2->self_scm ());
1192 scm_gc_unprotect_object (p1->self_scm ());
1193 scm_gc_unprotect_object (seq->self_scm ());
1198 TODO: should make alias TimingContext for Score
1201 sp-> set_mus_property ("context-type", ly_str02scm ( "Score"));
1206 shorthand_command_req { $$ = $1; }
1207 | verbose_command_req { $$ = $1; }
1210 shorthand_command_req:
1218 $$ = new Barcheck_req;
1224 Span_req*b= new Span_req;
1225 b->set_span_dir (START);
1226 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1230 Span_req*b= new Span_req;
1231 b->set_span_dir ( STOP);
1232 b->set_mus_property ("span-type", ly_str02scm ("beam"));
1236 $$ = new Breathing_sign_req;
1239 $$ = new Porrectus_req;
1243 verbose_command_req:
1244 COMMANDSPANREQUEST bare_int STRING { /*TODO: junkme */
1245 Span_req * sp_p = new Span_req;
1246 sp_p-> set_span_dir ( Direction ($2));
1247 sp_p->set_mus_property ("span-type",$3);
1248 sp_p->set_spot (THIS->here_input ());
1252 Mark_req * m = new Mark_req;
1256 Mark_req *m = new Mark_req;
1257 m->set_mus_property ("label", $2);
1264 Break_req * b = new Break_req;
1266 if (!gh_number_p (s))
1269 b->set_mus_property ("penalty", s);
1270 b->set_spot (THIS->here_input ());
1273 | SKIP duration_length {
1274 Skip_req * skip_p = new Skip_req;
1275 skip_p->set_mus_property ("duration", $2);
1283 Key_change_req *key_p= new Key_change_req;
1286 | KEY NOTENAME_PITCH SCM_IDENTIFIER {
1287 Key_change_req *key_p= new Key_change_req;
1289 key_p->set_mus_property ("pitch-alist", $3);
1290 ((Music* )key_p)->transpose (* unsmob_pitch ($2));
1297 $$ = new Link_array<Request>;
1299 | post_requests post_request {
1300 $2->set_spot (THIS->here_input ());
1312 request_that_take_dir:
1315 | script_abbreviation {
1316 SCM s = THIS->lexer_p_->lookup_identifier ("dash" + ly_scm2string ($1));
1317 Articulation_req *a = new Articulation_req;
1318 if (gh_string_p (s))
1319 a->set_mus_property ("articulation-type", s);
1320 else THIS->parser_error (_ ("Expecting string as script definition"));
1326 script_dir request_that_take_dir {
1327 if (Script_req * gs = dynamic_cast<Script_req*> ($2))
1328 gs->set_direction (Direction ($1));
1330 $2->origin ()->warning (_ ("Can't specify direction for this request"));
1336 REQUEST_IDENTIFIER {
1337 $$ = dynamic_cast<Request*> (unsmob_music ($1)->clone ());
1338 $$->set_spot (THIS->here_input ());
1340 | DYNAMICSCRIPT embedded_scm {
1342 TODO: junkme, use text-type == dynamic
1344 Text_script_req *d = new Text_script_req;
1345 d->set_mus_property ("text-type" , ly_symbol2scm ("dynamic"));
1346 d->set_mus_property ("text", $2);
1347 d->set_spot (THIS->here_input ());
1350 | SPANREQUEST bare_int STRING {
1351 Span_req * sp_p = new Span_req;
1352 sp_p->set_span_dir ( Direction ($2));
1353 sp_p->set_mus_property ("span-type", $3);
1354 sp_p->set_spot (THIS->here_input ());
1358 Tremolo_req* a = new Tremolo_req;
1359 a->set_spot (THIS->here_input ());
1360 a->set_mus_property ("tremolo-type", gh_int2scm ($1));
1364 Articulation_req * a = new Articulation_req;
1365 a->set_mus_property ("articulation-type", $2);
1366 a->set_spot (THIS->here_input ());
1370 duh, junk this syntax from the parser, if possible.
1373 Arpeggio_req *a = new Arpeggio_req;
1374 a->set_spot (THIS->here_input ());
1378 Glissando_req *g = new Glissando_req;
1379 g->set_spot /* No pun intended */ (THIS->here_input ());
1406 | NOTENAME_PITCH sup_quotes {
1407 Pitch p = *unsmob_pitch ($1);
1409 $$ = p.smobbed_copy ();
1411 | NOTENAME_PITCH sub_quotes {
1412 Pitch p =* unsmob_pitch ($1);
1415 $$ = p.smobbed_copy ();
1428 | TONICNAME_PITCH sup_quotes {
1429 Pitch p = *unsmob_pitch ($1);
1431 $$ = p.smobbed_copy ();
1433 | TONICNAME_PITCH sub_quotes {
1434 Pitch p =* unsmob_pitch ($1);
1437 $$ = p.smobbed_copy ();
1452 PITCH embedded_scm {
1454 if (!unsmob_pitch ($2)) {
1455 THIS->parser_error (_f ("Expecting musical-pitch value", 3));
1456 $$ = Pitch ().smobbed_copy ();
1462 DURATION embedded_scm {
1464 if (!unsmob_duration ($2))
1466 THIS->parser_error (_ ("Must have duration object"));
1467 $$ = Duration ().smobbed_copy ();
1474 if (!THIS->lexer_p_->lyric_state_b ())
1475 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1476 $$ = new Extender_req;
1482 if (!THIS->lexer_p_->lyric_state_b ())
1483 THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
1484 $$ = new Hyphen_req;
1489 close_request_parens {
1491 dynamic_cast<Span_req*> ($$)->set_span_dir ( START);
1494 close_request_parens:
1496 Span_req* s= new Span_req;
1498 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1501 Span_req* s= new Span_req;
1503 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1506 Span_req*s =new Span_req;
1508 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1511 Span_req*s =new Span_req;
1513 s->set_mus_property ("span-type", ly_str02scm ("decrescendo"));
1519 open_request_parens {
1521 dynamic_cast<Span_req*> ($$)->set_span_dir (STOP);
1525 open_request_parens:
1527 Span_req *s = new Span_req;
1528 s->set_mus_property ("span-type", ly_str02scm ( "crescendo"));
1533 Span_req* s= new Span_req;
1535 s->set_mus_property ("span-type", ly_str02scm ( "slur"));
1538 Span_req* s= new Span_req;
1540 s->set_mus_property ("span-type", ly_str02scm ( "phrasing-slur"));
1546 Text_script_req *t = new Text_script_req;
1547 t->set_mus_property ("text", $1);
1548 t->set_spot (THIS->here_input ());
1552 Text_script_req *t = new Text_script_req;
1553 t->set_mus_property ("text", $1);
1554 t->set_spot (THIS->here_input ());
1558 String ds = to_str ($1);
1559 Text_script_req* t = new Text_script_req;
1561 t->set_mus_property ("text", ly_str02scm (ds.ch_C ()));
1562 t->set_mus_property ("text-type" , ly_symbol2scm ("finger"));
1563 t->set_spot (THIS->here_input ());
1568 script_abbreviation:
1570 $$ = gh_str02scm ("Hat");
1573 $$ = gh_str02scm ("Plus");
1576 $$ = gh_str02scm ("Dash");
1579 $$ = gh_str02scm ("Bar");
1582 $$ = gh_str02scm ("Larger");
1585 $$ = gh_str02scm ("Dot");
1593 | '-' { $$ = CENTER; }
1598 $$ = new Link_array<Request>;
1600 | pre_requests open_request {
1612 multiplied_duration {
1615 | explicit_duration {
1620 optional_notemode_duration:
1622 $$ = THIS->default_duration_.smobbed_copy ();
1624 | multiplied_duration {
1627 | explicit_duration {
1633 bare_unsigned dots {
1635 if (!is_duration_b ($1))
1636 THIS->parser_error (_f ("not a duration: %d", $1));
1640 $$ = Duration (l, $2).smobbed_copy ();
1642 THIS->set_last_duration (unsmob_duration ($$));
1644 | DURATION_IDENTIFIER dots {
1645 Duration *d =unsmob_duration ($1);
1646 Duration k (d->duration_log (),d->dot_count () + $2);
1647 $$ = k.smobbed_copy ();
1649 THIS->set_last_duration (unsmob_duration ($$));
1656 multiplied_duration:
1660 | multiplied_duration '*' bare_unsigned {
1661 $$ = unsmob_duration ($$)->compressed ( $3) .smobbed_copy ();
1663 | multiplied_duration '*' FRACTION {
1664 Rational m (gh_scm2int (ly_car ($3)), gh_scm2int (ly_cdr ($3)));
1666 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
1671 FRACTION { $$ = $1; }
1672 | UNSIGNED '/' UNSIGNED {
1673 $$ = gh_cons (gh_int2scm ($1), gh_int2scm ($3));
1691 | ':' bare_unsigned {
1692 if (!is_duration_b ($2))
1693 THIS->parser_error (_f ("not a duration: %d", $2));
1713 p .notename_i_ = $1 - 1;
1716 Note_req * nr = new Note_req;
1717 $$ = nr->self_scm ();
1718 nr->set_mus_property ("pitch", p.smobbed_copy ());
1719 scm_gc_unprotect_object ($$);
1721 | bass_figure bass_mod {
1723 SCM sp = unsmob_music ($1)->get_mus_property ("pitch");
1724 unsmob_pitch (sp)->alteration_i_ += $2;
1726 unsmob_music ($1)->set_mus_property ("force-accidental", SCM_BOOL_T);
1735 | figure_list bass_figure {
1736 $$ = gh_cons ($2, $1);
1741 FIGURE_OPEN figure_list FIGURE_CLOSE {
1742 Music * m = new Request_chord (SCM_EOL);
1743 $2 = scm_reverse_x ($2, SCM_EOL);
1744 m->set_mus_property ("elements", $2);
1745 $$ = m->self_scm ();
1750 pitch exclamations questions optional_notemode_duration {
1752 Input i = THIS->pop_spot ();
1753 if (!THIS->lexer_p_->note_state_b ())
1754 THIS->parser_error (_ ("Have to be in Note mode for notes"));
1756 Note_req *n = new Note_req;
1758 n->set_mus_property ("pitch", $1);
1759 n->set_mus_property ("duration", $4);
1762 n->set_mus_property ("cautionary", SCM_BOOL_T);
1763 if ($2 % 2 || $3 % 2)
1764 n->set_mus_property ("force-accidental", SCM_BOOL_T);
1766 Simultaneous_music*v = new Request_chord (SCM_EOL);
1767 v->set_mus_property ("elements", scm_list_n (n->self_scm (), SCM_UNDEFINED));
1773 | figure_spec optional_notemode_duration {
1774 Music * m = unsmob_music ($1);
1775 Input i = THIS->pop_spot ();
1777 for (SCM s = m->get_mus_property ("elements"); gh_pair_p (s); s = ly_cdr (s))
1779 unsmob_music (ly_car (s))->set_mus_property ("duration", $2);
1783 | RESTNAME optional_notemode_duration {
1785 Input i = THIS->pop_spot ();
1786 SCM e = SCM_UNDEFINED;
1787 if (ly_scm2string ($1) =="s") {
1789 Skip_req * skip_p = new Skip_req;
1790 skip_p->set_mus_property ("duration" ,$2);
1791 skip_p->set_spot (i);
1792 e = skip_p->self_scm ();
1795 Rest_req * rest_req_p = new Rest_req;
1796 rest_req_p->set_mus_property ("duration", $2);
1797 rest_req_p->set_spot (i);
1798 e = rest_req_p->self_scm ();
1800 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1801 velt_p-> set_mus_property ("elements", scm_list_n (e,SCM_UNDEFINED));
1802 velt_p->set_spot (i);
1806 | MULTI_MEASURE_REST optional_notemode_duration {
1807 Input i = THIS->pop_spot ();
1809 Skip_req * sk = new Skip_req;
1810 sk->set_mus_property ("duration", $2);
1811 Span_req *sp1 = new Span_req;
1812 Span_req *sp2 = new Span_req;
1813 sp1-> set_span_dir ( START);
1814 sp2-> set_span_dir ( STOP);
1815 SCM r = ly_str02scm ("rest");
1816 sp1->set_mus_property ("span-type", r);
1817 sp2->set_mus_property ("span-type", r);
1819 Request_chord * rqc1 = new Request_chord (SCM_EOL);
1820 rqc1->set_mus_property ("elements", scm_list_n (sp1->self_scm (), SCM_UNDEFINED));
1821 Request_chord * rqc2 = new Request_chord (SCM_EOL);
1822 rqc2->set_mus_property ("elements", scm_list_n (sk->self_scm (), SCM_UNDEFINED));;
1823 Request_chord * rqc3 = new Request_chord (SCM_EOL);
1824 rqc3->set_mus_property ("elements", scm_list_n (sp2->self_scm (), SCM_UNDEFINED));;
1826 SCM ms = scm_list_n (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED);
1828 $$ = new Sequential_music (SCM_EOL);
1829 $$->set_mus_property ("elements", ms);
1831 | STRING optional_notemode_duration {
1832 Input i = THIS->pop_spot ();
1834 Lyric_req* lreq_p = new Lyric_req;
1835 lreq_p->set_mus_property ("text", $1);
1836 lreq_p->set_mus_property ("duration",$2);
1837 lreq_p->set_spot (i);
1838 Simultaneous_music* velt_p = new Request_chord (SCM_EOL);
1839 velt_p->set_mus_property ("elements", scm_list_n (lreq_p->self_scm (), SCM_UNDEFINED));
1844 Input i = THIS->pop_spot ();
1846 if (!THIS->lexer_p_->chord_state_b ())
1847 THIS->parser_error (_ ("Have to be in Chord mode for chords"));
1854 steno_tonic_pitch optional_notemode_duration chord_additions chord_subtractions chord_inversion chord_bass {
1855 $$ = Chord::get_chord ($1, $3, $4, $5, $6, $2);
1856 $$->set_spot (THIS->here_input ());
1863 | CHORD_COLON chord_notes {
1872 | chord_notes '.' chord_step {
1873 $$ = gh_append2 ($$, $3);
1881 | CHORD_CARET chord_notes {
1891 | '/' steno_tonic_pitch {
1900 | CHORD_BASS steno_tonic_pitch {
1907 $$ = gh_cons ($1, SCM_EOL);
1909 | CHORDMODIFIER_PITCH {
1910 $$ = gh_cons (unsmob_pitch ($1)->smobbed_copy (), SCM_EOL);
1912 | CHORDMODIFIER_PITCH chord_note { /* Ugh. */
1913 $$ = scm_list_n (unsmob_pitch ($1)->smobbed_copy (),
1921 m.notename_i_ = ($1 - 1) % 7;
1922 m.octave_i_ = $1 > 7 ? 1 : 0;
1923 m.alteration_i_ = 0;
1925 $$ = m.smobbed_copy ();
1927 | bare_unsigned '+' {
1929 m.notename_i_ = ($1 - 1) % 7;
1930 m.octave_i_ = $1 > 7 ? 1 : 0;
1931 m.alteration_i_ = 1;
1934 $$ = m.smobbed_copy ();
1936 | bare_unsigned CHORD_MINUS {
1938 m.notename_i_ = ($1 - 1) % 7;
1939 m.octave_i_ = $1 > 7 ? 1 : 0;
1940 m.alteration_i_ = -1;
1942 $$ = m.smobbed_copy ();
1950 number_expression '+' number_term {
1951 $$ = scm_sum ($1, $3);
1953 | number_expression '-' number_term {
1954 $$ = scm_difference ($1, $3);
1963 | number_factor '*' number_factor {
1964 $$ = scm_product ($1, $3);
1966 | number_factor '/' number_factor {
1967 $$ = scm_divide ($1, $3);
1972 '(' number_expression ')' {
1975 | '-' number_factor { /* %prec UNARY_MINUS */
1976 $$ = scm_difference ($2, SCM_UNDEFINED);
1984 $$ = gh_int2scm ($1);
1989 | NUMBER_IDENTIFIER {
1993 $$ = gh_double2scm (gh_scm2double ($1) CM );
1996 $$ = gh_double2scm (gh_scm2double ($1) PT);
1999 $$ = gh_double2scm (gh_scm2double ($1) INCH);
2002 $$ = gh_double2scm (gh_scm2double ($1) MM);
2005 $$ = gh_double2scm (gh_scm2double ($1) CHAR);
2021 if (scm_integer_p ($1) == SCM_BOOL_T)
2023 int k = gh_scm2int ($1);
2027 THIS->parser_error (_ ("need integer number arg"));
2041 | STRING_IDENTIFIER {
2044 | string '+' string {
2045 $$ = scm_string_append (scm_list_n ($1, $3, SCM_UNDEFINED));
2052 | exclamations '!' { $$ ++; }
2057 | questions '?' { $$ ++; }
2064 My_lily_parser::set_yydebug (bool b)
2071 extern My_lily_parser * current_parser;
2074 My_lily_parser::do_yyparse ()
2077 current_parser = this;;
2078 yyparse ((void*)this);