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. */
65 %nonassoc REPEAT REPEAT_IDENTIFIER
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 '^' '_'
84 HYPHEN EXTENDER DURATION_IDENTIFIER
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 SCORELINES "\\score-lines"
273 %token SEQUENTIAL "\\sequential"
275 %token SIMULTANEOUS "\\simultaneous"
276 %token TEMPO "\\tempo"
278 %token UNSET "\\unset"
281 /* Keyword token exceptions. */
282 %token NEWCONTEXT "\\new"
285 /* Other string tokens. */
287 %token CHORD_BASS "/+"
288 %token CHORD_CARET "^"
289 %token CHORD_COLON ":"
290 %token CHORD_MINUS "-"
291 %token CHORD_SLASH "/"
292 %token ANGLE_OPEN "<"
293 %token ANGLE_CLOSE ">"
294 %token DOUBLE_ANGLE_OPEN "<<"
295 %token DOUBLE_ANGLE_CLOSE ">>"
296 %token E_BACKSLASH "\\"
297 %token E_EXCLAMATION "\\!"
302 If we give names, Bison complains.
304 %token FIGURE_CLOSE /* "\\>" */
305 %token FIGURE_OPEN /* "\\<" */
306 %token FIGURE_SPACE "_"
309 %token MULTI_MEASURE_REST
315 /* Artificial tokens, for more generic function syntax */
316 %token EXPECT_MARKUP "markup?"
317 %token EXPECT_SCM "scheme?"
318 %token BACKUP "(backed-up?)"
319 %token REPARSE "(reparsed?)"
320 %token EXPECT_MARKUP_LIST "markup-list?"
321 %token EXPECT_OPTIONAL "optional?"
322 /* After the last argument. */
323 %token EXPECT_NO_MORE_ARGS;
325 /* An artificial token for parsing embedded Lilypond */
326 %token EMBEDDED_LILY "#{"
328 %token BOOK_IDENTIFIER
329 %token CHORD_BODY_IDENTIFIER
330 %token CHORD_MODIFIER
331 %token CHORD_REPETITION
332 %token CONTEXT_DEF_IDENTIFIER
333 %token CONTEXT_MOD_IDENTIFIER
335 %token PITCH_IDENTIFIER
336 %token DURATION_IDENTIFIER
337 %token EVENT_IDENTIFIER
338 %token EVENT_FUNCTION
341 %token MARKUP_FUNCTION
342 %token MARKUP_LIST_FUNCTION
343 %token MARKUP_IDENTIFIER
344 %token MARKUPLIST_IDENTIFIER
345 %token MUSIC_FUNCTION
346 %token MUSIC_IDENTIFIER
347 %token NOTENAME_PITCH
348 %token NUMBER_IDENTIFIER
349 %token OUTPUT_DEF_IDENTIFIER
351 %token REPEAT_IDENTIFIER
355 %token SCM_IDENTIFIER
359 %token TONICNAME_PITCH
363 /* We don't assign precedence to / and *, because we might need varied
364 prec levels in different prods */
373 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
374 parser->lexer_->push_note_state (nn);
375 } embedded_lilypond {
376 parser->lexer_->pop_state ();
381 lilypond: /* empty */ { $$ = SCM_UNSPECIFIED; }
382 | lilypond toplevel_expression {
384 | lilypond assignment {
387 parser->error_level_ = 1;
390 parser->error_level_ = 1;
397 parser->lexer_->add_scope (get_header (parser));
399 parser->lexer_->set_identifier (ly_symbol2scm ("$defaultheader"), $2);
402 SCM proc = parser->lexer_->lookup_identifier ("toplevel-book-handler");
403 scm_call_2 (proc, parser->self_scm (), $1);
406 SCM proc = parser->lexer_->lookup_identifier ("toplevel-bookpart-handler");
407 scm_call_2 (proc, parser->self_scm (), $1);
410 SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
411 scm_call_2 (proc, parser->self_scm (), $1);
414 SCM proc = parser->lexer_->lookup_identifier ("toplevel-music-handler");
415 scm_call_2 (proc, parser->self_scm (), $1);
418 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
419 scm_call_2 (proc, parser->self_scm (), scm_list_1 ($1));
422 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
423 scm_call_2 (proc, parser->self_scm (), $1);
426 // Evaluate and ignore #xxx, as opposed to \xxx
427 parser->lexer_->eval_scm_token ($1);
429 | embedded_scm_active
431 SCM out = SCM_UNDEFINED;
432 if (Text_interface::is_markup ($1))
433 out = scm_list_1 ($1);
434 else if (Text_interface::is_markup_list ($1))
436 if (scm_is_pair (out))
438 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
439 scm_call_2 (proc, parser->self_scm (), out);
440 } else if (!scm_is_eq ($1, SCM_UNSPECIFIED))
441 parser->parser_error (@1, _("bad expression type"));
445 Output_def * od = unsmob_output_def ($1);
447 if (od->c_variable ("is-paper") == SCM_BOOL_T)
448 id = ly_symbol2scm ("$defaultpaper");
449 else if (od->c_variable ("is-midi") == SCM_BOOL_T)
450 id = ly_symbol2scm ("$defaultmidi");
451 else if (od->c_variable ("is-layout") == SCM_BOOL_T)
452 id = ly_symbol2scm ("$defaultlayout");
454 parser->lexer_->set_identifier (id, $1);
461 $$ = parser->lexer_->eval_scm_token ($1);
471 embedded_scm_bare_arg:
475 $$ = parser->lexer_->eval_scm_token ($1);
478 | context_modification
480 | context_def_spec_block
486 /* The generic version may end in music, or not */
493 /* embedded_scm_arg is _not_ casting pitches to music by default, this
494 * has to be done by the function itself. Note that this may cause
495 * the results of scm_function_call or embedded_scm_bare_arg to be
496 * turned into music from pitches as well. Note that this creates a
497 * distinctly awkward situation for calculated drum pitches. Those
498 * are at the current point of time rejected as music constituents as
499 * they can't be distinguished from "proper" symbols.
503 embedded_scm_bare_arg
509 SCM_FUNCTION function_arglist {
510 $$ = MAKE_SYNTAX ("music-function", @$,
518 // FIXME: @$ does not contain a useful source location
519 // for empty rules, and the only token in the whole
520 // production, EMBEDDED_LILY, is synthetic and also
521 // contains no source location.
522 $$ = MAKE_SYNTAX ("void-music", @$);
525 | music_embedded music_embedded music_list {
526 $3 = scm_reverse_x ($3, SCM_EOL);
527 if (unsmob_music ($2))
528 $3 = scm_cons ($2, $3);
529 if (unsmob_music ($1))
530 $3 = scm_cons ($1, $3);
531 $$ = MAKE_SYNTAX ("sequential-music", @$, $3);
534 parser->error_level_ = 1;
535 $$ = SCM_UNSPECIFIED;
537 | INVALID embedded_lilypond {
538 parser->error_level_ = 1;
544 lilypond_header_body:
545 /* empty */ { $$ = SCM_UNSPECIFIED; }
546 | lilypond_header_body assignment {
549 | lilypond_header_body embedded_scm {
555 HEADER '{' lilypond_header_body '}' {
556 $$ = parser->lexer_->remove_scope ();
568 assignment_id '=' identifier_init {
569 parser->lexer_->set_identifier ($1, $3);
570 $$ = SCM_UNSPECIFIED;
572 | assignment_id property_path '=' identifier_init {
573 SCM path = scm_cons (scm_string_to_symbol ($1), $2);
574 parser->lexer_->set_identifier (path, $4);
575 $$ = SCM_UNSPECIFIED;
585 | context_def_spec_block
587 | post_event_nofinger post_events
589 $$ = scm_reverse_x ($2, SCM_EOL);
590 if (Music *m = unsmob_music ($1))
592 if (m->is_mus_type ("post-event-wrapper"))
594 (scm_list_2 (m->get_property ("elements"),
597 $$ = scm_cons ($1, $$);
600 && scm_is_null (scm_cdr ($$)))
604 Music * m = MY_MAKE_MUSIC ("PostEvents", @$);
605 m->set_property ("elements", $$);
606 $$ = m->unprotect ();
614 | context_modification
617 context_def_spec_block:
618 CONTEXT '{' context_def_spec_body '}'
621 unsmob_context_def ($$)->origin ()->set_spot (@$);
629 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
630 parser->lexer_->push_note_state (nn);
634 parser->lexer_->pop_state ();
639 context_mod_embedded:
642 if (unsmob_music ($1)) {
643 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
644 $1 = scm_call_2 (proc, parser->self_scm (), $1);
646 if (unsmob_context_mod ($1))
649 parser->parser_error (@1, _ ("not a context mod"));
650 $$ = Context_mod ().smobbed_copy ();
656 context_def_spec_body:
658 $$ = Context_def::make_scm ();
660 | CONTEXT_DEF_IDENTIFIER {
663 | context_def_spec_body context_mod {
664 if (!SCM_UNBNDP ($2))
665 unsmob_context_def ($$)->add_context_mod ($2);
667 | context_def_spec_body context_modification {
668 Context_def *td = unsmob_context_def ($$);
669 SCM new_mods = unsmob_context_mod ($2)->get_mods ();
670 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
671 td->add_context_mod (scm_car (m));
674 | context_def_spec_body context_mod_embedded {
675 Context_def *td = unsmob_context_def ($$);
676 SCM new_mods = unsmob_context_mod ($2)->get_mods ();
677 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
678 td->add_context_mod (scm_car (m));
686 BOOK '{' book_body '}' {
688 unsmob_book ($$)->origin ()->set_spot (@$);
690 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), SCM_BOOL_F);
695 * Use 'handlers' like for toplevel-* stuff?
696 * grok \layout and \midi? */
699 Book *book = new Book;
700 init_papers (parser);
701 book->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (parser->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
702 book->paper_->unprotect ();
703 push_paper (parser, book->paper_);
704 book->header_ = get_header (parser);
705 $$ = book->unprotect ();
706 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$);
709 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $1);
711 | book_body paper_block {
712 unsmob_book ($1)->paper_ = unsmob_output_def ($2);
713 set_paper (parser, unsmob_output_def ($2));
715 | book_body bookpart_block {
716 SCM proc = parser->lexer_->lookup_identifier ("book-bookpart-handler");
717 scm_call_2 (proc, $1, $2);
719 | book_body score_block {
720 SCM proc = parser->lexer_->lookup_identifier ("book-score-handler");
721 scm_call_2 (proc, $1, $2);
723 | book_body composite_music {
724 SCM proc = parser->lexer_->lookup_identifier ("book-music-handler");
725 scm_call_3 (proc, parser->self_scm (), $1, $2);
727 | book_body full_markup {
728 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
729 scm_call_2 (proc, $1, scm_list_1 ($2));
731 | book_body full_markup_list {
732 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
733 scm_call_2 (proc, $1, $2);
735 | book_body SCM_TOKEN {
736 // Evaluate and ignore #xxx, as opposed to \xxx
737 parser->lexer_->eval_scm_token ($2);
739 | book_body embedded_scm_active
741 SCM out = SCM_UNDEFINED;
742 if (Text_interface::is_markup ($2))
743 out = scm_list_1 ($2);
744 else if (Text_interface::is_markup_list ($2))
746 if (scm_is_pair (out))
748 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
749 scm_call_2 (proc, $1, out);
750 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
751 parser->parser_error (@2, _("bad expression type"));
755 parser->lexer_->add_scope (unsmob_book ($1)->header_);
758 Book *book = unsmob_book ($1);
760 book->scores_ = SCM_EOL;
761 book->bookparts_ = SCM_EOL;
766 BOOKPART '{' bookpart_body '}' {
768 unsmob_book ($$)->origin ()->set_spot (@$);
769 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F);
775 Book *book = new Book;
776 $$ = book->unprotect ();
777 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $$);
780 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $1);
782 | bookpart_body paper_block {
783 unsmob_book ($$)->paper_ = unsmob_output_def ($2);
785 | bookpart_body score_block {
786 SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler");
787 scm_call_2 (proc, $1, $2);
789 | bookpart_body composite_music {
790 SCM proc = parser->lexer_->lookup_identifier ("bookpart-music-handler");
791 scm_call_3 (proc, parser->self_scm (), $1, $2);
793 | bookpart_body full_markup {
794 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
795 scm_call_2 (proc, $1, scm_list_1 ($2));
797 | bookpart_body full_markup_list {
798 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
799 scm_call_2 (proc, $1, $2);
801 | bookpart_body SCM_TOKEN {
802 // Evaluate and ignore #xxx, as opposed to \xxx
803 parser->lexer_->eval_scm_token ($2);
805 | bookpart_body embedded_scm_active
807 SCM out = SCM_UNDEFINED;
808 if (Text_interface::is_markup ($2))
809 out = scm_list_1 ($2);
810 else if (Text_interface::is_markup_list ($2))
812 if (scm_is_pair (out))
814 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
815 scm_call_2 (proc, $1, out);
816 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
817 parser->parser_error (@2, _("bad expression type"));
821 Book *book = unsmob_book ($1);
822 if (!ly_is_module (book->header_))
823 book->header_ = ly_make_module (false);
824 parser->lexer_->add_scope (book->header_);
826 | bookpart_body error {
827 Book *book = unsmob_book ($1);
829 book->scores_ = SCM_EOL;
834 SCORE '{' score_body '}' {
841 SCM scorify = ly_lily_module_constant ("scorify-music");
842 $$ = scm_call_2 (scorify, $1, parser->self_scm ());
844 unsmob_score ($$)->origin ()->set_spot (@$);
846 | embedded_scm_active {
848 if (unsmob_score ($1))
849 score = new Score (*unsmob_score ($1));
852 parser->parser_error (@1, _("score expected"));
854 unsmob_score ($$)->origin ()->set_spot (@$);
855 $$ = score->unprotect ();
859 Score *score = unsmob_score ($1);
860 if (!ly_is_module (score->get_header ()))
861 score->set_header (ly_make_module (false));
862 parser->lexer_->add_scope (score->get_header ());
864 | score_body output_def {
865 Output_def *od = unsmob_output_def ($2);
866 if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
868 parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
873 unsmob_score ($1)->add_output_def (od);
877 unsmob_score ($$)->error_found_ = true;
888 Output_def *od = unsmob_output_def ($1);
890 if (od->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
892 parser->parser_error (@1, _ ("need \\paper for paper block"));
893 $$ = get_paper (parser)->unprotect ();
900 output_def_body '}' {
903 parser->lexer_->remove_scope ();
904 parser->lexer_->pop_state ();
910 Output_def *p = get_paper (parser);
911 p->input_origin_ = @$;
912 parser->lexer_->add_scope (p->scope_);
913 $$ = p->unprotect ();
916 Output_def *p = get_midi (parser);
917 $$ = p->unprotect ();
918 parser->lexer_->add_scope (p->scope_);
921 Output_def *p = get_layout (parser);
923 parser->lexer_->add_scope (p->scope_);
924 $$ = p->unprotect ();
928 output_def_head_with_mode_switch:
930 parser->lexer_->push_initial_state ();
935 // We need this weird nonterminal because both music as well as a
936 // context definition can start with \context and the difference is
937 // only apparent after looking at the next token. If it is '{', there
938 // is still time to escape from notes mode.
940 music_or_context_def:
942 | context_def_spec_block
946 output_def_head_with_mode_switch '{' {
948 unsmob_output_def ($$)->input_origin_.set_spot (@$);
950 | output_def_head_with_mode_switch '{' OUTPUT_DEF_IDENTIFIER {
951 Output_def *o = unsmob_output_def ($3);
952 o->input_origin_.set_spot (@$);
954 parser->lexer_->remove_scope ();
955 parser->lexer_->add_scope (o->scope_);
957 | output_def_body assignment {
960 | output_def_body embedded_scm {
965 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
966 parser->lexer_->push_note_state (nn);
967 } music_or_context_def
969 parser->lexer_->pop_state ();
970 if (unsmob_context_def ($3))
971 assign_context_def (unsmob_output_def ($1), $3);
974 SCM proc = parser->lexer_->lookup_identifier
975 ("output-def-music-handler");
976 scm_call_3 (proc, parser->self_scm (),
980 | output_def_body error {
986 TEMPO steno_duration '=' tempo_range {
987 $$ = MAKE_SYNTAX ("tempo", @$, SCM_EOL, $2, $4);
989 | TEMPO scalar steno_duration '=' tempo_range {
990 $$ = MAKE_SYNTAX ("tempo", @$, $2, $3, $5);
993 $$ = MAKE_SYNTAX ("tempo", @$, $2);
998 The representation of a list is reversed to have efficient append. */
1004 | music_list music_embedded {
1005 if (unsmob_music ($2))
1006 $$ = scm_cons ($2, $1);
1008 | music_list error {
1009 Music *m = MY_MAKE_MUSIC("Music", @$);
1011 m->set_property ("error-found", SCM_BOOL_T);
1012 $$ = scm_cons (m->self_scm (), $1);
1013 m->unprotect (); /* UGH */
1020 $$ = scm_reverse_x ($2, SCM_EOL);
1025 | lyric_element_music
1031 if (unsmob_music ($1)->is_mus_type ("post-event")) {
1032 parser->parser_error (@1, _ ("unexpected post-event"));
1033 $$ = SCM_UNSPECIFIED;
1036 | music_embedded_backup
1040 | music_embedded_backup BACKUP lyric_element_music
1046 music_embedded_backup:
1049 if (scm_is_eq ($1, SCM_UNSPECIFIED))
1051 else if (Music *m = unsmob_music ($1)) {
1052 if (m->is_mus_type ("post-event")) {
1053 parser->parser_error
1054 (@1, _ ("unexpected post-event"));
1055 $$ = SCM_UNSPECIFIED;
1058 } else if (parser->lexer_->is_lyric_state ()
1059 && Text_interface::is_markup ($1))
1060 MYBACKUP (LYRIC_ELEMENT, $1, @1);
1062 @$.warning (_ ("Ignoring non-music expression"));
1071 $$ = make_music_from_simple (parser, @1, $1);
1072 if (!unsmob_music ($$))
1074 parser->parser_error (@1, _ ("music expected"));
1075 $$ = MAKE_SYNTAX ("void-music", @$);
1078 | composite_music %prec COMPOSITE
1083 | composite_music %prec COMPOSITE
1087 REPEAT simple_string unsigned_number music
1089 $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, SCM_EOL);
1091 | REPEAT_IDENTIFIER music
1093 $$ = MAKE_SYNTAX ("repeat", @$, scm_car ($1), scm_cdr ($1),
1096 | REPEAT simple_string unsigned_number music ALTERNATIVE braced_music_list
1098 $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, $6);
1100 | REPEAT_IDENTIFIER music ALTERNATIVE braced_music_list
1102 $$ = MAKE_SYNTAX ("repeat", @$, scm_car ($1), scm_cdr ($1),
1108 SEQUENTIAL braced_music_list {
1109 $$ = MAKE_SYNTAX ("sequential-music", @$, $2);
1111 | braced_music_list {
1112 $$ = MAKE_SYNTAX ("sequential-music", @$, $1);
1117 SIMULTANEOUS braced_music_list {
1118 $$ = MAKE_SYNTAX ("simultaneous-music", @$, $2);
1120 | DOUBLE_ANGLE_OPEN music_list DOUBLE_ANGLE_CLOSE {
1121 $$ = MAKE_SYNTAX ("simultaneous-music", @$, scm_reverse_x ($2, SCM_EOL));
1127 | music_property_def
1131 context_modification:
1134 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
1135 parser->lexer_->push_note_state (nn);
1136 } '{' context_mod_list '}'
1138 parser->lexer_->pop_state ();
1141 | WITH CONTEXT_MOD_IDENTIFIER
1145 | CONTEXT_MOD_IDENTIFIER
1149 | WITH context_modification_arg
1151 if (unsmob_music ($2)) {
1152 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
1153 $2 = scm_call_2 (proc, parser->self_scm (), $2);
1155 if (unsmob_context_mod ($2))
1158 parser->parser_error (@2, _ ("not a context mod"));
1159 $$ = Context_mod ().smobbed_copy ();
1164 context_modification_arg:
1169 optional_context_mod:
1173 | context_modification
1181 $$ = Context_mod ().smobbed_copy ();
1183 | context_mod_list context_mod {
1184 if (!SCM_UNBNDP ($2))
1185 unsmob_context_mod ($1)->add_context_mod ($2);
1187 | context_mod_list CONTEXT_MOD_IDENTIFIER {
1188 Context_mod *md = unsmob_context_mod ($2);
1190 unsmob_context_mod ($1)->add_context_mods (md->get_mods ());
1192 | context_mod_list context_mod_embedded {
1193 unsmob_context_mod ($1)->add_context_mods
1194 (unsmob_context_mod ($2)->get_mods ());
1203 /* Music that can be parsed without lookahead */
1206 | complex_music_prefix closed_music
1208 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
1210 | music_function_call_closed
1216 | grouped_music_list
1220 simultaneous_music { $$ = $1; }
1221 | sequential_music { $$ = $1; }
1224 /* Function argument lists are arguably the most complex part in the
1225 * parser. They are pretty tricky to understand because of the way
1226 * they are processed, and because of optional arguments that can be
1227 * omitted. When there are several optional arguments in a row,
1228 * omitting one automatically omits all following arguments. Optional
1229 * arguments can only be omitted when either
1231 * a) the omission is explicitly started with \default
1232 * b) the omission is implicitly started by an argument not matching
1233 * its predicate, and there is a mandatory argument later that can
1234 * "catch" the argument that does not fit.
1236 * When argument parsing starts, the lexer pushes EXPECT_SCM tokens
1237 * (corresponding to mandatory arguments and having a predicate
1238 * function as semantic value) or EXPECT_OPTIONAL EXPECT_SCM (where
1239 * the semantic value of the EXPECT_OPTIONAL token is the default to
1240 * use when the optional argument is omitted, and EXPECT_SCM again has
1241 * the argument predicate as semantic value) in reverse order to the
1242 * parser, followed by EXPECT_NO_MORE_ARGS. The argument list is then
1243 * processed inside-out while actual tokens are consumed.
1245 * This means that the argument list tokens determine the actions
1246 * taken as they arrive. The structure of the argument list is known
1247 * to the parser and stored in its parse stack when the first argument
1248 * is being parsed. What the parser does not know is which predicates
1249 * will match and whether or not \default will be appearing in the
1250 * argument list, and where.
1252 * Many of the basic nonterminals used for argument list scanning come
1253 * in a "normal" and a "closed" flavor. A closed expression is one
1254 * that can be parsed without a lookahead token. That makes it
1255 * feasible for an optional argument that may need to be skipped:
1256 * skipping can only be accomplished by pushing back the token into
1257 * the lexer, and that only works when there is no lookahead token.
1259 * Sequences of 0 or more optional arguments are scanned using either
1260 * function_arglist_backup or function_arglist_nonbackup. The first
1261 * is used when optional arguments are followed by at least one
1262 * mandatory argument: in that case optional arguments may be skipped
1263 * by either a false predicate (in which case the expression will be
1264 * pushed back as one or more tokens, preceded by a BACKUP token) or
1265 * by using \default.
1267 * If optional arguments are at the end of the argument list, they are
1268 * instead scanned using function_arglist_nonbackup: here the only
1269 * manner to enter into skipping of optional arguments is the use of
1272 * The argument list of a normal function call is parsed using
1273 * function_arglist. The part of an argument list before a mandatory
1274 * argument is parsed using function_arglist_optional.
1276 * The difference is that leading optional arguments are scanned using
1277 * function_arglist_nonbackup and function_arglist_backup,
1280 * Most other details are obvious in the rules themselves.
1284 function_arglist_nonbackup_common:
1285 EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup FRACTION
1287 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1289 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup post_event_nofinger
1291 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1293 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' UNSIGNED
1295 SCM n = scm_difference ($5, SCM_UNDEFINED);
1296 if (scm_is_true (scm_call_1 ($2, n)))
1297 $$ = scm_cons (n, $3);
1299 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
1300 t->set_property ("digit", $5);
1301 $$ = check_scheme_arg (parser, @4, t->unprotect (),
1306 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL
1308 $$ = check_scheme_arg (parser, @4,
1309 scm_difference ($5, SCM_UNDEFINED),
1312 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' NUMBER_IDENTIFIER
1314 $$ = check_scheme_arg (parser, @4,
1315 scm_difference ($5, SCM_UNDEFINED),
1320 function_arglist_closed_nonbackup:
1321 function_arglist_nonbackup_common
1322 | function_arglist_closed_common
1323 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg_closed
1325 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1327 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup bare_number_closed
1329 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1331 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
1333 $$ = check_scheme_arg (parser, @4,
1334 try_string_variants ($2, $4),
1337 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
1339 $$ = check_scheme_arg (parser, @4,
1340 try_string_variants ($2, $4),
1343 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup full_markup
1345 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1351 | SYMBOL_LIST '.' symbol_list_rev
1353 $$ = scm_append (scm_list_2 ($1, scm_reverse_x ($3, SCM_EOL)));
1359 | symbol_list_rev '.' symbol_list_part
1361 $$ = scm_append_x (scm_list_2 ($3, $1));
1365 // symbol_list_part delivers elements in reverse copy.
1370 SCM sym_l_p = ly_lily_module_constant ("symbol-list?");
1371 $$ = try_string_variants (sym_l_p, $1);
1372 if (SCM_UNBNDP ($$)) {
1373 parser->parser_error (@1, _("not a symbol"));
1376 $$ = scm_reverse ($$);
1381 symbol_list_element:
1387 function_arglist_nonbackup:
1388 function_arglist_nonbackup_common
1389 | function_arglist_common
1390 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg
1392 if (scm_is_true (scm_call_1 ($2, $4)))
1393 $$ = scm_cons ($4, $3);
1395 $$ = check_scheme_arg (parser, @4,
1396 make_music_from_simple
1400 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup bare_number_common
1402 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1404 | function_arglist_nonbackup_reparse REPARSE duration_length
1406 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1408 | function_arglist_nonbackup_reparse REPARSE bare_number_common
1410 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1412 | function_arglist_nonbackup_reparse REPARSE SCM_ARG
1414 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1416 | function_arglist_nonbackup_reparse REPARSE lyric_element_music
1418 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1420 | function_arglist_nonbackup_reparse REPARSE symbol_list_arg
1422 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1426 function_arglist_nonbackup_reparse:
1427 EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
1430 SCM res = try_string_variants ($2, $4);
1431 if (!SCM_UNBNDP (res))
1432 if (scm_is_pair (res))
1433 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1435 MYREPARSE (@4, $2, SCM_ARG, res);
1436 else if (scm_is_true
1438 ($2, make_music_from_simple
1440 MYREPARSE (@4, $2, STRING, $4);
1442 MYREPARSE (@4, $2, SCM_ARG, $4);
1444 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
1447 SCM res = try_string_variants ($2, $4);
1448 if (!SCM_UNBNDP (res))
1449 if (scm_is_pair (res))
1450 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1452 MYREPARSE (@4, $2, SCM_ARG, res);
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_nonbackup full_markup
1464 if (scm_is_true (scm_call_1 ($2, $4)))
1465 MYREPARSE (@4, $2, SCM_ARG, $4);
1466 else if (scm_is_true
1468 ($2, make_music_from_simple
1470 MYREPARSE (@4, $2, STRING, $4);
1472 MYREPARSE (@4, $2, SCM_ARG, $4);
1474 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup UNSIGNED
1477 if (scm_is_true (scm_call_1 ($2, $4)))
1478 MYREPARSE (@4, $2, REAL, $4);
1480 SCM d = make_duration ($4);
1481 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
1482 MYREPARSE (@4, $2, REAL, $4); // trigger error
1484 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
1487 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER {
1489 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
1494 function_arglist_backup:
1495 function_arglist_backup_common
1496 | function_arglist_common
1499 function_arglist_backup_common:
1500 EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup embedded_scm_arg_closed
1502 if (scm_is_true (scm_call_1 ($2, $4)))
1504 $$ = scm_cons ($4, $3);
1506 $$ = scm_cons (loc_on_music (@3, $1), $3);
1507 MYBACKUP (SCM_ARG, $4, @4);
1510 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup REPEAT simple_string unsigned_number
1512 $4 = MAKE_SYNTAX ("repeat", @4, $5, $6,
1513 MY_MAKE_MUSIC ("Music", @4)->unprotect (),
1515 if (scm_is_true (scm_call_1 ($2, $4)))
1518 MYREPARSE (@4, $2, REPEAT_IDENTIFIER, scm_cons ($5, $6));
1520 $$ = scm_cons (loc_on_music (@3, $1), $3);
1521 MYBACKUP (REPEAT_IDENTIFIER, scm_cons ($5, $6), @4);
1524 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup chord_body
1526 if (scm_is_true (scm_call_1 ($2, $4)))
1529 MYREPARSE (@4, $2, CHORD_BODY_IDENTIFIER, $4);
1531 $$ = scm_cons (loc_on_music (@3, $1), $3);
1532 MYBACKUP (CHORD_BODY_IDENTIFIER, $4, @4);
1535 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup post_event_nofinger
1537 if (scm_is_true (scm_call_1 ($2, $4)))
1539 $$ = scm_cons ($4, $3);
1541 $$ = scm_cons (loc_on_music (@3, $1), $3);
1542 MYBACKUP (EVENT_IDENTIFIER, $4, @4);
1545 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup full_markup
1547 if (scm_is_true (scm_call_1 ($2, $4)))
1548 $$ = scm_cons ($4, $3);
1550 $$ = scm_cons (loc_on_music (@3, $1), $3);
1551 MYBACKUP (LYRIC_ELEMENT, $4, @4);
1554 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup UNSIGNED
1556 if (scm_is_true (scm_call_1 ($2, $4)))
1558 MYREPARSE (@4, $2, REAL, $4);
1561 SCM d = make_duration ($4);
1562 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
1564 $$ = scm_cons (loc_on_music (@3, $1), $3);
1565 MYBACKUP (UNSIGNED, $4, @4);
1567 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
1572 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup REAL
1574 if (scm_is_true (scm_call_1 ($2, $4)))
1577 MYREPARSE (@4, $2, REAL, $4);
1579 $$ = scm_cons (loc_on_music (@3, $1), $3);
1580 MYBACKUP (REAL, $4, @4);
1583 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup NUMBER_IDENTIFIER
1585 if (scm_is_true (scm_call_1 ($2, $4)))
1587 $$ = scm_cons ($4, $3);
1589 $$ = scm_cons (loc_on_music (@3, $1), $3);
1590 MYBACKUP (NUMBER_IDENTIFIER, $4, @4);
1593 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup FRACTION
1595 if (scm_is_true (scm_call_1 ($2, $4)))
1597 $$ = scm_cons ($4, $3);
1599 $$ = scm_cons (loc_on_music (@3, $1), $3);
1600 MYBACKUP (FRACTION, $4, @4);
1603 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' UNSIGNED
1605 SCM n = scm_difference ($5, SCM_UNDEFINED);
1606 if (scm_is_true (scm_call_1 ($2, n))) {
1608 MYREPARSE (@5, $2, REAL, n);
1610 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
1611 t->set_property ("digit", $5);
1612 $$ = t->unprotect ();
1613 if (scm_is_true (scm_call_1 ($2, $$)))
1614 $$ = scm_cons ($$, $3);
1616 $$ = scm_cons (loc_on_music (@3, $1), $3);
1617 MYBACKUP (UNSIGNED, $5, @5);
1618 parser->lexer_->push_extra_token ('-');
1623 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' REAL
1625 SCM n = scm_difference ($5, SCM_UNDEFINED);
1626 if (scm_is_true (scm_call_1 ($2, n))) {
1627 MYREPARSE (@5, $2, REAL, n);
1630 $$ = scm_cons (loc_on_music (@3, $1), $3);
1631 MYBACKUP (REAL, n, @5);
1634 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' NUMBER_IDENTIFIER
1636 SCM n = scm_difference ($5, SCM_UNDEFINED);
1637 if (scm_is_true (scm_call_1 ($2, n))) {
1638 $$ = scm_cons (n, $3);
1640 $$ = scm_cons (loc_on_music (@3, $1), $3);
1641 MYBACKUP (NUMBER_IDENTIFIER, n, @5);
1644 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup PITCH_IDENTIFIER
1646 if (scm_is_true (scm_call_1 ($2, $4)))
1648 $$ = scm_cons ($4, $3);
1650 $$ = scm_cons (loc_on_music (@3, $1), $3);
1651 MYBACKUP (PITCH_IDENTIFIER, $4, @4);
1654 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup NOTENAME_PITCH
1656 if (scm_is_true (scm_call_1 ($2, $4)))
1658 MYREPARSE (@4, $2, NOTENAME_PITCH, $4);
1661 $$ = scm_cons (loc_on_music (@3, $1), $3);
1662 MYBACKUP (NOTENAME_PITCH, $4, @4);
1665 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup TONICNAME_PITCH
1667 if (scm_is_true (scm_call_1 ($2, $4)))
1669 MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
1672 $$ = scm_cons (loc_on_music (@3, $1), $3);
1673 MYBACKUP (TONICNAME_PITCH, $4, @4);
1676 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup DURATION_IDENTIFIER
1678 if (scm_is_true (scm_call_1 ($2, $4)))
1680 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
1683 $$ = scm_cons (loc_on_music (@3, $1), $3);
1684 MYBACKUP (DURATION_IDENTIFIER, $4, @4);
1687 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup SCM_IDENTIFIER
1689 SCM res = try_string_variants ($2, $4);
1690 if (!SCM_UNBNDP (res))
1691 if (scm_is_pair (res)) {
1693 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1696 $$ = scm_cons (res, $3);
1698 $$ = scm_cons (loc_on_music (@3, $1), $3);
1699 MYBACKUP (SCM_IDENTIFIER, $4, @4);
1702 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup STRING
1704 SCM res = try_string_variants ($2, $4);
1705 if (!SCM_UNBNDP (res))
1706 if (scm_is_pair (res)) {
1708 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1711 $$ = scm_cons (res, $3);
1713 $$ = scm_cons (loc_on_music (@3, $1), $3);
1714 MYBACKUP (STRING, $4, @4);
1717 | function_arglist_backup REPARSE music_assign
1719 if (scm_is_true (scm_call_1 ($2, $3)))
1720 $$ = scm_cons ($3, $1);
1722 $$ = check_scheme_arg (parser, @3,
1723 make_music_from_simple
1727 | function_arglist_backup REPARSE bare_number_common
1729 $$ = check_scheme_arg (parser, @3,
1732 | function_arglist_backup REPARSE duration_length
1734 $$ = check_scheme_arg (parser, @3,
1737 | function_arglist_backup REPARSE symbol_list_arg
1739 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1744 function_arglist_nonbackup
1745 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
1747 $$ = scm_cons (loc_on_music (@4, $1), $3);
1751 function_arglist_skip_nonbackup:
1752 function_arglist_nonbackup
1753 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup
1755 $$ = scm_cons (loc_on_music (@3, $1), $3);
1759 function_arglist_common:
1760 EXPECT_NO_MORE_ARGS {
1763 | EXPECT_SCM function_arglist_optional embedded_scm_arg
1765 if (scm_is_true (scm_call_1 ($1, $3)))
1766 $$ = scm_cons ($3, $2);
1768 $$ = check_scheme_arg (parser, @3,
1769 make_music_from_simple
1773 | EXPECT_SCM function_arglist_optional bare_number_common
1775 $$ = check_scheme_arg (parser, @3,
1778 | EXPECT_SCM function_arglist_optional FRACTION
1780 $$ = check_scheme_arg (parser, @3,
1783 | EXPECT_SCM function_arglist_optional post_event_nofinger
1785 $$ = check_scheme_arg (parser, @3,
1788 | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
1790 SCM n = scm_difference ($4, SCM_UNDEFINED);
1791 $$ = check_scheme_arg (parser, @4, n, $2, $1);
1793 | function_arglist_common_reparse REPARSE SCM_ARG
1795 $$ = check_scheme_arg (parser, @3,
1798 | function_arglist_common_reparse REPARSE lyric_element_music
1800 $$ = check_scheme_arg (parser, @3,
1803 | function_arglist_common_reparse REPARSE bare_number_common
1805 $$ = check_scheme_arg (parser, @3,
1808 | function_arglist_common_reparse REPARSE duration_length
1810 $$ = check_scheme_arg (parser, @3,
1813 | function_arglist_common_reparse REPARSE symbol_list_arg
1815 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1819 function_arglist_common_reparse:
1820 EXPECT_SCM function_arglist_optional SCM_IDENTIFIER
1823 SCM res = try_string_variants ($1, $3);
1824 if (!SCM_UNBNDP (res))
1825 if (scm_is_pair (res))
1826 MYREPARSE (@3, $1, SYMBOL_LIST, res);
1828 MYREPARSE (@3, $1, SCM_ARG, res);
1829 else if (scm_is_true
1831 ($1, make_music_from_simple (parser, @3, $3))))
1832 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1834 // This is going to flag a syntax error, we
1835 // know the predicate to be false.
1836 MYREPARSE (@3, $1, SCM_ARG, $3);
1838 | EXPECT_SCM function_arglist_optional STRING
1841 SCM res = try_string_variants ($1, $3);
1842 if (!SCM_UNBNDP (res))
1843 if (scm_is_pair (res))
1844 MYREPARSE (@3, $1, SYMBOL_LIST, res);
1846 MYREPARSE (@3, $1, SCM_ARG, res);
1847 else if (scm_is_true
1849 ($1, make_music_from_simple (parser, @3, $3))))
1850 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1852 // This is going to flag a syntax error, we
1853 // know the predicate to be false.
1854 MYREPARSE (@3, $1, SCM_ARG, $3);
1856 | EXPECT_SCM function_arglist_optional full_markup
1859 if (scm_is_true (scm_call_1 ($1, $3)))
1860 MYREPARSE (@3, $1, SCM_ARG, $3);
1861 else if (scm_is_true
1863 ($1, make_music_from_simple (parser, @3, $3))))
1864 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1866 // This is going to flag a syntax error, we
1867 // know the predicate to be false.
1868 MYREPARSE (@3, $1, SCM_ARG, $3);
1870 | EXPECT_SCM function_arglist_optional UNSIGNED
1873 if (scm_is_true (scm_call_1 ($1, $3)))
1874 MYREPARSE (@3, $1, REAL, $3);
1876 SCM d = make_duration ($3);
1877 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($1, d)))
1878 MYREPARSE (@3, $1, REAL, $3);
1880 MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
1883 | EXPECT_SCM function_arglist_optional DURATION_IDENTIFIER
1886 MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
1888 | EXPECT_SCM function_arglist_optional '-' UNSIGNED
1891 SCM n = scm_difference ($4, SCM_UNDEFINED);
1892 if (scm_is_true (scm_call_1 ($1, n)))
1893 MYREPARSE (@4, $1, REAL, n);
1895 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @4);
1896 t->set_property ("digit", $4);
1897 SCM m = t->unprotect ();
1898 if (scm_is_true (scm_call_1 ($1, m)))
1899 MYREPARSE (@4, $1, SCM_ARG, m);
1901 MYREPARSE (@4, $1, SCM_ARG, $4);
1905 | EXPECT_SCM function_arglist_optional '-' REAL
1908 SCM n = scm_difference ($4, SCM_UNDEFINED);
1909 MYREPARSE (@4, $1, REAL, n);
1913 function_arglist_closed:
1914 function_arglist_closed_nonbackup
1915 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
1917 $$ = scm_cons (loc_on_music (@4, $1), $3);
1921 function_arglist_closed_common:
1922 EXPECT_NO_MORE_ARGS {
1925 | EXPECT_SCM function_arglist_optional embedded_scm_arg_closed
1927 $$ = check_scheme_arg (parser, @3,
1930 | EXPECT_SCM function_arglist_optional bare_number_common_closed
1932 $$ = check_scheme_arg (parser, @3,
1935 | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
1937 $$ = check_scheme_arg (parser, @3,
1938 scm_difference ($4, SCM_UNDEFINED),
1941 | EXPECT_SCM function_arglist_optional post_event_nofinger
1943 $$ = check_scheme_arg (parser, @3,
1946 | EXPECT_SCM function_arglist_optional FRACTION
1948 $$ = check_scheme_arg (parser, @3,
1951 | function_arglist_common_reparse REPARSE SCM_ARG
1953 $$ = check_scheme_arg (parser, @3,
1956 | function_arglist_common_reparse REPARSE bare_number_common_closed
1958 $$ = check_scheme_arg (parser, @3,
1961 | function_arglist_common_reparse REPARSE symbol_list_arg
1963 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1967 function_arglist_optional:
1968 function_arglist_backup
1969 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup DEFAULT
1971 $$ = scm_cons (loc_on_music (@4, $1), $3);
1973 | function_arglist_skip_backup BACKUP
1976 function_arglist_skip_backup:
1977 function_arglist_backup
1978 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup
1980 $$ = scm_cons (loc_on_music (@3, $1), $3);
1984 embedded_scm_closed:
1986 | scm_function_call_closed
1989 embedded_scm_arg_closed:
1990 embedded_scm_bare_arg
1991 | scm_function_call_closed
1995 scm_function_call_closed:
1996 SCM_FUNCTION function_arglist_closed {
1997 $$ = MAKE_SYNTAX ("music-function", @$,
2002 music_function_call:
2003 MUSIC_FUNCTION function_arglist {
2004 $$ = MAKE_SYNTAX ("music-function", @$,
2011 /**/ { $$ = SCM_EOL; }
2012 | '=' simple_string {
2019 | repeated_music { $$ = $1; }
2020 | re_rhythmed_music { $$ = $1; }
2021 | complex_music_prefix music
2023 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
2027 complex_music_prefix:
2028 CONTEXT symbol optional_id optional_context_mod {
2029 Context_mod *ctxmod = unsmob_context_mod ($4);
2032 mods = ctxmod->get_mods ();
2033 $$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_F);
2035 | NEWCONTEXT symbol optional_id optional_context_mod {
2036 Context_mod *ctxmod = unsmob_context_mod ($4);
2039 mods = ctxmod->get_mods ();
2040 $$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_T);
2045 mode_changing_head grouped_music_list {
2046 if ($1 == ly_symbol2scm ("chords"))
2048 $$ = MAKE_SYNTAX ("unrelativable-music", @$, $2);
2054 parser->lexer_->pop_state ();
2056 | mode_changing_head_with_context optional_context_mod grouped_music_list {
2057 Context_mod *ctxmod = unsmob_context_mod ($2);
2060 mods = ctxmod->get_mods ();
2061 $$ = MAKE_SYNTAX ("context-specification", @$, $1, SCM_EOL, mods, SCM_BOOL_T, $3);
2062 if ($1 == ly_symbol2scm ("ChordNames"))
2064 $$ = MAKE_SYNTAX ("unrelativable-music", @$, $$);
2066 parser->lexer_->pop_state ();
2072 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
2073 parser->lexer_->push_note_state (nn);
2075 $$ = ly_symbol2scm ("notes");
2079 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2080 parser->lexer_->push_note_state (nn);
2082 $$ = ly_symbol2scm ("drums");
2085 parser->lexer_->push_figuredbass_state ();
2087 $$ = ly_symbol2scm ("figures");
2090 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2091 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2092 nn = parser->lexer_->lookup_identifier ("pitchnames");
2093 parser->lexer_->push_chord_state (nn);
2094 $$ = ly_symbol2scm ("chords");
2098 { parser->lexer_->push_lyric_state ();
2099 $$ = ly_symbol2scm ("lyrics");
2103 mode_changing_head_with_context:
2105 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2106 parser->lexer_->push_note_state (nn);
2108 $$ = ly_symbol2scm ("DrumStaff");
2111 parser->lexer_->push_figuredbass_state ();
2113 $$ = ly_symbol2scm ("FiguredBass");
2116 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2117 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2118 nn = parser->lexer_->lookup_identifier ("pitchnames");
2119 parser->lexer_->push_chord_state (nn);
2120 $$ = ly_symbol2scm ("ChordNames");
2123 { parser->lexer_->push_lyric_state ();
2124 $$ = ly_symbol2scm ("Lyrics");
2129 ADDLYRICS { parser->lexer_->push_lyric_state (); }
2132 /* Can also use music at the expensive of two S/Rs similar to
2133 \repeat \alternative */
2134 parser->lexer_->pop_state ();
2136 $$ = scm_cons ($3, SCM_EOL);
2138 | new_lyrics ADDLYRICS {
2139 parser->lexer_->push_lyric_state ();
2141 parser->lexer_->pop_state ();
2142 $$ = scm_cons ($4, $1);
2147 composite_music new_lyrics {
2148 $$ = MAKE_SYNTAX ("add-lyrics", @$, $1, scm_reverse_x ($2, SCM_EOL));
2150 | LYRICSTO simple_string {
2151 parser->lexer_->push_lyric_state ();
2153 parser->lexer_->pop_state ();
2154 $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $4);
2159 CHANGE STRING '=' STRING {
2160 $$ = MAKE_SYNTAX ("context-change", @$, scm_string_to_symbol ($2), $4);
2167 $$ = scm_reverse_x ($1, SCM_EOL);
2169 | symbol_list_rev property_path {
2170 $$ = scm_reverse_x ($1, $2);
2176 $$ = scm_list_3 (ly_symbol2scm ("assign"), $1, $3);
2179 $$ = scm_list_2 (ly_symbol2scm ("unset"), $2);
2181 | OVERRIDE property_path '=' scalar {
2182 if (scm_ilength ($2) < 2) {
2183 parser->parser_error (@2, _("bad grob property path"));
2186 $$ = scm_cons (ly_symbol2scm ("push"),
2187 scm_cons2 (scm_car ($2),
2192 | REVERT revert_arg {
2193 $$ = scm_cons (ly_symbol2scm ("pop"), $2);
2197 // This is all quite awkward for the sake of substantial backward
2198 // compatibility while at the same time allowing a more "natural" form
2199 // of specification not separating grob specification from grob
2200 // property path. The purpose of this definition of revert_arg is to
2201 // allow the symbol list which specifies grob and property to revert
2202 // to be optionally be split into two parts after the grob (which in
2203 // this case is just the first element of the list). symbol_list_part
2204 // is only one path component, but it can be parsed without lookahead,
2205 // so we can follow it with a synthetic BACKUP token when needed. If
2206 // the first symbol_list_part already contains multiple elements (only
2207 // possible if a Scheme expression provides them), we just parse for
2208 // additional elements introduced by '.', which is what the
2209 // SYMBOL_LIST backup in connection with the immediately following
2210 // rule using symbol_list_arg does.
2212 // As long as we don't have our coffers filled with both grob and at
2213 // least one grob property specification, the rest of the required
2214 // symbol list chain may be provided either with or without a leading
2215 // dot. This is for both allowing the traditional
2216 // \revert Accidental #'color
2217 // as well as well as the "naive" form
2218 // \revert Accidental.color
2221 revert_arg_backup BACKUP symbol_list_arg
2230 if (scm_is_null ($1)
2231 || scm_is_null (scm_cdr ($1)))
2232 MYBACKUP (SCM_ARG, $1, @1);
2234 MYBACKUP (SYMBOL_LIST, scm_reverse_x ($1, SCM_EOL), @1);
2238 // revert_arg_part delivers results in reverse
2241 | revert_arg_backup BACKUP SCM_ARG '.' symbol_list_part
2243 $$ = scm_append_x (scm_list_2 ($5, $3));
2245 | revert_arg_backup BACKUP SCM_ARG symbol_list_part
2247 $$ = scm_append_x (scm_list_2 ($4, $3));
2252 CONSISTS { $$ = ly_symbol2scm ("consists"); }
2253 | REMOVE { $$ = ly_symbol2scm ("remove"); }
2255 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
2256 | DEFAULTCHILD { $$ = ly_symbol2scm ("default-child"); }
2257 | DENIES { $$ = ly_symbol2scm ("denies"); }
2259 | ALIAS { $$ = ly_symbol2scm ("alias"); }
2260 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
2261 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
2262 | NAME { $$ = ly_symbol2scm ("context-name"); }
2266 property_operation { $$ = $1; }
2267 | context_def_mod STRING {
2268 $$ = scm_list_2 ($1, $2);
2270 | context_def_mod embedded_scm
2272 if (!scm_is_string ($2)
2273 && ly_symbol2scm ("consists") != $1
2274 && ly_symbol2scm ("remove") != $1)
2277 parser->parser_error (@1, _ ("only \\consists and \\remove take non-string argument."));
2281 $$ = scm_list_2 ($1, $2);
2286 // If defined, at least two members.
2290 SCM l = scm_reverse_x ($1, SCM_EOL);
2293 (scm_object_property (scm_car (l),
2294 ly_symbol2scm ("is-grob?"))))
2295 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2296 if (scm_is_null (l) || scm_is_null (scm_cdr (l))) {
2297 parser->parser_error (@1, _ ("bad grob property path"));
2304 // If defined, at least three members
2308 if (!SCM_UNBNDP ($1) && scm_is_null (scm_cddr ($1)))
2310 parser->parser_error (@1, _ ("bad grob property path"));
2314 | grob_prop_spec property_path
2316 if (!SCM_UNBNDP ($1)) {
2317 $$ = scm_append_x (scm_list_2 ($1, $2));
2318 if (scm_is_null (scm_cddr ($$))) {
2319 parser->parser_error (@$, _ ("bad grob property path"));
2327 // Exactly two elements or undefined
2331 SCM l = scm_reverse_x ($1, SCM_EOL);
2332 switch (scm_ilength (l)) {
2334 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2338 parser->parser_error (@1, _ ("bad context property path"));
2345 simple_music_property_def:
2346 OVERRIDE grob_prop_path '=' scalar {
2347 if (SCM_UNBNDP ($2))
2350 $$ = scm_list_5 (scm_car ($2),
2351 ly_symbol2scm ("OverrideProperty"),
2357 | REVERT simple_revert_context revert_arg {
2358 $$ = scm_list_4 ($2,
2359 ly_symbol2scm ("RevertProperty"),
2363 | SET context_prop_spec '=' scalar {
2364 if (SCM_UNBNDP ($2))
2367 $$ = scm_list_4 (scm_car ($2),
2368 ly_symbol2scm ("PropertySet"),
2372 | UNSET context_prop_spec {
2373 if (SCM_UNBNDP ($2))
2376 $$ = scm_list_3 (scm_car ($2),
2377 ly_symbol2scm ("PropertyUnset"),
2383 // This is all quite awkward for the sake of substantial backward
2384 // compatibility while at the same time allowing a more "natural" form
2385 // of specification not separating grob specification from grob
2386 // property path. The purpose of this definition of
2387 // simple_revert_context is to allow the symbol list which specifies
2388 // grob and property to revert to be optionally be split into two
2389 // parts after the grob (which may be preceded by a context
2390 // specification, a case which we distinguish by checking whether the
2391 // first symbol is a valid grob symbol instead).
2393 // See revert_arg above for the main work horse of this arrangement.
2394 // simple_revert_context just caters for the context and delegates the
2395 // rest of the job to revert_arg.
2397 simple_revert_context:
2400 $1 = scm_reverse_x ($1, SCM_EOL);
2401 if (scm_is_null ($1)
2403 (scm_object_property (scm_car ($1),
2404 ly_symbol2scm ("is-grob?")))) {
2405 $$ = ly_symbol2scm ("Bottom");
2406 parser->lexer_->push_extra_token (SCM_IDENTIFIER, $1);
2409 parser->lexer_->push_extra_token (SCM_IDENTIFIER,
2416 simple_music_property_def {
2417 if (SCM_UNBNDP ($1))
2418 $$ = MAKE_SYNTAX ("void-music", @1);
2420 $$ = LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("property-operation"), scm_cons2 (parser->self_scm (), make_input (@$), $1));
2431 simple_string: STRING {
2436 if (scm_is_string ($1)) {
2439 parser->parser_error (@1, (_ ("simple string expected")));
2440 $$ = scm_string (SCM_EOL);
2447 $$ = scm_string_to_symbol ($1);
2451 // This is a bit of overkill but makes the same
2452 // routine responsible for all symbol interpretations.
2453 $$ = try_string_variants (ly_lily_module_constant ("symbol?"),
2455 if (SCM_UNBNDP ($$))
2457 parser->parser_error (@1, (_ ("symbol expected")));
2458 // Generate a unique symbol in case it is used
2459 // for an assignment or similar
2460 $$ = scm_make_symbol (ly_string2scm ("undefined"));
2469 // The following is a rather defensive variant of admitting
2470 // negative numbers: the grammar would permit number_factor or
2471 // even number_expression. However, function arguments allow
2472 // only this simple kind of negative number, so to have things
2473 // like \tweak and \override behave reasonably similar, it
2474 // makes sense to rule out things like -- which are rather an
2475 // accent in function argument contexts.
2478 $$ = scm_difference ($2, SCM_UNDEFINED);
2486 simple_element post_events {
2487 // Let the rhythmic music iterator sort this mess out.
2488 if (scm_is_pair ($2)) {
2489 $$ = make_music_from_simple (parser, @1, $1);
2490 if (unsmob_music ($$))
2491 unsmob_music ($$)->set_property ("articulations",
2492 scm_reverse_x ($2, SCM_EOL));
2495 parser->parser_error (@1, _("music expected"));
2496 $$ = MAKE_SYNTAX ("void-music", @1);
2500 | simple_chord_elements post_events {
2501 SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
2504 /* why is this giving wrong start location? -ns
2506 i.set_location (@1, @2);
2507 $$ = MAKE_SYNTAX ("event-chord", i, elts);
2509 | CHORD_REPETITION optional_notemode_duration post_events {
2511 i.set_location (@1, @3);
2512 $$ = MAKE_SYNTAX ("repetition-chord", i,
2513 $2, scm_reverse_x ($3, SCM_EOL));
2515 | MULTI_MEASURE_REST optional_notemode_duration post_events {
2517 i.set_location (@1, @3);
2518 $$ = MAKE_SYNTAX ("multi-measure-rest", i, $2,
2519 scm_reverse_x ($3, SCM_EOL));
2522 | note_chord_element
2527 chord_body optional_notemode_duration post_events
2529 Music *m = unsmob_music ($1);
2530 SCM dur = unsmob_duration ($2)->smobbed_copy ();
2531 SCM es = m->get_property ("elements");
2532 SCM postevs = scm_reverse_x ($3, SCM_EOL);
2534 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
2535 unsmob_music (scm_car (s))->set_property ("duration", dur);
2536 es = ly_append2 (es, postevs);
2538 m-> set_property ("elements", es);
2540 $$ = m->self_scm ();
2545 ANGLE_OPEN chord_body_elements ANGLE_CLOSE
2547 $$ = MAKE_SYNTAX ("event-chord", @$, scm_reverse_x ($2, SCM_EOL));
2549 | CHORD_BODY_IDENTIFIER
2552 chord_body_elements:
2553 /* empty */ { $$ = SCM_EOL; }
2554 | chord_body_elements chord_body_element {
2555 if (!SCM_UNBNDP ($2))
2556 $$ = scm_cons ($2, $1);
2561 pitch exclamations questions octave_check post_events
2563 bool q = to_boolean ($3);
2564 bool ex = to_boolean ($2);
2568 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
2569 n->set_property ("pitch", $1);
2571 n->set_property ("cautionary", SCM_BOOL_T);
2573 n->set_property ("force-accidental", SCM_BOOL_T);
2575 if (scm_is_pair (post)) {
2576 SCM arts = scm_reverse_x (post, SCM_EOL);
2577 n->set_property ("articulations", arts);
2579 if (scm_is_number (check))
2581 int q = scm_to_int (check);
2582 n->set_property ("absolute-octave", scm_from_int (q-1));
2585 $$ = n->unprotect ();
2587 | DRUM_PITCH post_events {
2588 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
2589 n->set_property ("drum-type", $1);
2591 if (scm_is_pair ($2)) {
2592 SCM arts = scm_reverse_x ($2, SCM_EOL);
2593 n->set_property ("articulations", arts);
2595 $$ = n->unprotect ();
2597 | music_function_chord_body
2599 Music *m = unsmob_music ($1);
2601 while (m && m->is_mus_type ("music-wrapper-music")) {
2602 $$ = m->get_property ("element");
2603 m = unsmob_music ($$);
2606 if (!(m && m->is_mus_type ("rhythmic-event"))) {
2607 parser->parser_error (@$, _ ("not a rhythmic event"));
2613 music_function_chord_body:
2618 // Event functions may only take closed arglists, otherwise it would
2619 // not be clear whether a following postevent should be associated
2620 // with the last argument of the event function or with the expression
2621 // for which the function call acts itself as event.
2623 music_function_call_closed:
2624 MUSIC_FUNCTION function_arglist_closed {
2625 $$ = MAKE_SYNTAX ("music-function", @$,
2630 event_function_event:
2631 EVENT_FUNCTION function_arglist_closed {
2632 $$ = MAKE_SYNTAX ("music-function", @$,
2654 | post_events post_event {
2656 if (Music *m = unsmob_music ($2))
2658 if (m->is_mus_type ("post-event-wrapper"))
2660 for (SCM p = m->get_property ("elements");
2664 $$ = scm_cons (scm_car (p), $$);
2668 $$ = scm_cons ($2, $$);
2674 post_event_nofinger:
2675 direction_less_event {
2678 | script_dir music_function_call_closed {
2680 if (!unsmob_music ($2)->is_mus_type ("post-event")) {
2681 parser->parser_error (@2, _ ("post-event expected"));
2682 $$ = SCM_UNSPECIFIED;
2683 } else if (!SCM_UNBNDP ($1))
2685 unsmob_music ($$)->set_property ("direction", $1);
2689 if (!parser->lexer_->is_lyric_state ())
2690 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2691 $$ = MY_MAKE_MUSIC ("HyphenEvent", @$)->unprotect ();
2694 if (!parser->lexer_->is_lyric_state ())
2695 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2696 $$ = MY_MAKE_MUSIC ("ExtenderEvent", @$)->unprotect ();
2698 | script_dir direction_reqd_event {
2699 if (!SCM_UNBNDP ($1))
2701 Music *m = unsmob_music ($2);
2702 m->set_property ("direction", $1);
2706 | script_dir direction_less_event {
2707 if (!SCM_UNBNDP ($1))
2709 Music *m = unsmob_music ($2);
2710 m->set_property ("direction", $1);
2717 unsmob_music ($$)->set_property ("direction", scm_from_int (UP));
2722 unsmob_music ($$)->set_property ("direction", scm_from_int (DOWN));
2733 string_number_event:
2735 Music *s = MY_MAKE_MUSIC ("StringNumberEvent", @$);
2736 s->set_property ("string-number", $1);
2737 $$ = s->unprotect ();
2741 direction_less_event:
2743 | EVENT_IDENTIFIER {
2747 Music *a = MY_MAKE_MUSIC ("TremoloEvent", @$);
2748 a->set_property ("tremolo-type", $1);
2749 $$ = a->unprotect ();
2751 | event_function_event
2754 direction_reqd_event:
2758 | script_abbreviation {
2759 SCM s = parser->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
2760 Music *a = MY_MAKE_MUSIC ("ArticulationEvent", @$);
2761 if (scm_is_string (s))
2762 a->set_property ("articulation-type", s);
2763 else parser->parser_error (@1, _ ("expecting string as script definition"));
2764 $$ = a->unprotect ();
2769 /**/ { $$ = SCM_EOL; }
2770 | '=' quotes { $$ = $2; }
2784 $$ = scm_from_int (1);
2787 $$ = scm_oneplus ($1);
2793 $$ = scm_from_int (-1);
2796 $$ = scm_oneminus ($1);
2801 NOTENAME_PITCH quotes {
2802 if (!scm_is_eq (SCM_INUM0, $2))
2804 Pitch p = *unsmob_pitch ($1);
2805 p = p.transposed (Pitch (scm_to_int ($2),0,0));
2806 $$ = p.smobbed_copy ();
2816 TONICNAME_PITCH quotes {
2817 if (!scm_is_eq (SCM_INUM0, $2))
2819 Pitch p = *unsmob_pitch ($1);
2820 p = p.transposed (Pitch (scm_to_int ($2),0,0));
2821 $$ = p.smobbed_copy ();
2833 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2834 t->set_property ("text", $1);
2835 $$ = t->unprotect ();
2838 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2839 t->set_property ("text",
2840 make_simple_markup ($1));
2841 $$ = t->unprotect ();
2843 | embedded_scm_closed
2845 Music *m = unsmob_music ($1);
2846 if (m && m->is_mus_type ("post-event"))
2848 else if (Text_interface::is_markup ($1)) {
2849 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2850 t->set_property ("text", $1);
2851 $$ = t->unprotect ();
2853 parser->parser_error (@1, _ ("not an articulation"));
2859 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @$);
2860 t->set_property ("digit", $1);
2861 $$ = t->unprotect ();
2865 script_abbreviation:
2867 $$ = scm_from_locale_string ("Hat");
2870 $$ = scm_from_locale_string ("Plus");
2873 $$ = scm_from_locale_string ("Dash");
2876 $$ = scm_from_locale_string ("Bang");
2879 $$ = scm_from_locale_string ("Larger");
2882 $$ = scm_from_locale_string ("Dot");
2885 $$ = scm_from_locale_string ("Underscore");
2890 '_' { $$ = scm_from_int (DOWN); }
2891 | '^' { $$ = scm_from_int (UP); }
2892 | '-' { $$ = SCM_UNDEFINED; }
2896 multiplied_duration {
2901 maybe_notemode_duration:
2905 | multiplied_duration {
2907 parser->default_duration_ = *unsmob_duration ($$);
2912 optional_notemode_duration:
2913 maybe_notemode_duration
2915 if (SCM_UNBNDP ($$))
2916 $$ = parser->default_duration_.smobbed_copy ();
2922 $$ = make_duration ($1, scm_to_int ($2));
2923 if (SCM_UNBNDP ($$))
2925 parser->parser_error (@1, _ ("not a duration"));
2926 $$ = Duration ().smobbed_copy ();
2929 | DURATION_IDENTIFIER dots {
2930 Duration *d = unsmob_duration ($1);
2931 Duration k (d->duration_log (),
2932 d->dot_count () + scm_to_int ($2));
2933 k = k.compressed (d->factor ());
2934 scm_remember_upto_here_1 ($1);
2935 $$ = k.smobbed_copy ();
2939 multiplied_duration:
2943 | multiplied_duration '*' UNSIGNED {
2944 $$ = unsmob_duration ($$)->compressed (scm_to_int ($3)).smobbed_copy ();
2946 | multiplied_duration '*' FRACTION {
2947 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2949 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2958 $$ = scm_oneplus ($1);
2967 if (SCM_UNBNDP (make_duration ($2)))
2968 parser->parser_error (@2, _ ("not a duration"));
2974 UNSIGNED { $$ = $1; }
2975 | STRING { $$ = $1; }
2976 | full_markup { $$ = $1; }
2979 // as an integer, it needs to be non-negative, and otherwise
2980 // it needs to be suitable as a markup.
2981 if (scm_is_integer ($1)
2982 ? scm_is_true (scm_negative_p ($1))
2983 : !Text_interface::is_markup ($1))
2985 parser->parser_error (@1, _ ("bass number expected"));
2991 figured_bass_alteration:
2992 '-' { $$ = ly_rational2scm (FLAT_ALTERATION); }
2993 | '+' { $$ = ly_rational2scm (SHARP_ALTERATION); }
2994 | '!' { $$ = scm_from_int (0); }
2999 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
3000 $$ = bfr->unprotect ();
3003 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
3004 $$ = bfr->self_scm ();
3006 if (scm_is_number ($1))
3007 bfr->set_property ("figure", $1);
3008 else if (Text_interface::is_markup ($1))
3009 bfr->set_property ("text", $1);
3015 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
3017 | bass_figure figured_bass_alteration {
3018 Music *m = unsmob_music ($1);
3019 if (scm_to_double ($2)) {
3020 SCM salter = m->get_property ("alteration");
3021 SCM alter = scm_is_number (salter) ? salter : scm_from_int (0);
3022 m->set_property ("alteration",
3023 scm_sum (alter, $2));
3025 m->set_property ("alteration", scm_from_int (0));
3028 | bass_figure figured_bass_modification {
3029 Music *m = unsmob_music ($1);
3030 m->set_property ($2, SCM_BOOL_T);
3035 figured_bass_modification:
3037 $$ = ly_symbol2scm ("augmented");
3040 $$ = ly_symbol2scm ("no-continuation");
3043 $$ = ly_symbol2scm ("diminished");
3046 $$ = ly_symbol2scm ("augmented-slash");
3056 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
3064 | figure_list br_bass_figure {
3065 $$ = scm_cons ($2, $1);
3070 FIGURE_OPEN figure_list FIGURE_CLOSE {
3071 $$ = scm_reverse_x ($2, SCM_EOL);
3077 /**/ { $$ = SCM_BOOL_F; }
3078 | REST { $$ = SCM_BOOL_T; }
3082 pitch exclamations questions octave_check maybe_notemode_duration optional_rest {
3083 if (!parser->lexer_->is_note_state ())
3084 parser->parser_error (@1, _ ("have to be in Note mode for notes"));
3085 if (!SCM_UNBNDP ($2)
3087 || scm_is_number ($4)
3089 || scm_is_true ($6))
3092 if (scm_is_true ($6))
3093 n = MY_MAKE_MUSIC ("RestEvent", @$);
3095 n = MY_MAKE_MUSIC ("NoteEvent", @$);
3097 n->set_property ("pitch", $1);
3098 if (SCM_UNBNDP ($5))
3099 n->set_property ("duration",
3100 parser->default_duration_.smobbed_copy ());
3102 n->set_property ("duration", $5);
3104 if (scm_is_number ($4))
3106 int q = scm_to_int ($4);
3107 n->set_property ("absolute-octave", scm_from_int (q-1));
3110 if (to_boolean ($3))
3111 n->set_property ("cautionary", SCM_BOOL_T);
3112 if (to_boolean ($2) || to_boolean ($3))
3113 n->set_property ("force-accidental", SCM_BOOL_T);
3115 $$ = n->unprotect ();
3118 | DRUM_PITCH optional_notemode_duration {
3119 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
3120 n->set_property ("duration", $2);
3121 n->set_property ("drum-type", $1);
3123 $$ = n->unprotect ();
3125 | RESTNAME optional_notemode_duration {
3127 if (ly_scm2string ($1) == "s") {
3129 ev = MY_MAKE_MUSIC ("SkipEvent", @$);
3132 ev = MY_MAKE_MUSIC ("RestEvent", @$);
3135 ev->set_property ("duration", $2);
3136 $$ = ev->unprotect ();
3140 simple_chord_elements:
3142 if (!parser->lexer_->is_chord_state ())
3143 parser->parser_error (@1, _ ("have to be in Chord mode for chords"));
3146 | figure_spec optional_notemode_duration {
3147 for (SCM s = $1; scm_is_pair (s); s = scm_cdr (s))
3149 unsmob_music (scm_car (s))->set_property ("duration", $2);
3157 if (!parser->lexer_->is_lyric_state ())
3158 parser->parser_error (@1, _ ("markup outside of text script or \\lyricmode"));
3162 if (!parser->lexer_->is_lyric_state ())
3163 parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode"));
3169 lyric_element_music:
3170 lyric_element optional_notemode_duration post_events {
3171 $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
3172 if (scm_is_pair ($3))
3173 unsmob_music ($$)->set_property
3174 ("articulations", scm_reverse_x ($3, SCM_EOL));
3179 steno_tonic_pitch optional_notemode_duration {
3180 $$ = make_chord_elements (@$, $1, $2, SCM_EOL);
3182 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
3183 SCM its = scm_reverse_x ($4, SCM_EOL);
3184 $$ = make_chord_elements (@$, $1, $2, scm_cons ($3, its));
3192 | chord_items chord_item {
3193 $$ = scm_cons ($2, $$);
3199 $$ = ly_symbol2scm ("chord-colon");
3202 $$ = ly_symbol2scm ("chord-caret");
3204 | CHORD_SLASH steno_tonic_pitch {
3205 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
3207 | CHORD_BASS steno_tonic_pitch {
3208 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
3217 $$ = scm_reverse_x ($1, SCM_EOL);
3225 step_number { $$ = scm_cons ($1, SCM_EOL); }
3226 | step_numbers '.' step_number {
3227 $$ = scm_cons ($3, $$);
3233 $$ = make_chord_step ($1, 0);
3236 $$ = make_chord_step ($1, SHARP_ALTERATION);
3238 | UNSIGNED CHORD_MINUS {
3239 $$ = make_chord_step ($1, FLAT_ALTERATION);
3247 | UNSIGNED '-' UNSIGNED {
3248 $$ = scm_cons ($1, $3);
3255 TODO: should deprecate in favor of Scheme?
3259 number_expression '+' number_term {
3260 $$ = scm_sum ($1, $3);
3262 | number_expression '-' number_term {
3263 $$ = scm_difference ($1, $3);
3272 | number_factor '*' number_factor {
3273 $$ = scm_product ($1, $3);
3275 | number_factor '/' number_factor {
3276 $$ = scm_divide ($1, $3);
3281 '-' number_factor { /* %prec UNARY_MINUS */
3282 $$ = scm_difference ($2, SCM_UNDEFINED);
3288 bare_number_common_closed
3289 | REAL NUMBER_IDENTIFIER
3291 $$ = scm_product ($1, $2);
3295 bare_number_common_closed:
3303 | UNSIGNED NUMBER_IDENTIFIER {
3304 $$ = scm_product ($1, $2);
3310 | bare_number_common_closed
3319 { $$ = SCM_UNDEFINED; }
3322 if (SCM_UNBNDP ($1))
3330 { $$ = SCM_UNDEFINED; }
3333 if (SCM_UNBNDP ($1))
3342 { parser->lexer_->push_markup_state (); }
3345 parser->lexer_->pop_state ();
3351 { parser->lexer_->push_markup_state (); }
3354 parser->lexer_->pop_state ();
3360 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
3362 | markup_head_1_list simple_markup
3364 $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
3365 @2, $1, scm_list_1 ($2)));
3375 if (Text_interface::is_markup ($1))
3376 MYBACKUP (MARKUP_IDENTIFIER, $1, @1);
3377 else if (Text_interface::is_markup_list ($1))
3378 MYBACKUP (MARKUPLIST_IDENTIFIER, $1, @1);
3380 parser->parser_error (@1, _ ("not a markup"));
3381 MYBACKUP (MARKUP_IDENTIFIER, scm_string (SCM_EOL), @1);
3388 markup_composed_list {
3391 | markup_uncomposed_list
3394 markup_uncomposed_list:
3395 markup_braced_list {
3398 | markup_command_list {
3399 $$ = scm_list_1 ($1);
3401 | markup_scm MARKUPLIST_IDENTIFIER
3406 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
3407 parser->lexer_->push_note_state (nn);
3408 } '{' score_body '}' {
3409 $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $4));
3410 parser->lexer_->pop_state ();
3414 markup_composed_list:
3415 markup_head_1_list markup_uncomposed_list {
3416 $$ = MAKE_SYNTAX ("composed-markup-list",
3422 '{' markup_braced_list_body '}' {
3423 $$ = scm_reverse_x ($2, SCM_EOL);
3427 markup_braced_list_body:
3428 /* empty */ { $$ = SCM_EOL; }
3429 | markup_braced_list_body markup {
3430 $$ = scm_cons ($2, $1);
3432 | markup_braced_list_body markup_list {
3433 $$ = scm_reverse_x ($2, $1);
3437 markup_command_list:
3438 MARKUP_LIST_FUNCTION markup_command_list_arguments {
3439 $$ = scm_cons ($1, scm_reverse_x($2, SCM_EOL));
3443 markup_command_basic_arguments:
3444 EXPECT_MARKUP_LIST markup_command_list_arguments markup_list {
3445 $$ = scm_cons ($3, $2);
3447 | EXPECT_SCM markup_command_list_arguments embedded_scm_closed {
3448 $$ = check_scheme_arg (parser, @3, $3, $2, $1);
3450 | EXPECT_NO_MORE_ARGS {
3455 markup_command_list_arguments:
3456 markup_command_basic_arguments { $$ = $1; }
3457 | EXPECT_MARKUP markup_command_list_arguments markup {
3458 $$ = scm_cons ($3, $2);
3463 MARKUP_FUNCTION EXPECT_MARKUP markup_command_list_arguments {
3464 $$ = scm_cons ($1, scm_reverse_x ($3, SCM_EOL));
3469 markup_head_1_item {
3470 $$ = scm_list_1 ($1);
3472 | markup_head_1_list markup_head_1_item {
3473 $$ = scm_cons ($2, $1);
3479 $$ = make_simple_markup ($1);
3482 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
3483 parser->lexer_->push_note_state (nn);
3484 } '{' score_body '}' {
3485 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $4);
3486 parser->lexer_->pop_state ();
3488 | MARKUP_FUNCTION markup_command_basic_arguments {
3489 $$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
3491 | markup_scm MARKUP_IDENTIFIER
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 ();