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 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_BODY_IDENTIFIER
329 %token CHORD_MODIFIER
330 %token CHORD_REPETITION
331 %token CONTEXT_DEF_IDENTIFIER
332 %token CONTEXT_MOD_IDENTIFIER
334 %token PITCH_IDENTIFIER
335 %token DURATION_IDENTIFIER
336 %token EVENT_IDENTIFIER
337 %token EVENT_FUNCTION
340 %token MARKUP_FUNCTION
341 %token MARKUP_LIST_FUNCTION
342 %token MARKUP_IDENTIFIER
343 %token MARKUPLIST_IDENTIFIER
344 %token MUSIC_FUNCTION
345 %token MUSIC_IDENTIFIER
346 %token NOTENAME_PITCH
347 %token NUMBER_IDENTIFIER
348 %token OUTPUT_DEF_IDENTIFIER
350 %token REPEAT_IDENTIFIER
354 %token SCM_IDENTIFIER
358 %token TONICNAME_PITCH
362 /* We don't assign precedence to / and *, because we might need varied
363 prec levels in different prods */
372 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
373 parser->lexer_->push_note_state (nn);
374 } embedded_lilypond {
375 parser->lexer_->pop_state ();
380 lilypond: /* empty */ { $$ = SCM_UNSPECIFIED; }
381 | lilypond toplevel_expression {
383 | lilypond assignment {
386 parser->error_level_ = 1;
389 parser->error_level_ = 1;
396 parser->lexer_->add_scope (get_header (parser));
398 parser->lexer_->set_identifier (ly_symbol2scm ("$defaultheader"), $2);
401 SCM proc = parser->lexer_->lookup_identifier ("toplevel-book-handler");
402 scm_call_2 (proc, parser->self_scm (), $1);
405 SCM proc = parser->lexer_->lookup_identifier ("toplevel-bookpart-handler");
406 scm_call_2 (proc, parser->self_scm (), $1);
409 SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler");
410 scm_call_2 (proc, parser->self_scm (), $1);
413 SCM proc = parser->lexer_->lookup_identifier ("toplevel-music-handler");
414 scm_call_2 (proc, parser->self_scm (), $1);
417 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
418 scm_call_2 (proc, parser->self_scm (), scm_list_1 ($1));
421 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
422 scm_call_2 (proc, parser->self_scm (), $1);
425 // Evaluate and ignore #xxx, as opposed to \xxx
426 parser->lexer_->eval_scm_token ($1);
428 | embedded_scm_active
430 SCM out = SCM_UNDEFINED;
431 if (Text_interface::is_markup ($1))
432 out = scm_list_1 ($1);
433 else if (Text_interface::is_markup_list ($1))
435 if (scm_is_pair (out))
437 SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler");
438 scm_call_2 (proc, parser->self_scm (), out);
439 } else if (!scm_is_eq ($1, SCM_UNSPECIFIED))
440 parser->parser_error (@1, _("bad expression type"));
444 Output_def * od = unsmob_output_def ($1);
446 if (od->c_variable ("is-paper") == SCM_BOOL_T)
447 id = ly_symbol2scm ("$defaultpaper");
448 else if (od->c_variable ("is-midi") == SCM_BOOL_T)
449 id = ly_symbol2scm ("$defaultmidi");
450 else if (od->c_variable ("is-layout") == SCM_BOOL_T)
451 id = ly_symbol2scm ("$defaultlayout");
453 parser->lexer_->set_identifier (id, $1);
460 $$ = parser->lexer_->eval_scm_token ($1);
470 embedded_scm_bare_arg:
474 $$ = parser->lexer_->eval_scm_token ($1);
477 | context_modification
479 | context_def_spec_block
485 /* The generic version may end in music, or not */
492 /* embedded_scm_arg is _not_ casting pitches to music by default, this
493 * has to be done by the function itself. Note that this may cause
494 * the results of scm_function_call or embedded_scm_bare_arg to be
495 * turned into music from pitches as well. Note that this creates a
496 * distinctly awkward situation for calculated drum pitches. Those
497 * are at the current point of time rejected as music constituents as
498 * they can't be distinguished from "proper" symbols.
502 embedded_scm_bare_arg
508 SCM_FUNCTION function_arglist {
509 $$ = MAKE_SYNTAX ("music-function", @$,
517 // FIXME: @$ does not contain a useful source location
518 // for empty rules, and the only token in the whole
519 // production, EMBEDDED_LILY, is synthetic and also
520 // contains no source location.
521 $$ = MAKE_SYNTAX ("void-music", @$);
524 | music_embedded music_embedded music_list {
525 $3 = scm_reverse_x ($3, SCM_EOL);
526 if (unsmob_music ($2))
527 $3 = scm_cons ($2, $3);
528 if (unsmob_music ($1))
529 $3 = scm_cons ($1, $3);
530 $$ = MAKE_SYNTAX ("sequential-music", @$, $3);
533 parser->error_level_ = 1;
534 $$ = SCM_UNSPECIFIED;
536 | INVALID embedded_lilypond {
537 parser->error_level_ = 1;
543 lilypond_header_body:
544 /* empty */ { $$ = SCM_UNSPECIFIED; }
545 | lilypond_header_body assignment {
548 | lilypond_header_body embedded_scm {
554 HEADER '{' lilypond_header_body '}' {
555 $$ = parser->lexer_->remove_scope ();
567 assignment_id '=' identifier_init {
568 parser->lexer_->set_identifier ($1, $3);
569 $$ = SCM_UNSPECIFIED;
571 | assignment_id property_path '=' identifier_init {
572 SCM path = scm_cons (scm_string_to_symbol ($1), $2);
573 parser->lexer_->set_identifier (path, $4);
574 $$ = SCM_UNSPECIFIED;
584 | context_def_spec_block
586 | post_event_nofinger post_events
588 $$ = scm_reverse_x ($2, SCM_EOL);
589 if (Music *m = unsmob_music ($1))
591 if (m->is_mus_type ("post-event-wrapper"))
593 (scm_list_2 (m->get_property ("elements"),
596 $$ = scm_cons ($1, $$);
599 && scm_is_null (scm_cdr ($$)))
603 Music * m = MY_MAKE_MUSIC ("PostEvents", @$);
604 m->set_property ("elements", $$);
605 $$ = m->unprotect ();
613 | context_modification
616 context_def_spec_block:
617 CONTEXT '{' context_def_spec_body '}'
620 unsmob_context_def ($$)->origin ()->set_spot (@$);
628 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
629 parser->lexer_->push_note_state (nn);
633 parser->lexer_->pop_state ();
638 context_mod_embedded:
641 if (unsmob_music ($1)) {
642 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
643 $1 = scm_call_2 (proc, parser->self_scm (), $1);
645 if (unsmob_context_mod ($1))
648 parser->parser_error (@1, _ ("not a context mod"));
649 $$ = Context_mod ().smobbed_copy ();
655 context_def_spec_body:
657 $$ = Context_def::make_scm ();
659 | CONTEXT_DEF_IDENTIFIER {
662 | context_def_spec_body context_mod {
663 if (!SCM_UNBNDP ($2))
664 unsmob_context_def ($$)->add_context_mod ($2);
666 | context_def_spec_body context_modification {
667 Context_def *td = unsmob_context_def ($$);
668 SCM new_mods = unsmob_context_mod ($2)->get_mods ();
669 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
670 td->add_context_mod (scm_car (m));
673 | context_def_spec_body context_mod_embedded {
674 Context_def *td = unsmob_context_def ($$);
675 SCM new_mods = unsmob_context_mod ($2)->get_mods ();
676 for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) {
677 td->add_context_mod (scm_car (m));
685 BOOK '{' book_body '}' {
687 unsmob_book ($$)->origin ()->set_spot (@$);
689 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), SCM_BOOL_F);
694 * Use 'handlers' like for toplevel-* stuff?
695 * grok \layout and \midi? */
698 Book *book = new Book;
699 init_papers (parser);
700 book->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (parser->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
701 book->paper_->unprotect ();
702 push_paper (parser, book->paper_);
703 book->header_ = get_header (parser);
704 $$ = book->unprotect ();
705 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$);
708 parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $1);
710 | book_body paper_block {
711 unsmob_book ($1)->paper_ = unsmob_output_def ($2);
712 set_paper (parser, unsmob_output_def ($2));
714 | book_body bookpart_block {
715 SCM proc = parser->lexer_->lookup_identifier ("book-bookpart-handler");
716 scm_call_2 (proc, $1, $2);
718 | book_body score_block {
719 SCM proc = parser->lexer_->lookup_identifier ("book-score-handler");
720 scm_call_2 (proc, $1, $2);
722 | book_body composite_music {
723 SCM proc = parser->lexer_->lookup_identifier ("book-music-handler");
724 scm_call_3 (proc, parser->self_scm (), $1, $2);
726 | book_body full_markup {
727 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
728 scm_call_2 (proc, $1, scm_list_1 ($2));
730 | book_body full_markup_list {
731 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
732 scm_call_2 (proc, $1, $2);
734 | book_body SCM_TOKEN {
735 // Evaluate and ignore #xxx, as opposed to \xxx
736 parser->lexer_->eval_scm_token ($2);
738 | book_body embedded_scm_active
740 SCM out = SCM_UNDEFINED;
741 if (Text_interface::is_markup ($2))
742 out = scm_list_1 ($2);
743 else if (Text_interface::is_markup_list ($2))
745 if (scm_is_pair (out))
747 SCM proc = parser->lexer_->lookup_identifier ("book-text-handler");
748 scm_call_2 (proc, $1, out);
749 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
750 parser->parser_error (@2, _("bad expression type"));
754 parser->lexer_->add_scope (unsmob_book ($1)->header_);
757 Book *book = unsmob_book ($1);
759 book->scores_ = SCM_EOL;
760 book->bookparts_ = SCM_EOL;
765 BOOKPART '{' bookpart_body '}' {
767 unsmob_book ($$)->origin ()->set_spot (@$);
768 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F);
774 Book *book = new Book;
775 $$ = book->unprotect ();
776 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $$);
779 parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $1);
781 | bookpart_body paper_block {
782 unsmob_book ($$)->paper_ = unsmob_output_def ($2);
784 | bookpart_body score_block {
785 SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler");
786 scm_call_2 (proc, $1, $2);
788 | bookpart_body composite_music {
789 SCM proc = parser->lexer_->lookup_identifier ("bookpart-music-handler");
790 scm_call_3 (proc, parser->self_scm (), $1, $2);
792 | bookpart_body full_markup {
793 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
794 scm_call_2 (proc, $1, scm_list_1 ($2));
796 | bookpart_body full_markup_list {
797 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
798 scm_call_2 (proc, $1, $2);
800 | bookpart_body SCM_TOKEN {
801 // Evaluate and ignore #xxx, as opposed to \xxx
802 parser->lexer_->eval_scm_token ($2);
804 | bookpart_body embedded_scm_active
806 SCM out = SCM_UNDEFINED;
807 if (Text_interface::is_markup ($2))
808 out = scm_list_1 ($2);
809 else if (Text_interface::is_markup_list ($2))
811 if (scm_is_pair (out))
813 SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler");
814 scm_call_2 (proc, $1, out);
815 } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
816 parser->parser_error (@2, _("bad expression type"));
820 Book *book = unsmob_book ($1);
821 if (!ly_is_module (book->header_))
822 book->header_ = ly_make_module (false);
823 parser->lexer_->add_scope (book->header_);
825 | bookpart_body error {
826 Book *book = unsmob_book ($1);
828 book->scores_ = SCM_EOL;
833 SCORE '{' score_body '}' {
840 SCM scorify = ly_lily_module_constant ("scorify-music");
841 $$ = scm_call_2 (scorify, $1, parser->self_scm ());
843 unsmob_score ($$)->origin ()->set_spot (@$);
845 | embedded_scm_active {
847 if (unsmob_score ($1))
848 score = new Score (*unsmob_score ($1));
851 parser->parser_error (@1, _("score expected"));
853 unsmob_score ($$)->origin ()->set_spot (@$);
854 $$ = score->unprotect ();
858 Score *score = unsmob_score ($1);
859 if (!ly_is_module (score->get_header ()))
860 score->set_header (ly_make_module (false));
861 parser->lexer_->add_scope (score->get_header ());
863 | score_body output_def {
864 Output_def *od = unsmob_output_def ($2);
865 if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
867 parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead"));
872 unsmob_score ($1)->add_output_def (od);
876 unsmob_score ($$)->error_found_ = true;
887 Output_def *od = unsmob_output_def ($1);
889 if (od->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
891 parser->parser_error (@1, _ ("need \\paper for paper block"));
892 $$ = get_paper (parser)->unprotect ();
899 output_def_body '}' {
902 parser->lexer_->remove_scope ();
903 parser->lexer_->pop_state ();
909 Output_def *p = get_paper (parser);
910 p->input_origin_ = @$;
911 parser->lexer_->add_scope (p->scope_);
912 $$ = p->unprotect ();
915 Output_def *p = get_midi (parser);
916 $$ = p->unprotect ();
917 parser->lexer_->add_scope (p->scope_);
920 Output_def *p = get_layout (parser);
922 parser->lexer_->add_scope (p->scope_);
923 $$ = p->unprotect ();
927 output_def_head_with_mode_switch:
929 parser->lexer_->push_initial_state ();
934 // We need this weird nonterminal because both music as well as a
935 // context definition can start with \context and the difference is
936 // only apparent after looking at the next token. If it is '{', there
937 // is still time to escape from notes mode.
939 music_or_context_def:
941 | context_def_spec_block
945 output_def_head_with_mode_switch '{' {
947 unsmob_output_def ($$)->input_origin_.set_spot (@$);
949 | output_def_head_with_mode_switch '{' OUTPUT_DEF_IDENTIFIER {
950 Output_def *o = unsmob_output_def ($3);
951 o->input_origin_.set_spot (@$);
953 parser->lexer_->remove_scope ();
954 parser->lexer_->add_scope (o->scope_);
956 | output_def_body assignment {
959 | output_def_body embedded_scm {
964 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
965 parser->lexer_->push_note_state (nn);
966 } music_or_context_def
968 parser->lexer_->pop_state ();
969 if (unsmob_context_def ($3))
970 assign_context_def (unsmob_output_def ($1), $3);
973 SCM proc = parser->lexer_->lookup_identifier
974 ("output-def-music-handler");
975 scm_call_3 (proc, parser->self_scm (),
979 | output_def_body error {
985 TEMPO steno_duration '=' tempo_range {
986 $$ = MAKE_SYNTAX ("tempo", @$, SCM_EOL, $2, $4);
988 | TEMPO scalar steno_duration '=' tempo_range {
989 $$ = MAKE_SYNTAX ("tempo", @$, $2, $3, $5);
992 $$ = MAKE_SYNTAX ("tempo", @$, $2);
997 The representation of a list is reversed to have efficient append. */
1003 | music_list music_embedded {
1004 if (unsmob_music ($2))
1005 $$ = scm_cons ($2, $1);
1007 | music_list error {
1008 Music *m = MY_MAKE_MUSIC("Music", @$);
1010 m->set_property ("error-found", SCM_BOOL_T);
1011 $$ = scm_cons (m->self_scm (), $1);
1012 m->unprotect (); /* UGH */
1019 $$ = scm_reverse_x ($2, SCM_EOL);
1024 | lyric_element_music
1030 if (unsmob_music ($1)->is_mus_type ("post-event")) {
1031 parser->parser_error (@1, _ ("unexpected post-event"));
1032 $$ = SCM_UNSPECIFIED;
1035 | music_embedded_backup
1039 | music_embedded_backup BACKUP lyric_element_music
1045 music_embedded_backup:
1048 if (scm_is_eq ($1, SCM_UNSPECIFIED))
1050 else if (Music *m = unsmob_music ($1)) {
1051 if (m->is_mus_type ("post-event")) {
1052 parser->parser_error
1053 (@1, _ ("unexpected post-event"));
1054 $$ = SCM_UNSPECIFIED;
1057 } else if (parser->lexer_->is_lyric_state ()
1058 && Text_interface::is_markup ($1))
1059 MYBACKUP (LYRIC_ELEMENT, $1, @1);
1061 @$.warning (_ ("Ignoring non-music expression"));
1070 $$ = make_music_from_simple (parser, @1, $1);
1071 if (!unsmob_music ($$))
1073 parser->parser_error (@1, _ ("music expected"));
1074 $$ = MAKE_SYNTAX ("void-music", @$);
1077 | composite_music %prec COMPOSITE
1082 | composite_music %prec COMPOSITE
1086 REPEAT simple_string unsigned_number music
1088 $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, SCM_EOL);
1090 | REPEAT_IDENTIFIER music
1092 $$ = MAKE_SYNTAX ("repeat", @$, scm_car ($1), scm_cdr ($1),
1095 | REPEAT simple_string unsigned_number music ALTERNATIVE braced_music_list
1097 $$ = MAKE_SYNTAX ("repeat", @$, $2, $3, $4, $6);
1099 | REPEAT_IDENTIFIER music ALTERNATIVE braced_music_list
1101 $$ = MAKE_SYNTAX ("repeat", @$, scm_car ($1), scm_cdr ($1),
1107 SEQUENTIAL braced_music_list {
1108 $$ = MAKE_SYNTAX ("sequential-music", @$, $2);
1110 | braced_music_list {
1111 $$ = MAKE_SYNTAX ("sequential-music", @$, $1);
1116 SIMULTANEOUS braced_music_list {
1117 $$ = MAKE_SYNTAX ("simultaneous-music", @$, $2);
1119 | DOUBLE_ANGLE_OPEN music_list DOUBLE_ANGLE_CLOSE {
1120 $$ = MAKE_SYNTAX ("simultaneous-music", @$, scm_reverse_x ($2, SCM_EOL));
1126 | music_property_def
1130 context_modification:
1133 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
1134 parser->lexer_->push_note_state (nn);
1135 } '{' context_mod_list '}'
1137 parser->lexer_->pop_state ();
1140 | WITH CONTEXT_MOD_IDENTIFIER
1144 | CONTEXT_MOD_IDENTIFIER
1148 | WITH context_modification_arg
1150 if (unsmob_music ($2)) {
1151 SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler");
1152 $2 = scm_call_2 (proc, parser->self_scm (), $2);
1154 if (unsmob_context_mod ($2))
1157 parser->parser_error (@2, _ ("not a context mod"));
1158 $$ = Context_mod ().smobbed_copy ();
1163 context_modification_arg:
1168 optional_context_mod:
1172 | context_modification
1180 $$ = Context_mod ().smobbed_copy ();
1182 | context_mod_list context_mod {
1183 if (!SCM_UNBNDP ($2))
1184 unsmob_context_mod ($1)->add_context_mod ($2);
1186 | context_mod_list CONTEXT_MOD_IDENTIFIER {
1187 Context_mod *md = unsmob_context_mod ($2);
1189 unsmob_context_mod ($1)->add_context_mods (md->get_mods ());
1191 | context_mod_list context_mod_embedded {
1192 unsmob_context_mod ($1)->add_context_mods
1193 (unsmob_context_mod ($2)->get_mods ());
1202 /* Music that can be parsed without lookahead */
1205 | complex_music_prefix closed_music
1207 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
1209 | music_function_call_closed
1215 | grouped_music_list
1219 simultaneous_music { $$ = $1; }
1220 | sequential_music { $$ = $1; }
1223 /* Function argument lists are arguably the most complex part in the
1224 * parser. They are pretty tricky to understand because of the way
1225 * they are processed, and because of optional arguments that can be
1226 * omitted. When there are several optional arguments in a row,
1227 * omitting one automatically omits all following arguments. Optional
1228 * arguments can only be omitted when either
1230 * a) the omission is explicitly started with \default
1231 * b) the omission is implicitly started by an argument not matching
1232 * its predicate, and there is a mandatory argument later that can
1233 * "catch" the argument that does not fit.
1235 * When argument parsing starts, the lexer pushes EXPECT_SCM tokens
1236 * (corresponding to mandatory arguments and having a predicate
1237 * function as semantic value) or EXPECT_OPTIONAL EXPECT_SCM (where
1238 * the semantic value of the EXPECT_OPTIONAL token is the default to
1239 * use when the optional argument is omitted, and EXPECT_SCM again has
1240 * the argument predicate as semantic value) in reverse order to the
1241 * parser, followed by EXPECT_NO_MORE_ARGS. The argument list is then
1242 * processed inside-out while actual tokens are consumed.
1244 * This means that the argument list tokens determine the actions
1245 * taken as they arrive. The structure of the argument list is known
1246 * to the parser and stored in its parse stack when the first argument
1247 * is being parsed. What the parser does not know is which predicates
1248 * will match and whether or not \default will be appearing in the
1249 * argument list, and where.
1251 * Many of the basic nonterminals used for argument list scanning come
1252 * in a "normal" and a "closed" flavor. A closed expression is one
1253 * that can be parsed without a lookahead token. That makes it
1254 * feasible for an optional argument that may need to be skipped:
1255 * skipping can only be accomplished by pushing back the token into
1256 * the lexer, and that only works when there is no lookahead token.
1258 * Sequences of 0 or more optional arguments are scanned using either
1259 * function_arglist_backup or function_arglist_nonbackup. The first
1260 * is used when optional arguments are followed by at least one
1261 * mandatory argument: in that case optional arguments may be skipped
1262 * by either a false predicate (in which case the expression will be
1263 * pushed back as one or more tokens, preceded by a BACKUP token) or
1264 * by using \default.
1266 * If optional arguments are at the end of the argument list, they are
1267 * instead scanned using function_arglist_nonbackup: here the only
1268 * manner to enter into skipping of optional arguments is the use of
1271 * The argument list of a normal function call is parsed using
1272 * function_arglist. The part of an argument list before a mandatory
1273 * argument is parsed using function_arglist_optional.
1275 * The difference is that leading optional arguments are scanned using
1276 * function_arglist_nonbackup and function_arglist_backup,
1279 * Most other details are obvious in the rules themselves.
1283 function_arglist_nonbackup_common:
1284 EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup FRACTION
1286 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1288 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup post_event_nofinger
1290 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1292 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' UNSIGNED
1294 SCM n = scm_difference ($5, SCM_UNDEFINED);
1295 if (scm_is_true (scm_call_1 ($2, n)))
1296 $$ = scm_cons (n, $3);
1298 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
1299 t->set_property ("digit", $5);
1300 $$ = check_scheme_arg (parser, @4, t->unprotect (),
1305 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL
1307 $$ = check_scheme_arg (parser, @4,
1308 scm_difference ($5, SCM_UNDEFINED),
1311 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' NUMBER_IDENTIFIER
1313 $$ = check_scheme_arg (parser, @4,
1314 scm_difference ($5, SCM_UNDEFINED),
1319 function_arglist_closed_nonbackup:
1320 function_arglist_nonbackup_common
1321 | function_arglist_closed_common
1322 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg_closed
1324 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1326 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup bare_number_closed
1328 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1330 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
1332 $$ = check_scheme_arg (parser, @4,
1333 try_string_variants ($2, $4),
1336 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
1338 $$ = check_scheme_arg (parser, @4,
1339 try_string_variants ($2, $4),
1342 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup full_markup
1344 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1350 | SYMBOL_LIST '.' symbol_list_rev
1352 $$ = scm_append (scm_list_2 ($1, scm_reverse_x ($3, SCM_EOL)));
1358 | symbol_list_rev '.' symbol_list_part
1360 $$ = scm_append_x (scm_list_2 ($3, $1));
1364 // symbol_list_part delivers elements in reverse copy.
1369 SCM sym_l_p = ly_lily_module_constant ("symbol-list?");
1370 $$ = try_string_variants (sym_l_p, $1);
1371 if (SCM_UNBNDP ($$)) {
1372 parser->parser_error (@1, _("not a symbol"));
1375 $$ = scm_reverse ($$);
1380 symbol_list_element:
1386 function_arglist_nonbackup:
1387 function_arglist_nonbackup_common
1388 | function_arglist_common
1389 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup embedded_scm_arg
1391 if (scm_is_true (scm_call_1 ($2, $4)))
1392 $$ = scm_cons ($4, $3);
1394 $$ = check_scheme_arg (parser, @4,
1395 make_music_from_simple
1399 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup bare_number_common
1401 $$ = check_scheme_arg (parser, @4, $4, $3, $2);
1403 | function_arglist_nonbackup_reparse REPARSE duration_length
1405 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1407 | function_arglist_nonbackup_reparse REPARSE bare_number_common
1409 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1411 | function_arglist_nonbackup_reparse REPARSE SCM_ARG
1413 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1415 | function_arglist_nonbackup_reparse REPARSE lyric_element_music
1417 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1419 | function_arglist_nonbackup_reparse REPARSE symbol_list_arg
1421 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1425 function_arglist_nonbackup_reparse:
1426 EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup SCM_IDENTIFIER
1429 SCM res = try_string_variants ($2, $4);
1430 if (!SCM_UNBNDP (res))
1431 if (scm_is_pair (res))
1432 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1434 MYREPARSE (@4, $2, SCM_ARG, res);
1435 else if (scm_is_true
1437 ($2, make_music_from_simple
1439 MYREPARSE (@4, $2, STRING, $4);
1441 MYREPARSE (@4, $2, SCM_ARG, $4);
1443 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup STRING
1446 SCM res = try_string_variants ($2, $4);
1447 if (!SCM_UNBNDP (res))
1448 if (scm_is_pair (res))
1449 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1451 MYREPARSE (@4, $2, SCM_ARG, res);
1452 else if (scm_is_true
1454 ($2, make_music_from_simple
1456 MYREPARSE (@4, $2, STRING, $4);
1458 MYREPARSE (@4, $2, SCM_ARG, $4);
1460 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup full_markup
1463 if (scm_is_true (scm_call_1 ($2, $4)))
1464 MYREPARSE (@4, $2, SCM_ARG, $4);
1465 else if (scm_is_true
1467 ($2, make_music_from_simple
1469 MYREPARSE (@4, $2, STRING, $4);
1471 MYREPARSE (@4, $2, SCM_ARG, $4);
1473 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup UNSIGNED
1476 if (scm_is_true (scm_call_1 ($2, $4)))
1477 MYREPARSE (@4, $2, REAL, $4);
1479 SCM d = make_duration ($4);
1480 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
1481 MYREPARSE (@4, $2, REAL, $4); // trigger error
1483 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
1486 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup DURATION_IDENTIFIER {
1488 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
1493 function_arglist_backup:
1494 function_arglist_backup_common
1495 | function_arglist_common
1498 function_arglist_backup_common:
1499 EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup embedded_scm_arg_closed
1501 if (scm_is_true (scm_call_1 ($2, $4)))
1503 $$ = scm_cons ($4, $3);
1505 $$ = scm_cons (loc_on_music (@3, $1), $3);
1506 MYBACKUP (SCM_ARG, $4, @4);
1509 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup REPEAT simple_string unsigned_number
1511 $4 = MAKE_SYNTAX ("repeat", @4, $5, $6,
1512 MY_MAKE_MUSIC ("Music", @4)->unprotect (),
1514 if (scm_is_true (scm_call_1 ($2, $4)))
1517 MYREPARSE (@4, $2, REPEAT_IDENTIFIER, scm_cons ($5, $6));
1519 $$ = scm_cons (loc_on_music (@3, $1), $3);
1520 MYBACKUP (REPEAT_IDENTIFIER, scm_cons ($5, $6), @4);
1523 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup chord_body
1525 if (scm_is_true (scm_call_1 ($2, $4)))
1528 MYREPARSE (@4, $2, CHORD_BODY_IDENTIFIER, $4);
1530 $$ = scm_cons (loc_on_music (@3, $1), $3);
1531 MYBACKUP (CHORD_BODY_IDENTIFIER, $4, @4);
1534 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup post_event_nofinger
1536 if (scm_is_true (scm_call_1 ($2, $4)))
1538 $$ = scm_cons ($4, $3);
1540 $$ = scm_cons (loc_on_music (@3, $1), $3);
1541 MYBACKUP (EVENT_IDENTIFIER, $4, @4);
1544 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup full_markup
1546 if (scm_is_true (scm_call_1 ($2, $4)))
1547 $$ = scm_cons ($4, $3);
1549 $$ = scm_cons (loc_on_music (@3, $1), $3);
1550 MYBACKUP (LYRIC_ELEMENT, $4, @4);
1553 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup UNSIGNED
1555 if (scm_is_true (scm_call_1 ($2, $4)))
1557 MYREPARSE (@4, $2, REAL, $4);
1560 SCM d = make_duration ($4);
1561 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($2, d)))
1563 $$ = scm_cons (loc_on_music (@3, $1), $3);
1564 MYBACKUP (UNSIGNED, $4, @4);
1566 MYREPARSE (@4, $2, DURATION_IDENTIFIER, d);
1571 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup REAL
1573 if (scm_is_true (scm_call_1 ($2, $4)))
1576 MYREPARSE (@4, $2, REAL, $4);
1578 $$ = scm_cons (loc_on_music (@3, $1), $3);
1579 MYBACKUP (REAL, $4, @4);
1582 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup NUMBER_IDENTIFIER
1584 if (scm_is_true (scm_call_1 ($2, $4)))
1586 $$ = scm_cons ($4, $3);
1588 $$ = scm_cons (loc_on_music (@3, $1), $3);
1589 MYBACKUP (NUMBER_IDENTIFIER, $4, @4);
1592 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup FRACTION
1594 if (scm_is_true (scm_call_1 ($2, $4)))
1596 $$ = scm_cons ($4, $3);
1598 $$ = scm_cons (loc_on_music (@3, $1), $3);
1599 MYBACKUP (FRACTION, $4, @4);
1602 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' UNSIGNED
1604 SCM n = scm_difference ($5, SCM_UNDEFINED);
1605 if (scm_is_true (scm_call_1 ($2, n))) {
1607 MYREPARSE (@5, $2, REAL, n);
1609 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
1610 t->set_property ("digit", $5);
1611 $$ = t->unprotect ();
1612 if (scm_is_true (scm_call_1 ($2, $$)))
1613 $$ = scm_cons ($$, $3);
1615 $$ = scm_cons (loc_on_music (@3, $1), $3);
1616 MYBACKUP (UNSIGNED, $5, @5);
1617 parser->lexer_->push_extra_token ('-');
1622 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' REAL
1624 SCM n = scm_difference ($5, SCM_UNDEFINED);
1625 if (scm_is_true (scm_call_1 ($2, n))) {
1626 MYREPARSE (@5, $2, REAL, n);
1629 $$ = scm_cons (loc_on_music (@3, $1), $3);
1630 MYBACKUP (REAL, n, @5);
1633 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' NUMBER_IDENTIFIER
1635 SCM n = scm_difference ($5, SCM_UNDEFINED);
1636 if (scm_is_true (scm_call_1 ($2, n))) {
1637 $$ = scm_cons (n, $3);
1639 $$ = scm_cons (loc_on_music (@3, $1), $3);
1640 MYBACKUP (NUMBER_IDENTIFIER, n, @5);
1643 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup PITCH_IDENTIFIER
1645 if (scm_is_true (scm_call_1 ($2, $4)))
1647 $$ = scm_cons ($4, $3);
1649 $$ = scm_cons (loc_on_music (@3, $1), $3);
1650 MYBACKUP (PITCH_IDENTIFIER, $4, @4);
1653 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup NOTENAME_PITCH
1655 if (scm_is_true (scm_call_1 ($2, $4)))
1657 MYREPARSE (@4, $2, NOTENAME_PITCH, $4);
1660 $$ = scm_cons (loc_on_music (@3, $1), $3);
1661 MYBACKUP (NOTENAME_PITCH, $4, @4);
1664 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup TONICNAME_PITCH
1666 if (scm_is_true (scm_call_1 ($2, $4)))
1668 MYREPARSE (@4, $2, TONICNAME_PITCH, $4);
1671 $$ = scm_cons (loc_on_music (@3, $1), $3);
1672 MYBACKUP (TONICNAME_PITCH, $4, @4);
1675 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup DURATION_IDENTIFIER
1677 if (scm_is_true (scm_call_1 ($2, $4)))
1679 MYREPARSE (@4, $2, DURATION_IDENTIFIER, $4);
1682 $$ = scm_cons (loc_on_music (@3, $1), $3);
1683 MYBACKUP (DURATION_IDENTIFIER, $4, @4);
1686 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup SCM_IDENTIFIER
1688 SCM res = try_string_variants ($2, $4);
1689 if (!SCM_UNBNDP (res))
1690 if (scm_is_pair (res)) {
1692 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1695 $$ = scm_cons (res, $3);
1697 $$ = scm_cons (loc_on_music (@3, $1), $3);
1698 MYBACKUP (SCM_IDENTIFIER, $4, @4);
1701 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup STRING
1703 SCM res = try_string_variants ($2, $4);
1704 if (!SCM_UNBNDP (res))
1705 if (scm_is_pair (res)) {
1707 MYREPARSE (@4, $2, SYMBOL_LIST, res);
1710 $$ = scm_cons (res, $3);
1712 $$ = scm_cons (loc_on_music (@3, $1), $3);
1713 MYBACKUP (STRING, $4, @4);
1716 | function_arglist_backup REPARSE music_assign
1718 if (scm_is_true (scm_call_1 ($2, $3)))
1719 $$ = scm_cons ($3, $1);
1721 $$ = check_scheme_arg (parser, @3,
1722 make_music_from_simple
1726 | function_arglist_backup REPARSE bare_number_common
1728 $$ = check_scheme_arg (parser, @3,
1731 | function_arglist_backup REPARSE duration_length
1733 $$ = check_scheme_arg (parser, @3,
1736 | function_arglist_backup REPARSE symbol_list_arg
1738 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1743 function_arglist_nonbackup
1744 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
1746 $$ = scm_cons (loc_on_music (@4, $1), $3);
1750 function_arglist_skip_nonbackup:
1751 function_arglist_nonbackup
1752 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup
1754 $$ = scm_cons (loc_on_music (@3, $1), $3);
1758 function_arglist_common:
1759 EXPECT_NO_MORE_ARGS {
1762 | EXPECT_SCM function_arglist_optional embedded_scm_arg
1764 if (scm_is_true (scm_call_1 ($1, $3)))
1765 $$ = scm_cons ($3, $2);
1767 $$ = check_scheme_arg (parser, @3,
1768 make_music_from_simple
1772 | EXPECT_SCM function_arglist_optional bare_number_common
1774 $$ = check_scheme_arg (parser, @3,
1777 | EXPECT_SCM function_arglist_optional FRACTION
1779 $$ = check_scheme_arg (parser, @3,
1782 | EXPECT_SCM function_arglist_optional post_event_nofinger
1784 $$ = check_scheme_arg (parser, @3,
1787 | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
1789 SCM n = scm_difference ($4, SCM_UNDEFINED);
1790 $$ = check_scheme_arg (parser, @4, n, $2, $1);
1792 | function_arglist_common_reparse REPARSE SCM_ARG
1794 $$ = check_scheme_arg (parser, @3,
1797 | function_arglist_common_reparse REPARSE lyric_element_music
1799 $$ = check_scheme_arg (parser, @3,
1802 | function_arglist_common_reparse REPARSE bare_number_common
1804 $$ = check_scheme_arg (parser, @3,
1807 | function_arglist_common_reparse REPARSE duration_length
1809 $$ = check_scheme_arg (parser, @3,
1812 | function_arglist_common_reparse REPARSE symbol_list_arg
1814 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1818 function_arglist_common_reparse:
1819 EXPECT_SCM function_arglist_optional SCM_IDENTIFIER
1822 SCM res = try_string_variants ($1, $3);
1823 if (!SCM_UNBNDP (res))
1824 if (scm_is_pair (res))
1825 MYREPARSE (@3, $1, SYMBOL_LIST, res);
1827 MYREPARSE (@3, $1, SCM_ARG, res);
1828 else if (scm_is_true
1830 ($1, make_music_from_simple (parser, @3, $3))))
1831 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1833 // This is going to flag a syntax error, we
1834 // know the predicate to be false.
1835 MYREPARSE (@3, $1, SCM_ARG, $3);
1837 | EXPECT_SCM function_arglist_optional STRING
1840 SCM res = try_string_variants ($1, $3);
1841 if (!SCM_UNBNDP (res))
1842 if (scm_is_pair (res))
1843 MYREPARSE (@3, $1, SYMBOL_LIST, res);
1845 MYREPARSE (@3, $1, SCM_ARG, res);
1846 else if (scm_is_true
1848 ($1, make_music_from_simple (parser, @3, $3))))
1849 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1851 // This is going to flag a syntax error, we
1852 // know the predicate to be false.
1853 MYREPARSE (@3, $1, SCM_ARG, $3);
1855 | EXPECT_SCM function_arglist_optional full_markup
1858 if (scm_is_true (scm_call_1 ($1, $3)))
1859 MYREPARSE (@3, $1, SCM_ARG, $3);
1860 else if (scm_is_true
1862 ($1, make_music_from_simple (parser, @3, $3))))
1863 MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
1865 // This is going to flag a syntax error, we
1866 // know the predicate to be false.
1867 MYREPARSE (@3, $1, SCM_ARG, $3);
1869 | EXPECT_SCM function_arglist_optional UNSIGNED
1872 if (scm_is_true (scm_call_1 ($1, $3)))
1873 MYREPARSE (@3, $1, REAL, $3);
1875 SCM d = make_duration ($3);
1876 if (SCM_UNBNDP (d) || scm_is_false (scm_call_1 ($1, d)))
1877 MYREPARSE (@3, $1, REAL, $3);
1879 MYREPARSE (@3, $1, DURATION_IDENTIFIER, d);
1882 | EXPECT_SCM function_arglist_optional DURATION_IDENTIFIER
1885 MYREPARSE (@3, $1, DURATION_IDENTIFIER, $3);
1887 | EXPECT_SCM function_arglist_optional '-' UNSIGNED
1890 SCM n = scm_difference ($4, SCM_UNDEFINED);
1891 if (scm_is_true (scm_call_1 ($1, n)))
1892 MYREPARSE (@4, $1, REAL, n);
1894 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @4);
1895 t->set_property ("digit", $4);
1896 SCM m = t->unprotect ();
1897 if (scm_is_true (scm_call_1 ($1, m)))
1898 MYREPARSE (@4, $1, SCM_ARG, m);
1900 MYREPARSE (@4, $1, SCM_ARG, $4);
1904 | EXPECT_SCM function_arglist_optional '-' REAL
1907 SCM n = scm_difference ($4, SCM_UNDEFINED);
1908 MYREPARSE (@4, $1, REAL, n);
1912 function_arglist_closed:
1913 function_arglist_closed_nonbackup
1914 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_nonbackup DEFAULT
1916 $$ = scm_cons (loc_on_music (@4, $1), $3);
1920 function_arglist_closed_common:
1921 EXPECT_NO_MORE_ARGS {
1924 | EXPECT_SCM function_arglist_optional embedded_scm_arg_closed
1926 $$ = check_scheme_arg (parser, @3,
1929 | EXPECT_SCM function_arglist_optional bare_number_common_closed
1931 $$ = check_scheme_arg (parser, @3,
1934 | EXPECT_SCM function_arglist_optional '-' NUMBER_IDENTIFIER
1936 $$ = check_scheme_arg (parser, @3,
1937 scm_difference ($4, SCM_UNDEFINED),
1940 | EXPECT_SCM function_arglist_optional post_event_nofinger
1942 $$ = check_scheme_arg (parser, @3,
1945 | EXPECT_SCM function_arglist_optional FRACTION
1947 $$ = check_scheme_arg (parser, @3,
1950 | function_arglist_common_reparse REPARSE SCM_ARG
1952 $$ = check_scheme_arg (parser, @3,
1955 | function_arglist_common_reparse REPARSE bare_number_common_closed
1957 $$ = check_scheme_arg (parser, @3,
1960 | function_arglist_common_reparse REPARSE symbol_list_arg
1962 $$ = check_scheme_arg (parser, @3, $3, $1, $2);
1966 function_arglist_optional:
1967 function_arglist_backup
1968 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup DEFAULT
1970 $$ = scm_cons (loc_on_music (@4, $1), $3);
1972 | function_arglist_skip_backup BACKUP
1975 function_arglist_skip_backup:
1976 function_arglist_backup
1977 | EXPECT_OPTIONAL EXPECT_SCM function_arglist_skip_backup
1979 $$ = scm_cons (loc_on_music (@3, $1), $3);
1983 embedded_scm_closed:
1985 | scm_function_call_closed
1988 embedded_scm_arg_closed:
1989 embedded_scm_bare_arg
1990 | scm_function_call_closed
1994 scm_function_call_closed:
1995 SCM_FUNCTION function_arglist_closed {
1996 $$ = MAKE_SYNTAX ("music-function", @$,
2001 music_function_call:
2002 MUSIC_FUNCTION function_arglist {
2003 $$ = MAKE_SYNTAX ("music-function", @$,
2010 /**/ { $$ = SCM_EOL; }
2011 | '=' simple_string {
2018 | repeated_music { $$ = $1; }
2019 | re_rhythmed_music { $$ = $1; }
2020 | complex_music_prefix music
2022 $$ = FINISH_MAKE_SYNTAX ($1, @$, $2);
2026 complex_music_prefix:
2027 CONTEXT symbol optional_id optional_context_mod {
2028 Context_mod *ctxmod = unsmob_context_mod ($4);
2031 mods = ctxmod->get_mods ();
2032 $$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_F);
2034 | NEWCONTEXT symbol optional_id optional_context_mod {
2035 Context_mod *ctxmod = unsmob_context_mod ($4);
2038 mods = ctxmod->get_mods ();
2039 $$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_T);
2044 mode_changing_head grouped_music_list {
2045 if ($1 == ly_symbol2scm ("chords"))
2047 $$ = MAKE_SYNTAX ("unrelativable-music", @$, $2);
2053 parser->lexer_->pop_state ();
2055 | mode_changing_head_with_context optional_context_mod grouped_music_list {
2056 Context_mod *ctxmod = unsmob_context_mod ($2);
2059 mods = ctxmod->get_mods ();
2060 $$ = MAKE_SYNTAX ("context-specification", @$, $1, SCM_EOL, mods, SCM_BOOL_T, $3);
2061 if ($1 == ly_symbol2scm ("ChordNames"))
2063 $$ = MAKE_SYNTAX ("unrelativable-music", @$, $$);
2065 parser->lexer_->pop_state ();
2071 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
2072 parser->lexer_->push_note_state (nn);
2074 $$ = ly_symbol2scm ("notes");
2078 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2079 parser->lexer_->push_note_state (nn);
2081 $$ = ly_symbol2scm ("drums");
2084 parser->lexer_->push_figuredbass_state ();
2086 $$ = ly_symbol2scm ("figures");
2089 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2090 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2091 nn = parser->lexer_->lookup_identifier ("pitchnames");
2092 parser->lexer_->push_chord_state (nn);
2093 $$ = ly_symbol2scm ("chords");
2097 { parser->lexer_->push_lyric_state ();
2098 $$ = ly_symbol2scm ("lyrics");
2102 mode_changing_head_with_context:
2104 SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames");
2105 parser->lexer_->push_note_state (nn);
2107 $$ = ly_symbol2scm ("DrumStaff");
2110 parser->lexer_->push_figuredbass_state ();
2112 $$ = ly_symbol2scm ("FiguredBass");
2115 SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers");
2116 parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn);
2117 nn = parser->lexer_->lookup_identifier ("pitchnames");
2118 parser->lexer_->push_chord_state (nn);
2119 $$ = ly_symbol2scm ("ChordNames");
2122 { parser->lexer_->push_lyric_state ();
2123 $$ = ly_symbol2scm ("Lyrics");
2128 ADDLYRICS { parser->lexer_->push_lyric_state (); }
2131 /* Can also use music at the expensive of two S/Rs similar to
2132 \repeat \alternative */
2133 parser->lexer_->pop_state ();
2135 $$ = scm_cons ($3, SCM_EOL);
2137 | new_lyrics ADDLYRICS {
2138 parser->lexer_->push_lyric_state ();
2140 parser->lexer_->pop_state ();
2141 $$ = scm_cons ($4, $1);
2146 composite_music new_lyrics {
2147 $$ = MAKE_SYNTAX ("add-lyrics", @$, $1, scm_reverse_x ($2, SCM_EOL));
2149 | LYRICSTO simple_string {
2150 parser->lexer_->push_lyric_state ();
2152 parser->lexer_->pop_state ();
2153 $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $4);
2158 CHANGE STRING '=' STRING {
2159 $$ = MAKE_SYNTAX ("context-change", @$, scm_string_to_symbol ($2), $4);
2166 $$ = scm_reverse_x ($1, SCM_EOL);
2168 | symbol_list_rev property_path {
2169 $$ = scm_reverse_x ($1, $2);
2175 $$ = scm_list_3 (ly_symbol2scm ("assign"), $1, $3);
2178 $$ = scm_list_2 (ly_symbol2scm ("unset"), $2);
2180 | OVERRIDE property_path '=' scalar {
2181 if (scm_ilength ($2) < 2) {
2182 parser->parser_error (@2, _("bad grob property path"));
2185 $$ = scm_cons (ly_symbol2scm ("push"),
2186 scm_cons2 (scm_car ($2),
2191 | REVERT revert_arg {
2192 $$ = scm_cons (ly_symbol2scm ("pop"), $2);
2196 // This is all quite awkward for the sake of substantial backward
2197 // compatibility while at the same time allowing a more "natural" form
2198 // of specification not separating grob specification from grob
2199 // property path. The purpose of this definition of revert_arg is to
2200 // allow the symbol list which specifies grob and property to revert
2201 // to be optionally be split into two parts after the grob (which in
2202 // this case is just the first element of the list). symbol_list_part
2203 // is only one path component, but it can be parsed without lookahead,
2204 // so we can follow it with a synthetic BACKUP token when needed. If
2205 // the first symbol_list_part already contains multiple elements (only
2206 // possible if a Scheme expression provides them), we just parse for
2207 // additional elements introduced by '.', which is what the
2208 // SYMBOL_LIST backup in connection with the immediately following
2209 // rule using symbol_list_arg does.
2211 // As long as we don't have our coffers filled with both grob and at
2212 // least one grob property specification, the rest of the required
2213 // symbol list chain may be provided either with or without a leading
2214 // dot. This is for both allowing the traditional
2215 // \revert Accidental #'color
2216 // as well as well as the "naive" form
2217 // \revert Accidental.color
2220 revert_arg_backup BACKUP symbol_list_arg
2229 if (scm_is_null ($1)
2230 || scm_is_null (scm_cdr ($1)))
2231 MYBACKUP (SCM_ARG, $1, @1);
2233 MYBACKUP (SYMBOL_LIST, scm_reverse_x ($1, SCM_EOL), @1);
2237 // revert_arg_part delivers results in reverse
2240 | revert_arg_backup BACKUP SCM_ARG '.' symbol_list_part
2242 $$ = scm_append_x (scm_list_2 ($5, $3));
2244 | revert_arg_backup BACKUP SCM_ARG symbol_list_part
2246 $$ = scm_append_x (scm_list_2 ($4, $3));
2251 CONSISTS { $$ = ly_symbol2scm ("consists"); }
2252 | REMOVE { $$ = ly_symbol2scm ("remove"); }
2254 | ACCEPTS { $$ = ly_symbol2scm ("accepts"); }
2255 | DEFAULTCHILD { $$ = ly_symbol2scm ("default-child"); }
2256 | DENIES { $$ = ly_symbol2scm ("denies"); }
2258 | ALIAS { $$ = ly_symbol2scm ("alias"); }
2259 | TYPE { $$ = ly_symbol2scm ("translator-type"); }
2260 | DESCRIPTION { $$ = ly_symbol2scm ("description"); }
2261 | NAME { $$ = ly_symbol2scm ("context-name"); }
2265 property_operation { $$ = $1; }
2266 | context_def_mod STRING {
2267 $$ = scm_list_2 ($1, $2);
2269 | context_def_mod embedded_scm
2271 if (!scm_is_string ($2)
2272 && ly_symbol2scm ("consists") != $1
2273 && ly_symbol2scm ("remove") != $1)
2276 parser->parser_error (@1, _ ("only \\consists and \\remove take non-string argument."));
2280 $$ = scm_list_2 ($1, $2);
2285 // If defined, at least two members.
2289 SCM l = scm_reverse_x ($1, SCM_EOL);
2292 (scm_object_property (scm_car (l),
2293 ly_symbol2scm ("is-grob?"))))
2294 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2295 if (scm_is_null (l) || scm_is_null (scm_cdr (l))) {
2296 parser->parser_error (@1, _ ("bad grob property path"));
2303 // If defined, at least three members
2307 if (!SCM_UNBNDP ($1) && scm_is_null (scm_cddr ($1)))
2309 parser->parser_error (@1, _ ("bad grob property path"));
2313 | grob_prop_spec property_path
2315 if (!SCM_UNBNDP ($1)) {
2316 $$ = scm_append_x (scm_list_2 ($1, $2));
2317 if (scm_is_null (scm_cddr ($$))) {
2318 parser->parser_error (@$, _ ("bad grob property path"));
2326 // Exactly two elements or undefined
2330 SCM l = scm_reverse_x ($1, SCM_EOL);
2331 switch (scm_ilength (l)) {
2333 l = scm_cons (ly_symbol2scm ("Bottom"), l);
2337 parser->parser_error (@1, _ ("bad context property path"));
2344 simple_music_property_def:
2345 OVERRIDE grob_prop_path '=' scalar {
2346 if (SCM_UNBNDP ($2))
2349 $$ = scm_list_5 (scm_car ($2),
2350 ly_symbol2scm ("OverrideProperty"),
2356 | REVERT simple_revert_context revert_arg {
2357 $$ = scm_list_4 ($2,
2358 ly_symbol2scm ("RevertProperty"),
2362 | SET context_prop_spec '=' scalar {
2363 if (SCM_UNBNDP ($2))
2366 $$ = scm_list_4 (scm_car ($2),
2367 ly_symbol2scm ("PropertySet"),
2371 | UNSET context_prop_spec {
2372 if (SCM_UNBNDP ($2))
2375 $$ = scm_list_3 (scm_car ($2),
2376 ly_symbol2scm ("PropertyUnset"),
2382 // This is all quite awkward for the sake of substantial backward
2383 // compatibility while at the same time allowing a more "natural" form
2384 // of specification not separating grob specification from grob
2385 // property path. The purpose of this definition of
2386 // simple_revert_context is to allow the symbol list which specifies
2387 // grob and property to revert to be optionally be split into two
2388 // parts after the grob (which may be preceded by a context
2389 // specification, a case which we distinguish by checking whether the
2390 // first symbol is a valid grob symbol instead).
2392 // See revert_arg above for the main work horse of this arrangement.
2393 // simple_revert_context just caters for the context and delegates the
2394 // rest of the job to revert_arg.
2396 simple_revert_context:
2399 $1 = scm_reverse_x ($1, SCM_EOL);
2400 if (scm_is_null ($1)
2402 (scm_object_property (scm_car ($1),
2403 ly_symbol2scm ("is-grob?")))) {
2404 $$ = ly_symbol2scm ("Bottom");
2405 parser->lexer_->push_extra_token (SCM_IDENTIFIER, $1);
2408 parser->lexer_->push_extra_token (SCM_IDENTIFIER,
2415 simple_music_property_def {
2416 if (SCM_UNBNDP ($1))
2417 $$ = MAKE_SYNTAX ("void-music", @1);
2419 $$ = LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("property-operation"), scm_cons2 (parser->self_scm (), make_input (@$), $1));
2430 simple_string: STRING {
2435 if (scm_is_string ($1)) {
2438 parser->parser_error (@1, (_ ("simple string expected")));
2439 $$ = scm_string (SCM_EOL);
2446 $$ = scm_string_to_symbol ($1);
2450 // This is a bit of overkill but makes the same
2451 // routine responsible for all symbol interpretations.
2452 $$ = try_string_variants (ly_lily_module_constant ("symbol?"),
2454 if (SCM_UNBNDP ($$))
2456 parser->parser_error (@1, (_ ("symbol expected")));
2457 // Generate a unique symbol in case it is used
2458 // for an assignment or similar
2459 $$ = scm_make_symbol (ly_string2scm ("undefined"));
2468 // The following is a rather defensive variant of admitting
2469 // negative numbers: the grammar would permit number_factor or
2470 // even number_expression. However, function arguments allow
2471 // only this simple kind of negative number, so to have things
2472 // like \tweak and \override behave reasonably similar, it
2473 // makes sense to rule out things like -- which are rather an
2474 // accent in function argument contexts.
2477 $$ = scm_difference ($2, SCM_UNDEFINED);
2485 simple_element post_events {
2486 // Let the rhythmic music iterator sort this mess out.
2487 if (scm_is_pair ($2)) {
2488 $$ = make_music_from_simple (parser, @1, $1);
2489 if (unsmob_music ($$))
2490 unsmob_music ($$)->set_property ("articulations",
2491 scm_reverse_x ($2, SCM_EOL));
2494 parser->parser_error (@1, _("music expected"));
2495 $$ = MAKE_SYNTAX ("void-music", @1);
2499 | simple_chord_elements post_events {
2500 SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
2503 /* why is this giving wrong start location? -ns
2505 i.set_location (@1, @2);
2506 $$ = MAKE_SYNTAX ("event-chord", i, elts);
2508 | CHORD_REPETITION optional_notemode_duration post_events {
2510 i.set_location (@1, @3);
2511 $$ = MAKE_SYNTAX ("repetition-chord", i,
2512 $2, scm_reverse_x ($3, SCM_EOL));
2514 | MULTI_MEASURE_REST optional_notemode_duration post_events {
2516 i.set_location (@1, @3);
2517 $$ = MAKE_SYNTAX ("multi-measure-rest", i, $2,
2518 scm_reverse_x ($3, SCM_EOL));
2521 | note_chord_element
2526 chord_body optional_notemode_duration post_events
2528 Music *m = unsmob_music ($1);
2529 SCM dur = unsmob_duration ($2)->smobbed_copy ();
2530 SCM es = m->get_property ("elements");
2531 SCM postevs = scm_reverse_x ($3, SCM_EOL);
2533 for (SCM s = es; scm_is_pair (s); s = scm_cdr (s))
2534 unsmob_music (scm_car (s))->set_property ("duration", dur);
2535 es = ly_append2 (es, postevs);
2537 m-> set_property ("elements", es);
2539 $$ = m->self_scm ();
2544 ANGLE_OPEN chord_body_elements ANGLE_CLOSE
2546 $$ = MAKE_SYNTAX ("event-chord", @$, scm_reverse_x ($2, SCM_EOL));
2548 | CHORD_BODY_IDENTIFIER
2551 chord_body_elements:
2552 /* empty */ { $$ = SCM_EOL; }
2553 | chord_body_elements chord_body_element {
2554 if (!SCM_UNBNDP ($2))
2555 $$ = scm_cons ($2, $1);
2560 pitch exclamations questions octave_check post_events
2562 bool q = to_boolean ($3);
2563 bool ex = to_boolean ($2);
2567 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
2568 n->set_property ("pitch", $1);
2570 n->set_property ("cautionary", SCM_BOOL_T);
2572 n->set_property ("force-accidental", SCM_BOOL_T);
2574 if (scm_is_pair (post)) {
2575 SCM arts = scm_reverse_x (post, SCM_EOL);
2576 n->set_property ("articulations", arts);
2578 if (scm_is_number (check))
2580 int q = scm_to_int (check);
2581 n->set_property ("absolute-octave", scm_from_int (q-1));
2584 $$ = n->unprotect ();
2586 | DRUM_PITCH post_events {
2587 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
2588 n->set_property ("drum-type", $1);
2590 if (scm_is_pair ($2)) {
2591 SCM arts = scm_reverse_x ($2, SCM_EOL);
2592 n->set_property ("articulations", arts);
2594 $$ = n->unprotect ();
2596 | music_function_chord_body
2598 Music *m = unsmob_music ($1);
2600 while (m && m->is_mus_type ("music-wrapper-music")) {
2601 $$ = m->get_property ("element");
2602 m = unsmob_music ($$);
2605 if (!(m && m->is_mus_type ("rhythmic-event"))) {
2606 parser->parser_error (@$, _ ("not a rhythmic event"));
2612 music_function_chord_body:
2617 // Event functions may only take closed arglists, otherwise it would
2618 // not be clear whether a following postevent should be associated
2619 // with the last argument of the event function or with the expression
2620 // for which the function call acts itself as event.
2622 music_function_call_closed:
2623 MUSIC_FUNCTION function_arglist_closed {
2624 $$ = MAKE_SYNTAX ("music-function", @$,
2629 event_function_event:
2630 EVENT_FUNCTION function_arglist_closed {
2631 $$ = MAKE_SYNTAX ("music-function", @$,
2653 | post_events post_event {
2655 if (Music *m = unsmob_music ($2))
2657 if (m->is_mus_type ("post-event-wrapper"))
2659 for (SCM p = m->get_property ("elements");
2663 $$ = scm_cons (scm_car (p), $$);
2667 $$ = scm_cons ($2, $$);
2673 post_event_nofinger:
2674 direction_less_event {
2677 | script_dir music_function_call_closed {
2679 if (!unsmob_music ($2)->is_mus_type ("post-event")) {
2680 parser->parser_error (@2, _ ("post-event expected"));
2681 $$ = SCM_UNSPECIFIED;
2682 } else if (!SCM_UNBNDP ($1))
2684 unsmob_music ($$)->set_property ("direction", $1);
2688 if (!parser->lexer_->is_lyric_state ())
2689 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2690 $$ = MY_MAKE_MUSIC ("HyphenEvent", @$)->unprotect ();
2693 if (!parser->lexer_->is_lyric_state ())
2694 parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
2695 $$ = MY_MAKE_MUSIC ("ExtenderEvent", @$)->unprotect ();
2697 | script_dir direction_reqd_event {
2698 if (!SCM_UNBNDP ($1))
2700 Music *m = unsmob_music ($2);
2701 m->set_property ("direction", $1);
2705 | script_dir direction_less_event {
2706 if (!SCM_UNBNDP ($1))
2708 Music *m = unsmob_music ($2);
2709 m->set_property ("direction", $1);
2716 unsmob_music ($$)->set_property ("direction", scm_from_int (UP));
2721 unsmob_music ($$)->set_property ("direction", scm_from_int (DOWN));
2732 string_number_event:
2734 Music *s = MY_MAKE_MUSIC ("StringNumberEvent", @$);
2735 s->set_property ("string-number", $1);
2736 $$ = s->unprotect ();
2740 direction_less_event:
2742 | EVENT_IDENTIFIER {
2746 Music *a = MY_MAKE_MUSIC ("TremoloEvent", @$);
2747 a->set_property ("tremolo-type", $1);
2748 $$ = a->unprotect ();
2750 | event_function_event
2753 direction_reqd_event:
2757 | script_abbreviation {
2758 SCM s = parser->lexer_->lookup_identifier ("dash" + ly_scm2string ($1));
2759 Music *a = MY_MAKE_MUSIC ("ArticulationEvent", @$);
2760 if (scm_is_string (s))
2761 a->set_property ("articulation-type", s);
2762 else parser->parser_error (@1, _ ("expecting string as script definition"));
2763 $$ = a->unprotect ();
2768 /**/ { $$ = SCM_EOL; }
2769 | '=' quotes { $$ = $2; }
2783 $$ = scm_from_int (1);
2786 $$ = scm_oneplus ($1);
2792 $$ = scm_from_int (-1);
2795 $$ = scm_oneminus ($1);
2800 NOTENAME_PITCH quotes {
2801 if (!scm_is_eq (SCM_INUM0, $2))
2803 Pitch p = *unsmob_pitch ($1);
2804 p = p.transposed (Pitch (scm_to_int ($2),0,0));
2805 $$ = p.smobbed_copy ();
2815 TONICNAME_PITCH quotes {
2816 if (!scm_is_eq (SCM_INUM0, $2))
2818 Pitch p = *unsmob_pitch ($1);
2819 p = p.transposed (Pitch (scm_to_int ($2),0,0));
2820 $$ = p.smobbed_copy ();
2832 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2833 t->set_property ("text", $1);
2834 $$ = t->unprotect ();
2837 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2838 t->set_property ("text",
2839 make_simple_markup ($1));
2840 $$ = t->unprotect ();
2842 | embedded_scm_closed
2844 Music *m = unsmob_music ($1);
2845 if (m && m->is_mus_type ("post-event"))
2847 else if (Text_interface::is_markup ($1)) {
2848 Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
2849 t->set_property ("text", $1);
2850 $$ = t->unprotect ();
2852 parser->parser_error (@1, _ ("not an articulation"));
2858 Music *t = MY_MAKE_MUSIC ("FingeringEvent", @$);
2859 t->set_property ("digit", $1);
2860 $$ = t->unprotect ();
2864 script_abbreviation:
2866 $$ = scm_from_locale_string ("Hat");
2869 $$ = scm_from_locale_string ("Plus");
2872 $$ = scm_from_locale_string ("Dash");
2875 $$ = scm_from_locale_string ("Bang");
2878 $$ = scm_from_locale_string ("Larger");
2881 $$ = scm_from_locale_string ("Dot");
2884 $$ = scm_from_locale_string ("Underscore");
2889 '_' { $$ = scm_from_int (DOWN); }
2890 | '^' { $$ = scm_from_int (UP); }
2891 | '-' { $$ = SCM_UNDEFINED; }
2895 multiplied_duration {
2900 maybe_notemode_duration:
2904 | multiplied_duration {
2906 parser->default_duration_ = *unsmob_duration ($$);
2911 optional_notemode_duration:
2912 maybe_notemode_duration
2914 if (SCM_UNBNDP ($$))
2915 $$ = parser->default_duration_.smobbed_copy ();
2921 $$ = make_duration ($1, scm_to_int ($2));
2922 if (SCM_UNBNDP ($$))
2924 parser->parser_error (@1, _ ("not a duration"));
2925 $$ = Duration ().smobbed_copy ();
2928 | DURATION_IDENTIFIER dots {
2929 Duration *d = unsmob_duration ($1);
2930 Duration k (d->duration_log (),
2931 d->dot_count () + scm_to_int ($2));
2932 k = k.compressed (d->factor ());
2933 scm_remember_upto_here_1 ($1);
2934 $$ = k.smobbed_copy ();
2938 multiplied_duration:
2942 | multiplied_duration '*' UNSIGNED {
2943 $$ = unsmob_duration ($$)->compressed (scm_to_int ($3)).smobbed_copy ();
2945 | multiplied_duration '*' FRACTION {
2946 Rational m (scm_to_int (scm_car ($3)), scm_to_int (scm_cdr ($3)));
2948 $$ = unsmob_duration ($$)->compressed (m).smobbed_copy ();
2957 $$ = scm_oneplus ($1);
2966 if (SCM_UNBNDP (make_duration ($2)))
2967 parser->parser_error (@2, _ ("not a duration"));
2973 UNSIGNED { $$ = $1; }
2974 | STRING { $$ = $1; }
2975 | full_markup { $$ = $1; }
2978 // as an integer, it needs to be non-negative, and otherwise
2979 // it needs to be suitable as a markup.
2980 if (scm_is_integer ($1)
2981 ? scm_is_true (scm_negative_p ($1))
2982 : !Text_interface::is_markup ($1))
2984 parser->parser_error (@1, _ ("bass number expected"));
2990 figured_bass_alteration:
2991 '-' { $$ = ly_rational2scm (FLAT_ALTERATION); }
2992 | '+' { $$ = ly_rational2scm (SHARP_ALTERATION); }
2993 | '!' { $$ = scm_from_int (0); }
2998 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
2999 $$ = bfr->unprotect ();
3002 Music *bfr = MY_MAKE_MUSIC ("BassFigureEvent", @$);
3003 $$ = bfr->self_scm ();
3005 if (scm_is_number ($1))
3006 bfr->set_property ("figure", $1);
3007 else if (Text_interface::is_markup ($1))
3008 bfr->set_property ("text", $1);
3014 unsmob_music ($1)->set_property ("bracket-stop", SCM_BOOL_T);
3016 | bass_figure figured_bass_alteration {
3017 Music *m = unsmob_music ($1);
3018 if (scm_to_double ($2)) {
3019 SCM salter = m->get_property ("alteration");
3020 SCM alter = scm_is_number (salter) ? salter : scm_from_int (0);
3021 m->set_property ("alteration",
3022 scm_sum (alter, $2));
3024 m->set_property ("alteration", scm_from_int (0));
3027 | bass_figure figured_bass_modification {
3028 Music *m = unsmob_music ($1);
3029 m->set_property ($2, SCM_BOOL_T);
3034 figured_bass_modification:
3036 $$ = ly_symbol2scm ("augmented");
3039 $$ = ly_symbol2scm ("no-continuation");
3042 $$ = ly_symbol2scm ("diminished");
3045 $$ = ly_symbol2scm ("augmented-slash");
3055 unsmob_music ($$)->set_property ("bracket-start", SCM_BOOL_T);
3063 | figure_list br_bass_figure {
3064 $$ = scm_cons ($2, $1);
3069 FIGURE_OPEN figure_list FIGURE_CLOSE {
3070 $$ = scm_reverse_x ($2, SCM_EOL);
3076 /**/ { $$ = SCM_BOOL_F; }
3077 | REST { $$ = SCM_BOOL_T; }
3081 pitch exclamations questions octave_check maybe_notemode_duration optional_rest {
3082 if (!parser->lexer_->is_note_state ())
3083 parser->parser_error (@1, _ ("have to be in Note mode for notes"));
3084 if (!SCM_UNBNDP ($2)
3086 || scm_is_number ($4)
3088 || scm_is_true ($6))
3091 if (scm_is_true ($6))
3092 n = MY_MAKE_MUSIC ("RestEvent", @$);
3094 n = MY_MAKE_MUSIC ("NoteEvent", @$);
3096 n->set_property ("pitch", $1);
3097 if (SCM_UNBNDP ($5))
3098 n->set_property ("duration",
3099 parser->default_duration_.smobbed_copy ());
3101 n->set_property ("duration", $5);
3103 if (scm_is_number ($4))
3105 int q = scm_to_int ($4);
3106 n->set_property ("absolute-octave", scm_from_int (q-1));
3109 if (to_boolean ($3))
3110 n->set_property ("cautionary", SCM_BOOL_T);
3111 if (to_boolean ($2) || to_boolean ($3))
3112 n->set_property ("force-accidental", SCM_BOOL_T);
3114 $$ = n->unprotect ();
3117 | DRUM_PITCH optional_notemode_duration {
3118 Music *n = MY_MAKE_MUSIC ("NoteEvent", @$);
3119 n->set_property ("duration", $2);
3120 n->set_property ("drum-type", $1);
3122 $$ = n->unprotect ();
3124 | RESTNAME optional_notemode_duration {
3126 if (ly_scm2string ($1) == "s") {
3128 ev = MY_MAKE_MUSIC ("SkipEvent", @$);
3131 ev = MY_MAKE_MUSIC ("RestEvent", @$);
3134 ev->set_property ("duration", $2);
3135 $$ = ev->unprotect ();
3139 simple_chord_elements:
3141 if (!parser->lexer_->is_chord_state ())
3142 parser->parser_error (@1, _ ("have to be in Chord mode for chords"));
3145 | figure_spec optional_notemode_duration {
3146 for (SCM s = $1; scm_is_pair (s); s = scm_cdr (s))
3148 unsmob_music (scm_car (s))->set_property ("duration", $2);
3156 if (!parser->lexer_->is_lyric_state ())
3157 parser->parser_error (@1, _ ("markup outside of text script or \\lyricmode"));
3161 if (!parser->lexer_->is_lyric_state ())
3162 parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode"));
3168 lyric_element_music:
3169 lyric_element optional_notemode_duration post_events {
3170 $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
3171 if (scm_is_pair ($3))
3172 unsmob_music ($$)->set_property
3173 ("articulations", scm_reverse_x ($3, SCM_EOL));
3178 steno_tonic_pitch optional_notemode_duration {
3179 $$ = make_chord_elements (@$, $1, $2, SCM_EOL);
3181 | steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
3182 SCM its = scm_reverse_x ($4, SCM_EOL);
3183 $$ = make_chord_elements (@$, $1, $2, scm_cons ($3, its));
3191 | chord_items chord_item {
3192 $$ = scm_cons ($2, $$);
3198 $$ = ly_symbol2scm ("chord-colon");
3201 $$ = ly_symbol2scm ("chord-caret");
3203 | CHORD_SLASH steno_tonic_pitch {
3204 $$ = scm_list_2 (ly_symbol2scm ("chord-slash"), $2);
3206 | CHORD_BASS steno_tonic_pitch {
3207 $$ = scm_list_2 (ly_symbol2scm ("chord-bass"), $2);
3216 $$ = scm_reverse_x ($1, SCM_EOL);
3224 step_number { $$ = scm_cons ($1, SCM_EOL); }
3225 | step_numbers '.' step_number {
3226 $$ = scm_cons ($3, $$);
3232 $$ = make_chord_step ($1, 0);
3235 $$ = make_chord_step ($1, SHARP_ALTERATION);
3237 | UNSIGNED CHORD_MINUS {
3238 $$ = make_chord_step ($1, FLAT_ALTERATION);
3246 | UNSIGNED '-' UNSIGNED {
3247 $$ = scm_cons ($1, $3);
3254 TODO: should deprecate in favor of Scheme?
3258 number_expression '+' number_term {
3259 $$ = scm_sum ($1, $3);
3261 | number_expression '-' number_term {
3262 $$ = scm_difference ($1, $3);
3271 | number_factor '*' number_factor {
3272 $$ = scm_product ($1, $3);
3274 | number_factor '/' number_factor {
3275 $$ = scm_divide ($1, $3);
3280 '-' number_factor { /* %prec UNARY_MINUS */
3281 $$ = scm_difference ($2, SCM_UNDEFINED);
3287 bare_number_common_closed
3288 | REAL NUMBER_IDENTIFIER
3290 $$ = scm_product ($1, $2);
3294 bare_number_common_closed:
3302 | UNSIGNED NUMBER_IDENTIFIER {
3303 $$ = scm_product ($1, $2);
3309 | bare_number_common_closed
3318 { $$ = SCM_UNDEFINED; }
3321 if (SCM_UNBNDP ($1))
3329 { $$ = SCM_UNDEFINED; }
3332 if (SCM_UNBNDP ($1))
3341 { parser->lexer_->push_markup_state (); }
3344 parser->lexer_->pop_state ();
3350 { parser->lexer_->push_markup_state (); }
3353 parser->lexer_->pop_state ();
3358 simple_markup_list {
3359 $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
3361 | markup_head_1_list simple_markup
3363 $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
3364 @2, $1, scm_list_1 ($2)));
3374 if (Text_interface::is_markup ($1))
3375 MYBACKUP (MARKUP_IDENTIFIER, $1, @1);
3376 else if (Text_interface::is_markup_list ($1))
3377 MYBACKUP (MARKUPLIST_IDENTIFIER, $1, @1);
3379 parser->parser_error (@1, _ ("not a markup"));
3380 MYBACKUP (MARKUP_IDENTIFIER, scm_string (SCM_EOL), @1);
3387 markup_composed_list {
3390 | markup_uncomposed_list
3393 markup_uncomposed_list:
3394 markup_braced_list {
3397 | markup_command_list {
3398 $$ = scm_list_1 ($1);
3400 | markup_scm MARKUPLIST_IDENTIFIER
3410 $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $1));
3416 SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
3417 parser->lexer_->push_note_state (nn);
3418 } '{' score_body '}' {
3420 parser->lexer_->pop_state ();
3424 markup_composed_list:
3425 markup_head_1_list markup_uncomposed_list {
3426 $$ = MAKE_SYNTAX ("composed-markup-list",
3432 '{' markup_braced_list_body '}' {
3433 $$ = scm_reverse_x ($2, SCM_EOL);
3437 markup_braced_list_body:
3438 /* empty */ { $$ = SCM_EOL; }
3439 | markup_braced_list_body markup {
3440 $$ = scm_cons ($2, $1);
3442 | markup_braced_list_body simple_markup_list {
3443 $$ = scm_reverse_x ($2, $1);
3447 markup_command_list:
3448 MARKUP_LIST_FUNCTION markup_command_list_arguments {
3449 $$ = scm_cons ($1, scm_reverse_x($2, SCM_EOL));
3453 markup_command_basic_arguments:
3454 EXPECT_MARKUP_LIST markup_command_list_arguments markup_list {
3455 $$ = scm_cons ($3, $2);
3457 | EXPECT_SCM markup_command_list_arguments embedded_scm_closed {
3458 $$ = check_scheme_arg (parser, @3, $3, $2, $1);
3460 | EXPECT_NO_MORE_ARGS {
3465 markup_command_list_arguments:
3466 markup_command_basic_arguments { $$ = $1; }
3467 | EXPECT_MARKUP markup_command_list_arguments markup {
3468 $$ = scm_cons ($3, $2);
3473 MARKUP_FUNCTION EXPECT_MARKUP markup_command_list_arguments {
3474 $$ = scm_cons ($1, scm_reverse_x ($3, SCM_EOL));
3479 markup_head_1_item {
3480 $$ = scm_list_1 ($1);
3482 | markup_head_1_list markup_head_1_item {
3483 $$ = scm_cons ($2, $1);
3489 $$ = make_simple_markup ($1);
3491 | MARKUP_FUNCTION markup_command_basic_arguments {
3492 $$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
3494 | markup_scm MARKUP_IDENTIFIER
3500 $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $1);
3505 markup_head_1_list simple_markup
3507 $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
3508 @2, $1, scm_list_1 ($2)));
3518 Lily_parser::set_yydebug (bool x)
3524 Lily_parser::do_yyparse ()
3526 SCM retval = SCM_UNDEFINED;
3527 yyparse (this, &retval);
3537 It is a little strange to have this function in this file, but
3538 otherwise, we have to import music classes into the lexer.
3542 Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
3544 if (unsmob_book (sid)) {
3545 Book *book = unsmob_book (sid)->clone ();
3546 *destination = book->self_scm ();
3549 return BOOK_IDENTIFIER;
3550 } else if (scm_is_number (sid)) {
3552 return NUMBER_IDENTIFIER;
3553 } else if (unsmob_context_def (sid)) {
3554 Context_def *def= unsmob_context_def (sid)->clone ();
3556 *destination = def->self_scm ();
3559 return CONTEXT_DEF_IDENTIFIER;
3560 } else if (unsmob_context_mod (sid)) {
3561 *destination = unsmob_context_mod (sid)->smobbed_copy ();
3563 return CONTEXT_MOD_IDENTIFIER;
3564 } else if (Music *mus = unsmob_music (sid)) {
3565 mus = mus->clone ();
3566 *destination = mus->self_scm ();
3567 bool is_event = mus->is_mus_type ("post-event");
3569 return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
3570 } else if (unsmob_pitch (sid)) {
3571 *destination = unsmob_pitch (sid)->smobbed_copy ();
3572 return PITCH_IDENTIFIER;
3573 } else if (unsmob_duration (sid)) {
3574 *destination = unsmob_duration (sid)->smobbed_copy ();
3575 return DURATION_IDENTIFIER;
3576 } else if (unsmob_output_def (sid)) {
3577 Output_def *p = unsmob_output_def (sid);
3580 *destination = p->self_scm ();
3582 return OUTPUT_DEF_IDENTIFIER;
3589 get_next_unique_context_id ()
3591 return scm_from_locale_string ("$uniqueContextId");
3596 get_next_unique_lyrics_context_id ()
3598 static int new_context_count;
3600 snprintf (s, sizeof (s)-1, "uniqueContext%d", new_context_count++);
3601 return scm_from_locale_string (s);
3604 // check_scheme_arg checks one argument with a given predicate for use
3605 // in an argument list and throws a syntax error if it is unusable.
3606 // The argument is prepended to the argument list in any case. After
3607 // throwing a syntax error, the argument list is terminated with #f as
3608 // its last cdr in order to mark it as uncallable while not losing
3609 // track of its total length.
3611 // There are a few special considerations: if optional argument disp
3612 // is given (otherwise it defaults to SCM_UNDEFINED), it will be used
3613 // instead of arg in a prospective error message. This is useful if
3614 // arg is not the actual argument but rather a transformation of it.
3616 // If arg itself is SCM_UNDEFINED, the predicate is considered false
3617 // and an error message using disp is produced unconditionally.
3619 SCM check_scheme_arg (Lily_parser *parser, Input loc,
3620 SCM arg, SCM args, SCM pred, SCM disp)
3622 if (SCM_UNBNDP (arg))
3623 args = scm_cons (disp, args);
3625 args = scm_cons (arg, args);
3626 if (scm_is_true (scm_call_1 (pred, arg)))
3629 scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
3630 MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred,
3631 SCM_UNBNDP (disp) ? arg : disp);
3632 scm_set_cdr_x (scm_last_pair (args), SCM_BOOL_F);
3636 SCM loc_on_music (Input loc, SCM arg)
3638 if (Music *m = unsmob_music (arg))
3642 return m->unprotect ();
3648 try_string_variants (SCM pred, SCM str)
3650 // a matching predicate is always ok
3651 if (scm_is_true (scm_call_1 (pred, str)))
3653 // a symbol may be interpreted as a list of symbols if it helps
3654 if (scm_is_symbol (str)) {
3655 str = scm_list_1 (str);
3656 if (scm_is_true (scm_call_1 (pred, str)))
3658 return SCM_UNDEFINED;
3661 // If this cannot be a string representation of a symbol list,
3664 if (!is_regular_identifier (str, true))
3665 return SCM_UNDEFINED;
3667 str = scm_string_split (str, SCM_MAKE_CHAR ('.'));
3668 for (SCM p = str; scm_is_pair (p); p = scm_cdr (p))
3669 scm_set_car_x (p, scm_string_to_symbol (scm_car (p)));
3671 // Let's attempt the symbol list interpretation first.
3673 if (scm_is_true (scm_call_1 (pred, str)))
3676 // If there is just one symbol in the list, we might interpret
3677 // it as a single symbol
3679 if (scm_is_null (scm_cdr (str)))
3681 str = scm_car (str);
3682 if (scm_is_true (scm_call_1 (pred, str)))
3686 return SCM_UNDEFINED;
3690 is_regular_identifier (SCM id, bool multiple)
3692 if (!scm_is_string (id))
3695 string str = ly_scm2string (id);
3697 bool middle = false;
3699 for (string::iterator it=str.begin(); it != str.end (); it++)
3702 if ((c >= 'a' && c <= 'z')
3703 || (c >= 'A' && c <= 'Z')
3706 else if (middle && (c == '-' || c == '_' || (multiple && c == '.')))
3715 make_music_from_simple (Lily_parser *parser, Input loc, SCM simple)
3717 if (unsmob_music (simple))
3719 if (parser->lexer_->is_note_state ()) {
3720 if (scm_is_symbol (simple)) {
3721 Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
3722 n->set_property ("duration", parser->default_duration_.smobbed_copy ());
3723 n->set_property ("drum-type", simple);
3724 return n->unprotect ();
3726 if (unsmob_pitch (simple)) {
3727 Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
3728 n->set_property ("duration", parser->default_duration_.smobbed_copy ());
3729 n->set_property ("pitch", simple);
3730 return n->unprotect ();
3733 } else if (parser->lexer_->is_lyric_state ()) {
3734 if (Text_interface::is_markup (simple))
3735 return MAKE_SYNTAX ("lyric-event", loc, simple,
3736 parser->default_duration_.smobbed_copy ());
3737 } else if (parser->lexer_->is_chord_state ()) {
3738 if (unsmob_pitch (simple))
3739 return make_chord_elements (loc, simple,
3740 parser->default_duration_.smobbed_copy (),
3747 make_music_with_input (SCM name, Input where)
3749 Music *m = make_music_by_name (name);
3750 m->set_spot (where);
3755 make_simple_markup (SCM a)
3761 make_duration (SCM d, int dots)
3763 int t = scm_to_int (d);
3764 if (t > 0 && (t & (t-1)) == 0)
3765 return Duration (intlog2 (t), dots).smobbed_copy ();
3767 return SCM_UNDEFINED;
3771 make_chord_step (SCM step_scm, Rational alter)
3773 int step = scm_to_int (step_scm);
3776 alter += FLAT_ALTERATION;
3780 Pitch m ((step -1) / 7, (step - 1) % 7, alter);
3781 return m.smobbed_copy ();
3786 make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list)
3788 SCM chord_ctor = ly_lily_module_constant ("construct-chord-elements");
3789 SCM res = scm_call_3 (chord_ctor, pitch, dur, modification_list);
3790 for (SCM s = res; scm_is_pair (s); s = scm_cdr (s))
3792 unsmob_music (scm_car (s))->set_spot (loc);
3798 yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser)
3800 Lily_lexer *lex = parser->lexer_;
3804 lex->prepare_for_next_token ();
3805 return lex->yylex ();