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--2012 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 char *p = scm_to_locale_string \
45 (scm_simple_format (SCM_BOOL_F, \
46 scm_from_locale_string ("~S"), \
47 scm_list_1 (value))); \
54 %parse-param {Lily_parser *parser}
55 %parse-param {SCM *retval}
56 %lex-param {Lily_parser *parser}
60 /* We use SCMs to do strings, because it saves us the trouble of
61 deleting them. Let's hope that a stack overflow doesn't trigger a move
62 of the parse stack onto the heap. */
68 /* The above precedences tackle the shift/reduce problem
71 \repeat .. \alternative
73 \repeat { \repeat .. \alternative }
77 \repeat { \repeat } \alternative
83 %right ':' UNSIGNED REAL E_UNSIGNED EVENT_IDENTIFIER EVENT_FUNCTION '^' '_'
86 /* The above are needed for collecting tremoli and other items (that
87 could otherwise be interpreted as belonging to the next function
88 argument) greedily, and together with the next rule will serve to
89 join numbers and units greedily instead of allowing them into
90 separate function arguments
93 %nonassoc NUMBER_IDENTIFIER
105 %{ // -*-Fundamental-*-
110 * The rules for who is protecting what are very shady. Uniformise
113 * There are too many lexical modes?
124 #include "context-def.hh"
125 #include "context-mod.hh"
126 #include "dimensions.hh"
127 #include "file-path.hh"
129 #include "international.hh"
130 #include "lily-guile.hh"
131 #include "lily-lexer.hh"
132 #include "lily-parser.hh"
136 #include "output-def.hh"
137 #include "paper-book.hh"
138 #include "scm-hash.hh"
140 #include "text-interface.hh"
144 Lily_parser::parser_error (Input const *i, Lily_parser *parser, SCM *, const string &s)
146 parser->parser_error (*i, s);
149 #define MYBACKUP(Token, Value, Location) \
151 if (yychar == YYEMPTY) \
154 parser->lexer_->push_extra_token (Token, Value); \
155 parser->lexer_->push_extra_token (BACKUP); \
157 parser->parser_error \
158 (Location, _("Too much lookahead")); \
163 #define MYREPARSE(Location, Pred, Token, Value) \
165 if (yychar == YYEMPTY) \
167 parser->lexer_->push_extra_token (Token, Value); \
168 parser->lexer_->push_extra_token (REPARSE, \
171 parser->parser_error \
172 (Location, _("Too much lookahead")); \
181 #define MY_MAKE_MUSIC(x, spot) \
182 make_music_with_input (ly_symbol2scm (x), \
183 parser->lexer_->override_input (spot))
186 - Don't use lily module, create a new module instead.
187 - delay application of the function
189 #define LOWLEVEL_MAKE_SYNTAX(proc, args) \
190 scm_apply_0 (proc, args)
191 /* Syntactic Sugar. */
192 #define MAKE_SYNTAX(name, location, ...) \
193 LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (parser->self_scm (), make_input (parser->lexer_->override_input (location)), ##__VA_ARGS__, SCM_UNDEFINED))
194 #define START_MAKE_SYNTAX(name, ...) \
195 scm_list_n (ly_lily_module_constant (name) , ##__VA_ARGS__, SCM_UNDEFINED)
196 #define FINISH_MAKE_SYNTAX(start, location, ...) \
197 LOWLEVEL_MAKE_SYNTAX (scm_car (start), scm_cons2 (parser->self_scm (), make_input (parser->lexer_->override_input (location)), scm_append_x (scm_list_2 (scm_cdr (start), scm_list_n (__VA_ARGS__, SCM_UNDEFINED)))))
199 SCM get_next_unique_context_id ();
200 SCM get_next_unique_lyrics_context_id ();
207 #define _(x) gettext (x)
211 static Music *make_music_with_input (SCM name, Input where);
212 SCM check_scheme_arg (Lily_parser *parser, Input loc,
213 SCM arg, SCM args, SCM pred, SCM disp = SCM_UNDEFINED);
214 SCM make_music_from_simple (Lily_parser *parser, Input loc, SCM pitch);
215 SCM loc_on_music (Input loc, SCM arg);
216 SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list);
217 SCM make_chord_step (SCM step, Rational alter);
218 SCM make_simple_markup (SCM a);
219 SCM make_duration (SCM t, int dots = 0);
220 bool is_regular_identifier (SCM id, bool multiple=false);
221 SCM try_string_variants (SCM pred, SCM str);
222 int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser);
226 /* The third option is an alias that will be used to display the
227 syntax error. Bison CVS now correctly handles backslash escapes.
229 FIXME: Bison needs to translate some of these, eg, STRING.
233 /* Keyword tokens with plain escaped name. */
234 %token END_OF_FILE 0 "end of input"
235 %token ACCEPTS "\\accepts"
236 %token ADDLYRICS "\\addlyrics"
237 %token ALIAS "\\alias"
238 %token ALTERNATIVE "\\alternative"
240 %token BOOKPART "\\bookpart"
241 %token CHANGE "\\change"
242 %token CHORDMODE "\\chordmode"
243 %token CHORDS "\\chords"
244 %token CONSISTS "\\consists"
245 %token CONTEXT "\\context"
246 %token DEFAULT "\\default"
247 %token DEFAULTCHILD "\\defaultchild"
248 %token DENIES "\\denies"
249 %token DESCRIPTION "\\description"
250 %token DRUMMODE "\\drummode"
251 %token DRUMS "\\drums"
252 %token FIGUREMODE "\\figuremode"
253 %token FIGURES "\\figures"
254 %token HEADER "\\header"
255 %token INVALID "\\version-error"
256 %token LAYOUT "\\layout"
257 %token LYRICMODE "\\lyricmode"
258 %token LYRICS "\\lyrics"
259 %token LYRICSTO "\\lyricsto"
260 %token MARKUP "\\markup"
261 %token MARKUPLIST "\\markuplist"
264 %token NOTEMODE "\\notemode"
265 %token OVERRIDE "\\override"
266 %token PAPER "\\paper"
267 %token REMOVE "\\remove"
268 %token REPEAT "\\repeat"
270 %token REVERT "\\revert"
271 %token SCORE "\\score"
272 %token SEQUENTIAL "\\sequential"
274 %token SIMULTANEOUS "\\simultaneous"
275 %token TEMPO "\\tempo"
277 %token UNSET "\\unset"
280 /* Keyword token exceptions. */
281 %token NEWCONTEXT "\\new"
284 /* Other string tokens. */
286 %token CHORD_BASS "/+"
287 %token CHORD_CARET "^"
288 %token CHORD_COLON ":"
289 %token CHORD_MINUS "-"
290 %token CHORD_SLASH "/"
291 %token ANGLE_OPEN "<"
292 %token ANGLE_CLOSE ">"
293 %token DOUBLE_ANGLE_OPEN "<<"
294 %token DOUBLE_ANGLE_CLOSE ">>"
295 %token E_BACKSLASH "\\"
296 %token E_EXCLAMATION "\\!"
301 If we give names, Bison complains.
303 %token FIGURE_CLOSE /* "\\>" */
304 %token FIGURE_OPEN /* "\\<" */
305 %token FIGURE_SPACE "_"
308 %token MULTI_MEASURE_REST
314 /* Artificial tokens, for more generic function syntax */
315 %token EXPECT_MARKUP "markup?"
316 %token EXPECT_SCM "scheme?"
317 %token BACKUP "(backed-up?)"
318 %token REPARSE "(reparsed?)"
319 %token EXPECT_MARKUP_LIST "markup-list?"
320 %token EXPECT_OPTIONAL "optional?"
321 /* After the last argument. */
322 %token EXPECT_NO_MORE_ARGS;
324 /* An artificial token for parsing embedded Lilypond */
325 %token EMBEDDED_LILY "#{"
327 %token BOOK_IDENTIFIER
328 %token CHORD_MODIFIER
329 %token CHORD_REPETITION
330 %token CONTEXT_DEF_IDENTIFIER
331 %token CONTEXT_MOD_IDENTIFIER
333 %token PITCH_IDENTIFIER
334 %token DURATION_IDENTIFIER
335 %token EVENT_IDENTIFIER
336 %token EVENT_FUNCTION
339 %token MARKUP_FUNCTION
340 %token MARKUP_LIST_FUNCTION
341 %token MARKUP_IDENTIFIER
342 %token MARKUPLIST_IDENTIFIER
343 %token MUSIC_FUNCTION
344 %token MUSIC_IDENTIFIER
345 %token NOTENAME_PITCH
346 %token NUMBER_IDENTIFIER
347 %token OUTPUT_DEF_IDENTIFIER
352 %token SCM_IDENTIFIER
356 %token TONICNAME_PITCH
360 /* We don't assign precedence to / and *, because we might need varied
361 prec levels in different prods */
370 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
371 parser->lexer_->push_note_state (nn);
372 } embedded_lilypond {
373 parser->lexer_->pop_state ();
378 lilypond: /* empty */ { $$ = SCM_UNSPECIFIED; }
379 | lilypond toplevel_expression {
381 | lilypond assignment {
384 parser->error_level_ = 1;
387 parser->error_level_ = 1;
394 parser->lexer_->add_scope (get_header (parser));
396 parser->lexer_->set_identifier (ly_symbol2scm ("$defaultheader"), $2);
399 SCM proc = parser->lexer_->lookup_identifier ("toplevel-book-handler");
400 scm_call_2 (proc, parser->self_scm (), $1);
403 SCM proc = parser->lexer_->lookup_identifier ("toplevel-bookpart-handler");
404 scm_call_2 (proc, parser->self_scm (), $1);
407 SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
408 scm_call_2 (proc, parser->self_scm (), $1);
411 SCM proc = parser->lexer_->lookup_identifier ("toplevel-music-handler");
412 scm_call_2 (proc, parser->self_scm (), $1);
415 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
416 scm_call_2 (proc, parser->self_scm (), scm_list_1 ($1));
419 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
420 scm_call_2 (proc, parser->self_scm (), $1);
423 // Evaluate and ignore #xxx, as opposed to \xxx
424 parser->lexer_->eval_scm_token ($1);
426 | embedded_scm_active
428 SCM out = SCM_UNDEFINED;
429 if (Text_interface::is_markup ($1))
430 out = scm_list_1 ($1);
431 else if (Text_interface::is_markup_list ($1))
433 if (scm_is_pair (out))
435 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
436 scm_call_2 (proc, parser->self_scm (), out);
437 } else if (!scm_is_eq ($1, SCM_UNSPECIFIED))
438 parser->parser_error (@1, _("bad expression type"));
442 Output_def * od = unsmob_output_def ($1);
444 if (od->c_variable ("is-paper") == SCM_BOOL_T)
445 id = ly_symbol2scm ("$defaultpaper");
446 else if (od->c_variable ("is-midi") == SCM_BOOL_T)
447 id = ly_symbol2scm ("$defaultmidi");
448 else if (od->c_variable ("is-layout") == SCM_BOOL_T)
449 id = ly_symbol2scm ("$defaultlayout");
451 parser->lexer_->set_identifier (id, $1);
458 $$ = parser->lexer_->eval_scm_token ($1);
468 embedded_scm_bare_arg:
472 $$ = parser->lexer_->eval_scm_token ($1);
475 | context_modification
477 | context_def_spec_block
483 /* The generic version may end in music, or not */
490 /* embedded_scm_arg is _not_ casting pitches to music by default, this
491 * has to be done by the function itself. Note that this may cause
492 * the results of scm_function_call or embedded_scm_bare_arg to be
493 * turned into music from pitches as well. Note that this creates a
494 * distinctly awkward situation for calculated drum pitches. Those
495 * are at the current point of time rejected as music constituents as
496 * they can't be distinguished from "proper" symbols.
500 embedded_scm_bare_arg
506 SCM_FUNCTION function_arglist {
507 $$ = MAKE_SYNTAX ("music-function", @$,
515 // FIXME: @$ does not contain a useful source location
516 // for empty rules, and the only token in the whole
517 // production, EMBEDDED_LILY, is synthetic and also
518 // contains no source location.
519 $$ = MAKE_SYNTAX ("void-music", @$);
522 | music_embedded music_embedded music_list {
523 $3 = scm_reverse_x ($3, SCM_EOL);
524 if (unsmob_music ($2))
525 $3 = scm_cons ($2, $3);
526 if (unsmob_music ($1))
527 $3 = scm_cons ($1, $3);
528 $$ = MAKE_SYNTAX ("sequential-music", @$, $3);
531 parser->error_level_ = 1;
532 $$ = SCM_UNSPECIFIED;
534 | INVALID embedded_lilypond {
535 parser->error_level_ = 1;
541 lilypond_header_body:
542 /* empty */ { $$ = SCM_UNSPECIFIED; }
543 | lilypond_header_body assignment {
546 | lilypond_header_body embedded_scm {
552 HEADER '{' lilypond_header_body '}' {
553 $$ = parser->lexer_->remove_scope ();
565 assignment_id '=' identifier_init {
566 parser->lexer_->set_identifier ($1, $3);
567 $$ = SCM_UNSPECIFIED;
569 | assignment_id property_path '=' identifier_init {
570 SCM path = scm_cons (scm_string_to_symbol ($1), $2);
571 parser->lexer_->set_identifier (path, $4);
572 $$ = SCM_UNSPECIFIED;
582 | context_def_spec_block
584 | post_event_nofinger post_events
586 $$ = scm_reverse_x ($2, SCM_EOL);
587 if (Music *m = unsmob_music ($1))
589 if (m->is_mus_type ("post-event-wrapper"))
591 (scm_list_2 (m->get_property ("elements"),
594 $$ = scm_cons ($1, $$);
597 && scm_is_null (scm_cdr ($$)))
601 Music * m = MY_MAKE_MUSIC ("PostEvents", @$);
602 m->set_property ("elements", $$);
603 $$ = m->unprotect ();
611 | context_modification
614 context_def_spec_block:
615 CONTEXT '{' context_def_spec_body '}'
618 unsmob_context_def ($$)->origin ()->set_spot (@$);
626 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
627 parser->lexer_->push_note_state (nn);
631 parser->lexer_->pop_state ();
636 context_mod_embedded:
639 if (unsmob_music ($1)) {
640 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
641 $1 = scm_call_2 (proc, parser->self_scm (), $1);
643 if (unsmob_context_mod ($1))
646 parser->parser_error (@1, _ ("not a context mod"));
647 $$ = Context_mod ().smobbed_copy ();
653 context_def_spec_body:
655 $$ = Context_def::make_scm ();
657 | CONTEXT_DEF_IDENTIFIER {
660 | context_def_spec_body context_mod {
661 if (!SCM_UNBNDP ($2))
662 unsmob_context_def ($$)->add_context_mod ($2);
664 | context_def_spec_body context_modification {
665 Context_def *td = unsmob_context_def ($$);
666 SCM new_mods = unsmob_context_mod ($2)->get_mods ();
667 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
668 td->add_context_mod (scm_car (m));
671 | context_def_spec_body context_mod_embedded {
672 Context_def *td = unsmob_context_def ($$);
673 SCM new_mods = unsmob_context_mod ($2)->get_mods ();
674 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
675 td->add_context_mod (scm_car (m));
683 BOOK '{' book_body '}' {
685 unsmob_book ($$)->origin ()->set_spot (@$);
687 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), SCM_BOOL_F);
692 * Use 'handlers' like for toplevel-* stuff?
693 * grok \layout and \midi? */
696 Book *book = new Book;
697 init_papers (parser);
698 book->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (parser->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
699 book->paper_->unprotect ();
700 push_paper (parser, book->paper_);
701 book->header_ = get_header (parser);
702 $$ = book->unprotect ();
703 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$);
706 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $1);
708 | book_body paper_block {
709 unsmob_book ($1)->paper_ = unsmob_output_def ($2);
710 set_paper (parser, unsmob_output_def ($2));
712 | book_body bookpart_block {
713 SCM proc = parser->lexer_->lookup_identifier ("book-bookpart-handler");
714 scm_call_2 (proc, $1, $2);
716 | book_body score_block {
717 SCM proc = parser->lexer_->lookup_identifier ("book-score-handler");
718 scm_call_2 (proc, $1, $2);
720 | book_body composite_music {
721 SCM proc = parser->lexer_->lookup_identifier ("book-music-handler");
722 scm_call_3 (proc, parser->self_scm (), $1, $2);
724 | book_body full_markup {
725 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
726 scm_call_2 (proc, $1, scm_list_1 ($2));
728 | book_body full_markup_list {
729 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
730 scm_call_2 (proc, $1, $2);
732 | book_body SCM_TOKEN {
733 // Evaluate and ignore #xxx, as opposed to \xxx
734 parser->lexer_->eval_scm_token ($2);
736 | book_body embedded_scm_active
738 SCM out = SCM_UNDEFINED;
739 if (Text_interface::is_markup ($2))
740 out = scm_list_1 ($2);
741 else if (Text_interface::is_markup_list ($2))
743 if (scm_is_pair (out))
745 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
746 scm_call_2 (proc, $1, out);
747 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
748 parser->parser_error (@2, _("bad expression type"));
752 parser->lexer_->add_scope (unsmob_book ($1)->header_);
755 Book *book = unsmob_book ($1);
757 book->scores_ = SCM_EOL;
758 book->bookparts_ = SCM_EOL;
763 BOOKPART '{' bookpart_body '}' {
765 unsmob_book ($$)->origin ()->set_spot (@$);
766 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F);
772 Book *book = new Book;
773 $$ = book->unprotect ();
774 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $$);
777 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $1);
779 | bookpart_body paper_block {
780 unsmob_book ($$)->paper_ = unsmob_output_def ($2);
782 | bookpart_body score_block {
783 SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler");
784 scm_call_2 (proc, $1, $2);
786 | bookpart_body composite_music {
787 SCM proc = parser->lexer_->lookup_identifier ("bookpart-music-handler");
788 scm_call_3 (proc, parser->self_scm (), $1, $2);
790 | bookpart_body full_markup {
791 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
792 scm_call_2 (proc, $1, scm_list_1 ($2));
794 | bookpart_body full_markup_list {
795 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
796 scm_call_2 (proc, $1, $2);
798 | bookpart_body SCM_TOKEN {
799 // Evaluate and ignore #xxx, as opposed to \xxx
800 parser->lexer_->eval_scm_token ($2);
802 | bookpart_body embedded_scm_active
804 SCM out = SCM_UNDEFINED;
805 if (Text_interface::is_markup ($2))
806 out = scm_list_1 ($2);
807 else if (Text_interface::is_markup_list ($2))
809 if (scm_is_pair (out))
811 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
812 scm_call_2 (proc, $1, out);
813 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
814 parser->parser_error (@2, _("bad expression type"));
818 Book *book = unsmob_book ($1);
819 if (!ly_is_module (book->header_))
820 book->header_ = ly_make_module (false);
821 parser->lexer_->add_scope (book->header_);
823 | bookpart_body error {
824 Book *book = unsmob_book ($1);
826 book->scores_ = SCM_EOL;
831 SCORE '{' score_body '}' {
838 SCM scorify = ly_lily_module_constant ("scorify-music");
839 $$ = scm_call_2 (scorify, $1, parser->self_scm ());
841 unsmob_score ($$)->origin ()->set_spot (@$);
843 | embedded_scm_active {
845 if (unsmob_score ($1))
846 score = new Score (*unsmob_score ($1));
849 parser->parser_error (@1, _("score expected"));
851 unsmob_score ($$)->origin ()->set_spot (@$);
852 $$ = score->unprotect ();
856 Score *score = unsmob_score ($1);
857 if (!ly_is_module (score->get_header ()))
858 score->set_header (ly_make_module (false));
859 parser->lexer_->add_scope (score->get_header ());
861 | score_body output_def {
862 Output_def *od = unsmob_output_def ($2);
863 if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
865 parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
870 unsmob_score ($1)->add_output_def (od);
874 unsmob_score ($$)->error_found_ = true;
885 Output_def *od = unsmob_output_def ($1);
887 if (od->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
889 parser->parser_error (@1, _ ("need \\paper for paper block"));
890 $$ = get_paper (parser)->unprotect ();
897 output_def_body '}' {
900 parser->lexer_->remove_scope ();
901 parser->lexer_->pop_state ();
907 Output_def *p = get_paper (parser);
908 p->input_origin_ = @$;
909 parser->lexer_->add_scope (p->scope_);
910 $$ = p->unprotect ();
913 Output_def *p = get_midi (parser);
914 $$ = p->unprotect ();
915 parser->lexer_->add_scope (p->scope_);
918 Output_def *p = get_layout (parser);
920 parser->lexer_->add_scope (p->scope_);
921 $$ = p->unprotect ();
925 output_def_head_with_mode_switch:
927 parser->lexer_->push_initial_state ();
932 // We need this weird nonterminal because both music as well as a
933 // context definition can start with \context and the difference is
934 // only apparent after looking at the next token. If it is '{', there
935 // is still time to escape from notes mode.
937 music_or_context_def:
939 | context_def_spec_block
943 output_def_head_with_mode_switch '{' {
945 unsmob_output_def ($$)->input_origin_.set_spot (@$);
947 | output_def_head_with_mode_switch '{' OUTPUT_DEF_IDENTIFIER {
948 Output_def *o = unsmob_output_def ($3);
949 o->input_origin_.set_spot (@$);
951 parser->lexer_->remove_scope ();
952 parser->lexer_->add_scope (o->scope_);
954 | output_def_body assignment {
957 | output_def_body embedded_scm {
962 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
963 parser->lexer_->push_note_state (nn);
964 } music_or_context_def
966 parser->lexer_->pop_state ();
967 if (unsmob_context_def ($3))
968 assign_context_def (unsmob_output_def ($1), $3);
971 SCM proc = parser->lexer_->lookup_identifier
972 ("output-def-music-handler");
973 scm_call_3 (proc, parser->self_scm (),
977 | output_def_body error {
983 TEMPO steno_duration '=' tempo_range {
984 $$ = MAKE_SYNTAX ("tempo", @$, SCM_EOL, $2, $4);
986 | TEMPO scalar_closed steno_duration '=' tempo_range {
987 $$ = MAKE_SYNTAX ("tempo", @$, $2, $3, $5);
990 $$ = MAKE_SYNTAX ("tempo", @$, $2);
995 The representation of a list is reversed to have efficient append. */
1001 | music_list music_embedded {
1002 if (unsmob_music ($2))
1003 $$ = scm_cons ($2, $1);
1005 | music_list error {
1006 Music *m = MY_MAKE_MUSIC("Music", @$);
1008 m->set_property ("error-found", SCM_BOOL_T);
1009 $$ = scm_cons (m->self_scm (), $1);
1010 m->unprotect (); /* UGH */
1017 $$ = scm_reverse_x ($2, SCM_EOL);
1022 | lyric_element_music
1028 if (unsmob_music ($1)->is_mus_type ("post-event")) {
1029 parser->parser_error (@1, _ ("unexpected post-event"));
1030 $$ = SCM_UNSPECIFIED;
1033 | music_embedded_backup
1037 | music_embedded_backup BACKUP lyric_element_music
1043 music_embedded_backup:
1046 if (scm_is_eq ($1, SCM_UNSPECIFIED))
1048 else if (Music *m = unsmob_music ($1)) {
1049 if (m->is_mus_type ("post-event")) {
1050 parser->parser_error
1051 (@1, _ ("unexpected post-event"));
1052 $$ = SCM_UNSPECIFIED;
1055 } else if (parser->lexer_->is_lyric_state ()
1056 && Text_interface::is_markup ($1))
1057 MYBACKUP (LYRIC_ELEMENT, $1, @1);
1059 @$.warning (_ ("Ignoring non-music expression"));
1068 $$ = make_music_from_simple (parser, @1, $1);
1069 if (!unsmob_music ($$))
1071 parser->parser_error (@1, _ ("music expected"));
1072 $$ = MAKE_SYNTAX ("void-music", @$);
1075 | composite_music %prec COMPOSITE
1080 | composite_music %prec COMPOSITE
1084 REPEAT simple_string unsigned_number music
1086 $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, SCM_EOL);
1088 | REPEAT simple_string unsigned_number music ALTERNATIVE braced_music_list
1090 $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, $6);
1095 SEQUENTIAL braced_music_list {
1096 $$ = MAKE_SYNTAX ("sequential-music", @$, $2);
1098 | braced_music_list {
1099 $$ = MAKE_SYNTAX ("sequential-music", @$, $1);
1104 SIMULTANEOUS braced_music_list {
1105 $$ = MAKE_SYNTAX ("simultaneous-music", @$, $2);
1107 | DOUBLE_ANGLE_OPEN music_list DOUBLE_ANGLE_CLOSE {
1108 $$ = MAKE_SYNTAX ("simultaneous-music", @$, scm_reverse_x ($2, SCM_EOL));
1114 | music_property_def
1118 context_modification:
1121 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
1122 parser->lexer_->push_note_state (nn);
1123 } '{' context_mod_list '}'
1125 parser->lexer_->pop_state ();
1128 | WITH CONTEXT_MOD_IDENTIFIER
1132 | CONTEXT_MOD_IDENTIFIER
1136 | WITH context_modification_arg
1138 if (unsmob_music ($2)) {
1139 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
1140 $2 = scm_call_2 (proc, parser->self_scm (), $2);
1142 if (unsmob_context_mod ($2))
1145 parser->parser_error (@2, _ ("not a context mod"));
1146 $$ = Context_mod ().smobbed_copy ();
1151 context_modification_arg:
1156 optional_context_mod:
1160 | context_modification
1168 $$ = Context_mod ().smobbed_copy ();
1170 | context_mod_list context_mod {
1171 if (!SCM_UNBNDP ($2))
1172 unsmob_context_mod ($1)->add_context_mod ($2);
1174 | context_mod_list CONTEXT_MOD_IDENTIFIER {
1175 Context_mod *md = unsmob_context_mod ($2);
1177 unsmob_context_mod ($1)->add_context_mods (md->get_mods ());
1179 | context_mod_list context_mod_embedded {
1180 unsmob_context_mod ($1)->add_context_mods
1181 (unsmob_context_mod ($2)->get_mods ());
1190 /* Music that can be parsed without lookahead */
1193 | complex_music_prefix closed_music
1195 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
1197 | music_function_call_closed
1203 | grouped_music_list
1207 simultaneous_music { $$ = $1; }
1208 | sequential_music { $$ = $1; }
1211 /* Function argument lists are arguably the most complex part in the
1212 * parser. They are pretty tricky to understand because of the way
1213 * they are processed, and because of optional arguments that can be
1214 * omitted. When there are several optional arguments in a row,
1215 * omitting one automatically omits all following arguments. Optional
1216 * arguments can only be omitted when either
1218 * a) the omission is explicitly started with \default
1219 * b) the omission is implicitly started by an argument not matching
1220 * its predicate, and there is a mandatory argument later that can
1221 * "catch" the argument that does not fit.
1223 * When argument parsing starts, the lexer pushes EXPECT_SCM tokens
1224 * (corresponding to mandatory arguments and having a predicate
1225 * function as semantic value) or EXPECT_OPTIONAL EXPECT_SCM (where
1226 * the semantic value of the EXPECT_OPTIONAL token is the default to
1227 * use when the optional argument is omitted, and EXPECT_SCM again has
1228 * the argument predicate as semantic value) in reverse order to the
1229 * parser, followed by EXPECT_NO_MORE_ARGS. The argument list is then
1230 * processed inside-out while actual tokens are consumed.
1232 * This means that the argument list tokens determine the actions
1233 * taken as they arrive. The structure of the argument list is known
1234 * to the parser and stored in its parse stack when the first argument
1235 * is being parsed. What the parser does not know is which predicates
1236 * will match and whether or not \default will be appearing in the
1237 * argument list, and where.
1239 * Many of the basic nonterminals used for argument list scanning come
1240 * in a "normal" and a "closed" flavor. A closed expression is one
1241 * that can be parsed without a lookahead token. That makes it
1242 * feasible for an optional argument that may need to be skipped:
1243 * skipping can only be accomplished by pushing back the token into
1244 * the lexer, and that only works when there is no lookahead token.
1246 * Sequences of 0 or more optional arguments are scanned using either
1247 * function_arglist_backup or function_arglist_nonbackup. The first
1248 * is used when optional arguments are followed by at least one
1249 * mandatory argument: in that case optional arguments may be skipped
1250 * by either a false predicate (in which case the expression will be
1251 * pushed back as one or more tokens, preceded by a BACKUP token) or
1252 * by using \default.
1254 * If optional arguments are at the end of the argument list, they are
1255 * instead scanned using function_arglist_nonbackup: here the only
1256 * manner to enter into skipping of optional arguments is the use of
1259 * The argument list of a normal function call is parsed using
1260 * function_arglist. The part of an argument list before a mandatory
1261 * argument is parsed using function_arglist_optional.
1263 * The difference is that leading optional arguments are scanned using
1264 * function_arglist_nonbackup and function_arglist_backup,
1267 * Most other details are obvious in the rules themselves.
1271 function_arglist_nonbackup_common:
1272 EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup FRACTION
1274 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1276 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup post_event_nofinger
1278 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1280 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' UNSIGNED
1282 SCM n = scm_difference ($5, SCM_UNDEFINED);
1283 if (scm_is_true (scm_call_1 ($2, n)))
1284 $$ = scm_cons (n, $3);
1286 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
1287 t->set_property ("digit", $5);
1288 $$ = check_scheme_arg (parser, @4, t->unprotect (),
1293 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL
1295 $$ = check_scheme_arg (parser, @4,
1296 scm_difference ($5, SCM_UNDEFINED),
1299 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' NUMBER_IDENTIFIER
1301 $$ = check_scheme_arg (parser, @4,
1302 scm_difference ($5, SCM_UNDEFINED),
1307 function_arglist_closed_nonbackup:
1308 function_arglist_nonbackup_common
1309 | function_arglist_closed_common
1310 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg_closed
1312 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1314 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_nonbackup bare_number_closed
1316 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1318 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
1320 $$ = check_scheme_arg (parser, @4,
1321 try_string_variants ($2, $4),
1324 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
1326 $$ = check_scheme_arg (parser, @4,
1327 try_string_variants ($2, $4),
1330 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup full_markup
1332 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1338 | SYMBOL_LIST '.' symbol_list_rev
1340 $$ = scm_append (scm_list_2 ($1, scm_reverse_x ($3, SCM_EOL)));
1346 | symbol_list_rev '.' symbol_list_part
1348 $$ = scm_append_x (scm_list_2 ($3, $1));
1352 // symbol_list_part delivers elements in reverse copy.
1357 SCM sym_l_p = ly_lily_module_constant ("symbol-list?");
1358 $$ = try_string_variants (sym_l_p, $1);
1359 if (SCM_UNBNDP ($$)) {
1360 parser->parser_error (@1, _("not a symbol"));
1363 $$ = scm_reverse ($$);
1368 symbol_list_element:
1374 function_arglist_nonbackup:
1375 function_arglist_nonbackup_common
1376 | function_arglist_common
1377 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg
1379 if (scm_is_true (scm_call_1 ($2, $4)))
1380 $$ = scm_cons ($4, $3);
1382 $$ = check_scheme_arg (parser, @4,
1383 make_music_from_simple
1387 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_nonbackup bare_number_common
1389 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1391 | function_arglist_nonbackup_reparse REPARSE duration_length
1393 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1395 | function_arglist_nonbackup_reparse REPARSE bare_number_common
1397 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1399 | function_arglist_nonbackup_reparse REPARSE SCM_ARG
1401 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1403 | function_arglist_nonbackup_reparse REPARSE lyric_element_music
1405 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1407 | function_arglist_nonbackup_reparse REPARSE symbol_list_arg
1409 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1413 function_arglist_nonbackup_reparse:
1414 EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
1417 SCM res = try_string_variants ($2, $4);
1418 if (!SCM_UNBNDP (res))
1419 if (scm_is_pair (res))
1420 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1422 MYREPARSE (@4, $2, SCM_ARG, res);
1423 else if (scm_is_true
1425 ($2, make_music_from_simple
1427 MYREPARSE (@4, $2, STRING, $4);
1429 MYREPARSE (@4, $2, SCM_ARG, $4);
1431 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
1434 SCM res = try_string_variants ($2, $4);
1435 if (!SCM_UNBNDP (res))
1436 if (scm_is_pair (res))
1437 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1439 MYREPARSE (@4, $2, SCM_ARG, res);
1440 else if (scm_is_true
1442 ($2, make_music_from_simple
1444 MYREPARSE (@4, $2, STRING, $4);
1446 MYREPARSE (@4, $2, SCM_ARG, $4);
1448 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup full_markup
1451 if (scm_is_true (scm_call_1 ($2, $4)))
1452 MYREPARSE (@4, $2, SCM_ARG, $4);
1453 else if (scm_is_true
1455 ($2, make_music_from_simple
1457 MYREPARSE (@4, $2, STRING, $4);
1459 MYREPARSE (@4, $2, SCM_ARG, $4);
1461 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_nonbackup UNSIGNED
1464 if (scm_is_true (scm_call_1 ($2, $4)))
1465 MYREPARSE (@4, $2, REAL, $4);
1467 SCM d = make_duration ($4);
1468 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
1469 MYREPARSE (@4, $2, REAL, $4); // trigger error
1471 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
1474 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_nonbackup DURATION_IDENTIFIER {
1476 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
1481 function_arglist_backup:
1482 function_arglist_backup_common
1483 | function_arglist_common
1486 function_arglist_closed_backup:
1487 function_arglist_backup_common
1488 | function_arglist_closed_common
1491 function_arglist_backup_common:
1492 EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup embedded_scm_arg_closed
1494 if (scm_is_true (scm_call_1 ($2, $4)))
1496 $$ = scm_cons ($4, $3);
1498 $$ = scm_cons (loc_on_music (@3, $1), $3);
1499 MYBACKUP (SCM_ARG, $4, @4);
1502 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup post_event_nofinger
1504 if (scm_is_true (scm_call_1 ($2, $4)))
1506 $$ = scm_cons ($4, $3);
1508 $$ = scm_cons (loc_on_music (@3, $1), $3);
1509 MYBACKUP (EVENT_IDENTIFIER, $4, @4);
1512 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup full_markup
1514 if (scm_is_true (scm_call_1 ($2, $4)))
1515 $$ = scm_cons ($4, $3);
1517 $$ = scm_cons (loc_on_music (@3, $1), $3);
1518 MYBACKUP (LYRIC_ELEMENT, $4, @4);
1521 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_backup UNSIGNED
1523 if (scm_is_true (scm_call_1 ($2, $4)))
1525 MYREPARSE (@4, $2, REAL, $4);
1528 SCM d = make_duration ($4);
1529 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
1531 $$ = scm_cons (loc_on_music (@3, $1), $3);
1532 MYBACKUP (UNSIGNED, $4, @4);
1534 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
1539 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_backup REAL
1541 if (scm_is_true (scm_call_1 ($2, $4)))
1544 MYREPARSE (@4, $2, REAL, $4);
1546 $$ = scm_cons (loc_on_music (@3, $1), $3);
1547 MYBACKUP (REAL, $4, @4);
1550 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_backup NUMBER_IDENTIFIER
1552 if (scm_is_true (scm_call_1 ($2, $4)))
1554 $$ = scm_cons ($4, $3);
1556 $$ = scm_cons (loc_on_music (@3, $1), $3);
1557 MYBACKUP (NUMBER_IDENTIFIER, $4, @4);
1560 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup FRACTION
1562 if (scm_is_true (scm_call_1 ($2, $4)))
1564 $$ = scm_cons ($4, $3);
1566 $$ = scm_cons (loc_on_music (@3, $1), $3);
1567 MYBACKUP (FRACTION, $4, @4);
1570 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' UNSIGNED
1572 SCM n = scm_difference ($5, SCM_UNDEFINED);
1573 if (scm_is_true (scm_call_1 ($2, n))) {
1575 MYREPARSE (@5, $2, REAL, n);
1577 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
1578 t->set_property ("digit", $5);
1579 $$ = t->unprotect ();
1580 if (scm_is_true (scm_call_1 ($2, $$)))
1581 $$ = scm_cons ($$, $3);
1583 $$ = scm_cons (loc_on_music (@3, $1), $3);
1584 MYBACKUP (UNSIGNED, $5, @5);
1585 parser->lexer_->push_extra_token ('-');
1590 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' REAL
1592 SCM n = scm_difference ($5, SCM_UNDEFINED);
1593 if (scm_is_true (scm_call_1 ($2, n))) {
1594 MYREPARSE (@5, $2, REAL, n);
1597 $$ = scm_cons (loc_on_music (@3, $1), $3);
1598 MYBACKUP (REAL, n, @5);
1601 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' NUMBER_IDENTIFIER
1603 SCM n = scm_difference ($5, SCM_UNDEFINED);
1604 if (scm_is_true (scm_call_1 ($2, n))) {
1605 $$ = scm_cons (n, $3);
1607 $$ = scm_cons (loc_on_music (@3, $1), $3);
1608 MYBACKUP (NUMBER_IDENTIFIER, n, @5);
1611 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup PITCH_IDENTIFIER
1613 if (scm_is_true (scm_call_1 ($2, $4)))
1615 $$ = scm_cons ($4, $3);
1617 $$ = scm_cons (loc_on_music (@3, $1), $3);
1618 MYBACKUP (PITCH_IDENTIFIER, $4, @4);
1621 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup NOTENAME_PITCH
1623 if (scm_is_true (scm_call_1 ($2, $4)))
1625 MYREPARSE (@4, $2, NOTENAME_PITCH, $4);
1628 $$ = scm_cons (loc_on_music (@3, $1), $3);
1629 MYBACKUP (NOTENAME_PITCH, $4, @4);
1632 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup TONICNAME_PITCH
1634 if (scm_is_true (scm_call_1 ($2, $4)))
1636 MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
1639 $$ = scm_cons (loc_on_music (@3, $1), $3);
1640 MYBACKUP (TONICNAME_PITCH, $4, @4);
1643 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_backup DURATION_IDENTIFIER
1645 if (scm_is_true (scm_call_1 ($2, $4)))
1647 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
1650 $$ = scm_cons (loc_on_music (@3, $1), $3);
1651 MYBACKUP (DURATION_IDENTIFIER, $4, @4);
1654 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup SCM_IDENTIFIER
1656 SCM res = try_string_variants ($2, $4);
1657 if (!SCM_UNBNDP (res))
1658 if (scm_is_pair (res)) {
1660 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1663 $$ = scm_cons (res, $3);
1665 $$ = scm_cons (loc_on_music (@3, $1), $3);
1666 MYBACKUP (SCM_IDENTIFIER, $4, @4);
1669 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup STRING
1671 SCM res = try_string_variants ($2, $4);
1672 if (!SCM_UNBNDP (res))
1673 if (scm_is_pair (res)) {
1675 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1678 $$ = scm_cons (res, $3);
1680 $$ = scm_cons (loc_on_music (@3, $1), $3);
1681 MYBACKUP (STRING, $4, @4);
1684 | function_arglist_backup REPARSE bare_number_common
1686 $$ = check_scheme_arg (parser, @3,
1689 | function_arglist_backup REPARSE duration_length
1691 $$ = check_scheme_arg (parser, @3,
1694 | function_arglist_backup REPARSE symbol_list_arg
1696 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1698 | function_arglist_backup REPARSE pitch_also_in_chords
1700 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1705 function_arglist_nonbackup
1706 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
1708 $$ = scm_cons (loc_on_music (@4, $1), $3);
1712 function_arglist_skip_nonbackup:
1713 function_arglist_nonbackup
1714 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup
1716 $$ = scm_cons (loc_on_music (@3, $1), $3);
1720 function_arglist_common:
1721 EXPECT_NO_MORE_ARGS {
1724 | EXPECT_SCM function_arglist_optional embedded_scm_arg
1726 if (scm_is_true (scm_call_1 ($1, $3)))
1727 $$ = scm_cons ($3, $2);
1729 $$ = check_scheme_arg (parser, @3,
1730 make_music_from_simple
1734 | EXPECT_SCM function_arglist_closed_optional bare_number_common
1736 $$ = check_scheme_arg (parser, @3,
1739 | EXPECT_SCM function_arglist_optional FRACTION
1741 $$ = check_scheme_arg (parser, @3,
1744 | EXPECT_SCM function_arglist_optional post_event_nofinger
1746 $$ = check_scheme_arg (parser, @3,
1749 | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
1751 SCM n = scm_difference ($4, SCM_UNDEFINED);
1752 $$ = check_scheme_arg (parser, @4, n, $2, $1);
1754 | function_arglist_common_reparse REPARSE SCM_ARG
1756 $$ = check_scheme_arg (parser, @3,
1759 | function_arglist_common_reparse REPARSE lyric_element_music
1761 $$ = check_scheme_arg (parser, @3,
1764 | function_arglist_common_reparse REPARSE bare_number_common
1766 $$ = check_scheme_arg (parser, @3,
1769 | function_arglist_common_reparse REPARSE duration_length
1771 $$ = check_scheme_arg (parser, @3,
1774 | function_arglist_common_reparse REPARSE symbol_list_arg
1776 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1780 function_arglist_common_reparse:
1781 EXPECT_SCM function_arglist_optional SCM_IDENTIFIER
1784 SCM res = try_string_variants ($1, $3);
1785 if (!SCM_UNBNDP (res))
1786 if (scm_is_pair (res))
1787 MYREPARSE (@3, $1, SYMBOL_LIST, res);
1789 MYREPARSE (@3, $1, SCM_ARG, res);
1790 else if (scm_is_true
1792 ($1, make_music_from_simple (parser, @3, $3))))
1793 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1795 // This is going to flag a syntax error, we
1796 // know the predicate to be false.
1797 MYREPARSE (@3, $1, SCM_ARG, $3);
1799 | EXPECT_SCM function_arglist_optional STRING
1802 SCM res = try_string_variants ($1, $3);
1803 if (!SCM_UNBNDP (res))
1804 if (scm_is_pair (res))
1805 MYREPARSE (@3, $1, SYMBOL_LIST, res);
1807 MYREPARSE (@3, $1, SCM_ARG, res);
1808 else if (scm_is_true
1810 ($1, make_music_from_simple (parser, @3, $3))))
1811 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1813 // This is going to flag a syntax error, we
1814 // know the predicate to be false.
1815 MYREPARSE (@3, $1, SCM_ARG, $3);
1817 | EXPECT_SCM function_arglist_optional full_markup
1820 if (scm_is_true (scm_call_1 ($1, $3)))
1821 MYREPARSE (@3, $1, SCM_ARG, $3);
1822 else if (scm_is_true
1824 ($1, make_music_from_simple (parser, @3, $3))))
1825 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1827 // This is going to flag a syntax error, we
1828 // know the predicate to be false.
1829 MYREPARSE (@3, $1, SCM_ARG, $3);
1831 | EXPECT_SCM function_arglist_closed_optional UNSIGNED
1834 if (scm_is_true (scm_call_1 ($1, $3)))
1835 MYREPARSE (@3, $1, REAL, $3);
1837 SCM d = make_duration ($3);
1838 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($1, d)))
1839 MYREPARSE (@3, $1, REAL, $3);
1841 MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
1844 | EXPECT_SCM function_arglist_closed_optional DURATION_IDENTIFIER
1847 MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
1849 | EXPECT_SCM function_arglist_optional '-' UNSIGNED
1852 SCM n = scm_difference ($4, SCM_UNDEFINED);
1853 if (scm_is_true (scm_call_1 ($1, n)))
1854 MYREPARSE (@4, $1, REAL, n);
1856 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @4);
1857 t->set_property ("digit", $4);
1858 SCM m = t->unprotect ();
1859 if (scm_is_true (scm_call_1 ($1, m)))
1860 MYREPARSE (@4, $1, SCM_ARG, m);
1862 MYREPARSE (@4, $1, SCM_ARG, $4);
1866 | EXPECT_SCM function_arglist_optional '-' REAL
1869 SCM n = scm_difference ($4, SCM_UNDEFINED);
1870 MYREPARSE (@4, $1, REAL, n);
1874 function_arglist_closed:
1875 function_arglist_closed_nonbackup
1876 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
1878 $$ = scm_cons (loc_on_music (@4, $1), $3);
1882 function_arglist_closed_common:
1883 EXPECT_NO_MORE_ARGS {
1886 | EXPECT_SCM function_arglist_optional embedded_scm_arg_closed
1888 $$ = check_scheme_arg (parser, @3,
1891 | EXPECT_SCM function_arglist_closed_optional bare_number_common_closed
1893 $$ = check_scheme_arg (parser, @3,
1896 | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
1898 $$ = check_scheme_arg (parser, @3,
1899 scm_difference ($4, SCM_UNDEFINED),
1902 | EXPECT_SCM function_arglist_optional post_event_nofinger
1904 $$ = check_scheme_arg (parser, @3,
1907 | EXPECT_SCM function_arglist_optional FRACTION
1909 $$ = check_scheme_arg (parser, @3,
1912 | function_arglist_common_reparse REPARSE SCM_ARG
1914 $$ = check_scheme_arg (parser, @3,
1917 | function_arglist_common_reparse REPARSE bare_number_common_closed
1919 $$ = check_scheme_arg (parser, @3,
1922 | function_arglist_common_reparse REPARSE symbol_list_arg
1924 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1928 function_arglist_optional:
1929 function_arglist_backup
1930 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup DEFAULT
1932 $$ = scm_cons (loc_on_music (@4, $1), $3);
1934 | function_arglist_skip_backup BACKUP
1937 function_arglist_skip_backup:
1938 function_arglist_backup
1939 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup
1941 $$ = scm_cons (loc_on_music (@3, $1), $3);
1945 function_arglist_closed_optional:
1946 function_arglist_closed_backup
1947 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup DEFAULT
1949 $$ = scm_cons (loc_on_music (@4, $1), $3);
1951 | function_arglist_skip_backup BACKUP
1954 embedded_scm_closed:
1956 | scm_function_call_closed
1959 embedded_scm_arg_closed:
1960 embedded_scm_bare_arg
1961 | scm_function_call_closed
1965 scm_function_call_closed:
1966 SCM_FUNCTION function_arglist_closed {
1967 $$ = MAKE_SYNTAX ("music-function", @$,
1972 music_function_call:
1973 MUSIC_FUNCTION function_arglist {
1974 $$ = MAKE_SYNTAX ("music-function", @$,
1981 /**/ { $$ = SCM_EOL; }
1982 | '=' simple_string {
1989 | repeated_music { $$ = $1; }
1990 | re_rhythmed_music { $$ = $1; }
1991 | complex_music_prefix music
1993 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
1997 complex_music_prefix:
1998 CONTEXT symbol optional_id optional_context_mod {
1999 Context_mod *ctxmod = unsmob_context_mod ($4);
2002 mods = ctxmod->get_mods ();
2003 $$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_F);
2005 | NEWCONTEXT symbol optional_id optional_context_mod {
2006 Context_mod *ctxmod = unsmob_context_mod ($4);
2009 mods = ctxmod->get_mods ();
2010 $$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_T);
2015 mode_changing_head grouped_music_list {
2016 if ($1 == ly_symbol2scm ("chords"))
2018 $$ = MAKE_SYNTAX ("unrelativable-music", @$, $2);
2024 parser->lexer_->pop_state ();
2026 | mode_changing_head_with_context optional_context_mod grouped_music_list {
2027 Context_mod *ctxmod = unsmob_context_mod ($2);
2030 mods = ctxmod->get_mods ();
2031 $$ = MAKE_SYNTAX ("context-specification", @$, $1, SCM_EOL, mods, SCM_BOOL_T, $3);
2032 if ($1 == ly_symbol2scm ("ChordNames"))
2034 $$ = MAKE_SYNTAX ("unrelativable-music", @$, $$);
2036 parser->lexer_->pop_state ();
2042 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
2043 parser->lexer_->push_note_state (nn);
2045 $$ = ly_symbol2scm ("notes");
2049 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2050 parser->lexer_->push_note_state (nn);
2052 $$ = ly_symbol2scm ("drums");
2055 parser->lexer_->push_figuredbass_state ();
2057 $$ = ly_symbol2scm ("figures");
2060 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2061 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2062 nn = parser->lexer_->lookup_identifier ("pitchnames");
2063 parser->lexer_->push_chord_state (nn);
2064 $$ = ly_symbol2scm ("chords");
2068 { parser->lexer_->push_lyric_state ();
2069 $$ = ly_symbol2scm ("lyrics");
2073 mode_changing_head_with_context:
2075 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2076 parser->lexer_->push_note_state (nn);
2078 $$ = ly_symbol2scm ("DrumStaff");
2081 parser->lexer_->push_figuredbass_state ();
2083 $$ = ly_symbol2scm ("FiguredBass");
2086 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2087 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2088 nn = parser->lexer_->lookup_identifier ("pitchnames");
2089 parser->lexer_->push_chord_state (nn);
2090 $$ = ly_symbol2scm ("ChordNames");
2093 { parser->lexer_->push_lyric_state ();
2094 $$ = ly_symbol2scm ("Lyrics");
2099 ADDLYRICS { parser->lexer_->push_lyric_state (); }
2102 /* Can also use music at the expensive of two S/Rs similar to
2103 \repeat \alternative */
2104 parser->lexer_->pop_state ();
2106 $$ = scm_cons ($3, SCM_EOL);
2108 | new_lyrics ADDLYRICS {
2109 parser->lexer_->push_lyric_state ();
2111 parser->lexer_->pop_state ();
2112 $$ = scm_cons ($4, $1);
2117 composite_music new_lyrics {
2118 $$ = MAKE_SYNTAX ("add-lyrics", @$, $1, scm_reverse_x ($2, SCM_EOL));
2120 | LYRICSTO simple_string {
2121 parser->lexer_->push_lyric_state ();
2123 parser->lexer_->pop_state ();
2124 $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $4);
2129 CHANGE STRING '=' STRING {
2130 $$ = MAKE_SYNTAX ("context-change", @$, scm_string_to_symbol ($2), $4);
2137 $$ = scm_reverse_x ($1, SCM_EOL);
2139 | symbol_list_rev property_path {
2140 $$ = scm_reverse_x ($1, $2);
2146 $$ = scm_list_3 (ly_symbol2scm ("assign"), $1, $3);
2149 $$ = scm_list_2 (ly_symbol2scm ("unset"), $2);
2151 | OVERRIDE property_path '=' scalar {
2152 if (scm_ilength ($2) < 2) {
2153 parser->parser_error (@2, _("bad grob property path"));
2156 $$ = scm_cons (ly_symbol2scm ("push"),
2157 scm_cons2 (scm_car ($2),
2162 | REVERT revert_arg {
2163 $$ = scm_cons (ly_symbol2scm ("pop"), $2);
2167 // This is all quite awkward for the sake of substantial backward
2168 // compatibility while at the same time allowing a more "natural" form
2169 // of specification not separating grob specification from grob
2170 // property path. The purpose of this definition of revert_arg is to
2171 // allow the symbol list which specifies grob and property to revert
2172 // to be optionally be split into two parts after the grob (which in
2173 // this case is just the first element of the list). symbol_list_part
2174 // is only one path component, but it can be parsed without lookahead,
2175 // so we can follow it with a synthetic BACKUP token when needed. If
2176 // the first symbol_list_part already contains multiple elements (only
2177 // possible if a Scheme expression provides them), we just parse for
2178 // additional elements introduced by '.', which is what the
2179 // SYMBOL_LIST backup in connection with the immediately following
2180 // rule using symbol_list_arg does.
2182 // As long as we don't have our coffers filled with both grob and at
2183 // least one grob property specification, the rest of the required
2184 // symbol list chain may be provided either with or without a leading
2185 // dot. This is for both allowing the traditional
2186 // \revert Accidental #'color
2187 // as well as well as the "naive" form
2188 // \revert Accidental.color
2191 revert_arg_backup BACKUP symbol_list_arg
2200 if (scm_is_null ($1)
2201 || scm_is_null (scm_cdr ($1)))
2202 MYBACKUP (SCM_ARG, $1, @1);
2204 MYBACKUP (SYMBOL_LIST, scm_reverse_x ($1, SCM_EOL), @1);
2208 // revert_arg_part delivers results in reverse
2211 | revert_arg_backup BACKUP SCM_ARG '.' symbol_list_part
2213 $$ = scm_append_x (scm_list_2 ($5, $3));
2215 | revert_arg_backup BACKUP SCM_ARG symbol_list_part
2217 $$ = scm_append_x (scm_list_2 ($4, $3));
2222 CONSISTS { $$ = ly_symbol2scm ("consists"); }
2223 | REMOVE { $$ = ly_symbol2scm ("remove"); }
2225 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
2226 | DEFAULTCHILD { $$ = ly_symbol2scm ("default-child"); }
2227 | DENIES { $$ = ly_symbol2scm ("denies"); }
2229 | ALIAS { $$ = ly_symbol2scm ("alias"); }
2230 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
2231 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
2232 | NAME { $$ = ly_symbol2scm ("context-name"); }
2236 property_operation { $$ = $1; }
2237 | context_def_mod STRING {
2238 $$ = scm_list_2 ($1, $2);
2240 | context_def_mod embedded_scm
2242 if (!scm_is_string ($2)
2243 && ly_symbol2scm ("consists") != $1
2244 && ly_symbol2scm ("remove") != $1)
2247 parser->parser_error (@1, _ ("only \\consists and \\remove take non-string argument."));
2251 $$ = scm_list_2 ($1, $2);
2256 // If defined, at least two members.
2260 SCM l = scm_reverse_x ($1, SCM_EOL);
2263 (scm_object_property (scm_car (l),
2264 ly_symbol2scm ("is-grob?"))))
2265 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2266 if (scm_is_null (l) || scm_is_null (scm_cdr (l))) {
2267 parser->parser_error (@1, _ ("bad grob property path"));
2274 // If defined, at least three members
2278 if (!SCM_UNBNDP ($1) && scm_is_null (scm_cddr ($1)))
2280 parser->parser_error (@1, _ ("bad grob property path"));
2284 | grob_prop_spec property_path
2286 if (!SCM_UNBNDP ($1)) {
2287 $$ = scm_append_x (scm_list_2 ($1, $2));
2288 if (scm_is_null (scm_cddr ($$))) {
2289 parser->parser_error (@$, _ ("bad grob property path"));
2297 // Exactly two elements or undefined
2301 SCM l = scm_reverse_x ($1, SCM_EOL);
2302 switch (scm_ilength (l)) {
2304 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2308 parser->parser_error (@1, _ ("bad context property path"));
2315 simple_music_property_def:
2316 OVERRIDE grob_prop_path '=' scalar {
2317 if (SCM_UNBNDP ($2))
2320 $$ = scm_list_5 (scm_car ($2),
2321 ly_symbol2scm ("OverrideProperty"),
2327 | REVERT simple_revert_context revert_arg {
2328 $$ = scm_list_4 ($2,
2329 ly_symbol2scm ("RevertProperty"),
2333 | SET context_prop_spec '=' scalar {
2334 if (SCM_UNBNDP ($2))
2337 $$ = scm_list_4 (scm_car ($2),
2338 ly_symbol2scm ("PropertySet"),
2342 | UNSET context_prop_spec {
2343 if (SCM_UNBNDP ($2))
2346 $$ = scm_list_3 (scm_car ($2),
2347 ly_symbol2scm ("PropertyUnset"),
2353 // This is all quite awkward for the sake of substantial backward
2354 // compatibility while at the same time allowing a more "natural" form
2355 // of specification not separating grob specification from grob
2356 // property path. The purpose of this definition of
2357 // simple_revert_context is to allow the symbol list which specifies
2358 // grob and property to revert to be optionally be split into two
2359 // parts after the grob (which may be preceded by a context
2360 // specification, a case which we distinguish by checking whether the
2361 // first symbol is a valid grob symbol instead).
2363 // See revert_arg above for the main work horse of this arrangement.
2364 // simple_revert_context just caters for the context and delegates the
2365 // rest of the job to revert_arg.
2367 simple_revert_context:
2370 $1 = scm_reverse_x ($1, SCM_EOL);
2371 if (scm_is_null ($1)
2373 (scm_object_property (scm_car ($1),
2374 ly_symbol2scm ("is-grob?")))) {
2375 $$ = ly_symbol2scm ("Bottom");
2376 parser->lexer_->push_extra_token (SCM_IDENTIFIER, $1);
2379 parser->lexer_->push_extra_token (SCM_IDENTIFIER,
2386 simple_music_property_def {
2387 if (SCM_UNBNDP ($1))
2388 $$ = MAKE_SYNTAX ("void-music", @1);
2390 $$ = LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("property-operation"), scm_cons2 (parser->self_scm (), make_input (@$), $1));
2401 simple_string: STRING {
2406 if (scm_is_string ($1)) {
2409 parser->parser_error (@1, (_ ("simple string expected")));
2410 $$ = scm_string (SCM_EOL);
2417 $$ = scm_string_to_symbol ($1);
2421 // This is a bit of overkill but makes the same
2422 // routine responsible for all symbol interpretations.
2423 $$ = try_string_variants (ly_lily_module_constant ("symbol?"),
2425 if (SCM_UNBNDP ($$))
2427 parser->parser_error (@1, (_ ("symbol expected")));
2428 // Generate a unique symbol in case it is used
2429 // for an assignment or similar
2430 $$ = scm_make_symbol (ly_string2scm ("undefined"));
2439 // The following is a rather defensive variant of admitting
2440 // negative numbers: the grammar would permit number_factor or
2441 // even number_expression. However, function arguments allow
2442 // only this simple kind of negative number, so to have things
2443 // like \tweak and \override behave reasonably similar, it
2444 // makes sense to rule out things like -- which are rather an
2445 // accent in function argument contexts.
2448 $$ = scm_difference ($2, SCM_UNDEFINED);
2456 embedded_scm_arg_closed
2458 // for scalar_closed to be an actually closed (no lookahead)
2459 // expression, we'd need to use bare_number_closed here. It
2460 // turns out that the only use of scalar_closed in TEMPO is
2461 // not of the kind requiring the full closedness criterion.
2465 $$ = scm_difference ($2, SCM_UNDEFINED);
2474 simple_element post_events {
2475 // Let the rhythmic music iterator sort this mess out.
2476 if (scm_is_pair ($2)) {
2477 $$ = make_music_from_simple (parser, @1, $1);
2478 if (unsmob_music ($$))
2479 unsmob_music ($$)->set_property ("articulations",
2480 scm_reverse_x ($2, SCM_EOL));
2483 parser->parser_error (@1, _("music expected"));
2484 $$ = MAKE_SYNTAX ("void-music", @1);
2488 | simple_chord_elements post_events {
2489 SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
2492 /* why is this giving wrong start location? -ns
2494 i.set_location (@1, @2);
2495 $$ = MAKE_SYNTAX ("event-chord", i, elts);
2497 | CHORD_REPETITION optional_notemode_duration post_events {
2499 i.set_location (@1, @3);
2500 $$ = MAKE_SYNTAX ("repetition-chord", i,
2501 $2, scm_reverse_x ($3, SCM_EOL));
2503 | MULTI_MEASURE_REST optional_notemode_duration post_events {
2505 i.set_location (@1, @3);
2506 $$ = MAKE_SYNTAX ("multi-measure-rest", i, $2,
2507 scm_reverse_x ($3, SCM_EOL));
2510 | note_chord_element
2515 chord_body optional_notemode_duration post_events
2517 Music *m = unsmob_music ($1);
2518 SCM dur = unsmob_duration ($2)->smobbed_copy ();
2519 SCM es = m->get_property ("elements");
2520 SCM postevs = scm_reverse_x ($3, SCM_EOL);
2522 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
2523 unsmob_music (scm_car (s))->set_property ("duration", dur);
2524 es = ly_append2 (es, postevs);
2526 m-> set_property ("elements", es);
2528 $$ = m->self_scm ();
2533 ANGLE_OPEN chord_body_elements ANGLE_CLOSE
2535 $$ = MAKE_SYNTAX ("event-chord", @$, scm_reverse_x ($2, SCM_EOL));
2539 chord_body_elements:
2540 /* empty */ { $$ = SCM_EOL; }
2541 | chord_body_elements chord_body_element {
2542 if (!SCM_UNBNDP ($2))
2543 $$ = scm_cons ($2, $1);
2548 pitch exclamations questions octave_check post_events
2550 bool q = to_boolean ($3);
2551 bool ex = to_boolean ($2);
2555 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
2556 n->set_property ("pitch", $1);
2558 n->set_property ("cautionary", SCM_BOOL_T);
2560 n->set_property ("force-accidental", SCM_BOOL_T);
2562 if (scm_is_pair (post)) {
2563 SCM arts = scm_reverse_x (post, SCM_EOL);
2564 n->set_property ("articulations", arts);
2566 if (scm_is_number (check))
2568 int q = scm_to_int (check);
2569 n->set_property ("absolute-octave", scm_from_int (q-1));
2572 $$ = n->unprotect ();
2574 | DRUM_PITCH post_events {
2575 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
2576 n->set_property ("drum-type", $1);
2578 if (scm_is_pair ($2)) {
2579 SCM arts = scm_reverse_x ($2, SCM_EOL);
2580 n->set_property ("articulations", arts);
2582 $$ = n->unprotect ();
2584 | music_function_chord_body
2586 Music *m = unsmob_music ($1);
2588 while (m && m->is_mus_type ("music-wrapper-music")) {
2589 $$ = m->get_property ("element");
2590 m = unsmob_music ($$);
2593 if (!(m && m->is_mus_type ("rhythmic-event"))) {
2594 parser->parser_error (@$, _ ("not a rhythmic event"));
2600 music_function_chord_body:
2605 // Event functions may only take closed arglists, otherwise it would
2606 // not be clear whether a following postevent should be associated
2607 // with the last argument of the event function or with the expression
2608 // for which the function call acts itself as event.
2610 music_function_call_closed:
2611 MUSIC_FUNCTION function_arglist_closed {
2612 $$ = MAKE_SYNTAX ("music-function", @$,
2617 event_function_event:
2618 EVENT_FUNCTION function_arglist_closed {
2619 $$ = MAKE_SYNTAX ("music-function", @$,
2641 | post_events post_event {
2643 if (Music *m = unsmob_music ($2))
2645 if (m->is_mus_type ("post-event-wrapper"))
2647 for (SCM p = m->get_property ("elements");
2651 $$ = scm_cons (scm_car (p), $$);
2655 $$ = scm_cons ($2, $$);
2661 post_event_nofinger:
2662 direction_less_event {
2665 | script_dir music_function_call_closed {
2667 if (!unsmob_music ($2)->is_mus_type ("post-event")) {
2668 parser->parser_error (@2, _ ("post-event expected"));
2669 $$ = SCM_UNSPECIFIED;
2670 } else if (!SCM_UNBNDP ($1))
2672 unsmob_music ($$)->set_property ("direction", $1);
2676 if (!parser->lexer_->is_lyric_state ())
2677 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2678 $$ = MY_MAKE_MUSIC ("HyphenEvent", @$)->unprotect ();
2681 if (!parser->lexer_->is_lyric_state ())
2682 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2683 $$ = MY_MAKE_MUSIC ("ExtenderEvent", @$)->unprotect ();
2685 | script_dir direction_reqd_event {
2686 if (!SCM_UNBNDP ($1))
2688 Music *m = unsmob_music ($2);
2689 m->set_property ("direction", $1);
2693 | script_dir direction_less_event {
2694 if (!SCM_UNBNDP ($1))
2696 Music *m = unsmob_music ($2);
2697 m->set_property ("direction", $1);
2704 unsmob_music ($$)->set_property ("direction", scm_from_int (UP));
2709 unsmob_music ($$)->set_property ("direction", scm_from_int (DOWN));
2720 string_number_event:
2722 Music *s = MY_MAKE_MUSIC ("StringNumberEvent", @$);
2723 s->set_property ("string-number", $1);
2724 $$ = s->unprotect ();
2728 direction_less_event:
2730 | EVENT_IDENTIFIER {
2734 Music *a = MY_MAKE_MUSIC ("TremoloEvent", @$);
2735 a->set_property ("tremolo-type", $1);
2736 $$ = a->unprotect ();
2738 | event_function_event
2741 direction_reqd_event:
2745 | script_abbreviation {
2746 SCM s = parser->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
2747 Music *a = MY_MAKE_MUSIC ("ArticulationEvent", @$);
2748 if (scm_is_string (s))
2749 a->set_property ("articulation-type", s);
2750 else parser->parser_error (@1, _ ("expecting string as script definition"));
2751 $$ = a->unprotect ();
2756 /**/ { $$ = SCM_EOL; }
2757 | '=' quotes { $$ = $2; }
2771 $$ = scm_from_int (1);
2774 $$ = scm_oneplus ($1);
2780 $$ = scm_from_int (-1);
2783 $$ = scm_oneminus ($1);
2788 NOTENAME_PITCH quotes {
2789 if (!scm_is_eq (SCM_INUM0, $2))
2791 Pitch p = *unsmob_pitch ($1);
2792 p = p.transposed (Pitch (scm_to_int ($2),0,0));
2793 $$ = p.smobbed_copy ();
2803 TONICNAME_PITCH quotes {
2804 if (!scm_is_eq (SCM_INUM0, $2))
2806 Pitch p = *unsmob_pitch ($1);
2807 p = p.transposed (Pitch (scm_to_int ($2),0,0));
2808 $$ = p.smobbed_copy ();
2818 pitch_also_in_chords:
2825 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2826 t->set_property ("text", $1);
2827 $$ = t->unprotect ();
2830 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2831 t->set_property ("text",
2832 make_simple_markup ($1));
2833 $$ = t->unprotect ();
2835 | embedded_scm_closed
2837 Music *m = unsmob_music ($1);
2838 if (m && m->is_mus_type ("post-event"))
2840 else if (Text_interface::is_markup ($1)) {
2841 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2842 t->set_property ("text", $1);
2843 $$ = t->unprotect ();
2845 parser->parser_error (@1, _ ("not an articulation"));
2851 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @$);
2852 t->set_property ("digit", $1);
2853 $$ = t->unprotect ();
2857 script_abbreviation:
2859 $$ = scm_from_locale_string ("Hat");
2862 $$ = scm_from_locale_string ("Plus");
2865 $$ = scm_from_locale_string ("Dash");
2868 $$ = scm_from_locale_string ("Bang");
2871 $$ = scm_from_locale_string ("Larger");
2874 $$ = scm_from_locale_string ("Dot");
2877 $$ = scm_from_locale_string ("Underscore");
2882 '_' { $$ = scm_from_int (DOWN); }
2883 | '^' { $$ = scm_from_int (UP); }
2884 | '-' { $$ = SCM_UNDEFINED; }
2888 multiplied_duration {
2893 maybe_notemode_duration:
2897 | multiplied_duration {
2899 parser->default_duration_ = *unsmob_duration ($$);
2904 optional_notemode_duration:
2905 maybe_notemode_duration
2907 if (SCM_UNBNDP ($$))
2908 $$ = parser->default_duration_.smobbed_copy ();
2914 $$ = make_duration ($1, scm_to_int ($2));
2915 if (SCM_UNBNDP ($$))
2917 parser->parser_error (@1, _ ("not a duration"));
2918 $$ = Duration ().smobbed_copy ();
2921 | DURATION_IDENTIFIER dots {
2922 Duration *d = unsmob_duration ($1);
2923 Duration k (d->duration_log (),
2924 d->dot_count () + scm_to_int ($2));
2925 k = k.compressed (d->factor ());
2926 scm_remember_upto_here_1 ($1);
2927 $$ = k.smobbed_copy ();
2931 multiplied_duration:
2935 | multiplied_duration '*' UNSIGNED {
2936 $$ = unsmob_duration ($$)->compressed (scm_to_int ($3)).smobbed_copy ();
2938 | multiplied_duration '*' FRACTION {
2939 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2941 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2950 $$ = scm_oneplus ($1);
2959 if (SCM_UNBNDP (make_duration ($2)))
2960 parser->parser_error (@2, _ ("not a duration"));
2966 UNSIGNED { $$ = $1; }
2967 | STRING { $$ = $1; }
2968 | full_markup { $$ = $1; }
2971 // as an integer, it needs to be non-negative, and otherwise
2972 // it needs to be suitable as a markup.
2973 if (scm_is_integer ($1)
2974 ? scm_is_true (scm_negative_p ($1))
2975 : !Text_interface::is_markup ($1))
2977 parser->parser_error (@1, _ ("bass number expected"));
2983 figured_bass_alteration:
2984 '-' { $$ = ly_rational2scm (FLAT_ALTERATION); }
2985 | '+' { $$ = ly_rational2scm (SHARP_ALTERATION); }
2986 | '!' { $$ = scm_from_int (0); }
2991 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
2992 $$ = bfr->unprotect ();
2995 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
2996 $$ = bfr->self_scm ();
2998 if (scm_is_number ($1))
2999 bfr->set_property ("figure", $1);
3000 else if (Text_interface::is_markup ($1))
3001 bfr->set_property ("text", $1);
3007 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
3009 | bass_figure figured_bass_alteration {
3010 Music *m = unsmob_music ($1);
3011 if (scm_to_double ($2)) {
3012 SCM salter = m->get_property ("alteration");
3013 SCM alter = scm_is_number (salter) ? salter : scm_from_int (0);
3014 m->set_property ("alteration",
3015 scm_sum (alter, $2));
3017 m->set_property ("alteration", scm_from_int (0));
3020 | bass_figure figured_bass_modification {
3021 Music *m = unsmob_music ($1);
3022 m->set_property ($2, SCM_BOOL_T);
3027 figured_bass_modification:
3029 $$ = ly_symbol2scm ("augmented");
3032 $$ = ly_symbol2scm ("no-continuation");
3035 $$ = ly_symbol2scm ("diminished");
3038 $$ = ly_symbol2scm ("augmented-slash");
3048 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
3056 | figure_list br_bass_figure {
3057 $$ = scm_cons ($2, $1);
3062 FIGURE_OPEN figure_list FIGURE_CLOSE {
3063 $$ = scm_reverse_x ($2, SCM_EOL);
3069 /**/ { $$ = SCM_BOOL_F; }
3070 | REST { $$ = SCM_BOOL_T; }
3074 pitch exclamations questions octave_check maybe_notemode_duration optional_rest {
3075 if (!parser->lexer_->is_note_state ())
3076 parser->parser_error (@1, _ ("have to be in Note mode for notes"));
3077 if (!SCM_UNBNDP ($2)
3079 || scm_is_number ($4)
3081 || scm_is_true ($6))
3084 if (scm_is_true ($6))
3085 n = MY_MAKE_MUSIC ("RestEvent", @$);
3087 n = MY_MAKE_MUSIC ("NoteEvent", @$);
3089 n->set_property ("pitch", $1);
3090 if (SCM_UNBNDP ($5))
3091 n->set_property ("duration",
3092 parser->default_duration_.smobbed_copy ());
3094 n->set_property ("duration", $5);
3096 if (scm_is_number ($4))
3098 int q = scm_to_int ($4);
3099 n->set_property ("absolute-octave", scm_from_int (q-1));
3102 if (to_boolean ($3))
3103 n->set_property ("cautionary", SCM_BOOL_T);
3104 if (to_boolean ($2) || to_boolean ($3))
3105 n->set_property ("force-accidental", SCM_BOOL_T);
3107 $$ = n->unprotect ();
3110 | DRUM_PITCH optional_notemode_duration {
3111 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
3112 n->set_property ("duration", $2);
3113 n->set_property ("drum-type", $1);
3115 $$ = n->unprotect ();
3117 | RESTNAME optional_notemode_duration {
3119 if (ly_scm2string ($1) == "s") {
3121 ev = MY_MAKE_MUSIC ("SkipEvent", @$);
3124 ev = MY_MAKE_MUSIC ("RestEvent", @$);
3127 ev->set_property ("duration", $2);
3128 $$ = ev->unprotect ();
3132 simple_chord_elements:
3134 if (!parser->lexer_->is_chord_state ())
3135 parser->parser_error (@1, _ ("have to be in Chord mode for chords"));
3138 | figure_spec optional_notemode_duration {
3139 for (SCM s = $1; scm_is_pair (s); s = scm_cdr (s))
3141 unsmob_music (scm_car (s))->set_property ("duration", $2);
3149 if (!parser->lexer_->is_lyric_state ())
3150 parser->parser_error (@1, _ ("markup outside of text script or \\lyricmode"));
3154 if (!parser->lexer_->is_lyric_state ())
3155 parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode"));
3161 lyric_element_music:
3162 lyric_element optional_notemode_duration post_events {
3163 $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
3164 if (scm_is_pair ($3))
3165 unsmob_music ($$)->set_property
3166 ("articulations", scm_reverse_x ($3, SCM_EOL));
3171 steno_tonic_pitch optional_notemode_duration {
3172 $$ = make_chord_elements (@$, $1, $2, SCM_EOL);
3174 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
3175 SCM its = scm_reverse_x ($4, SCM_EOL);
3176 $$ = make_chord_elements (@$, $1, $2, scm_cons ($3, its));
3184 | chord_items chord_item {
3185 $$ = scm_cons ($2, $$);
3191 $$ = ly_symbol2scm ("chord-colon");
3194 $$ = ly_symbol2scm ("chord-caret");
3196 | CHORD_SLASH steno_tonic_pitch {
3197 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
3199 | CHORD_BASS steno_tonic_pitch {
3200 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
3209 $$ = scm_reverse_x ($1, SCM_EOL);
3217 step_number { $$ = scm_cons ($1, SCM_EOL); }
3218 | step_numbers '.' step_number {
3219 $$ = scm_cons ($3, $$);
3225 $$ = make_chord_step ($1, 0);
3228 $$ = make_chord_step ($1, SHARP_ALTERATION);
3230 | UNSIGNED CHORD_MINUS {
3231 $$ = make_chord_step ($1, FLAT_ALTERATION);
3239 | UNSIGNED '-' UNSIGNED {
3240 $$ = scm_cons ($1, $3);
3247 TODO: should deprecate in favor of Scheme?
3251 number_expression '+' number_term {
3252 $$ = scm_sum ($1, $3);
3254 | number_expression '-' number_term {
3255 $$ = scm_difference ($1, $3);
3264 | number_factor '*' number_factor {
3265 $$ = scm_product ($1, $3);
3267 | number_factor '/' number_factor {
3268 $$ = scm_divide ($1, $3);
3273 '-' number_factor { /* %prec UNARY_MINUS */
3274 $$ = scm_difference ($2, SCM_UNDEFINED);
3280 bare_number_common_closed
3281 | REAL NUMBER_IDENTIFIER
3283 $$ = scm_product ($1, $2);
3287 bare_number_common_closed:
3295 | UNSIGNED NUMBER_IDENTIFIER {
3296 $$ = scm_product ($1, $2);
3302 | bare_number_common_closed
3311 { $$ = SCM_UNDEFINED; }
3314 if (SCM_UNBNDP ($1))
3322 { $$ = SCM_UNDEFINED; }
3325 if (SCM_UNBNDP ($1))
3334 { parser->lexer_->push_markup_state (); }
3337 parser->lexer_->pop_state ();
3343 { parser->lexer_->push_markup_state (); }
3346 parser->lexer_->pop_state ();
3351 simple_markup_list {
3352 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
3354 | markup_head_1_list simple_markup
3356 $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
3357 @2, $1, scm_list_1 ($2)));
3367 if (Text_interface::is_markup ($1))
3368 MYBACKUP (MARKUP_IDENTIFIER, $1, @1);
3369 else if (Text_interface::is_markup_list ($1))
3370 MYBACKUP (MARKUPLIST_IDENTIFIER, $1, @1);
3372 parser->parser_error (@1, _ ("not a markup"));
3373 MYBACKUP (MARKUP_IDENTIFIER, scm_string (SCM_EOL), @1);
3380 markup_composed_list {
3383 | markup_uncomposed_list
3386 markup_uncomposed_list:
3387 markup_braced_list {
3390 | markup_command_list {
3391 $$ = scm_list_1 ($1);
3393 | markup_scm MARKUPLIST_IDENTIFIER
3403 $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $1));
3409 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
3410 parser->lexer_->push_note_state (nn);
3411 } '{' score_body '}' {
3413 parser->lexer_->pop_state ();
3417 markup_composed_list:
3418 markup_head_1_list markup_uncomposed_list {
3419 $$ = MAKE_SYNTAX ("composed-markup-list",
3425 '{' markup_braced_list_body '}' {
3426 $$ = scm_reverse_x ($2, SCM_EOL);
3430 markup_braced_list_body:
3431 /* empty */ { $$ = SCM_EOL; }
3432 | markup_braced_list_body markup {
3433 $$ = scm_cons ($2, $1);
3435 | markup_braced_list_body simple_markup_list {
3436 $$ = scm_reverse_x ($2, $1);
3440 markup_command_list:
3441 MARKUP_LIST_FUNCTION markup_command_list_arguments {
3442 $$ = scm_cons ($1, scm_reverse_x($2, SCM_EOL));
3446 markup_command_basic_arguments:
3447 EXPECT_MARKUP_LIST markup_command_list_arguments markup_list {
3448 $$ = scm_cons ($3, $2);
3450 | EXPECT_SCM markup_command_list_arguments embedded_scm_closed {
3451 $$ = check_scheme_arg (parser, @3, $3, $2, $1);
3453 | EXPECT_NO_MORE_ARGS {
3458 markup_command_list_arguments:
3459 markup_command_basic_arguments { $$ = $1; }
3460 | EXPECT_MARKUP markup_command_list_arguments markup {
3461 $$ = scm_cons ($3, $2);
3466 MARKUP_FUNCTION EXPECT_MARKUP markup_command_list_arguments {
3467 $$ = scm_cons ($1, scm_reverse_x ($3, SCM_EOL));
3472 markup_head_1_item {
3473 $$ = scm_list_1 ($1);
3475 | markup_head_1_list markup_head_1_item {
3476 $$ = scm_cons ($2, $1);
3482 $$ = make_simple_markup ($1);
3484 | MARKUP_FUNCTION markup_command_basic_arguments {
3485 $$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
3487 | markup_scm MARKUP_IDENTIFIER
3493 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $1);
3498 markup_head_1_list simple_markup
3500 $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
3501 @2, $1, scm_list_1 ($2)));
3511 Lily_parser::set_yydebug (bool x)
3517 Lily_parser::do_yyparse ()
3519 SCM retval = SCM_UNDEFINED;
3520 yyparse (this, &retval);
3530 It is a little strange to have this function in this file, but
3531 otherwise, we have to import music classes into the lexer.
3535 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
3537 if (unsmob_book (sid)) {
3538 Book *book = unsmob_book (sid)->clone ();
3539 *destination = book->self_scm ();
3542 return BOOK_IDENTIFIER;
3543 } else if (scm_is_number (sid)) {
3545 return NUMBER_IDENTIFIER;
3546 } else if (unsmob_context_def (sid)) {
3547 Context_def *def= unsmob_context_def (sid)->clone ();
3549 *destination = def->self_scm ();
3552 return CONTEXT_DEF_IDENTIFIER;
3553 } else if (unsmob_context_mod (sid)) {
3554 *destination = unsmob_context_mod (sid)->smobbed_copy ();
3556 return CONTEXT_MOD_IDENTIFIER;
3557 } else if (Music *mus = unsmob_music (sid)) {
3558 mus = mus->clone ();
3559 *destination = mus->self_scm ();
3560 bool is_event = mus->is_mus_type ("post-event");
3562 return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
3563 } else if (unsmob_pitch (sid)) {
3564 *destination = unsmob_pitch (sid)->smobbed_copy ();
3565 return PITCH_IDENTIFIER;
3566 } else if (unsmob_duration (sid)) {
3567 *destination = unsmob_duration (sid)->smobbed_copy ();
3568 return DURATION_IDENTIFIER;
3569 } else if (unsmob_output_def (sid)) {
3570 Output_def *p = unsmob_output_def (sid);
3573 *destination = p->self_scm ();
3575 return OUTPUT_DEF_IDENTIFIER;
3582 get_next_unique_context_id ()
3584 return scm_from_locale_string ("$uniqueContextId");
3589 get_next_unique_lyrics_context_id ()
3591 static int new_context_count;
3593 snprintf (s, sizeof (s)-1, "uniqueContext%d", new_context_count++);
3594 return scm_from_locale_string (s);
3597 // check_scheme_arg checks one argument with a given predicate for use
3598 // in an argument list and throws a syntax error if it is unusable.
3599 // The argument is prepended to the argument list in any case. After
3600 // throwing a syntax error, the argument list is terminated with #f as
3601 // its last cdr in order to mark it as uncallable while not losing
3602 // track of its total length.
3604 // There are a few special considerations: if optional argument disp
3605 // is given (otherwise it defaults to SCM_UNDEFINED), it will be used
3606 // instead of arg in a prospective error message. This is useful if
3607 // arg is not the actual argument but rather a transformation of it.
3609 // If arg itself is SCM_UNDEFINED, the predicate is considered false
3610 // and an error message using disp is produced unconditionally.
3612 SCM check_scheme_arg (Lily_parser *parser, Input loc,
3613 SCM arg, SCM args, SCM pred, SCM disp)
3615 if (SCM_UNBNDP (arg))
3616 args = scm_cons (disp, args);
3618 args = scm_cons (arg, args);
3619 if (scm_is_true (scm_call_1 (pred, arg)))
3622 scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
3623 MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred,
3624 SCM_UNBNDP (disp) ? arg : disp);
3625 scm_set_cdr_x (scm_last_pair (args), SCM_BOOL_F);
3629 SCM loc_on_music (Input loc, SCM arg)
3631 if (Music *m = unsmob_music (arg))
3635 return m->unprotect ();
3641 try_string_variants (SCM pred, SCM str)
3643 // a matching predicate is always ok
3644 if (scm_is_true (scm_call_1 (pred, str)))
3646 // a symbol may be interpreted as a list of symbols if it helps
3647 if (scm_is_symbol (str)) {
3648 str = scm_list_1 (str);
3649 if (scm_is_true (scm_call_1 (pred, str)))
3651 return SCM_UNDEFINED;
3654 // If this cannot be a string representation of a symbol list,
3657 if (!is_regular_identifier (str, true))
3658 return SCM_UNDEFINED;
3660 str = scm_string_split (str, SCM_MAKE_CHAR ('.'));
3661 for (SCM p = str; scm_is_pair (p); p = scm_cdr (p))
3662 scm_set_car_x (p, scm_string_to_symbol (scm_car (p)));
3664 // Let's attempt the symbol list interpretation first.
3666 if (scm_is_true (scm_call_1 (pred, str)))
3669 // If there is just one symbol in the list, we might interpret
3670 // it as a single symbol
3672 if (scm_is_null (scm_cdr (str)))
3674 str = scm_car (str);
3675 if (scm_is_true (scm_call_1 (pred, str)))
3679 return SCM_UNDEFINED;
3683 is_regular_identifier (SCM id, bool multiple)
3685 if (!scm_is_string (id))
3688 string str = ly_scm2string (id);
3690 bool middle = false;
3692 for (string::iterator it=str.begin(); it != str.end (); it++)
3695 if ((c >= 'a' && c <= 'z')
3696 || (c >= 'A' && c <= 'Z')
3699 else if (middle && (c == '-' || c == '_' || (multiple && c == '.')))
3708 make_music_from_simple (Lily_parser *parser, Input loc, SCM simple)
3710 if (unsmob_music (simple))
3712 if (parser->lexer_->is_note_state ()) {
3713 if (scm_is_symbol (simple)) {
3714 Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
3715 n->set_property ("duration", parser->default_duration_.smobbed_copy ());
3716 n->set_property ("drum-type", simple);
3717 return n->unprotect ();
3719 if (unsmob_pitch (simple)) {
3720 Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
3721 n->set_property ("duration", parser->default_duration_.smobbed_copy ());
3722 n->set_property ("pitch", simple);
3723 return n->unprotect ();
3726 } else if (parser->lexer_->is_lyric_state ()) {
3727 if (Text_interface::is_markup (simple))
3728 return MAKE_SYNTAX ("lyric-event", loc, simple,
3729 parser->default_duration_.smobbed_copy ());
3730 } else if (parser->lexer_->is_chord_state ()) {
3731 if (unsmob_pitch (simple))
3732 return make_chord_elements (loc, simple,
3733 parser->default_duration_.smobbed_copy (),
3740 make_music_with_input (SCM name, Input where)
3742 Music *m = make_music_by_name (name);
3743 m->set_spot (where);
3748 make_simple_markup (SCM a)
3754 make_duration (SCM d, int dots)
3756 int t = scm_to_int (d);
3757 if (t > 0 && (t & (t-1)) == 0)
3758 return Duration (intlog2 (t), dots).smobbed_copy ();
3760 return SCM_UNDEFINED;
3764 make_chord_step (SCM step_scm, Rational alter)
3766 int step = scm_to_int (step_scm);
3769 alter += FLAT_ALTERATION;
3773 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
3774 return m.smobbed_copy ();
3779 make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list)
3781 SCM chord_ctor = ly_lily_module_constant ("construct-chord-elements");
3782 SCM res = scm_call_3 (chord_ctor, pitch, dur, modification_list);
3783 for (SCM s = res; scm_is_pair (s); s = scm_cdr (s))
3785 unsmob_music (scm_car (s))->set_spot (loc);
3791 yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser)
3793 Lily_lexer *lex = parser->lexer_;
3797 lex->prepare_for_next_token ();
3798 return lex->yylex ();