1 /* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: t -*- */
3 This file is part of LilyPond, the GNU music typesetter.
5 Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 Jan Nieuwenhuizen <janneke@gnu.org>
8 LilyPond is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 LilyPond is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
22 /* Mode and indentation are at best a rough approximation based on TAB
23 * formatting (reasonable for compatibility with unspecific editor
24 * modes as Bison modes are hard to find) and need manual correction
25 * frequently. Without a reasonably dependable way of formatting a
26 * Bison file sensibly, there is little point in trying to fix the
27 * inconsistent state of indentation.
32 #define yyerror Lily_parser::parser_error
34 /* We use custom location type: Input objects */
37 #define YYLLOC_DEFAULT(Current,Rhs,N) \
38 ((Current).set_location ((Rhs)[1], (Rhs)[N]))
40 #define YYPRINT(file, type, value) \
42 if (scm_is_eq (value, SCM_UNSPECIFIED)) \
44 SCM s = Display::value_to_lily_string (value); \
45 char *p = scm_to_locale_string (s); \
52 %parse-param {Lily_parser *parser}
53 %parse-param {SCM *retval}
54 %lex-param {Lily_parser *parser}
58 /* We use SCMs to do strings, because it saves us the trouble of
59 deleting them. Let's hope that a stack overflow doesn't trigger a move
60 of the parse stack onto the heap. */
66 /* The above precedences tackle the shift/reduce problem
69 \repeat .. \alternative
71 \repeat { \repeat .. \alternative }
75 \repeat { \repeat } \alternative
81 %right ':' UNSIGNED REAL E_UNSIGNED EVENT_IDENTIFIER EVENT_FUNCTION '^' '_'
82 HYPHEN EXTENDER DURATION_IDENTIFIER '!'
84 /* The above are needed for collecting tremoli and other items (that
85 could otherwise be interpreted as belonging to the next function
86 argument) greedily, and together with the next rule will serve to
87 join numbers and units greedily instead of allowing them into
88 separate function arguments
91 %nonassoc NUMBER_IDENTIFIER
103 %{ // -*-Fundamental-*-
108 * The rules for who is protecting what are very shady. Uniformise
111 * There are too many lexical modes?
122 #include "context.hh"
123 #include "context-def.hh"
124 #include "context-mod.hh"
125 #include "dimensions.hh"
126 #include "file-path.hh"
128 #include "international.hh"
129 #include "lily-guile.hh"
130 #include "lily-lexer.hh"
131 #include "lily-parser.hh"
132 #include "ly-module.hh"
136 #include "output-def.hh"
137 #include "paper-book.hh"
138 #include "scm-hash.hh"
140 #include "text-interface.hh"
142 #include "lily-imports.hh"
145 Lily_parser::parser_error (Input const *i, Lily_parser *parser, SCM *, const string &s)
147 parser->parser_error (*i, s);
150 // The following are somewhat precarious constructs as they may change
151 // the value of the lookahead token. That implies that the lookahead
152 // token must not yet have made an impact on the state stack other
153 // than causing the reduction of the current rule, or switching the
154 // lookahead token while Bison is mulling it over will cause trouble.
156 #define MYBACKUP(Token, Value, Location) \
158 if (yychar != YYEMPTY) \
159 parser->lexer_->push_extra_token \
160 (yylloc, yychar, yylval); \
162 parser->lexer_->push_extra_token \
163 (Location, Token, Value); \
164 parser->lexer_->push_extra_token (Location, BACKUP); \
169 #define MYREPARSE(Location, Pred, Token, Value) \
171 if (yychar != YYEMPTY) \
172 parser->lexer_->push_extra_token \
173 (yylloc, yychar, yylval); \
174 parser->lexer_->push_extra_token \
175 (Location, Token, Value); \
176 parser->lexer_->push_extra_token \
177 (Location, REPARSE, Pred); \
186 #define MY_MAKE_MUSIC(x, spot) \
187 make_music_with_input (ly_symbol2scm (x), \
188 parser->lexer_->override_input (spot))
191 - delay application of the function
194 #define LOWLEVEL_MAKE_SYNTAX(location, proc, ...) \
196 (parser->lexer_->override_input (location).smobbed_copy (), \
200 /* Syntactic Sugar. */
201 #define MAKE_SYNTAX(name, location, ...) \
202 LOWLEVEL_MAKE_SYNTAX (location, Syntax::name, ##__VA_ARGS__)
204 #define START_MAKE_SYNTAX(name, ...) \
205 scm_list_n (Syntax::name, ##__VA_ARGS__, SCM_UNDEFINED)
207 #define FINISH_MAKE_SYNTAX(start, location, ...) \
208 LOWLEVEL_MAKE_SYNTAX \
213 (scm_list_2 (scm_cdr (start), \
214 scm_list_n (__VA_ARGS__, SCM_UNDEFINED))))
216 SCM get_next_unique_context_id ();
217 SCM get_next_unique_lyrics_context_id ();
224 #define _(x) gettext (x)
228 static Music *make_music_with_input (SCM name, Input where);
229 SCM check_scheme_arg (Lily_parser *parser, Input loc,
230 SCM arg, SCM args, SCM pred, SCM disp = SCM_UNDEFINED);
231 SCM make_music_from_simple (Lily_parser *parser, Input loc, SCM pitch);
232 SCM loc_on_music (Lily_parser *parser, Input loc, SCM arg);
233 SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list);
234 SCM make_chord_step (SCM step, Rational alter);
235 SCM make_simple_markup (SCM a);
236 SCM make_duration (SCM t, int dots = 0, SCM factor = SCM_UNDEFINED);
237 bool is_regular_identifier (SCM id, bool multiple=false);
238 SCM try_string_variants (SCM pred, SCM str);
239 int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser);
243 /* The third option is an alias that will be used to display the
244 syntax error. Bison CVS now correctly handles backslash escapes.
246 FIXME: Bison needs to translate some of these, eg, STRING.
250 /* Keyword tokens with plain escaped name. */
251 %token END_OF_FILE 0 "end of input"
252 %token ACCEPTS "\\accepts"
253 %token ADDLYRICS "\\addlyrics"
254 %token ALIAS "\\alias"
255 %token ALTERNATIVE "\\alternative"
257 %token BOOKPART "\\bookpart"
258 %token CHANGE "\\change"
259 %token CHORDMODE "\\chordmode"
260 %token CHORDS "\\chords"
261 %token CONSISTS "\\consists"
262 %token CONTEXT "\\context"
263 %token DEFAULT "\\default"
264 %token DEFAULTCHILD "\\defaultchild"
265 %token DENIES "\\denies"
266 %token DESCRIPTION "\\description"
267 %token DRUMMODE "\\drummode"
268 %token DRUMS "\\drums"
270 %token FIGUREMODE "\\figuremode"
271 %token FIGURES "\\figures"
272 %token HEADER "\\header"
273 %token INVALID "\\version-error"
274 %token LAYOUT "\\layout"
275 %token LYRICMODE "\\lyricmode"
276 %token LYRICS "\\lyrics"
277 %token LYRICSTO "\\lyricsto"
278 %token MARKUP "\\markup"
279 %token MARKUPLIST "\\markuplist"
282 %token NOTEMODE "\\notemode"
283 %token OVERRIDE "\\override"
284 %token PAPER "\\paper"
285 %token REMOVE "\\remove"
286 %token REPEAT "\\repeat"
288 %token REVERT "\\revert"
289 %token SCORE "\\score"
290 %token SCORELINES "\\score-lines"
291 %token SEQUENTIAL "\\sequential"
293 %token SIMULTANEOUS "\\simultaneous"
294 %token TEMPO "\\tempo"
296 %token UNSET "\\unset"
299 /* Keyword token exceptions. */
300 %token NEWCONTEXT "\\new"
303 /* Other string tokens. */
305 %token CHORD_BASS "/+"
306 %token CHORD_CARET "^"
307 %token CHORD_COLON ":"
308 %token CHORD_MINUS "-"
309 %token CHORD_SLASH "/"
310 %token ANGLE_OPEN "<"
311 %token ANGLE_CLOSE ">"
312 %token DOUBLE_ANGLE_OPEN "<<"
313 %token DOUBLE_ANGLE_CLOSE ">>"
314 %token E_BACKSLASH "\\"
315 %token E_EXCLAMATION "\\!"
320 If we give names, Bison complains.
322 %token FIGURE_CLOSE /* "\\>" */
323 %token FIGURE_OPEN /* "\\<" */
324 %token FIGURE_SPACE "_"
327 %token MULTI_MEASURE_REST
333 /* Artificial tokens, for more generic function syntax */
334 %token EXPECT_MARKUP "markup?"
335 %token EXPECT_SCM "scheme?"
336 %token BACKUP "(backed-up?)"
337 %token REPARSE "(reparsed?)"
338 %token EXPECT_MARKUP_LIST "markup-list?"
339 %token EXPECT_OPTIONAL "optional?"
340 /* After the last argument. */
341 %token EXPECT_NO_MORE_ARGS;
343 /* An artificial token for parsing embedded Lilypond */
344 %token EMBEDDED_LILY "#{"
346 %token BOOK_IDENTIFIER
347 %token CHORD_MODIFIER
348 %token CHORD_REPETITION
349 %token CONTEXT_MOD_IDENTIFIER
351 /* Artificial token for durations in argument lists */
353 %token DURATION_IDENTIFIER
354 %token EVENT_IDENTIFIER
355 %token EVENT_FUNCTION
357 %token LOOKUP_IDENTIFIER
359 %token MARKUP_FUNCTION
360 %token MARKUP_LIST_FUNCTION
361 %token MARKUP_IDENTIFIER
362 %token MARKUPLIST_IDENTIFIER
363 %token MUSIC_FUNCTION
364 %token MUSIC_IDENTIFIER
365 %token NOTENAME_PITCH
366 %token NUMBER_IDENTIFIER
367 %token PITCH_IDENTIFIER
372 %token SCM_IDENTIFIER
376 %token TONICNAME_PITCH
380 /* We don't assign precedence to / and *, because we might need varied
381 prec levels in different prods */
390 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
391 parser->lexer_->push_note_state (nn);
392 } embedded_lilypond {
393 parser->lexer_->pop_state ();
398 lilypond: /* empty */ { $$ = SCM_UNSPECIFIED; }
399 | lilypond toplevel_expression {
401 | lilypond assignment {
404 parser->error_level_ = 1;
407 parser->error_level_ = 1;
414 parser->lexer_->add_scope (get_header (parser));
416 parser->lexer_->set_identifier (ly_symbol2scm ("$defaultheader"), $2);
419 SCM proc = parser->lexer_->lookup_identifier ("toplevel-book-handler");
420 scm_call_1 (proc, $1);
423 SCM proc = parser->lexer_->lookup_identifier ("toplevel-bookpart-handler");
424 scm_call_1 (proc, $1);
427 SCM proc = parser->lexer_->lookup_identifier
428 (unsmob<Book>($1)->paper_
429 ? "toplevel-book-handler"
430 : "toplevel-bookpart-handler");
431 scm_call_1 (proc, $1);
434 SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
435 scm_call_1 (proc, $1);
438 SCM proc = parser->lexer_->lookup_identifier ("toplevel-music-handler");
439 scm_call_1 (proc, $1);
442 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
443 scm_call_1 (proc, scm_list_1 ($1));
446 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
447 scm_call_1 (proc, $1);
450 // Evaluate and ignore #xxx, as opposed to \xxx
451 parser->lexer_->eval_scm_token ($1, @1);
453 | embedded_scm_active
455 SCM out = SCM_UNDEFINED;
456 if (Text_interface::is_markup ($1))
457 out = scm_list_1 ($1);
458 else if (Text_interface::is_markup_list ($1))
460 if (scm_is_pair (out))
462 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
463 scm_call_1 (proc, out);
464 } else if (unsmob<Score> ($1))
466 SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
467 scm_call_1 (proc, $1);
468 } else if (Output_def * od = unsmob<Output_def> ($1)) {
471 if (to_boolean (od->c_variable ("is-paper")))
472 id = ly_symbol2scm ("$defaultpaper");
473 else if (to_boolean (od->c_variable ("is-midi")))
474 id = ly_symbol2scm ("$defaultmidi");
475 else if (to_boolean (od->c_variable ("is-layout")))
476 id = ly_symbol2scm ("$defaultlayout");
478 parser->lexer_->set_identifier (id, $1);
479 } else if (!scm_is_eq ($1, SCM_UNSPECIFIED))
480 parser->parser_error (@1, _("bad expression type"));
484 Output_def * od = unsmob<Output_def> ($1);
486 if (to_boolean (od->c_variable ("is-paper")))
487 id = ly_symbol2scm ("$defaultpaper");
488 else if (to_boolean (od->c_variable ("is-midi")))
489 id = ly_symbol2scm ("$defaultmidi");
490 else if (to_boolean (od->c_variable ("is-layout")))
491 id = ly_symbol2scm ("$defaultlayout");
493 parser->lexer_->set_identifier (id, $1);
499 | LOOKUP_IDENTIFIER '.' symbol_list_rev
501 $$ = loc_on_music (parser, @$,
502 nested_property ($1, scm_reverse_x ($3, SCM_EOL)));
509 $$ = parser->lexer_->eval_scm_token ($1, @1);
520 embedded_scm_bare_arg:
524 $$ = parser->lexer_->eval_scm_token ($1, @1);
529 | context_modification
531 | context_def_spec_block
538 /* The generic version may end in music, or not */
546 /* embedded_scm_arg is _not_ casting pitches to music by default, this
547 * has to be done by the function itself. Note that this may cause
548 * the results of scm_function_call or embedded_scm_bare_arg to be
549 * turned into music from pitches as well. Note that this creates a
550 * distinctly awkward situation for calculated drum pitches. Those
551 * are at the current point of time rejected as music constituents as
552 * they can't be distinguished from "proper" symbols.
556 embedded_scm_bare_arg
562 SCM_FUNCTION function_arglist {
563 $$ = MAKE_SYNTAX (music_function, @$,
568 embedded_lilypond_number:
569 '-' embedded_lilypond_number
571 $$ = scm_difference ($2, SCM_UNDEFINED);
574 | UNSIGNED NUMBER_IDENTIFIER
576 $$ = scm_product ($1, $2);
583 // FIXME: @$ does not contain a useful source location
584 // for empty rules, and the only token in the whole
585 // production, EMBEDDED_LILY, is synthetic and also
586 // contains no source location.
587 $$ = MAKE_SYNTAX (void_music, @$);
589 | identifier_init_nonumber
590 | embedded_lilypond_number
591 | post_event post_events
593 $$ = scm_reverse_x ($2, SCM_EOL);
594 if (Music *m = unsmob<Music> ($1))
596 if (m->is_mus_type ("post-event-wrapper"))
598 (scm_list_2 (m->get_property ("elements"),
601 $$ = scm_cons ($1, $$);
604 && scm_is_null (scm_cdr ($$)))
608 Music * m = MY_MAKE_MUSIC ("PostEvents", @$);
609 m->set_property ("elements", $$);
610 $$ = m->unprotect ();
613 | multiplied_duration
614 | music_embedded music_embedded music_list {
615 $3 = scm_reverse_x ($3, SCM_EOL);
616 if (unsmob<Music> ($2))
617 $3 = scm_cons ($2, $3);
618 if (unsmob<Music> ($1))
619 $3 = scm_cons ($1, $3);
620 $$ = MAKE_SYNTAX (sequential_music, @$, $3);
623 parser->error_level_ = 1;
624 $$ = SCM_UNSPECIFIED;
626 | INVALID embedded_lilypond {
627 parser->error_level_ = 1;
633 lilypond_header_body:
634 /* empty */ { $$ = SCM_UNSPECIFIED; }
635 | lilypond_header_body assignment {
638 | lilypond_header_body embedded_scm {
644 HEADER '{' lilypond_header_body '}' {
645 $$ = parser->lexer_->remove_scope ();
657 assignment_id '=' identifier_init {
658 parser->lexer_->set_identifier ($1, $3);
659 $$ = SCM_UNSPECIFIED;
661 | assignment_id '.' property_path '=' identifier_init {
662 SCM path = scm_cons (scm_string_to_symbol ($1), $3);
663 parser->lexer_->set_identifier (path, $5);
664 $$ = SCM_UNSPECIFIED;
666 | assignment_id ',' property_path '=' identifier_init {
667 SCM path = scm_cons (scm_string_to_symbol ($1), $3);
668 parser->lexer_->set_identifier (path, $5);
669 $$ = SCM_UNSPECIFIED;
675 identifier_init_nonumber
677 | symbol_list_part_bare '.' property_path
679 $$ = scm_reverse_x ($1, $3);
681 | symbol_list_part_bare ',' property_path
683 $$ = scm_reverse_x ($1, $3);
685 | post_event_nofinger post_events
687 $$ = scm_reverse_x ($2, SCM_EOL);
688 if (Music *m = unsmob<Music> ($1))
690 if (m->is_mus_type ("post-event-wrapper"))
692 (scm_list_2 (m->get_property ("elements"),
695 $$ = scm_cons ($1, $$);
698 && scm_is_null (scm_cdr ($$)))
702 Music * m = MY_MAKE_MUSIC ("PostEvents", @$);
703 m->set_property ("elements", $$);
704 $$ = m->unprotect ();
709 identifier_init_nonumber:
714 | context_def_spec_block
722 | context_modification
723 | partial_function ETC
725 $$ = MAKE_SYNTAX (partial_music_function, @$,
726 scm_reverse_x ($1, SCM_EOL));
732 MUSIC_FUNCTION function_arglist_partial
734 $$ = scm_acons ($1, $2, SCM_EOL);
736 | EVENT_FUNCTION function_arglist_partial
738 $$ = scm_acons ($1, $2, SCM_EOL);
740 | SCM_FUNCTION function_arglist_partial
742 $$ = scm_acons ($1, $2, SCM_EOL);
744 | OVERRIDE grob_prop_path '='
747 $$ = scm_list_1 (SCM_BOOL_F);
750 (scm_list_3 (Syntax::property_override_function,
751 scm_cdr ($2), scm_car ($2)),
754 | SET context_prop_spec '='
757 $$ = scm_list_1 (SCM_BOOL_F);
760 (scm_list_3 (Syntax::property_set_function,
761 scm_cadr ($2), scm_car ($2)),
764 | MUSIC_FUNCTION EXPECT_SCM function_arglist_optional partial_function
766 $$ = scm_acons ($1, $3, $4);
768 | EVENT_FUNCTION EXPECT_SCM function_arglist_optional partial_function
770 $$ = scm_acons ($1, $3, $4);
772 | SCM_FUNCTION EXPECT_SCM function_arglist_optional partial_function
774 $$ = scm_acons ($1, $3, $4);
776 | OVERRIDE grob_prop_path '=' partial_function
779 $$ = scm_list_1 (SCM_BOOL_F);
782 (scm_list_3 (Syntax::property_override_function,
783 scm_cdr ($2), scm_car ($2)),
786 | SET context_prop_spec '=' partial_function
789 $$ = scm_list_1 (SCM_BOOL_F);
792 (scm_list_3 (Syntax::property_set_function,
793 scm_cadr ($2), scm_car ($2)),
796 | MUSIC_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function
798 $$ = scm_acons ($1, $4, $5);
800 | EVENT_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function
802 $$ = scm_acons ($1, $4, $5);
804 | SCM_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function
806 $$ = scm_acons ($1, $4, $5);
810 context_def_spec_block:
811 CONTEXT '{' context_def_spec_body '}'
814 Context_def *td = unsmob<Context_def> ($$);
816 $$ = Context_def::make_scm ();
817 td = unsmob<Context_def> ($$);
819 td->origin ()->set_spot (@$);
827 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
828 parser->lexer_->push_note_state (nn);
832 parser->lexer_->pop_state ();
838 context_def_spec_body:
840 $$ = SCM_UNSPECIFIED;
842 | context_def_spec_body context_mod {
843 if (!SCM_UNBNDP ($2)) {
844 Context_def *td = unsmob<Context_def> ($$);
846 $$ = Context_def::make_scm ();
847 td = unsmob<Context_def> ($$);
849 unsmob<Context_def> ($$)->add_context_mod ($2);
852 | context_def_spec_body context_modification {
853 Context_def *td = unsmob<Context_def> ($$);
855 $$ = Context_def::make_scm ();
856 td = unsmob<Context_def> ($$);
858 SCM new_mods = unsmob<Context_mod> ($2)->get_mods ();
859 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
860 td->add_context_mod (scm_car (m));
863 | context_def_spec_body context_mod_arg {
864 Context_def *td = unsmob<Context_def> ($1);
865 if (scm_is_eq ($2, SCM_UNSPECIFIED))
867 else if (!td && unsmob<Context_def> ($2))
871 $$ = Context_def::make_scm ();
872 td = unsmob<Context_def> ($$);
874 if (unsmob<Music> ($2)) {
875 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
876 $2 = scm_call_1 (proc, $2);
878 if (Context_mod *cm = unsmob<Context_mod> ($2)) {
879 for (SCM m = cm->get_mods (); scm_is_pair (m); m = scm_cdr (m)) {
880 td->add_context_mod (scm_car (m));
883 parser->parser_error (@2, _ ("not a context mod"));
891 BOOK '{' book_body '}' {
893 unsmob<Book> ($$)->origin ()->set_spot (@$);
895 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), SCM_BOOL_F);
900 * Use 'handlers' like for toplevel-* stuff?
901 * grok \layout and \midi? */
904 Book *book = new Book;
905 init_papers (parser);
906 book->paper_ = dynamic_cast<Output_def*> (unsmob<Output_def> (parser->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
907 book->paper_->unprotect ();
908 push_paper (parser, book->paper_);
909 book->header_ = get_header (parser);
910 $$ = book->unprotect ();
911 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$);
914 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $1);
916 | book_body paper_block {
917 unsmob<Book> ($1)->paper_ = unsmob<Output_def> ($2);
918 set_paper (parser, unsmob<Output_def> ($2));
920 | book_body bookpart_block {
921 SCM proc = parser->lexer_->lookup_identifier ("book-bookpart-handler");
922 scm_call_2 (proc, $1, $2);
924 | book_body score_block {
925 SCM proc = parser->lexer_->lookup_identifier ("book-score-handler");
926 scm_call_2 (proc, $1, $2);
928 | book_body composite_music {
929 SCM proc = parser->lexer_->lookup_identifier ("book-music-handler");
930 scm_call_2 (proc, $1, $2);
932 | book_body full_markup {
933 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
934 scm_call_2 (proc, $1, scm_list_1 ($2));
936 | book_body full_markup_list {
937 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
938 scm_call_2 (proc, $1, $2);
940 | book_body SCM_TOKEN {
941 // Evaluate and ignore #xxx, as opposed to \xxx
942 parser->lexer_->eval_scm_token ($2, @2);
944 | book_body embedded_scm_active
946 SCM out = SCM_UNDEFINED;
947 if (Text_interface::is_markup ($2))
948 out = scm_list_1 ($2);
949 else if (Text_interface::is_markup_list ($2))
951 if (scm_is_pair (out))
953 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
954 scm_call_2 (proc, $1, out);
955 } else if (unsmob<Score> ($2))
957 SCM proc = parser->lexer_->lookup_identifier ("book-score-handler");
958 scm_call_2 (proc, $1, $2);
959 } else if (Output_def *od = unsmob<Output_def> ($2)) {
962 if (to_boolean (od->c_variable ("is-paper")))
963 id = ly_symbol2scm ("$defaultpaper");
964 else if (to_boolean (od->c_variable ("is-midi")))
965 id = ly_symbol2scm ("$defaultmidi");
966 else if (to_boolean (od->c_variable ("is-layout")))
967 id = ly_symbol2scm ("$defaultlayout");
969 parser->lexer_->set_identifier (id, $2);
970 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
971 parser->parser_error (@2, _("bad expression type"));
975 parser->lexer_->add_scope (unsmob<Book> ($1)->header_);
978 Book *book = unsmob<Book> ($1);
980 book->scores_ = SCM_EOL;
981 book->bookparts_ = SCM_EOL;
986 BOOKPART '{' bookpart_body '}' {
988 unsmob<Book> ($$)->origin ()->set_spot (@$);
989 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F);
995 Book *book = new Book;
996 $$ = book->unprotect ();
997 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $$);
1000 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $1);
1002 | bookpart_body paper_block {
1003 unsmob<Book> ($$)->paper_ = unsmob<Output_def> ($2);
1005 | bookpart_body score_block {
1006 SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler");
1007 scm_call_2 (proc, $1, $2);
1009 | bookpart_body composite_music {
1010 SCM proc = parser->lexer_->lookup_identifier ("bookpart-music-handler");
1011 scm_call_2 (proc, $1, $2);
1013 | bookpart_body full_markup {
1014 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
1015 scm_call_2 (proc, $1, scm_list_1 ($2));
1017 | bookpart_body full_markup_list {
1018 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
1019 scm_call_2 (proc, $1, $2);
1021 | bookpart_body SCM_TOKEN {
1022 // Evaluate and ignore #xxx, as opposed to \xxx
1023 parser->lexer_->eval_scm_token ($2, @2);
1025 | bookpart_body embedded_scm_active
1027 SCM out = SCM_UNDEFINED;
1028 if (Text_interface::is_markup ($2))
1029 out = scm_list_1 ($2);
1030 else if (Text_interface::is_markup_list ($2))
1032 if (scm_is_pair (out))
1034 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
1035 scm_call_2 (proc, $1, out);
1036 } else if (unsmob<Score> ($2))
1038 SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler");
1039 scm_call_2 (proc, $1, $2);
1040 } else if (Output_def *od = unsmob<Output_def> ($2)) {
1043 if (to_boolean (od->c_variable ("is-paper")))
1044 id = ly_symbol2scm ("$defaultpaper");
1045 else if (to_boolean (od->c_variable ("is-midi")))
1046 id = ly_symbol2scm ("$defaultmidi");
1047 else if (to_boolean (od->c_variable ("is-layout")))
1048 id = ly_symbol2scm ("$defaultlayout");
1050 parser->lexer_->set_identifier (id, $2);
1051 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
1052 parser->parser_error (@2, _("bad expression type"));
1056 Book *book = unsmob<Book> ($1);
1057 if (!ly_is_module (book->header_))
1058 book->header_ = ly_make_module (false);
1059 parser->lexer_->add_scope (book->header_);
1061 | bookpart_body error {
1062 Book *book = unsmob<Book> ($1);
1064 book->scores_ = SCM_EOL;
1069 SCORE '{' score_body '}' {
1070 unsmob<Score> ($3)->origin ()->set_spot (@$);
1077 if (!unsmob<Score> ($1)) {
1078 parser->parser_error (@1, _("Missing music in \\score"));
1079 $$ = (new Score)->unprotect ();
1080 if (scm_is_pair ($1) && ly_is_module (scm_car ($1)))
1082 unsmob<Score> ($$)->set_header (scm_car ($1));
1085 for (SCM p = scm_reverse_x ($1, SCM_EOL);
1086 scm_is_pair (p); p = scm_cdr (p))
1088 unsmob<Score> ($$)->
1089 add_output_def (unsmob<Output_def> (scm_car (p)));
1093 | score_body error {
1094 unsmob<Score> ($$)->error_found_ = true;
1109 | score_items score_item
1111 Output_def *od = unsmob<Output_def> ($2);
1113 if (to_boolean (od->lookup_variable (ly_symbol2scm ("is-paper"))))
1115 parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
1117 $2 = SCM_UNSPECIFIED;
1119 } else if (!unsmob<Score> ($$)) {
1120 if (unsmob<Music> ($2)) {
1121 $2 = Lily::scorify_music ($2);
1123 if (unsmob<Score> ($2))
1126 $2 = SCM_UNSPECIFIED;
1129 Score *score = unsmob<Score> ($$);
1130 if (score && scm_is_pair ($1)) {
1131 if (ly_is_module (scm_car ($1)))
1133 score->set_header (scm_car ($1));
1136 for (SCM p = scm_reverse_x ($1, SCM_EOL);
1137 scm_is_pair (p); p = scm_cdr (p))
1139 score->add_output_def (unsmob<Output_def> (scm_car (p)));
1144 score->add_output_def (od);
1145 else if (scm_is_pair ($$) && ly_is_module (scm_car ($$)))
1146 scm_set_cdr_x ($$, scm_cons ($2, scm_cdr ($$)));
1148 $$ = scm_cons ($2, $$);
1149 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
1150 parser->parser_error (@2, _("Spurious expression in \\score"));
1154 if (Score *score = unsmob<Score> ($1)) {
1155 if (!ly_is_module (score->get_header ()))
1156 score->set_header (ly_make_module (false));
1157 parser->lexer_->add_scope (score->get_header ());
1159 if (!scm_is_pair ($1) || !ly_is_module (scm_car ($1)))
1160 $1 = scm_cons (ly_make_module (false), $1);
1161 parser->lexer_->add_scope (scm_car ($1));
1176 Output_def *od = unsmob<Output_def> ($1);
1178 if (!to_boolean (od->lookup_variable (ly_symbol2scm ("is-paper"))))
1180 parser->parser_error (@1, _ ("need \\paper for paper block"));
1181 $$ = get_paper (parser)->unprotect ();
1188 output_def_body '}' {
1189 if (scm_is_pair ($1))
1192 parser->lexer_->remove_scope ();
1193 parser->lexer_->pop_state ();
1199 Output_def *p = get_paper (parser);
1200 p->input_origin_ = @$;
1201 parser->lexer_->add_scope (p->scope_);
1202 $$ = p->unprotect ();
1205 Output_def *p = get_midi (parser);
1206 $$ = p->unprotect ();
1207 parser->lexer_->add_scope (p->scope_);
1210 Output_def *p = get_layout (parser);
1212 parser->lexer_->add_scope (p->scope_);
1213 $$ = p->unprotect ();
1217 output_def_head_with_mode_switch:
1219 parser->lexer_->push_initial_state ();
1224 // We need this weird nonterminal because both music as well as a
1225 // context definition can start with \context and the difference is
1226 // only apparent after looking at the next token. If it is '{', there
1227 // is still time to escape from notes mode.
1229 music_or_context_def:
1231 | context_def_spec_block
1235 output_def_head_with_mode_switch '{' {
1236 unsmob<Output_def> ($1)->input_origin_.set_spot (@$);
1237 // This is a stupid trick to mark the beginning of the
1238 // body for deciding whether to allow
1239 // embedded_scm_active to have an output definition
1240 $$ = scm_list_1 ($1);
1242 | output_def_body assignment {
1243 if (scm_is_pair ($1))
1246 | output_def_body embedded_scm_active
1248 // We don't switch into note mode for Scheme functions
1249 // here. Does not seem warranted/required in output
1251 if (scm_is_pair ($1))
1253 Output_def *o = unsmob<Output_def> ($2);
1255 o->input_origin_.set_spot (@$);
1256 $1 = o->self_scm ();
1257 parser->lexer_->remove_scope ();
1258 parser->lexer_->add_scope (o->scope_);
1259 $2 = SCM_UNSPECIFIED;
1263 if (unsmob<Context_def> ($2))
1264 assign_context_def (unsmob<Output_def> ($1), $2);
1265 // Seems unlikely, but let's be complete:
1266 else if (unsmob<Music> ($2))
1268 SCM proc = parser->lexer_->lookup_identifier
1269 ("output-def-music-handler");
1270 scm_call_2 (proc, $1, $2);
1271 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
1272 parser->parser_error (@2, _("bad expression type"));
1275 | output_def_body SCM_TOKEN {
1276 if (scm_is_pair ($1))
1278 // Evaluate and ignore #xxx, as opposed to \xxx
1279 parser->lexer_->eval_scm_token ($2, @2);
1283 if (scm_is_pair ($1))
1285 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
1286 parser->lexer_->push_note_state (nn);
1287 } music_or_context_def
1289 parser->lexer_->pop_state ();
1290 if (unsmob<Context_def> ($3))
1291 assign_context_def (unsmob<Output_def> ($1), $3);
1294 SCM proc = parser->lexer_->lookup_identifier
1295 ("output-def-music-handler");
1296 scm_call_2 (proc, $1, $3);
1300 | output_def_body error {
1306 TEMPO steno_duration '=' tempo_range {
1307 $$ = MAKE_SYNTAX (tempo, @$, SCM_EOL, $2, $4);
1309 | TEMPO text steno_duration '=' tempo_range {
1310 $$ = MAKE_SYNTAX (tempo, @$, $2, $3, $5);
1313 $$ = MAKE_SYNTAX (tempo, @$, $2);
1318 The representation of a list is reversed to have efficient append. */
1324 | music_list music_embedded {
1325 if (unsmob<Music> ($2))
1326 $$ = scm_cons ($2, $1);
1328 | music_list error {
1329 Music *m = MY_MAKE_MUSIC("Music", @$);
1331 m->set_property ("error-found", SCM_BOOL_T);
1332 $$ = scm_cons (m->self_scm (), $1);
1333 m->unprotect (); /* UGH */
1340 $$ = scm_reverse_x ($2, SCM_EOL);
1345 | lyric_element_music
1352 $$ = make_music_from_simple (parser, @1, $1);
1353 if (!unsmob<Music> ($$))
1355 parser->parser_error (@1, _ ("music expected"));
1356 $$ = MAKE_SYNTAX (void_music, @$);
1364 if (unsmob<Music> ($1)->is_mus_type ("post-event")) {
1365 parser->parser_error (@1, _ ("unexpected post-event"));
1366 $$ = SCM_UNSPECIFIED;
1369 | music_embedded_backup
1373 | music_embedded_backup BACKUP lyric_element_music
1377 | multiplied_duration post_events
1379 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
1381 parser->default_duration_ = *unsmob<Duration> ($1);
1382 n->set_property ("duration", $1);
1384 if (scm_is_pair ($2))
1385 n->set_property ("articulations",
1386 scm_reverse_x ($2, SCM_EOL));
1387 $$ = n->unprotect ();
1391 music_embedded_backup:
1394 if (scm_is_eq ($1, SCM_UNSPECIFIED))
1396 else if (Music *m = unsmob<Music> ($1)) {
1397 if (m->is_mus_type ("post-event")) {
1398 parser->parser_error
1399 (@1, _ ("unexpected post-event"));
1400 $$ = SCM_UNSPECIFIED;
1403 } else if (parser->lexer_->is_lyric_state ()
1404 && Text_interface::is_markup ($1))
1405 MYBACKUP (LYRIC_ELEMENT, $1, @1);
1407 @$.warning (_ ("Ignoring non-music expression"));
1413 // music_assign does not need to contain lyrics: there are no
1414 // assignments in lyricmode.
1417 | composite_music %prec COMPOSITE
1421 REPEAT simple_string unsigned_number music
1423 $$ = MAKE_SYNTAX (repeat, @$, $2, $3, $4, SCM_EOL);
1425 | REPEAT simple_string unsigned_number music ALTERNATIVE braced_music_list
1427 $$ = MAKE_SYNTAX (repeat, @$, $2, $3, $4, $6);
1432 SEQUENTIAL braced_music_list {
1433 $$ = MAKE_SYNTAX (sequential_music, @$, $2);
1435 | braced_music_list {
1436 $$ = MAKE_SYNTAX (sequential_music, @$, $1);
1441 SIMULTANEOUS braced_music_list {
1442 $$ = MAKE_SYNTAX (simultaneous_music, @$, $2);
1444 | DOUBLE_ANGLE_OPEN music_list DOUBLE_ANGLE_CLOSE {
1445 $$ = MAKE_SYNTAX (simultaneous_music, @$, scm_reverse_x ($2, SCM_EOL));
1451 | music_property_def
1455 context_modification:
1458 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
1459 parser->lexer_->push_note_state (nn);
1460 } '{' context_mod_list '}'
1462 parser->lexer_->pop_state ();
1465 | WITH CONTEXT_MOD_IDENTIFIER
1469 | CONTEXT_MOD_IDENTIFIER
1473 | WITH context_modification_arg
1475 if (unsmob<Music> ($2)) {
1476 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
1477 $2 = scm_call_1 (proc, $2);
1479 if (unsmob<Context_mod> ($2))
1482 parser->parser_error (@2, _ ("not a context mod"));
1483 $$ = Context_mod ().smobbed_copy ();
1488 context_modification_arg:
1493 optional_context_mod:
1497 | context_modification
1505 $$ = Context_mod ().smobbed_copy ();
1507 | context_mod_list context_mod {
1508 if (!SCM_UNBNDP ($2))
1509 unsmob<Context_mod> ($1)->add_context_mod ($2);
1511 | context_mod_list CONTEXT_MOD_IDENTIFIER {
1512 Context_mod *md = unsmob<Context_mod> ($2);
1514 unsmob<Context_mod> ($1)->add_context_mods (md->get_mods ());
1516 | context_mod_list context_mod_arg {
1517 if (scm_is_eq ($2, SCM_UNSPECIFIED))
1519 else if (unsmob<Music> ($2)) {
1520 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
1521 $2 = scm_call_1 (proc, $2);
1523 if (unsmob<Context_mod> ($2))
1524 unsmob<Context_mod> ($$)->add_context_mods
1525 (unsmob<Context_mod> ($2)->get_mods ());
1527 parser->parser_error (@2, _ ("not a context mod"));
1533 CONTEXT symbol optional_id optional_context_mod {
1534 Context_mod *ctxmod = unsmob<Context_mod> ($4);
1537 mods = ctxmod->get_mods ();
1538 $$ = START_MAKE_SYNTAX (context_specification, $2, $3, mods, SCM_BOOL_F);
1540 | NEWCONTEXT symbol optional_id optional_context_mod {
1541 Context_mod *ctxmod = unsmob<Context_mod> ($4);
1544 mods = ctxmod->get_mods ();
1545 $$ = START_MAKE_SYNTAX (context_specification, $2, $3, mods, SCM_BOOL_T);
1550 ADDLYRICS optional_context_mod lyric_mode_music {
1551 Context_mod *ctxmod = unsmob<Context_mod> ($2);
1554 mods = ctxmod->get_mods ();
1555 $$ = scm_acons ($3, mods, SCM_EOL);
1557 | new_lyrics ADDLYRICS optional_context_mod lyric_mode_music {
1558 Context_mod *ctxmod = unsmob<Context_mod> ($3);
1561 mods = ctxmod->get_mods ();
1562 $$ = scm_acons ($4, mods, $1);
1566 /* basic_music is basically the same as composite_music but with
1567 * context-prefixed music and lyricized music explicitly removed. The
1568 * reason is that in a sequence
1570 * \new Staff \new Voice { ... } \addlyrics { ... } \addlyrics { ... }
1572 * we need to group both \addlyrics together (as they go with the same
1573 * voice) but then combine them with \new Voice { ... }, meaning that
1574 * combining \new Voice { ... } needs higher priority than
1575 * { ... } \addlyrics, and *not* have \new Staff \new Voice { ... }
1576 * combine before combining \new Voice { ... } \addlyrics: only one
1577 * layer of context-prefixed music should assemble before \addlyrics
1578 * is integrated. Total mess, and we sort this mess out with explicit
1579 * rules preferring a single context-prefix.
1586 | LYRICSTO simple_string lyric_mode_music {
1587 $$ = MAKE_SYNTAX (lyric_combine, @$, $2, SCM_EOL, $3);
1589 | LYRICSTO symbol '=' simple_string lyric_mode_music
1591 $$ = MAKE_SYNTAX (lyric_combine, @$, $3, $2, $4);
1601 contexted_basic_music:
1602 context_prefix contextable_music new_lyrics
1605 i.set_location (@1, @2);
1606 $$ = FINISH_MAKE_SYNTAX ($1, i, $2);
1607 $$ = MAKE_SYNTAX (add_lyrics, @$, $$, scm_reverse_x ($3, SCM_EOL));
1609 | context_prefix contextable_music
1611 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
1613 | context_prefix contexted_basic_music
1615 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
1620 basic_music %prec COMPOSITE
1621 | contexted_basic_music
1622 | basic_music new_lyrics
1624 $$ = MAKE_SYNTAX (add_lyrics, @$, $1, scm_reverse_x ($2, SCM_EOL));
1631 | grouped_music_list
1635 simultaneous_music { $$ = $1; }
1636 | sequential_music { $$ = $1; }
1639 /* Function argument lists are arguably the most complex part in the
1640 * parser. They are pretty tricky to understand because of the way
1641 * they are processed, and because of optional arguments that can be
1642 * omitted. When there are several optional arguments in a row,
1643 * omitting one automatically omits all following arguments. Optional
1644 * arguments can only be omitted when either
1646 * a) the omission is explicitly started with \default
1647 * b) the omission is implicitly started by an argument not matching
1648 * its predicate, and there is a mandatory argument later that can
1649 * "catch" the argument that does not fit.
1651 * When argument parsing starts, the lexer pushes EXPECT_SCM tokens
1652 * (corresponding to mandatory arguments and having a predicate
1653 * function as semantic value) or EXPECT_OPTIONAL EXPECT_SCM (where
1654 * the semantic value of the EXPECT_OPTIONAL token is the default to
1655 * use when the optional argument is omitted, and EXPECT_SCM again has
1656 * the argument predicate as semantic value) in reverse order to the
1657 * parser, followed by EXPECT_NO_MORE_ARGS. The argument list is then
1658 * processed inside-out while actual tokens are consumed.
1660 * This means that the argument list tokens determine the actions
1661 * taken as they arrive. The structure of the argument list is known
1662 * to the parser and stored in its parse stack when the first argument
1663 * is being parsed. What the parser does not know is which predicates
1664 * will match and whether or not \default will be appearing in the
1665 * argument list, and where.
1667 * Sequences of 0 or more optional arguments are scanned using either
1668 * function_arglist_backup or function_arglist_nonbackup. The first
1669 * is used when optional arguments are followed by at least one
1670 * mandatory argument: in that case optional arguments may be skipped
1671 * by either a false predicate (in which case the expression will be
1672 * pushed back as one or more tokens, preceded by a BACKUP token) or
1673 * by using \default.
1675 * If optional arguments are at the end of the argument list, they are
1676 * instead scanned using function_arglist_nonbackup: here the only
1677 * manner to enter into skipping of optional arguments is the use of
1680 * The argument list of a normal function call is parsed using
1681 * function_arglist. The part of an argument list before a mandatory
1682 * argument is parsed using function_arglist_optional.
1684 * The difference is that leading optional arguments are scanned using
1685 * function_arglist_nonbackup and function_arglist_backup,
1688 * Most other details are obvious in the rules themselves.
1694 | SYMBOL_LIST '.' symbol_list_rev
1696 $$ = scm_append (scm_list_2 ($1, scm_reverse_x ($3, SCM_EOL)));
1698 | SYMBOL_LIST ',' symbol_list_rev
1700 $$ = scm_append (scm_list_2 ($1, scm_reverse_x ($3, SCM_EOL)));
1706 | symbol_list_rev '.' symbol_list_part
1708 $$ = scm_append_x (scm_list_2 ($3, $1));
1710 | symbol_list_rev ',' symbol_list_part
1712 $$ = scm_append_x (scm_list_2 ($3, $1));
1716 // symbol_list_part delivers elements in reverse copy.
1721 $$ = try_string_variants (Lily::key_list_p, $1);
1722 if (SCM_UNBNDP ($$)) {
1723 parser->parser_error (@1, _("not a key"));
1726 $$ = scm_reverse ($$);
1731 symbol_list_element:
1737 symbol_list_part_bare:
1740 $$ = try_string_variants (Lily::key_list_p, $1);
1741 if (SCM_UNBNDP ($$)) {
1742 parser->parser_error (@1, _("not a key"));
1745 $$ = scm_reverse ($$);
1749 $$ = scm_list_1 ($1);
1753 function_arglist_nonbackup:
1754 function_arglist_common
1755 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup post_event_nofinger
1757 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1759 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' UNSIGNED
1761 SCM n = scm_difference ($5, SCM_UNDEFINED);
1762 if (scm_is_true (scm_call_1 ($2, n)))
1763 $$ = scm_cons (n, $3);
1765 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
1766 t->set_property ("digit", $5);
1767 $$ = check_scheme_arg (parser, @4, t->unprotect (),
1771 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL
1773 $$ = check_scheme_arg (parser, @4,
1774 scm_difference ($5, SCM_UNDEFINED),
1777 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' NUMBER_IDENTIFIER
1779 $$ = check_scheme_arg (parser, @4,
1780 scm_difference ($5, SCM_UNDEFINED),
1783 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg
1785 if (scm_is_true (scm_call_1 ($2, $4)))
1786 $$ = scm_cons ($4, $3);
1788 $$ = check_scheme_arg (parser, @4,
1789 make_music_from_simple
1793 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup bare_number_common
1795 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1797 | function_arglist_nonbackup_reparse REPARSE pitch_or_music
1799 if (scm_is_true (scm_call_1 ($2, $3)))
1800 $$ = scm_cons ($3, $1);
1802 $$ = check_scheme_arg (parser, @3,
1803 make_music_from_simple
1807 | function_arglist_nonbackup_reparse REPARSE multiplied_duration
1809 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1811 | function_arglist_nonbackup_reparse REPARSE reparsed_rhythm
1813 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1815 | function_arglist_nonbackup_reparse REPARSE bare_number_common
1817 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1819 | function_arglist_nonbackup_reparse REPARSE SCM_ARG
1821 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1823 | function_arglist_nonbackup_reparse REPARSE lyric_element_music
1825 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1827 | function_arglist_nonbackup_reparse REPARSE symbol_list_arg
1829 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1835 DURATION_ARG dots multipliers post_events
1837 $$ = make_music_from_simple (parser, @$,
1838 make_duration ($1, scm_to_int ($2), $3));
1839 Music *m = unsmob<Music> ($$);
1841 if (scm_is_pair ($4))
1842 m->set_property ("articulations",
1843 scm_reverse_x ($4, SCM_EOL));
1847 function_arglist_nonbackup_reparse:
1848 EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
1851 SCM res = try_string_variants ($2, $4);
1852 if (!SCM_UNBNDP (res))
1853 if (scm_is_pair (res))
1854 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1856 MYREPARSE (@4, $2, SCM_ARG, res);
1857 else if (scm_is_true
1859 ($2, make_music_from_simple
1861 MYREPARSE (@4, $2, STRING, $4);
1863 MYREPARSE (@4, $2, SCM_ARG, $4);
1865 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup pitch
1870 ($2, make_music_from_simple
1872 MYREPARSE (@4, $2, PITCH_IDENTIFIER, $4);
1874 MYREPARSE (@4, $2, SCM_ARG, $4);
1876 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup steno_tonic_pitch
1881 ($2, make_music_from_simple
1883 MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
1885 MYREPARSE (@4, $2, SCM_ARG, $4);
1887 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
1890 SCM res = try_string_variants ($2, $4);
1891 if (!SCM_UNBNDP (res))
1892 if (scm_is_pair (res))
1893 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1895 MYREPARSE (@4, $2, SCM_ARG, res);
1896 else if (scm_is_true
1898 ($2, make_music_from_simple
1900 MYREPARSE (@4, $2, STRING, $4);
1902 MYREPARSE (@4, $2, SCM_ARG, $4);
1904 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup full_markup
1907 if (scm_is_true (scm_call_1 ($2, $4)))
1908 MYREPARSE (@4, $2, SCM_ARG, $4);
1909 else if (scm_is_true
1911 ($2, make_music_from_simple
1913 MYREPARSE (@4, $2, STRING, $4);
1915 MYREPARSE (@4, $2, SCM_ARG, $4);
1917 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup UNSIGNED
1920 if (scm_is_true (scm_call_1 ($2, $4)))
1921 // May be 3 \cm or similar
1922 MYREPARSE (@4, $2, REAL, $4);
1923 else if (scm_is_true (scm_call_1 ($2, scm_list_1 ($4))))
1924 MYREPARSE (@4, $2, SYMBOL_LIST, scm_list_1 ($4));
1926 SCM d = make_duration ($4);
1927 if (!SCM_UNBNDP (d)) {
1928 if (scm_is_true (scm_call_1 ($2, d)))
1929 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
1930 else if (scm_is_true
1932 ($2, make_music_from_simple (parser, @4, d))))
1933 MYREPARSE (@4, $2, DURATION_ARG, d);
1935 MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
1937 MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
1940 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER
1943 if (scm_is_true (scm_call_1 ($2, $4)))
1944 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
1945 else if (scm_is_true
1947 ($2, make_music_from_simple (parser, @4, $4))))
1948 MYREPARSE (@4, $2, DURATION_ARG, $4);
1950 MYREPARSE (@4, $2, SCM_ARG, $4); // trigger error
1955 // function_arglist_backup can't occur at the end of an argument
1957 function_arglist_backup:
1958 function_arglist_common
1959 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup embedded_scm_arg
1961 if (scm_is_true (scm_call_1 ($2, $4)))
1962 $$ = scm_cons ($4, $3);
1964 $$ = make_music_from_simple (parser, @4, $4);
1965 if (scm_is_true (scm_call_1 ($2, $$)))
1966 $$ = scm_cons ($$, $3);
1969 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
1970 MYBACKUP (SCM_ARG, $4, @4);
1974 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup post_event_nofinger
1976 if (scm_is_true (scm_call_1 ($2, $4)))
1978 $$ = scm_cons ($4, $3);
1980 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
1981 MYBACKUP (EVENT_IDENTIFIER, $4, @4);
1984 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup pitch
1988 ($2, make_music_from_simple
1992 MYREPARSE (@4, $2, PITCH_IDENTIFIER, $4);
1993 } else if (scm_is_true (scm_call_1 ($2, $4)))
1994 $$ = scm_cons ($4, $3);
1996 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
1997 MYBACKUP (PITCH_IDENTIFIER, $4, @4);
2000 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup steno_tonic_pitch
2004 ($2, make_music_from_simple
2008 MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
2009 } else if (scm_is_true (scm_call_1 ($2, $4)))
2010 $$ = scm_cons ($4, $3);
2012 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2013 MYBACKUP (TONICNAME_PITCH, $4, @4);
2016 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup full_markup
2018 if (scm_is_true (scm_call_1 ($2, $4)))
2019 $$ = scm_cons ($4, $3);
2021 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2022 MYBACKUP (SCM_IDENTIFIER, $4, @4);
2025 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup UNSIGNED
2028 if (scm_is_true (scm_call_1 ($2, $4)))
2029 // May be 3 \cm or similar
2030 MYREPARSE (@4, $2, REAL, $4);
2031 else if (scm_is_true (scm_call_1 ($2, scm_list_1 ($4))))
2032 MYREPARSE (@4, $2, SYMBOL_LIST, scm_list_1 ($4));
2034 SCM d = make_duration ($4);
2035 if (!SCM_UNBNDP (d)) {
2036 if (scm_is_true (scm_call_1 ($2, d)))
2037 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
2038 else if (scm_is_true
2040 ($2, make_music_from_simple (parser, @4, d))))
2041 MYREPARSE (@4, $2, DURATION_ARG, d);
2043 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2044 MYBACKUP (UNSIGNED, $4, @4);
2047 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2048 MYBACKUP (UNSIGNED, $4, @4);
2052 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup REAL
2054 if (scm_is_true (scm_call_1 ($2, $4)))
2057 MYREPARSE (@4, $2, REAL, $4);
2059 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2060 MYBACKUP (REAL, $4, @4);
2063 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup NUMBER_IDENTIFIER
2065 if (scm_is_true (scm_call_1 ($2, $4)))
2067 $$ = scm_cons ($4, $3);
2069 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2070 MYBACKUP (NUMBER_IDENTIFIER, $4, @4);
2073 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' UNSIGNED
2075 SCM n = scm_difference ($5, SCM_UNDEFINED);
2076 if (scm_is_true (scm_call_1 ($2, n))) {
2078 MYREPARSE (@5, $2, REAL, n);
2080 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
2081 t->set_property ("digit", $5);
2082 $$ = t->unprotect ();
2083 if (scm_is_true (scm_call_1 ($2, $$)))
2084 $$ = scm_cons ($$, $3);
2086 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2087 MYBACKUP (UNSIGNED, $5, @5);
2088 parser->lexer_->push_extra_token (@4, '-');
2092 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' REAL
2094 SCM n = scm_difference ($5, SCM_UNDEFINED);
2095 if (scm_is_true (scm_call_1 ($2, n))) {
2096 MYREPARSE (@5, $2, REAL, n);
2099 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2100 MYBACKUP (REAL, n, @5);
2103 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' NUMBER_IDENTIFIER
2105 SCM n = scm_difference ($5, SCM_UNDEFINED);
2106 if (scm_is_true (scm_call_1 ($2, n))) {
2107 $$ = scm_cons (n, $3);
2109 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2110 MYBACKUP (NUMBER_IDENTIFIER, n, @5);
2113 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup DURATION_IDENTIFIER
2116 if (scm_is_true (scm_call_1 ($2, $4)))
2117 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
2118 else if (scm_is_true
2120 ($2, make_music_from_simple (parser, @4, $4))))
2121 MYREPARSE (@4, $2, DURATION_ARG, $4);
2123 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2124 MYBACKUP (DURATION_IDENTIFIER, $4, @4);
2127 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup SCM_IDENTIFIER
2129 SCM res = try_string_variants ($2, $4);
2130 if (!SCM_UNBNDP (res))
2131 if (scm_is_pair (res)) {
2133 MYREPARSE (@4, $2, SYMBOL_LIST, res);
2136 $$ = scm_cons (res, $3);
2138 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2139 MYBACKUP (SCM_IDENTIFIER, $4, @4);
2142 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup STRING
2144 SCM res = try_string_variants ($2, $4);
2145 if (!SCM_UNBNDP (res))
2146 if (scm_is_pair (res)) {
2148 MYREPARSE (@4, $2, SYMBOL_LIST, res);
2151 $$ = scm_cons (res, $3);
2153 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2154 MYBACKUP (STRING, $4, @4);
2157 | function_arglist_backup REPARSE pitch_or_music
2159 if (scm_is_true (scm_call_1 ($2, $3)))
2160 $$ = scm_cons ($3, $1);
2162 $$ = check_scheme_arg (parser, @3,
2163 make_music_from_simple
2167 | function_arglist_backup REPARSE bare_number_common
2169 $$ = check_scheme_arg (parser, @3,
2172 | function_arglist_backup REPARSE multiplied_duration
2174 $$ = check_scheme_arg (parser, @3,
2177 | function_arglist_backup REPARSE reparsed_rhythm
2179 $$ = check_scheme_arg (parser, @3,
2182 | function_arglist_backup REPARSE symbol_list_arg
2184 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
2189 function_arglist_nonbackup
2190 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
2192 $$ = scm_cons (loc_on_music (parser, @4, $1), $3);
2196 function_arglist_skip_nonbackup:
2197 function_arglist_nonbackup
2198 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup
2200 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2204 // Partial function arglists are returned just in their incomplete
2205 // state: when combined with the music function, the missing parts of
2206 // the signature can be reconstructed
2208 // To serve as a partial arglist, the argument list must absolutely
2209 // _not_ be in "skipping optional arguments" mode since then there is
2210 // some backup token that has nowhere to go before \etc.
2212 // So we can skim off an arbitrary number of arguments from the end of
2213 // the argument list. The argument list remaining afterwards has to
2214 // be in not-skipping-optional-arguments mode.
2216 function_arglist_partial:
2217 EXPECT_SCM function_arglist_optional
2221 | EXPECT_SCM function_arglist_partial_optional
2225 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup
2229 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial
2235 function_arglist_partial_optional:
2236 EXPECT_SCM function_arglist_optional
2240 | EXPECT_SCM function_arglist_partial_optional
2244 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup
2248 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial_optional
2254 function_arglist_common:
2255 EXPECT_NO_MORE_ARGS {
2258 | EXPECT_SCM function_arglist_optional embedded_scm_arg
2260 if (scm_is_true (scm_call_1 ($1, $3)))
2261 $$ = scm_cons ($3, $2);
2263 $$ = check_scheme_arg (parser, @3,
2264 make_music_from_simple
2268 | EXPECT_SCM function_arglist_optional bare_number_common
2270 $$ = check_scheme_arg (parser, @3,
2273 | EXPECT_SCM function_arglist_optional post_event_nofinger
2275 $$ = check_scheme_arg (parser, @3,
2278 | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
2280 SCM n = scm_difference ($4, SCM_UNDEFINED);
2281 $$ = check_scheme_arg (parser, @4, n, $2, $1);
2283 | function_arglist_common_reparse REPARSE SCM_ARG
2285 $$ = check_scheme_arg (parser, @3,
2288 | function_arglist_common_reparse REPARSE lyric_element_music
2290 $$ = check_scheme_arg (parser, @3,
2293 | function_arglist_common_reparse REPARSE pitch_or_music
2295 if (scm_is_true (scm_call_1 ($2, $3)))
2296 $$ = scm_cons ($3, $1);
2298 $$ = check_scheme_arg (parser, @3,
2299 make_music_from_simple
2303 | function_arglist_common_reparse REPARSE bare_number_common
2305 $$ = check_scheme_arg (parser, @3,
2308 | function_arglist_common_reparse REPARSE multiplied_duration
2310 $$ = check_scheme_arg (parser, @3,
2313 | function_arglist_common_reparse REPARSE reparsed_rhythm
2315 $$ = check_scheme_arg (parser, @3,
2318 | function_arglist_common_reparse REPARSE symbol_list_arg
2320 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
2324 function_arglist_common_reparse:
2325 EXPECT_SCM function_arglist_optional SCM_IDENTIFIER
2328 SCM res = try_string_variants ($1, $3);
2329 if (!SCM_UNBNDP (res))
2330 if (scm_is_pair (res))
2331 MYREPARSE (@3, $1, SYMBOL_LIST, res);
2333 MYREPARSE (@3, $1, SCM_ARG, res);
2334 else if (scm_is_true
2336 ($1, make_music_from_simple (parser, @3, $3))))
2337 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
2339 // This is going to flag a syntax error, we
2340 // know the predicate to be false.
2341 MYREPARSE (@3, $1, SCM_ARG, $3);
2343 | EXPECT_SCM function_arglist_optional pitch
2348 ($1, make_music_from_simple
2350 MYREPARSE (@3, $1, PITCH_IDENTIFIER, $3);
2352 MYREPARSE (@3, $1, SCM_ARG, $3);
2354 | EXPECT_SCM function_arglist_optional steno_tonic_pitch
2359 ($1, make_music_from_simple
2361 MYREPARSE (@3, $1, TONICNAME_PITCH, $3);
2363 MYREPARSE (@3, $1, SCM_ARG, $3);
2365 | EXPECT_SCM function_arglist_optional STRING
2368 SCM res = try_string_variants ($1, $3);
2369 if (!SCM_UNBNDP (res))
2370 if (scm_is_pair (res))
2371 MYREPARSE (@3, $1, SYMBOL_LIST, res);
2373 MYREPARSE (@3, $1, SCM_ARG, res);
2374 else if (scm_is_true
2376 ($1, make_music_from_simple (parser, @3, $3))))
2377 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
2379 // This is going to flag a syntax error, we
2380 // know the predicate to be false.
2381 MYREPARSE (@3, $1, SCM_ARG, $3);
2383 | EXPECT_SCM function_arglist_optional full_markup
2386 if (scm_is_true (scm_call_1 ($1, $3)))
2387 MYREPARSE (@3, $1, SCM_ARG, $3);
2388 else if (scm_is_true
2390 ($1, make_music_from_simple (parser, @3, $3))))
2391 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
2393 // This is going to flag a syntax error, we
2394 // know the predicate to be false.
2395 MYREPARSE (@3, $1, SCM_ARG, $3);
2397 | EXPECT_SCM function_arglist_optional UNSIGNED
2400 if (scm_is_true (scm_call_1 ($1, $3)))
2401 // May be 3 \cm or similar
2402 MYREPARSE (@3, $1, REAL, $3);
2403 else if (scm_is_true (scm_call_1 ($1, scm_list_1 ($3))))
2404 MYREPARSE (@3, $1, SYMBOL_LIST, scm_list_1 ($3));
2406 SCM d = make_duration ($3);
2407 if (!SCM_UNBNDP (d)) {
2408 if (scm_is_true (scm_call_1 ($1, d)))
2409 MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
2410 else if (scm_is_true
2412 ($1, make_music_from_simple (parser, @3, d))))
2413 MYREPARSE (@3, $1, DURATION_ARG, d);
2415 MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
2417 MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
2420 | EXPECT_SCM function_arglist_optional DURATION_IDENTIFIER
2423 if (scm_is_true (scm_call_1 ($1, $3)))
2424 MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
2425 else if (scm_is_true
2427 ($1, make_music_from_simple (parser, @3, $3))))
2428 MYREPARSE (@3, $1, DURATION_ARG, $3);
2430 MYREPARSE (@3, $1, SCM_ARG, $3); // trigger error
2432 | EXPECT_SCM function_arglist_optional '-' UNSIGNED
2435 SCM n = scm_difference ($4, SCM_UNDEFINED);
2436 if (scm_is_true (scm_call_1 ($1, n)))
2437 MYREPARSE (@4, $1, REAL, n);
2439 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @4);
2440 t->set_property ("digit", $4);
2441 SCM m = t->unprotect ();
2442 if (scm_is_true (scm_call_1 ($1, m)))
2443 MYREPARSE (@4, $1, SCM_ARG, m);
2445 MYREPARSE (@4, $1, SCM_ARG, $4);
2448 | EXPECT_SCM function_arglist_optional '-' REAL
2451 SCM n = scm_difference ($4, SCM_UNDEFINED);
2452 MYREPARSE (@4, $1, REAL, n);
2456 function_arglist_optional:
2457 function_arglist_backup
2458 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup DEFAULT
2460 $$ = scm_cons (loc_on_music (parser, @4, $1), $3);
2462 | function_arglist_skip_backup BACKUP
2465 function_arglist_skip_backup:
2466 function_arglist_backup
2467 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup
2469 $$ = scm_cons (loc_on_music (parser, @3, $1), $3);
2473 music_function_call:
2474 MUSIC_FUNCTION function_arglist {
2475 $$ = MAKE_SYNTAX (music_function, @$,
2482 /**/ { $$ = SCM_EOL; }
2483 | '=' simple_string {
2488 // We must not have lookahead tokens parsed in lyric mode. In order
2489 // to save confusion, we take almost the same set as permitted with
2490 // \lyricmode and/or \lyrics. However, music identifiers are also
2491 // allowed, and they obviously do not require switching into lyrics
2492 // mode for parsing.
2496 parser->lexer_->push_lyric_state ();
2497 } grouped_music_list
2499 parser->lexer_->pop_state ();
2506 mode_changing_head grouped_music_list {
2507 if (scm_is_eq ($1, ly_symbol2scm ("chords")))
2509 $$ = MAKE_SYNTAX (unrelativable_music, @$, $2);
2515 parser->lexer_->pop_state ();
2517 | mode_changing_head_with_context optional_context_mod grouped_music_list {
2518 Context_mod *ctxmod = unsmob<Context_mod> ($2);
2521 mods = ctxmod->get_mods ();
2522 $$ = MAKE_SYNTAX (context_specification, @$, $1, SCM_EOL, mods, SCM_BOOL_T, $3);
2523 if (scm_is_eq ($1, ly_symbol2scm ("ChordNames")))
2525 $$ = MAKE_SYNTAX (unrelativable_music, @$, $$);
2527 parser->lexer_->pop_state ();
2533 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
2534 parser->lexer_->push_note_state (nn);
2536 $$ = ly_symbol2scm ("notes");
2540 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2541 parser->lexer_->push_note_state (nn);
2543 $$ = ly_symbol2scm ("drums");
2546 parser->lexer_->push_figuredbass_state ();
2548 $$ = ly_symbol2scm ("figures");
2551 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2552 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2553 nn = parser->lexer_->lookup_identifier ("pitchnames");
2554 parser->lexer_->push_chord_state (nn);
2555 $$ = ly_symbol2scm ("chords");
2559 { parser->lexer_->push_lyric_state ();
2560 $$ = ly_symbol2scm ("lyrics");
2564 mode_changing_head_with_context:
2566 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2567 parser->lexer_->push_note_state (nn);
2569 $$ = ly_symbol2scm ("DrumStaff");
2572 parser->lexer_->push_figuredbass_state ();
2574 $$ = ly_symbol2scm ("FiguredBass");
2577 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2578 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2579 nn = parser->lexer_->lookup_identifier ("pitchnames");
2580 parser->lexer_->push_chord_state (nn);
2581 $$ = ly_symbol2scm ("ChordNames");
2584 { parser->lexer_->push_lyric_state ();
2585 $$ = ly_symbol2scm ("Lyrics");
2590 CHANGE symbol '=' simple_string {
2591 $$ = MAKE_SYNTAX (context_change, @$, $2, $4);
2598 $$ = scm_reverse_x ($1, SCM_EOL);
2604 $$ = scm_list_3 (ly_symbol2scm ("assign"), $1, $3);
2607 $$ = scm_list_2 (ly_symbol2scm ("unset"), $2);
2609 | OVERRIDE revert_arg '=' scalar {
2610 if (scm_ilength ($2) < 2) {
2611 parser->parser_error (@2, _("bad grob property path"));
2614 $$ = scm_cons (ly_symbol2scm ("push"),
2615 scm_cons2 (scm_car ($2),
2620 | REVERT revert_arg {
2621 $$ = scm_cons (ly_symbol2scm ("pop"), $2);
2625 // This is all quite awkward for the sake of substantial backward
2626 // compatibility while at the same time allowing a more "natural" form
2627 // of specification not separating grob specification from grob
2628 // property path. The purpose of this definition of revert_arg is to
2629 // allow the symbol list which specifies grob and property to revert
2630 // to be optionally be split into two parts after the grob (which in
2631 // this case is just the first element of the list). symbol_list_part
2632 // is only one path component, but it can be parsed without lookahead,
2633 // so we can follow it with a synthetic BACKUP token when needed. If
2634 // the first symbol_list_part already contains multiple elements (only
2635 // possible if a Scheme expression provides them), we just parse for
2636 // additional elements introduced by '.', which is what the
2637 // SYMBOL_LIST backup in connection with the immediately following
2638 // rule using symbol_list_arg does.
2640 // As long as we don't have our coffers filled with both grob and at
2641 // least one grob property specification, the rest of the required
2642 // symbol list chain may be provided either with or without a leading
2643 // dot. This is for both allowing the traditional
2644 // \revert Accidental #'color
2645 // as well as well as the "naive" form
2646 // \revert Accidental.color
2649 revert_arg_backup BACKUP symbol_list_arg
2658 if (scm_is_null ($1)
2659 || scm_is_null (scm_cdr ($1)))
2660 MYBACKUP (SCM_ARG, $1, @1);
2662 MYBACKUP (SYMBOL_LIST, scm_reverse_x ($1, SCM_EOL), @1);
2666 // revert_arg_part delivers results in reverse
2669 | revert_arg_backup BACKUP SCM_ARG '.' symbol_list_part
2671 $$ = scm_append_x (scm_list_2 ($5, $3));
2673 | revert_arg_backup BACKUP SCM_ARG ',' symbol_list_part
2675 $$ = scm_append_x (scm_list_2 ($5, $3));
2677 | revert_arg_backup BACKUP SCM_ARG symbol_list_part
2679 $$ = scm_append_x (scm_list_2 ($4, $3));
2684 CONSISTS { $$ = ly_symbol2scm ("consists"); }
2685 | REMOVE { $$ = ly_symbol2scm ("remove"); }
2687 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
2688 | DEFAULTCHILD { $$ = ly_symbol2scm ("default-child"); }
2689 | DENIES { $$ = ly_symbol2scm ("denies"); }
2691 | ALIAS { $$ = ly_symbol2scm ("alias"); }
2692 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
2693 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
2694 | NAME { $$ = ly_symbol2scm ("context-name"); }
2698 property_operation { $$ = $1; }
2699 | context_def_mod STRING {
2700 $$ = scm_list_2 ($1, $2);
2702 | context_def_mod embedded_scm
2704 if (!scm_is_string ($2)
2705 && ly_symbol2scm ("consists") != $1
2706 && ly_symbol2scm ("remove") != $1)
2709 parser->parser_error (@1, _ ("only \\consists and \\remove take non-string argument."));
2713 $$ = scm_list_2 ($1, $2);
2718 // If defined, at least two members.
2722 SCM l = scm_reverse_x ($1, SCM_EOL);
2725 (scm_object_property (scm_car (l),
2726 ly_symbol2scm ("is-grob?"))))
2727 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2728 if (scm_is_null (l) || scm_is_null (scm_cdr (l))) {
2729 parser->parser_error (@1, _ ("bad grob property path"));
2736 // If defined, at least three members
2740 if (!SCM_UNBNDP ($1) && scm_is_null (scm_cddr ($1)))
2742 parser->parser_error (@1, _ ("bad grob property path"));
2746 | grob_prop_spec property_path
2748 if (!SCM_UNBNDP ($1)) {
2749 $$ = scm_append_x (scm_list_2 ($1, $2));
2750 if (scm_is_null (scm_cddr ($$))) {
2751 parser->parser_error (@$, _ ("bad grob property path"));
2759 // Exactly two elements or undefined
2763 SCM l = scm_reverse_x ($1, SCM_EOL);
2764 switch (scm_ilength (l)) {
2766 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2770 parser->parser_error (@1, _ ("bad context property path"));
2778 // This is all quite awkward for the sake of substantial backward
2779 // compatibility while at the same time allowing a more "natural" form
2780 // of specification not separating grob specification from grob
2781 // property path. The purpose of this definition of
2782 // simple_revert_context is to allow the symbol list which specifies
2783 // grob and property to revert to be optionally be split into two
2784 // parts after the grob (which may be preceded by a context
2785 // specification, a case which we distinguish by checking whether the
2786 // first symbol is a valid grob symbol instead).
2788 // See revert_arg above for the main work horse of this arrangement.
2789 // simple_revert_context just caters for the context and delegates the
2790 // rest of the job to revert_arg.
2792 simple_revert_context:
2795 $1 = scm_reverse_x ($1, SCM_EOL);
2796 if (scm_is_null ($1)
2798 (scm_object_property (scm_car ($1),
2799 ly_symbol2scm ("is-grob?")))) {
2800 $$ = ly_symbol2scm ("Bottom");
2801 parser->lexer_->push_extra_token (@1, SCM_IDENTIFIER, $1);
2804 parser->lexer_->push_extra_token (@1, SCM_IDENTIFIER,
2811 OVERRIDE grob_prop_path '=' scalar {
2812 if (SCM_UNBNDP ($2))
2813 $$ = MAKE_SYNTAX (void_music, @$);
2815 $$ = MAKE_SYNTAX (property_override, @$,
2820 | REVERT simple_revert_context revert_arg {
2821 $$ = MAKE_SYNTAX (property_revert, @$, $2, $3);
2823 | SET context_prop_spec '=' scalar {
2824 if (SCM_UNBNDP ($2))
2825 $$ = MAKE_SYNTAX (void_music, @$);
2827 $$ = MAKE_SYNTAX (property_set, @$,
2832 | UNSET context_prop_spec {
2833 if (SCM_UNBNDP ($2))
2834 $$ = MAKE_SYNTAX (void_music, @$);
2836 $$ = MAKE_SYNTAX (property_unset, @$,
2852 if (Text_interface::is_markup ($1)) {
2855 parser->parser_error (@1, (_ ("markup expected")));
2856 $$ = scm_string (SCM_EOL);
2861 simple_string: STRING
2864 if (scm_is_string ($1)) {
2867 parser->parser_error (@1, (_ ("simple string expected")));
2868 $$ = scm_string (SCM_EOL);
2875 $$ = scm_string_to_symbol ($1);
2879 // This is a bit of overkill but makes the same
2880 // routine responsible for all symbol interpretations.
2881 $$ = try_string_variants (Guile_user::symbol_p, $1);
2882 if (SCM_UNBNDP ($$))
2884 parser->parser_error (@1, (_ ("symbol expected")));
2885 // Generate a unique symbol in case it is used
2886 // for an assignment or similar
2887 $$ = scm_make_symbol (ly_string2scm ("undefined"));
2897 // The following is a rather defensive variant of admitting
2898 // negative numbers: the grammar would permit number_factor or
2899 // even number_expression. However, function arguments allow
2900 // only this simple kind of negative number, so to have things
2901 // like \tweak and \override behave reasonably similar, it
2902 // makes sense to rule out things like -- which are rather an
2903 // accent in function argument contexts.
2906 $$ = scm_difference ($2, SCM_UNDEFINED);
2909 | symbol_list_part_bare '.' property_path
2911 $$ = scm_reverse_x ($1, $3);
2913 | symbol_list_part_bare ',' property_path
2915 $$ = scm_reverse_x ($1, $3);
2920 simple_element post_events {
2921 // Let the rhythmic music iterator sort this mess out.
2922 if (scm_is_pair ($2)) {
2923 unsmob<Music> ($$)->set_property ("articulations",
2924 scm_reverse_x ($2, SCM_EOL));
2927 | CHORD_REPETITION optional_notemode_duration post_events {
2929 i.set_location (@1, @3);
2930 $$ = MAKE_SYNTAX (repetition_chord, i,
2931 $2, scm_reverse_x ($3, SCM_EOL));
2933 | MULTI_MEASURE_REST optional_notemode_duration post_events {
2935 i.set_location (@1, @3);
2936 $$ = MAKE_SYNTAX (multi_measure_rest, i, $2,
2937 scm_reverse_x ($3, SCM_EOL));
2940 | note_chord_element
2945 chord_body optional_notemode_duration post_events
2947 Music *m = unsmob<Music> ($1);
2948 SCM dur = unsmob<Duration> ($2)->smobbed_copy ();
2949 SCM es = m->get_property ("elements");
2950 SCM postevs = scm_reverse_x ($3, SCM_EOL);
2952 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
2953 unsmob<Music> (scm_car (s))->set_property ("duration", dur);
2954 es = ly_append2 (es, postevs);
2956 m->set_property ("elements", es);
2957 m->set_spot (parser->lexer_->override_input (@$));
2958 $$ = m->self_scm ();
2963 ANGLE_OPEN chord_body_elements ANGLE_CLOSE
2965 $$ = MAKE_SYNTAX (event_chord, @$, scm_reverse_x ($2, SCM_EOL));
2967 | FIGURE_OPEN figure_list FIGURE_CLOSE
2969 $$ = MAKE_SYNTAX (event_chord, @$, scm_reverse_x ($2, SCM_EOL));
2973 chord_body_elements:
2974 /* empty */ { $$ = SCM_EOL; }
2975 | chord_body_elements chord_body_element {
2976 if (!SCM_UNBNDP ($2))
2977 $$ = scm_cons ($2, $1);
2982 pitch_or_tonic_pitch exclamations questions octave_check post_events
2984 bool q = to_boolean ($3);
2985 bool ex = to_boolean ($2);
2989 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
2990 n->set_property ("pitch", $1);
2992 n->set_property ("cautionary", SCM_BOOL_T);
2994 n->set_property ("force-accidental", SCM_BOOL_T);
2996 if (scm_is_pair (post)) {
2997 SCM arts = scm_reverse_x (post, SCM_EOL);
2998 n->set_property ("articulations", arts);
3000 if (scm_is_number (check))
3002 int q = scm_to_int (check);
3003 n->set_property ("absolute-octave", scm_from_int (q-1));
3006 $$ = n->unprotect ();
3008 | DRUM_PITCH post_events {
3009 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
3010 n->set_property ("drum-type", $1);
3012 if (scm_is_pair ($2)) {
3013 SCM arts = scm_reverse_x ($2, SCM_EOL);
3014 n->set_property ("articulations", arts);
3016 $$ = n->unprotect ();
3018 | music_function_chord_body
3020 Music *m = unsmob<Music> ($1);
3022 while (m && m->is_mus_type ("music-wrapper-music")) {
3023 $$ = m->get_property ("element");
3024 m = unsmob<Music> ($$);
3027 if (!(m && m->is_mus_type ("rhythmic-event"))) {
3028 parser->parser_error (@$, _ ("not a rhythmic event"));
3034 music_function_chord_body:
3040 event_function_event:
3041 EVENT_FUNCTION function_arglist {
3042 $$ = MAKE_SYNTAX (music_function, @$,
3051 | post_events post_event {
3053 if (Music *m = unsmob<Music> ($2))
3055 if (m->is_mus_type ("post-event-wrapper"))
3057 for (SCM p = m->get_property ("elements");
3061 $$ = scm_cons (scm_car (p), $$);
3064 m->set_spot (parser->lexer_->override_input (@2));
3065 $$ = scm_cons ($2, $$);
3071 post_event_nofinger:
3072 direction_less_event {
3075 | script_dir music_function_call {
3077 if (!unsmob<Music> ($2)->is_mus_type ("post-event")) {
3078 parser->parser_error (@2, _ ("post-event expected"));
3079 $$ = SCM_UNSPECIFIED;
3080 } else if (!SCM_UNBNDP ($1))
3082 unsmob<Music> ($$)->set_property ("direction", $1);
3086 if (!parser->lexer_->is_lyric_state ())
3087 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
3088 $$ = MY_MAKE_MUSIC ("HyphenEvent", @$)->unprotect ();
3091 if (!parser->lexer_->is_lyric_state ())
3092 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
3093 $$ = MY_MAKE_MUSIC ("ExtenderEvent", @$)->unprotect ();
3095 | script_dir direction_reqd_event {
3096 if (!SCM_UNBNDP ($1))
3098 Music *m = unsmob<Music> ($2);
3099 m->set_property ("direction", $1);
3103 | script_dir direction_less_event {
3104 if (!SCM_UNBNDP ($1))
3106 Music *m = unsmob<Music> ($2);
3107 m->set_property ("direction", $1);
3114 unsmob<Music> ($$)->set_property ("direction", scm_from_int (UP));
3119 unsmob<Music> ($$)->set_property ("direction", scm_from_int (DOWN));
3130 string_number_event:
3132 Music *s = MY_MAKE_MUSIC ("StringNumberEvent", @$);
3133 s->set_property ("string-number", $1);
3134 $$ = s->unprotect ();
3138 direction_less_event:
3140 | EVENT_IDENTIFIER {
3144 Music *a = MY_MAKE_MUSIC ("TremoloEvent", @$);
3145 a->set_property ("tremolo-type", $1);
3146 $$ = a->unprotect ();
3148 | event_function_event
3151 direction_reqd_event:
3155 | script_abbreviation {
3156 SCM s = parser->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
3157 if (scm_is_string (s)) {
3158 Music *a = MY_MAKE_MUSIC ("ArticulationEvent", @$);
3159 a->set_property ("articulation-type", s);
3160 $$ = a->unprotect ();
3162 Music *original = unsmob<Music> (s);
3163 if (original && original->is_mus_type ("post-event")) {
3164 Music *a = original->clone ();
3165 a->set_spot (parser->lexer_->override_input (@$));
3166 $$ = a->unprotect ();
3168 parser->parser_error (@1, _ ("expecting string or post-event as script definition"));
3169 $$ = MY_MAKE_MUSIC ("PostEvents", @$)->unprotect ();
3176 /**/ { $$ = SCM_EOL; }
3177 | '=' quotes { $$ = $2; }
3191 $$ = scm_from_int (1);
3194 $$ = scm_oneplus ($1);
3200 $$ = scm_from_int (-1);
3203 $$ = scm_oneminus ($1);
3208 NOTENAME_PITCH quotes {
3209 if (!scm_is_eq (SCM_INUM0, $2))
3211 Pitch p = *unsmob<Pitch> ($1);
3212 p = p.transposed (Pitch (scm_to_int ($2), 0));
3213 $$ = p.smobbed_copy ();
3223 TONICNAME_PITCH quotes {
3224 if (!scm_is_eq (SCM_INUM0, $2))
3226 Pitch p = *unsmob<Pitch> ($1);
3227 p = p.transposed (Pitch (scm_to_int ($2), 0));
3228 $$ = p.smobbed_copy ();
3235 | PITCH_IDENTIFIER quotes {
3236 if (!scm_is_eq (SCM_INUM0, $2))
3238 Pitch p = *unsmob<Pitch> ($1);
3239 p = p.transposed (Pitch (scm_to_int ($2), 0));
3240 $$ = p.smobbed_copy ();
3245 pitch_or_tonic_pitch:
3252 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
3253 t->set_property ("text", $1);
3254 $$ = t->unprotect ();
3257 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
3258 t->set_property ("text",
3259 make_simple_markup ($1));
3260 $$ = t->unprotect ();
3264 Music *m = unsmob<Music> ($1);
3265 if (m && m->is_mus_type ("post-event"))
3267 else if (Text_interface::is_markup ($1)) {
3268 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
3269 t->set_property ("text", $1);
3270 $$ = t->unprotect ();
3272 parser->parser_error (@1, _ ("not an articulation"));
3278 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @$);
3279 t->set_property ("digit", $1);
3280 $$ = t->unprotect ();
3284 script_abbreviation:
3286 $$ = scm_from_ascii_string ("Hat");
3289 $$ = scm_from_ascii_string ("Plus");
3292 $$ = scm_from_ascii_string ("Dash");
3295 $$ = scm_from_ascii_string ("Bang");
3298 $$ = scm_from_ascii_string ("Larger");
3301 $$ = scm_from_ascii_string ("Dot");
3304 $$ = scm_from_ascii_string ("Underscore");
3309 '_' { $$ = scm_from_int (DOWN); }
3310 | '^' { $$ = scm_from_int (UP); }
3311 | '-' { $$ = SCM_UNDEFINED; }
3314 maybe_notemode_duration:
3318 | multiplied_duration {
3320 parser->default_duration_ = *unsmob<Duration> ($$);
3325 optional_notemode_duration:
3326 maybe_notemode_duration
3328 if (SCM_UNBNDP ($$))
3329 $$ = parser->default_duration_.smobbed_copy ();
3335 $$ = make_duration ($1, scm_to_int ($2));
3336 if (SCM_UNBNDP ($$))
3338 parser->parser_error (@1, _ ("not a duration"));
3339 $$ = Duration ().smobbed_copy ();
3342 | DURATION_IDENTIFIER dots {
3343 $$ = make_duration ($1, scm_to_int ($2));
3347 multiplied_duration:
3348 steno_duration multipliers {
3349 $$ = make_duration ($1, 0, $2);
3358 $$ = scm_oneplus ($1);
3367 | multipliers '*' UNSIGNED
3369 if (!SCM_UNBNDP ($1))
3370 $$ = scm_product ($1, $3);
3374 | multipliers '*' FRACTION
3376 if (!SCM_UNBNDP ($1))
3377 $$ = scm_product ($1, scm_divide (scm_car ($3),
3380 $$ = scm_divide (scm_car ($3), scm_cdr ($3));
3386 $$ = scm_from_int (parser->default_tremolo_type_);
3389 if (SCM_UNBNDP (make_duration ($2))) {
3390 parser->parser_error (@2, _ ("not a duration"));
3391 $$ = scm_from_int (parser->default_tremolo_type_);
3394 parser->default_tremolo_type_ = scm_to_int ($2);
3400 UNSIGNED { $$ = $1; }
3401 | STRING { $$ = $1; }
3402 | full_markup { $$ = $1; }
3405 // as an integer, it needs to be non-negative, and otherwise
3406 // it needs to be suitable as a markup.
3407 if (scm_is_integer ($1)
3408 ? scm_is_true (scm_negative_p ($1))
3409 : !Text_interface::is_markup ($1))
3411 parser->parser_error (@1, _ ("bass number expected"));
3417 figured_bass_alteration:
3418 '-' { $$ = ly_rational2scm (FLAT_ALTERATION); }
3419 | '+' { $$ = ly_rational2scm (SHARP_ALTERATION); }
3420 | '!' { $$ = scm_from_int (0); }
3425 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
3426 $$ = bfr->unprotect ();
3429 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
3430 $$ = bfr->self_scm ();
3432 if (scm_is_number ($1))
3433 bfr->set_property ("figure", $1);
3434 else if (Text_interface::is_markup ($1))
3435 bfr->set_property ("text", $1);
3441 unsmob<Music> ($1)->set_property ("bracket-stop", SCM_BOOL_T);
3443 | bass_figure figured_bass_alteration {
3444 Music *m = unsmob<Music> ($1);
3445 if (scm_to_double ($2)) {
3446 SCM salter = m->get_property ("alteration");
3447 SCM alter = scm_is_number (salter) ? salter : scm_from_int (0);
3448 m->set_property ("alteration",
3449 scm_sum (alter, $2));
3451 m->set_property ("alteration", scm_from_int (0));
3454 | bass_figure figured_bass_modification {
3455 Music *m = unsmob<Music> ($1);
3456 m->set_property ($2, SCM_BOOL_T);
3461 figured_bass_modification:
3463 $$ = ly_symbol2scm ("augmented");
3466 $$ = ly_symbol2scm ("no-continuation");
3469 $$ = ly_symbol2scm ("diminished");
3472 $$ = ly_symbol2scm ("augmented-slash");
3482 unsmob<Music> ($$)->set_property ("bracket-start", SCM_BOOL_T);
3490 | figure_list br_bass_figure {
3491 $$ = scm_cons ($2, $1);
3496 /**/ { $$ = SCM_BOOL_F; }
3497 | REST { $$ = SCM_BOOL_T; }
3501 pitch exclamations questions octave_check maybe_notemode_duration optional_rest post_events {
3502 if (!parser->lexer_->is_note_state ())
3503 parser->parser_error (@1, _ ("have to be in Note mode for notes"));
3504 if (!SCM_UNBNDP ($2)
3506 || scm_is_number ($4)
3509 || scm_is_pair ($7))
3512 if (scm_is_true ($6))
3513 n = MY_MAKE_MUSIC ("RestEvent", @$);
3515 n = MY_MAKE_MUSIC ("NoteEvent", @$);
3517 n->set_property ("pitch", $1);
3518 if (SCM_UNBNDP ($5))
3519 n->set_property ("duration",
3520 parser->default_duration_.smobbed_copy ());
3522 n->set_property ("duration", $5);
3524 if (scm_is_number ($4))
3526 int q = scm_to_int ($4);
3527 n->set_property ("absolute-octave", scm_from_int (q-1));
3530 if (to_boolean ($3))
3531 n->set_property ("cautionary", SCM_BOOL_T);
3532 if (to_boolean ($2) || to_boolean ($3))
3533 n->set_property ("force-accidental", SCM_BOOL_T);
3534 if (scm_is_pair ($7))
3535 n->set_property ("articulations",
3536 scm_reverse_x ($7, SCM_EOL));
3537 $$ = n->unprotect ();
3540 | new_chord post_events {
3541 if (!parser->lexer_->is_chord_state ())
3542 parser->parser_error (@1, _ ("have to be in Chord mode for chords"));
3543 if (scm_is_pair ($2)) {
3544 if (unsmob<Pitch> ($1))
3545 $1 = make_chord_elements (@1,
3547 parser->default_duration_.smobbed_copy (),
3550 SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
3552 $$ = MAKE_SYNTAX (event_chord, @1, elts);
3553 } else if (!unsmob<Pitch> ($1))
3554 $$ = MAKE_SYNTAX (event_chord, @1, $1);
3555 // A mere pitch drops through.
3560 DRUM_PITCH optional_notemode_duration {
3561 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
3562 n->set_property ("duration", $2);
3563 n->set_property ("drum-type", $1);
3565 $$ = n->unprotect ();
3567 | RESTNAME optional_notemode_duration {
3569 if (ly_scm2string ($1) == "s") {
3571 ev = MY_MAKE_MUSIC ("SkipEvent", @$);
3574 ev = MY_MAKE_MUSIC ("RestEvent", @$);
3577 ev->set_property ("duration", $2);
3578 $$ = ev->unprotect ();
3584 if (!parser->lexer_->is_lyric_state ())
3585 parser->parser_error (@1, _ ("markup outside of text script or \\lyricmode"));
3589 if (!parser->lexer_->is_lyric_state ())
3590 parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode"));
3596 lyric_element_music:
3597 lyric_element optional_notemode_duration post_events {
3598 $$ = MAKE_SYNTAX (lyric_event, @$, $1, $2);
3599 if (scm_is_pair ($3))
3600 unsmob<Music> ($$)->set_property
3601 ("articulations", scm_reverse_x ($3, SCM_EOL));
3605 // Can return a single pitch rather than a list.
3607 steno_tonic_pitch maybe_notemode_duration {
3608 if (SCM_UNBNDP ($2))
3611 $$ = make_chord_elements (@$, $1, $2, SCM_EOL);
3613 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
3614 SCM its = scm_reverse_x ($4, SCM_EOL);
3615 $$ = make_chord_elements (@$, $1, $2, scm_cons ($3, its));
3623 | chord_items chord_item {
3624 $$ = scm_cons ($2, $$);
3630 $$ = ly_symbol2scm ("chord-colon");
3633 $$ = ly_symbol2scm ("chord-caret");
3635 | CHORD_SLASH steno_tonic_pitch {
3636 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
3638 | CHORD_BASS steno_tonic_pitch {
3639 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
3648 $$ = scm_reverse_x ($1, SCM_EOL);
3656 step_number { $$ = scm_cons ($1, SCM_EOL); }
3657 | step_numbers '.' step_number {
3658 $$ = scm_cons ($3, $$);
3664 $$ = make_chord_step ($1, 0);
3667 $$ = make_chord_step ($1, SHARP_ALTERATION);
3669 | UNSIGNED CHORD_MINUS {
3670 $$ = make_chord_step ($1, FLAT_ALTERATION);
3678 | unsigned_number '-' unsigned_number {
3679 $$ = scm_cons ($1, $3);
3686 TODO: should deprecate in favor of Scheme?
3690 number_expression '+' number_term {
3691 $$ = scm_sum ($1, $3);
3693 | number_expression '-' number_term {
3694 $$ = scm_difference ($1, $3);
3703 | number_factor '*' number_factor {
3704 $$ = scm_product ($1, $3);
3706 | number_factor '/' number_factor {
3707 $$ = scm_divide ($1, $3);
3712 '-' number_factor { /* %prec UNARY_MINUS */
3713 $$ = scm_difference ($2, SCM_UNDEFINED);
3721 | REAL NUMBER_IDENTIFIER
3723 $$ = scm_product ($1, $2);
3730 | UNSIGNED NUMBER_IDENTIFIER {
3731 $$ = scm_product ($1, $2);
3739 if (!scm_is_integer ($1)
3740 || scm_is_true (scm_negative_p ($1)))
3742 parser->parser_error (@1, _("not an unsigned integer"));
3748 if (!scm_is_integer ($1)
3749 || scm_is_true (scm_negative_p ($1)))
3751 parser->parser_error (@1, _("not an unsigned integer"));
3758 { $$ = SCM_UNDEFINED; }
3761 if (SCM_UNBNDP ($1))
3769 // This precedence rule is rather weird. It triggers when '!' is
3770 // encountered after a pitch, and is used for deciding whether to save
3771 // this instead for a figure modification. This should not actually
3772 // occur in practice as pitches and figures are generated in different
3773 // modes. Using a greedy (%right) precedence makes sure that we don't
3774 // get stuck in a wrong interpretation.
3775 { $$ = SCM_UNDEFINED; } %prec ':'
3778 if (SCM_UNBNDP ($1))
3787 { parser->lexer_->push_markup_state (); }
3790 parser->lexer_->pop_state ();
3797 parser->lexer_->push_markup_state ();
3802 markup_mode markup_top {
3804 parser->lexer_->pop_state ();
3809 markup_mode markup_partial_function ETC
3811 $$ = MAKE_SYNTAX (partial_markup, @2, $2);
3812 parser->lexer_->pop_state ();
3818 $$ = scm_list_2 (Lily::line_markup, $1);
3820 | markup_head_1_list simple_markup
3822 $$ = scm_car (MAKE_SYNTAX (composed_markup_list,
3823 @2, $1, scm_list_1 ($2)));
3833 if (Text_interface::is_markup ($1))
3834 MYBACKUP (MARKUP_IDENTIFIER, $1, @1);
3835 else if (Text_interface::is_markup_list ($1))
3836 MYBACKUP (MARKUPLIST_IDENTIFIER, $1, @1);
3838 parser->parser_error (@1, _ ("not a markup"));
3839 MYBACKUP (MARKUP_IDENTIFIER, scm_string (SCM_EOL), @1);
3846 markup_composed_list {
3849 | markup_uncomposed_list
3852 markup_uncomposed_list:
3853 markup_braced_list {
3856 | markup_command_list {
3857 $$ = scm_list_1 ($1);
3859 | markup_scm MARKUPLIST_IDENTIFIER
3864 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
3865 parser->lexer_->push_note_state (nn);
3866 } '{' score_body '}' {
3867 Score *sc = unsmob<Score> ($4);
3868 sc->origin ()->set_spot (@$);
3869 if (sc->defs_.empty ()) {
3870 Output_def *od = get_layout (parser);
3871 sc->add_output_def (od);
3874 $$ = scm_list_1 (scm_list_2 (Lily::score_lines_markup_list, $4));
3875 parser->lexer_->pop_state ();
3879 markup_composed_list:
3880 markup_head_1_list markup_uncomposed_list {
3881 $$ = MAKE_SYNTAX (composed_markup_list,
3887 '{' markup_braced_list_body '}' {
3888 $$ = scm_reverse_x ($2, SCM_EOL);
3892 markup_braced_list_body:
3893 /* empty */ { $$ = SCM_EOL; }
3894 | markup_braced_list_body markup {
3895 $$ = scm_cons ($2, $1);
3897 | markup_braced_list_body markup_list {
3898 $$ = scm_reverse_x ($2, $1);
3902 markup_command_list:
3903 MARKUP_LIST_FUNCTION markup_command_list_arguments {
3904 $$ = scm_cons ($1, scm_reverse_x($2, SCM_EOL));
3908 markup_command_basic_arguments:
3909 EXPECT_MARKUP_LIST markup_command_list_arguments markup_list {
3910 $$ = scm_cons ($3, $2);
3912 | EXPECT_SCM markup_command_list_arguments embedded_scm {
3913 $$ = check_scheme_arg (parser, @3, $3, $2, $1);
3915 | EXPECT_NO_MORE_ARGS {
3920 markup_command_list_arguments:
3921 markup_command_basic_arguments { $$ = $1; }
3922 | EXPECT_MARKUP markup_command_list_arguments markup {
3923 $$ = scm_cons ($3, $2);
3927 markup_partial_function:
3928 MARKUP_FUNCTION markup_arglist_partial
3930 $$ = scm_list_1 (scm_cons ($1, scm_reverse_x ($2, SCM_EOL)));
3932 | markup_head_1_list MARKUP_FUNCTION markup_arglist_partial
3934 $$ = scm_cons (scm_cons ($2, scm_reverse_x ($3, SCM_EOL)),
3939 markup_arglist_partial:
3940 EXPECT_MARKUP markup_arglist_partial
3944 | EXPECT_SCM markup_arglist_partial
3948 | EXPECT_MARKUP markup_command_list_arguments
3952 | EXPECT_SCM markup_command_list_arguments
3959 MARKUP_FUNCTION EXPECT_MARKUP markup_command_list_arguments {
3960 $$ = scm_cons ($1, scm_reverse_x ($3, SCM_EOL));
3965 markup_head_1_item {
3966 $$ = scm_list_1 ($1);
3968 | markup_head_1_list markup_head_1_item {
3969 $$ = scm_cons ($2, $1);
3975 $$ = make_simple_markup ($1);
3978 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
3979 parser->lexer_->push_note_state (nn);
3980 } '{' score_body '}' {
3981 Score *sc = unsmob<Score> ($4);
3982 sc->origin ()->set_spot (@$);
3983 if (sc->defs_.empty ()) {
3984 Output_def *od = get_layout (parser);
3985 sc->add_output_def (od);
3988 $$ = scm_list_2 (Lily::score_markup, $4);
3989 parser->lexer_->pop_state ();
3991 | MARKUP_FUNCTION markup_command_basic_arguments {
3992 $$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
3994 | markup_scm MARKUP_IDENTIFIER
4001 markup_head_1_list simple_markup
4003 $$ = scm_car (MAKE_SYNTAX (composed_markup_list,
4004 @2, $1, scm_list_1 ($2)));
4014 Lily_parser::set_yydebug (bool x)
4020 Lily_parser::do_yyparse ()
4022 return scm_c_with_fluid (Lily::f_parser,
4024 do_yyparse_trampoline,
4025 static_cast <void *>(this));
4029 Lily_parser::do_yyparse_trampoline (void *parser)
4031 SCM retval = SCM_UNDEFINED;
4032 yyparse (static_cast <Lily_parser *>(parser), &retval);
4040 It is a little strange to have this function in this file, but
4041 otherwise, we have to import music classes into the lexer.
4045 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
4047 if (unsmob<Book> (sid)) {
4048 Book *book = unsmob<Book> (sid)->clone ();
4049 *destination = book->self_scm ();
4052 return BOOK_IDENTIFIER;
4053 } else if (scm_is_number (sid)) {
4055 return NUMBER_IDENTIFIER;
4056 } else if (unsmob<Context_def> (sid))
4058 *destination = unsmob<Context_def> (sid)->clone ()->unprotect ();
4059 return SCM_IDENTIFIER;
4060 } else if (unsmob<Context_mod> (sid)) {
4061 *destination = unsmob<Context_mod> (sid)->smobbed_copy ();
4062 return CONTEXT_MOD_IDENTIFIER;
4063 } else if (Music *mus = unsmob<Music> (sid)) {
4064 mus = mus->clone ();
4065 *destination = mus->self_scm ();
4066 bool is_event = mus->is_mus_type ("post-event");
4068 return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
4069 } else if (unsmob<Pitch> (sid)) {
4070 *destination = unsmob<Pitch> (sid)->smobbed_copy ();
4071 return PITCH_IDENTIFIER;
4072 } else if (unsmob<Duration> (sid)) {
4073 *destination = unsmob<Duration> (sid)->smobbed_copy ();
4074 return DURATION_IDENTIFIER;
4075 } else if (unsmob<Output_def> (sid)) {
4076 *destination = unsmob<Output_def> (sid)->clone ()->unprotect ();
4077 return SCM_IDENTIFIER;
4078 } else if (unsmob<Score> (sid)) {
4079 *destination = unsmob<Score> (sid)->clone ()->unprotect ();
4080 return SCM_IDENTIFIER;
4081 } else if (scm_is_pair (sid)
4082 && scm_is_pair (scm_car (sid))
4083 && scm_is_true (Lily::key_p (scm_caar (sid)))) {
4085 return LOOKUP_IDENTIFIER;
4091 get_next_unique_context_id ()
4093 return scm_from_ascii_string ("$uniqueContextId");
4098 get_next_unique_lyrics_context_id ()
4100 static int new_context_count;
4102 snprintf (s, sizeof (s)-1, "uniqueContext%d", new_context_count++);
4103 return scm_from_ascii_string (s);
4106 // check_scheme_arg checks one argument with a given predicate for use
4107 // in an argument list and throws a syntax error if it is unusable.
4108 // The argument is prepended to the argument list in any case. After
4109 // throwing a syntax error, the argument list is terminated with #f as
4110 // its last cdr in order to mark it as uncallable while not losing
4111 // track of its total length.
4113 // There are a few special considerations: if optional argument disp
4114 // is given (otherwise it defaults to SCM_UNDEFINED), it will be used
4115 // instead of arg in a prospective error message. This is useful if
4116 // arg is not the actual argument but rather a transformation of it.
4118 // If arg itself is SCM_UNDEFINED, the predicate is considered false
4119 // and an error message using disp is produced unconditionally.
4121 SCM check_scheme_arg (Lily_parser *parser, Input loc,
4122 SCM arg, SCM args, SCM pred, SCM disp)
4124 if (SCM_UNBNDP (arg))
4125 args = scm_cons (disp, args);
4127 args = scm_cons (arg, args);
4128 if (scm_is_true (scm_call_1 (pred, arg)))
4131 scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
4132 MAKE_SYNTAX (argument_error, loc, scm_length (args), pred,
4133 SCM_UNBNDP (disp) ? arg : disp);
4134 scm_set_cdr_x (scm_last_pair (args), SCM_BOOL_F);
4138 SCM loc_on_music (Lily_parser *parser, Input loc, SCM arg)
4140 if (Music *m = unsmob<Music> (arg))
4143 m->set_spot (parser->lexer_->override_input (loc));
4144 return m->unprotect ();
4150 try_string_variants (SCM pred, SCM str)
4152 // a matching predicate is always ok
4153 if (scm_is_true (scm_call_1 (pred, str)))
4155 // a symbol may be interpreted as a list of symbols if it helps
4156 if (scm_is_true (Lily::key_p (str))) {
4157 str = scm_list_1 (str);
4158 if (scm_is_true (scm_call_1 (pred, str)))
4160 return SCM_UNDEFINED;
4163 // If this cannot be a string representation of a symbol list,
4166 if (!is_regular_identifier (str, true))
4167 return SCM_UNDEFINED;
4169 str = scm_string_split (str, SCM_MAKE_CHAR ('.'));
4170 for (SCM p = str; scm_is_pair (p); p = scm_cdr (p))
4171 scm_set_car_x (p, scm_string_split (scm_car (p),
4172 SCM_MAKE_CHAR (',')));
4173 str = scm_append_x (str);
4174 for (SCM p = str; scm_is_pair (p); p = scm_cdr (p))
4175 scm_set_car_x (p, scm_string_to_symbol (scm_car (p)));
4177 // Let's attempt the symbol list interpretation first.
4179 if (scm_is_true (scm_call_1 (pred, str)))
4182 // If there is just one symbol in the list, we might interpret
4183 // it as a single symbol
4185 if (scm_is_null (scm_cdr (str)))
4187 str = scm_car (str);
4188 if (scm_is_true (scm_call_1 (pred, str)))
4192 return SCM_UNDEFINED;
4196 is_regular_identifier (SCM id, bool multiple)
4198 if (!scm_is_string (id))
4201 string str = ly_scm2string (id);
4203 bool middle = false;
4205 for (string::iterator it=str.begin(); it != str.end (); it++)
4208 if ((c >= 'a' && c <= 'z')
4209 || (c >= 'A' && c <= 'Z')
4212 else if (middle && (c == '-' || c == '_' || (multiple &&
4213 (c == '.' || c == ','))))
4222 make_music_from_simple (Lily_parser *parser, Input loc, SCM simple)
4224 if (unsmob<Music> (simple))
4226 if (parser->lexer_->is_note_state ()) {
4227 if (scm_is_symbol (simple)) {
4228 Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
4229 n->set_property ("duration", parser->default_duration_.smobbed_copy ());
4230 n->set_property ("drum-type", simple);
4231 return n->unprotect ();
4233 if (unsmob<Pitch> (simple)) {
4234 Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
4235 n->set_property ("duration", parser->default_duration_.smobbed_copy ());
4236 n->set_property ("pitch", simple);
4237 return n->unprotect ();
4240 if (scm_is_integer (simple))
4241 d = make_duration (simple);
4242 if (unsmob<Duration> (d)) {
4243 Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
4244 n->set_property ("duration", d);
4245 return n->unprotect ();
4248 } else if (parser->lexer_->is_lyric_state ()) {
4249 if (Text_interface::is_markup (simple))
4250 return MAKE_SYNTAX (lyric_event, loc, simple,
4251 parser->default_duration_.smobbed_copy ());
4252 } else if (parser->lexer_->is_chord_state ()) {
4253 if (unsmob<Pitch> (simple))
4257 make_chord_elements (loc, simple,
4258 parser->default_duration_.smobbed_copy (),
4265 make_music_with_input (SCM name, Input where)
4267 Music *m = make_music_by_name (name);
4268 m->set_spot (where);
4273 make_simple_markup (SCM a)
4279 make_duration (SCM d, int dots, SCM factor)
4283 if (Duration *dur = unsmob<Duration> (d)) {
4284 if (!dots && SCM_UNBNDP (factor))
4288 k = Duration (k.duration_log (), k.dot_count () + dots)
4289 .compressed (k.factor ());
4291 int t = scm_to_int (d);
4292 if (t > 0 && (t & (t-1)) == 0)
4293 k = Duration (intlog2 (t), dots);
4295 return SCM_UNDEFINED;
4298 if (!SCM_UNBNDP (factor))
4299 k = k.compressed (ly_scm2rational (factor));
4301 return k.smobbed_copy ();
4305 make_chord_step (SCM step_scm, Rational alter)
4307 Pitch m (0, scm_to_int (step_scm) - 1, alter);
4309 // Notename/octave are normalized
4310 if (m.get_notename () == 6)
4311 m = m.transposed (Pitch (0, 0, FLAT_ALTERATION));
4313 return m.smobbed_copy ();
4318 make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list)
4320 SCM res = Lily::construct_chord_elements (pitch, dur, modification_list);
4321 for (SCM s = res; scm_is_pair (s); s = scm_cdr (s))
4323 unsmob<Music> (scm_car (s))->set_spot (loc);
4329 yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser)
4331 Lily_lexer *lex = parser->lexer_;
4335 int tok = lex->pop_extra_token ();
4338 lex->prepare_for_next_token ();
4339 return lex->yylex ();