X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=a99dffcf3889056a2e4e01d128fd67639acc1bf4;hb=3eb0d21c7cac9360c37c3376c8771e6e29c1a588;hp=ee413b301feb33f4d16d4a372c4a4c4c0ccfd8bc;hpb=2c18ae02874d6e5bbb579603f4de64274ba9faaf;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index ee413b301f..a99dffcf38 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -113,7 +113,7 @@ or -%pure_parser +%pure-parser %locations @@ -157,7 +157,7 @@ using namespace std; #include "warn.hh" void -Lily_parser::parser_error (Input const *i, Lily_parser *parser, SCM *, string s) +Lily_parser::parser_error (Input const *i, Lily_parser *parser, SCM *, const string &s) { parser->parser_error (*i, s); } @@ -309,16 +309,8 @@ int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser); %token DOUBLE_ANGLE_OPEN "<<" %token DOUBLE_ANGLE_CLOSE ">>" %token E_BACKSLASH "\\" -%token E_ANGLE_CLOSE "\\>" -%token E_CHAR "\\C[haracter]" -%token E_CLOSE "\\)" %token E_EXCLAMATION "\\!" -%token E_BRACKET_OPEN "\\[" -%token E_OPEN "\\(" -%token E_BRACKET_CLOSE "\\]" -%token E_ANGLE_OPEN "\\<" %token E_PLUS "\\+" -%token E_TILDE "\\~" %token EXTENDER "__" /* @@ -531,6 +523,10 @@ scm_function_call: embedded_lilypond: /* empty */ { + // FIXME: @$ does not contain a useful source location + // for empty rules, and the only token in the whole + // production, EMBEDDED_LILY, is synthetic and also + // contains no source location. $$ = MAKE_SYNTAX ("void-music", @$); } | identifier_init @@ -630,12 +626,22 @@ context_def_spec_block: CONTEXT '{' context_def_spec_body '}' { $$ = $3; + unsmob_context_def ($$)->origin ()->set_spot (@$); } ; context_mod_arg: embedded_scm - | composite_music + | + { + SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); + parser->lexer_->push_note_state (nn); + } + composite_music + { + parser->lexer_->pop_state (); + $$ = $2; + } ; context_mod_embedded: @@ -649,6 +655,7 @@ context_mod_embedded: $$ = $1; else { parser->parser_error (@1, _ ("not a context mod")); + $$ = Context_mod ().smobbed_copy (); } } ; @@ -657,11 +664,9 @@ context_mod_embedded: context_def_spec_body: /**/ { $$ = Context_def::make_scm (); - unsmob_context_def ($$)->origin ()->set_spot (@$); } | CONTEXT_DEF_IDENTIFIER { $$ = $1; - unsmob_context_def ($$)->origin ()->set_spot (@$); } | context_def_spec_body context_mod { if (!SCM_UNBNDP ($2)) @@ -688,6 +693,7 @@ context_def_spec_body: book_block: BOOK '{' book_body '}' { $$ = $3; + unsmob_book ($$)->origin ()->set_spot (@$); pop_paper (parser); parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), SCM_BOOL_F); } @@ -700,7 +706,6 @@ book_body: { Book *book = new Book; init_papers (parser); - book->origin ()->set_spot (@$); book->paper_ = dynamic_cast (unsmob_output_def (parser->lexer_->lookup_identifier ("$defaultpaper"))->clone ()); book->paper_->unprotect (); push_paper (parser, book->paper_); @@ -709,7 +714,6 @@ book_body: parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$); } | BOOK_IDENTIFIER { - unsmob_book ($1)->origin ()->set_spot (@$); parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $1); } | book_body paper_block { @@ -769,6 +773,7 @@ book_body: bookpart_block: BOOKPART '{' bookpart_body '}' { $$ = $3; + unsmob_book ($$)->origin ()->set_spot (@$); parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F); } ; @@ -776,12 +781,10 @@ bookpart_block: bookpart_body: { Book *book = new Book; - book->origin ()->set_spot (@$); $$ = book->unprotect (); parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $$); } | BOOK_IDENTIFIER { - unsmob_book ($1)->origin ()->set_spot (@$); parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $1); } | bookpart_body paper_block { @@ -944,16 +947,7 @@ output_def_head_with_mode_switch: music_or_context_def: music_arg - { - parser->lexer_->pop_state (); - } - | CONTEXT - { - parser->lexer_->pop_state (); - } '{' context_def_spec_body '}' - { - $$ = $4; - } + | context_def_spec_block ; output_def_body: @@ -980,6 +974,7 @@ output_def_body: parser->lexer_->push_note_state (nn); } music_or_context_def { + parser->lexer_->pop_state (); if (unsmob_context_def ($3)) assign_context_def (unsmob_output_def ($1), $3); else { @@ -1046,7 +1041,18 @@ music_embedded: $$ = SCM_UNSPECIFIED; } } - | embedded_scm + | music_embedded_backup + { + $$ = $1; + } + | music_embedded_backup BACKUP lyric_element_music + { + $$ = $3; + } + ; + +music_embedded_backup: + embedded_scm { if (scm_is_eq ($1, SCM_UNSPECIFIED)) $$ = $1; @@ -1057,9 +1063,12 @@ music_embedded: $$ = SCM_UNSPECIFIED; } else $$ = $1; - } else { + } else if (parser->lexer_->is_lyric_state () + && Text_interface::is_markup ($1)) + MYBACKUP (LYRIC_ELEMENT, $1, @1); + else { @$.warning (_ ("Ignoring non-music expression")); - $$ = SCM_UNSPECIFIED; + $$ = $1; } } ; @@ -1115,7 +1124,11 @@ simple_music: ; context_modification: - WITH { parser->lexer_->push_initial_state (); } '{' context_mod_list '}' + WITH + { + SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); + parser->lexer_->push_note_state (nn); + } '{' context_mod_list '}' { parser->lexer_->pop_state (); $$ = $4; @@ -1128,8 +1141,12 @@ context_modification: { $$ = $1; } - | WITH embedded_scm_closed + | WITH context_modification_arg { + if (unsmob_music ($2)) { + SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler"); + $2 = scm_call_2 (proc, parser->self_scm (), $2); + } if (unsmob_context_mod ($2)) $$ = $2; else { @@ -1139,6 +1156,11 @@ context_modification: } ; +context_modification_arg: + embedded_scm_closed + | MUSIC_IDENTIFIER + ; + optional_context_mod: /**/ { $$ = SCM_EOL; @@ -1871,14 +1893,14 @@ complex_music: ; complex_music_prefix: - CONTEXT simple_string optional_id optional_context_mod { + CONTEXT symbol optional_id optional_context_mod { Context_mod *ctxmod = unsmob_context_mod ($4); SCM mods = SCM_EOL; if (ctxmod) mods = ctxmod->get_mods (); $$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_F); } - | NEWCONTEXT simple_string optional_id optional_context_mod { + | NEWCONTEXT symbol optional_id optional_context_mod { Context_mod *ctxmod = unsmob_context_mod ($4); SCM mods = SCM_EOL; if (ctxmod) @@ -2018,13 +2040,11 @@ property_path: ; property_operation: - STRING '=' scalar { - $$ = scm_list_3 (ly_symbol2scm ("assign"), - scm_string_to_symbol ($1), $3); + symbol '=' scalar { + $$ = scm_list_3 (ly_symbol2scm ("assign"), $1, $3); } - | UNSET simple_string { - $$ = scm_list_2 (ly_symbol2scm ("unset"), - scm_string_to_symbol ($2)); + | UNSET symbol { + $$ = scm_list_2 (ly_symbol2scm ("unset"), $2); } | OVERRIDE property_path '=' scalar { if (scm_ilength ($2) < 2) { @@ -2066,6 +2086,13 @@ property_operation: // \revert Accidental.color revert_arg: + revert_arg_backup BACKUP symbol_list_arg + { + $$ = $3; + } + ; + +revert_arg_backup: revert_arg_part { if (scm_is_null ($1) @@ -2074,20 +2101,16 @@ revert_arg: else MYBACKUP (SYMBOL_LIST, scm_reverse_x ($1, SCM_EOL), @1); } - | revert_arg BACKUP symbol_list_arg - { - $$ = $3; - } ; // revert_arg_part delivers results in reverse revert_arg_part: symbol_list_part - | revert_arg BACKUP SCM_ARG '.' symbol_list_part + | revert_arg_backup BACKUP SCM_ARG '.' symbol_list_part { $$ = scm_append_x (scm_list_2 ($5, $3)); } - | revert_arg BACKUP SCM_ARG symbol_list_part + | revert_arg_backup BACKUP SCM_ARG symbol_list_part { $$ = scm_append_x (scm_list_2 ($4, $3)); } @@ -2271,17 +2294,6 @@ string: $$ = $1; } | full_markup - | string '+' string { - if (!scm_is_string ($1)) { - parser->parser_error (@1, (_ ("simple string expected"))); - $1 = scm_string (SCM_EOL); - } - if (!scm_is_string ($3)) { - parser->parser_error (@3, (_ ("simple string expected"))); - $3 = scm_string (SCM_EOL); - } - $$ = scm_string_append (scm_list_2 ($1, $3)); - } ; simple_string: STRING { @@ -2298,20 +2310,61 @@ simple_string: STRING { } ; +symbol: + STRING { + $$ = scm_string_to_symbol ($1); + } + | embedded_scm_bare + { + // This is a bit of overkill but makes the same + // routine responsible for all symbol interpretations. + $$ = try_string_variants (ly_lily_module_constant ("symbol?"), + $1); + if (SCM_UNBNDP ($$)) + { + parser->parser_error (@1, (_ ("symbol expected"))); + // Generate a unique symbol in case it is used + // for an assignment or similar + $$ = scm_make_symbol (ly_string2scm ("undefined")); + } + } + ; + scalar: embedded_scm_arg | SCM_IDENTIFIER | bare_number + // The following is a rather defensive variant of admitting + // negative numbers: the grammar would permit number_factor or + // even number_expression. However, function arguments allow + // only this simple kind of negative number, so to have things + // like \tweak and \override behave reasonably similar, it + // makes sense to rule out things like -- which are rather an + // accent in function argument contexts. + | '-' bare_number + { + $$ = scm_difference ($2, SCM_UNDEFINED); + } | FRACTION - | lyric_element + | STRING + | full_markup ; scalar_closed: embedded_scm_arg_closed | SCM_IDENTIFIER + // for scalar_closed to be an actually closed (no lookahead) + // expression, we'd need to use bare_number_closed here. It + // turns out that the only use of scalar_closed in TEMPO is + // not of the kind requiring the full closedness criterion. | bare_number + | '-' bare_number + { + $$ = scm_difference ($2, SCM_UNDEFINED); + } | FRACTION - | lyric_element + | STRING + | full_markup ; @@ -2467,40 +2520,10 @@ command_element: command_event { $$ = $1; } - | E_BRACKET_OPEN { - Music *m = MY_MAKE_MUSIC ("LigatureEvent", @$); - m->set_property ("span-direction", scm_from_int (START)); - $$ = m->unprotect(); - } - | E_BRACKET_CLOSE { - Music *m = MY_MAKE_MUSIC ("LigatureEvent", @$); - m->set_property ("span-direction", scm_from_int (STOP)); - $$ = m->unprotect (); - } - | E_BACKSLASH { - $$ = MAKE_SYNTAX ("voice-separator", @$); - } - | '|' { - SCM pipe = parser->lexer_->lookup_identifier ("pipeSymbol"); - - Music *m = unsmob_music (pipe); - if (m) - { - m = m->clone (); - m->set_spot (@$); - $$ = m->unprotect (); - } - else - $$ = MAKE_SYNTAX ("bar-check", @$); - - } ; command_event: - E_TILDE { - $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent", @$)->unprotect (); - } - | tempo_event { + tempo_event { $$ = $1; } ; @@ -2597,55 +2620,8 @@ string_number_event: } ; -direction_less_char: - '[' { - $$ = ly_symbol2scm ("bracketOpenSymbol"); - } - | ']' { - $$ = ly_symbol2scm ("bracketCloseSymbol"); - } - | '~' { - $$ = ly_symbol2scm ("tildeSymbol"); - } - | '(' { - $$ = ly_symbol2scm ("parenthesisOpenSymbol"); - } - | ')' { - $$ = ly_symbol2scm ("parenthesisCloseSymbol"); - } - | E_EXCLAMATION { - $$ = ly_symbol2scm ("escapedExclamationSymbol"); - } - | E_OPEN { - $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol"); - } - | E_CLOSE { - $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol"); - } - | E_ANGLE_CLOSE { - $$ = ly_symbol2scm ("escapedBiggerSymbol"); - } - | E_ANGLE_OPEN { - $$ = ly_symbol2scm ("escapedSmallerSymbol"); - } - ; - direction_less_event: - direction_less_char { - SCM predefd = parser->lexer_->lookup_identifier_symbol ($1); - Music *m = 0; - if (unsmob_music (predefd)) - { - m = unsmob_music (predefd)->clone (); - m->set_spot (@$); - } - else - { - m = MY_MAKE_MUSIC ("Music", @$); - } - $$ = m->unprotect (); - } - | string_number_event + string_number_event | EVENT_IDENTIFIER { $$ = $1; } @@ -2783,8 +2759,8 @@ script_abbreviation: | '-' { $$ = scm_from_locale_string ("Dash"); } - | '|' { - $$ = scm_from_locale_string ("Bar"); + | '!' { + $$ = scm_from_locale_string ("Bang"); } | ANGLE_CLOSE { $$ = scm_from_locale_string ("Larger"); @@ -2941,38 +2917,23 @@ bass_figure: } | bass_figure figured_bass_modification { Music *m = unsmob_music ($1); - if ($2 == ly_symbol2scm ("plus")) - { - m->set_property ("augmented", SCM_BOOL_T); - } - else if ($2 == ly_symbol2scm ("slash")) - { - m->set_property ("diminished", SCM_BOOL_T); - } - else if ($2 == ly_symbol2scm ("exclamation")) - { - m->set_property ("no-continuation", SCM_BOOL_T); - } - else if ($2 == ly_symbol2scm ("backslash")) - { - m->set_property ("augmented-slash", SCM_BOOL_T); - } + m->set_property ($2, SCM_BOOL_T); } ; figured_bass_modification: E_PLUS { - $$ = ly_symbol2scm ("plus"); + $$ = ly_symbol2scm ("augmented"); } | E_EXCLAMATION { - $$ = ly_symbol2scm ("exclamation"); + $$ = ly_symbol2scm ("no-continuation"); } | '/' { - $$ = ly_symbol2scm ("slash"); + $$ = ly_symbol2scm ("diminished"); } | E_BACKSLASH { - $$ = ly_symbol2scm ("backslash"); + $$ = ly_symbol2scm ("augmented-slash"); } ; @@ -3083,9 +3044,13 @@ simple_chord_elements: lyric_element: full_markup { + if (!parser->lexer_->is_lyric_state ()) + parser->parser_error (@1, _ ("markup outside of text script or \\lyricmode")); $$ = $1; } | STRING { + if (!parser->lexer_->is_lyric_state ()) + parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode")); $$ = $1; } | LYRIC_ELEMENT @@ -3093,8 +3058,6 @@ lyric_element: lyric_element_music: lyric_element optional_notemode_duration post_events { - if (!parser->lexer_->is_lyric_state ()) - parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics")); $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2); if (scm_is_pair ($3)) unsmob_music ($$)->set_property @@ -3171,7 +3134,7 @@ tempo_range: UNSIGNED { $$ = $1; } - | UNSIGNED '~' UNSIGNED { + | UNSIGNED '-' UNSIGNED { $$ = scm_cons ($1, $3); } ; @@ -3277,8 +3240,10 @@ markup_top: simple_markup_list { $$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1); } - | markup_head_1_list simple_markup { - $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2))); + | markup_head_1_list simple_markup + { + $$ = scm_car (MAKE_SYNTAX ("composed-markup-list", + @2, $1, scm_list_1 ($2))); } | simple_markup { $$ = $1; @@ -3304,7 +3269,11 @@ simple_markup_list: markup_composed_list { $$ = $1; } - | markup_braced_list { + | markup_uncomposed_list + ; + +markup_uncomposed_list: + markup_braced_list { $$ = $1; } | markup_command_list { @@ -3335,9 +3304,9 @@ markup_score: ; markup_composed_list: - markup_head_1_list markup_braced_list { - $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2); - + markup_head_1_list markup_uncomposed_list { + $$ = MAKE_SYNTAX ("composed-markup-list", + @2, $1, $2); } ; @@ -3415,9 +3384,10 @@ simple_markup: ; markup: - markup_head_1_list simple_markup { - SCM mapper = ly_lily_module_constant ("map-markup-command-list"); - $$ = scm_car (scm_call_2 (mapper, $1, scm_list_1 ($2))); + markup_head_1_list simple_markup + { + $$ = scm_car (MAKE_SYNTAX ("composed-markup-list", + @2, $1, scm_list_1 ($2))); } | simple_markup { $$ = $1;