X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=270961ffd0fd2d1c68980e361cf7075d2efa936d;hb=5f508003be854d1f6ef3bf5cca09a99d4877ad91;hp=a324bd43172f2f893915434eaa8d485cb1a61b39;hpb=9de1c7467d9fceec1150156236b50bd7c668185a;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index a324bd4317..270961ffd0 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -232,6 +232,7 @@ SCM make_chord_step (SCM step, Rational alter); SCM make_simple_markup (SCM a); bool is_duration (int t); bool is_regular_identifier (SCM id); +SCM try_string_variants (SCM pred, SCM str); int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser); %} @@ -363,7 +364,6 @@ If we give names, Bison complains. %token FRACTION %token LYRICS_STRING %token LYRIC_ELEMENT -%token LYRIC_MARKUP_IDENTIFIER %token MARKUP_FUNCTION %token MARKUP_LIST_FUNCTION %token MARKUP_IDENTIFIER @@ -375,6 +375,7 @@ If we give names, Bison complains. %token OUTPUT_DEF_IDENTIFIER %token REAL %token RESTNAME +%token SCM_ARG %token SCM_FUNCTION %token SCM_IDENTIFIER %token SCM_TOKEN @@ -446,6 +447,24 @@ toplevel_expression: SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler"); scm_call_2 (proc, parser->self_scm (), $1); } + | SCM_TOKEN { + // Evaluate and ignore #xxx, as opposed to \xxx + parser->lexer_->eval_scm_token ($1); + } + | embedded_scm_active + { + SCM out = SCM_UNDEFINED; + if (Text_interface::is_markup ($1)) + out = scm_list_1 ($1); + else if (Text_interface::is_markup_list ($1)) + out = $1; + if (scm_is_pair (out)) + { + SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler"); + scm_call_2 (proc, parser->self_scm (), out); + } else if (!scm_is_eq ($1, SCM_UNSPECIFIED)) + parser->parser_error (@1, _("bad expression type")); + } | output_def { SCM id = SCM_EOL; Output_def * od = unsmob_output_def ($1); @@ -469,9 +488,17 @@ embedded_scm_bare: | SCM_IDENTIFIER ; +embedded_scm_active: + SCM_IDENTIFIER + | scm_function_call + ; + embedded_scm_bare_arg: - embedded_scm_bare - | STRING + SCM_ARG + | SCM_TOKEN + { + $$ = parser->lexer_->eval_scm_token ($1); + } | full_markup | full_markup_list | context_modification @@ -531,6 +558,9 @@ lilypond_header_body: /* empty */ { $$ = SCM_UNSPECIFIED; } | lilypond_header_body assignment { + } + | lilypond_header_body embedded_scm { + } ; @@ -558,7 +588,6 @@ assignment: parser->lexer_->set_identifier (path, $4); $$ = SCM_UNSPECIFIED; } - | embedded_scm { $$ = SCM_UNSPECIFIED; } ; @@ -687,11 +716,28 @@ book_body: SCM proc = parser->lexer_->lookup_identifier ("book-text-handler"); scm_call_2 (proc, $1, $2); } + | book_body SCM_TOKEN { + // Evaluate and ignore #xxx, as opposed to \xxx + parser->lexer_->eval_scm_token ($2); + } + | book_body embedded_scm_active + { + SCM out = SCM_UNDEFINED; + if (Text_interface::is_markup ($2)) + out = scm_list_1 ($2); + else if (Text_interface::is_markup_list ($2)) + out = $2; + if (scm_is_pair (out)) + { + SCM proc = parser->lexer_->lookup_identifier ("book-text-handler"); + scm_call_2 (proc, $1, out); + } else if (!scm_is_eq ($2, SCM_UNSPECIFIED)) + parser->parser_error (@2, _("bad expression type")); + } | book_body { parser->lexer_->add_scope (unsmob_book ($1)->header_); } lilypond_header - | book_body embedded_scm { } | book_body error { Book *book = unsmob_book ($1); book->paper_ = 0; @@ -737,6 +783,24 @@ bookpart_body: SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler"); scm_call_2 (proc, $1, $2); } + | bookpart_body SCM_TOKEN { + // Evaluate and ignore #xxx, as opposed to \xxx + parser->lexer_->eval_scm_token ($2); + } + | bookpart_body embedded_scm_active + { + SCM out = SCM_UNDEFINED; + if (Text_interface::is_markup ($2)) + out = scm_list_1 ($2); + else if (Text_interface::is_markup_list ($2)) + out = $2; + if (scm_is_pair (out)) + { + SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler"); + scm_call_2 (proc, $1, out); + } else if (!scm_is_eq ($2, SCM_UNSPECIFIED)) + parser->parser_error (@2, _("bad expression type")); + } | bookpart_body { Book *book = unsmob_book ($1); @@ -744,7 +808,6 @@ bookpart_body: book->header_ = ly_make_module (false); parser->lexer_->add_scope (book->header_); } lilypond_header - | bookpart_body embedded_scm { } | bookpart_body error { Book *book = unsmob_book ($1); book->paper_ = 0; @@ -879,6 +942,9 @@ output_def_body: } | output_def_body assignment { + } + | output_def_body embedded_scm { + } | output_def_body { @@ -972,7 +1038,6 @@ music_arg: music_assign: simple_music | composite_music %prec COMPOSITE - | lyric_element_music ; repeated_music: @@ -1117,7 +1182,7 @@ function_arglist_nonbackup_common: | EXPECT_OPTIONAL EXPECT_DURATION function_arglist_closed duration_length { $$ = scm_cons ($4, $3); } - | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed FRACTION + | EXPECT_OPTIONAL EXPECT_SCM function_arglist FRACTION { $$ = check_scheme_arg (parser, @4, $4, $3, $2); } @@ -1165,6 +1230,34 @@ function_arglist_closed_nonbackup: { $$ = check_scheme_arg (parser, @4, $4, $3, $2); } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist SCM_IDENTIFIER + { + SCM res = try_string_variants ($2, $4); + if (SCM_UNBNDP (res)) + $$ = check_scheme_arg (parser, @4, $4, $3, $2); + else + $$ = scm_cons (res, $3); + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING + { + SCM res = try_string_variants ($2, $4); + if (SCM_UNBNDP (res)) + $$ = check_scheme_arg (parser, @4, $4, $3, $2); + else + $$ = scm_cons (res, $3); + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING + { + SCM res = try_string_variants ($2, $4); + if (SCM_UNBNDP (res)) + $$ = check_scheme_arg (parser, @4, $4, $3, $2); + else + $$ = scm_cons (res, $3); + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup + { + $$ = check_scheme_arg (parser, @4, $4, $3, $2); + } ; function_arglist_nonbackup: @@ -1177,6 +1270,66 @@ function_arglist_nonbackup: { $$ = check_scheme_arg (parser, @4, $4, $3, $2); } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING + { + SCM res = try_string_variants ($2, $4); + if (SCM_UNBNDP (res)) + $$ = check_scheme_arg (parser, @4, $4, $3, $2); + else + $$ = scm_cons (res, $3); + } + | function_arglist_nonbackup_reparse REPARSE SCM_ARG + { + $$ = check_scheme_arg (parser, @3, $3, $1, $2); + } + | function_arglist_nonbackup_reparse REPARSE lyric_element_music + { + $$ = check_scheme_arg (parser, @3, $3, $1, $2); + } + ; + +function_arglist_nonbackup_reparse: + EXPECT_OPTIONAL EXPECT_SCM function_arglist SCM_IDENTIFIER + { + $$ = $3; + SCM res = try_string_variants ($2, $4); + if (!SCM_UNBNDP (res)) + MYREPARSE (@4, $2, SCM_ARG, res); + else if (scm_is_true + (scm_call_1 + ($2, make_music_from_simple + (parser, @4, $4)))) + MYREPARSE (@4, $2, LYRICS_STRING, $4); + else + MYREPARSE (@4, $2, SCM_ARG, $4); + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING + { + $$ = $3; + SCM res = try_string_variants ($2, $4); + if (!SCM_UNBNDP (res)) + MYREPARSE (@4, $2, SCM_ARG, res); + else if (scm_is_true + (scm_call_1 + ($2, make_music_from_simple + (parser, @4, $4)))) + MYREPARSE (@4, $2, LYRICS_STRING, $4); + else + MYREPARSE (@4, $2, SCM_ARG, $4); + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup + { + $$ = $3; + if (scm_is_true (scm_call_1 ($2, $4))) + MYREPARSE (@4, $2, SCM_ARG, $4); + else if (scm_is_true + (scm_call_1 + ($2, make_music_from_simple + (parser, @4, $4)))) + MYREPARSE (@4, $2, LYRICS_STRING, $4); + else + MYREPARSE (@4, $2, SCM_ARG, $4); + } ; function_arglist_keep: @@ -1197,7 +1350,7 @@ function_arglist_backup: $$ = scm_cons ($4, $3); } else { $$ = scm_cons (loc_on_music (@3, $1), $3); - MYBACKUP (SCM_IDENTIFIER, $4, @4); + MYBACKUP (SCM_ARG, $4, @4); } } | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_keep post_event_nofinger @@ -1210,21 +1363,13 @@ function_arglist_backup: MYBACKUP (EVENT_IDENTIFIER, $4, @4); } } - | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep lyric_element + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep lyric_markup { - // There is no point interpreting a lyrics string as - // an event, since we don't allow music possibly - // followed by durations or postevent into closed - // music, and we only accept closed music in optional - // arguments at the moment. If this changes, more - // complex schemes might become interesting here as - // well: see how we do this at the mandatory argument - // point. if (scm_is_true (scm_call_1 ($2, $4))) $$ = scm_cons ($4, $3); else { $$ = scm_cons (loc_on_music (@3, $1), $3); - MYBACKUP (LYRICS_STRING, $4, @4); + MYBACKUP (LYRIC_ELEMENT, $4, @4); } } | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_keep UNSIGNED @@ -1259,7 +1404,7 @@ function_arglist_backup: MYBACKUP (NUMBER_IDENTIFIER, $4, @4); } } - | EXPECT_OPTIONAL EXPECT_SCM function_arglist_closed_keep FRACTION + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep FRACTION { if (scm_is_true (scm_call_1 ($2, $4))) { @@ -1296,6 +1441,7 @@ function_arglist_backup: MYREPARSE (@5, $2, REAL, n); $$ = $3; } else { + $$ = scm_cons (loc_on_music (@3, $1), $3); MYBACKUP (REAL, n, @5); } } @@ -1305,6 +1451,7 @@ function_arglist_backup: if (scm_is_true (scm_call_1 ($2, n))) { $$ = scm_cons (n, $3); } else { + $$ = scm_cons (loc_on_music (@3, $1), $3); MYBACKUP (NUMBER_IDENTIFIER, n, @5); } } @@ -1316,16 +1463,41 @@ function_arglist_backup: { $$ = scm_cons ($4, $3); } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep SCM_IDENTIFIER + { + SCM res = try_string_variants ($2, $4); + if (!SCM_UNBNDP (res)) + $$ = scm_cons (res, $3); + else { + $$ = scm_cons (loc_on_music (@3, $1), $3); + MYBACKUP (SCM_IDENTIFIER, $4, @4); + } + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep STRING + { + SCM res = try_string_variants ($2, $4); + if (!SCM_UNBNDP (res)) + $$ = scm_cons (res, $3); + else { + $$ = scm_cons (loc_on_music (@3, $1), $3); + MYBACKUP (STRING, $4, @4); + } + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep LYRICS_STRING + { + SCM res = try_string_variants ($2, $4); + if (!SCM_UNBNDP (res)) + $$ = scm_cons (res, $3); + else { + $$ = scm_cons (loc_on_music (@3, $1), $3); + MYBACKUP (LYRICS_STRING, $4, @4); + } + } | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup BACKUP { $$ = scm_cons ($1, $3); MYBACKUP(0, SCM_UNDEFINED, @3); } - | function_arglist_backup REPARSE embedded_scm_arg_closed - { - $$ = check_scheme_arg (parser, @3, - $3, $1, $2); - } | function_arglist_backup REPARSE bare_number { $$ = check_scheme_arg (parser, @3, @@ -1350,7 +1522,7 @@ function_arglist_common: $$ = check_scheme_arg (parser, @3, $3, $2, $1); } - | EXPECT_SCM function_arglist_closed_optional FRACTION + | EXPECT_SCM function_arglist_optional FRACTION { $$ = check_scheme_arg (parser, @3, $3, $2, $1); @@ -1360,65 +1532,102 @@ function_arglist_common: $$ = check_scheme_arg (parser, @3, $3, $2, $1); } - | function_arglist_common_minus - | function_arglist_common_lyric - ; - -function_arglist_common_lyric: - EXPECT_SCM function_arglist_optional lyric_element + | EXPECT_SCM function_arglist_closed_optional '-' NUMBER_IDENTIFIER { - // We check how the predicate thinks about a lyrics - // event or about a markup. If it accepts neither, we - // backup the original token. Otherwise we commit to - // taking the token. Depending on what the predicate - // is willing to accept, we interpret as a string, as - // a lyric event, or ambiguously (meaning that if - // something looking like a duration or post event - // follows, we take the event, otherwise the string). - SCM lyric_event = MAKE_SYNTAX ("lyric-event", @3, $3, - parser->default_duration_.smobbed_copy ()); - if (scm_is_true (scm_call_1 ($1, $3))) - if (scm_is_true (scm_call_1 ($1, lyric_event))) - { - $$ = $2; - MYREPARSE (@3, $1, LYRICS_STRING, $3); - } else { - $$ = scm_cons ($3, $2); - } - else if (scm_is_true (scm_call_1 ($1, lyric_event))) - { - $$ = $2; - MYREPARSE (@3, $1, LYRIC_ELEMENT, $3); - } else { + SCM n = scm_difference ($4, SCM_UNDEFINED); + $$ = check_scheme_arg (parser, @4, n, $2, $1); + } + | EXPECT_SCM function_arglist_optional STRING + { + SCM res = try_string_variants ($1, $3); + if (!SCM_UNBNDP (res)) + $$ = scm_cons ($3, $2); + else // This is going to flag a syntax error, we // know the predicate to be false. - check_scheme_arg (parser, @3, - $3, $2, $1); - } + $$ = check_scheme_arg (parser, @3, + $3, $2, $1); + } + | function_arglist_common_reparse REPARSE SCM_ARG + { + $$ = check_scheme_arg (parser, @3, + $3, $1, $2); + } + | function_arglist_common_reparse REPARSE lyric_element_music + { + $$ = check_scheme_arg (parser, @3, + $3, $1, $2); } - | function_arglist_common_lyric REPARSE lyric_element_arg + | function_arglist_common_reparse REPARSE bare_number { - // This should never be false $$ = check_scheme_arg (parser, @3, $3, $1, $2); } ; -function_arglist_common_minus: - EXPECT_SCM function_arglist_closed_optional '-' UNSIGNED +function_arglist_common_reparse: + EXPECT_SCM function_arglist_optional SCM_IDENTIFIER { + $$ = $2; + SCM res = try_string_variants ($1, $3); + if (!SCM_UNBNDP (res)) + MYREPARSE (@3, $1, SCM_ARG, res); + else if (scm_is_true + (scm_call_1 + ($1, make_music_from_simple (parser, @3, $3)))) + MYREPARSE (@3, $1, LYRIC_ELEMENT, $3); + else + // This is going to flag a syntax error, we + // know the predicate to be false. + MYREPARSE (@3, $1, SCM_ARG, $3); + } + | EXPECT_SCM function_arglist_optional LYRICS_STRING + { + $$ = $2; + SCM res = try_string_variants ($1, $3); + if (!SCM_UNBNDP (res)) + MYREPARSE (@3, $1, SCM_ARG, res); + else if (scm_is_true + (scm_call_1 + ($1, make_music_from_simple (parser, @3, $3)))) + MYREPARSE (@3, $1, LYRIC_ELEMENT, $3); + else + // This is going to flag a syntax error, we + // know the predicate to be false. + MYREPARSE (@3, $1, SCM_ARG, $3); + } + | EXPECT_SCM function_arglist_optional lyric_markup + { + $$ = $2; + // We check how the predicate thinks about the + // unmodified lyric element. If it would be accepted + // in this form, we don't try interpreting is as lyric + // music. + if (scm_is_true (scm_call_1 ($1, $3))) + MYREPARSE (@3, $1, SCM_ARG, $3); + else if (scm_is_true + (scm_call_1 + ($1, make_music_from_simple (parser, @3, $3)))) + MYREPARSE (@3, $1, LYRIC_ELEMENT, $3); + else + // This is going to flag a syntax error, we + // know the predicate to be false. + MYREPARSE (@3, $1, SCM_ARG, $3); + } + | EXPECT_SCM function_arglist_closed_optional '-' UNSIGNED + { + $$ = $2; SCM n = scm_difference ($4, SCM_UNDEFINED); - if (scm_is_true (scm_call_1 ($1, n))) { - $$ = $2; + if (scm_is_true (scm_call_1 ($1, n))) MYREPARSE (@4, $1, REAL, n); - } else { + else { Music *t = MY_MAKE_MUSIC ("FingeringEvent", @4); t->set_property ("digit", $4); - $$ = t->unprotect (); - if (scm_is_true (scm_call_1 ($1, $$))) - $$ = scm_cons ($$, $2); + SCM m = t->unprotect (); + if (scm_is_true (scm_call_1 ($1, m))) + MYREPARSE (@4, $1, SCM_ARG, m); else - $$ = check_scheme_arg (parser, @3, n, $2, $1); + MYREPARSE (@4, $1, SCM_ARG, $4); } } @@ -1428,15 +1637,6 @@ function_arglist_common_minus: SCM n = scm_difference ($4, SCM_UNDEFINED); MYREPARSE (@4, $1, REAL, n); } - | EXPECT_SCM function_arglist_closed_optional '-' NUMBER_IDENTIFIER - { - SCM n = scm_difference ($4, SCM_UNDEFINED); - $$ = check_scheme_arg (parser, @4, n, $2, $1); - } - | function_arglist_common_minus REPARSE bare_number - { - $$ = check_scheme_arg (parser, @3, $3, $1, $2); - } ; function_arglist_closed: @@ -1456,28 +1656,6 @@ function_arglist_closed_common: $$ = check_scheme_arg (parser, @3, $3, $2, $1); } - | EXPECT_SCM function_arglist_closed_optional '-' UNSIGNED - { - SCM n = scm_difference ($4, SCM_UNDEFINED); - if (scm_is_true (scm_call_1 ($1, n))) { - $$ = scm_cons (n, $2); - } else { - Music *t = MY_MAKE_MUSIC ("FingeringEvent", @4); - t->set_property ("digit", $4); - $$ = t->unprotect (); - if (scm_is_true (scm_call_1 ($1, $$))) - $$ = scm_cons ($$, $2); - else - $$ = check_scheme_arg (parser, @3, n, $2, $1); - } - - } - | EXPECT_SCM function_arglist_closed_optional '-' REAL - { - $$ = check_scheme_arg (parser, @3, - scm_difference ($4, SCM_UNDEFINED), - $2, $1); - } | EXPECT_SCM function_arglist_closed_optional '-' NUMBER_IDENTIFIER { $$ = check_scheme_arg (parser, @3, @@ -1489,15 +1667,31 @@ function_arglist_closed_common: $$ = check_scheme_arg (parser, @3, $3, $2, $1); } - | EXPECT_SCM function_arglist_closed_optional FRACTION + | EXPECT_SCM function_arglist_optional FRACTION { $$ = check_scheme_arg (parser, @3, $3, $2, $1); } - | EXPECT_SCM function_arglist_optional lyric_element + | EXPECT_SCM function_arglist_optional STRING + { + SCM res = try_string_variants ($1, $3); + if (!SCM_UNBNDP (res)) + $$ = scm_cons ($3, $2); + else + // This is going to flag a syntax error, we + // know the predicate to be false. + $$ = check_scheme_arg (parser, @3, + $3, $2, $1); + } + | function_arglist_common_reparse REPARSE SCM_ARG { $$ = check_scheme_arg (parser, @3, - $3, $2, $1); + $3, $1, $2); + } + | function_arglist_common_reparse REPARSE bare_number + { + $$ = check_scheme_arg (parser, @3, + $3, $1, $2); } ; @@ -1872,16 +2066,7 @@ simple_string: STRING { | LYRICS_STRING { $$ = $1; } - | MARKUP_IDENTIFIER - { - if (scm_is_string ($1)) { - $$ = $1; - } else { - parser->parser_error (@1, (_ ("simple string expected"))); - $$ = scm_string (SCM_EOL); - } - } - | LYRIC_MARKUP_IDENTIFIER + | embedded_scm_bare { if (scm_is_string ($1)) { $$ = $1; @@ -1894,16 +2079,20 @@ simple_string: STRING { scalar: embedded_scm_arg + | SCM_IDENTIFIER | bare_number | FRACTION | lyric_element + | STRING ; scalar_closed: embedded_scm_arg_closed + | SCM_IDENTIFIER | bare_number | FRACTION | lyric_element + | STRING ; @@ -2332,6 +2521,18 @@ gen_text_def: make_simple_markup ($1)); $$ = t->unprotect (); } + | embedded_scm_bare + { + Music *m = unsmob_music ($1); + if (m && m->is_mus_type ("post-event")) + $$ = $1; + else if (Text_interface::is_markup ($1)) { + Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$); + t->set_property ("text", $1); + $$ = t->unprotect (); + } else + parser->parser_error (@1, _ ("not an articulation")); + } ; fingering: @@ -2457,6 +2658,18 @@ bass_number: UNSIGNED { $$ = $1; } | STRING { $$ = $1; } | full_markup { $$ = $1; } + | embedded_scm_bare + { + // as an integer, it needs to be non-negative, and otherwise + // it needs to be suitable as a markup. + if (scm_is_integer ($1) + ? scm_is_true (scm_negative_p ($1)) + : !Text_interface::is_markup ($1)) + { + parser->parser_error (@1, _ ("bass number expected")); + $$ = SCM_INUM0; + } + } ; figured_bass_alteration: @@ -2645,31 +2858,9 @@ lyric_element: | LYRICS_STRING { $$ = $1; } + | LYRIC_ELEMENT ; -lyric_element_arg: - lyric_element - | lyric_element multiplied_duration post_events { - $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2); - if (scm_is_pair ($3)) - unsmob_music ($$)->set_property - ("articulations", scm_reverse_x ($3, SCM_EOL)); - } - | lyric_element post_event post_events { - $$ = MAKE_SYNTAX ("lyric-event", @$, $1, - parser->default_duration_.smobbed_copy ()); - unsmob_music ($$)->set_property - ("articulations", scm_cons ($2, scm_reverse_x ($3, SCM_EOL))); - } - | LYRIC_ELEMENT optional_notemode_duration post_events { - $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2); - if (scm_is_pair ($3)) - unsmob_music ($$)->set_property - ("articulations", scm_reverse_x ($3, SCM_EOL)); - } - ; - - lyric_element_music: lyric_element optional_notemode_duration post_events { $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2); @@ -2837,10 +3028,7 @@ This should be done more dynamically if possible. */ lyric_markup: - LYRIC_MARKUP_IDENTIFIER { - $$ = $1; - } - | LYRIC_MARKUP + LYRIC_MARKUP { parser->lexer_->push_markup_state (); } markup_top { $$ = $3; @@ -2849,10 +3037,7 @@ lyric_markup: ; full_markup_list: - MARKUPLIST_IDENTIFIER { - $$ = $1; - } - | MARKUPLIST + MARKUPLIST { parser->lexer_->push_markup_state (); } markup_list { $$ = $3; @@ -2861,10 +3046,7 @@ full_markup_list: ; full_markup: - MARKUP_IDENTIFIER { - $$ = $1; - } - | MARKUP + MARKUP { parser->lexer_->push_markup_state (); } markup_top { $$ = $3; @@ -2900,10 +3082,7 @@ markup_scm: markup_list: - MARKUPLIST_IDENTIFIER { - $$ = $1; - } - | markup_composed_list { + markup_composed_list { $$ = $1; } | markup_braced_list { @@ -2985,12 +3164,6 @@ simple_markup: STRING { $$ = make_simple_markup ($1); } - | MARKUP_IDENTIFIER { - $$ = $1; - } - | LYRIC_MARKUP_IDENTIFIER { - $$ = $1; - } | SCORE { SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); parser->lexer_->push_note_state (nn); @@ -3094,14 +3267,6 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) *destination = p->self_scm (); p->unprotect (); return OUTPUT_DEF_IDENTIFIER; - } else if (Text_interface::is_markup (sid)) { - *destination = sid; - if (is_lyric_state ()) - return LYRIC_MARKUP_IDENTIFIER; - return MARKUP_IDENTIFIER; - } else if (Text_interface::is_markup_list (sid)) { - *destination = sid; - return MARKUPLIST_IDENTIFIER; } return -1; @@ -3146,23 +3311,42 @@ SCM loc_on_music (Input loc, SCM arg) return arg; } +SCM +try_string_variants (SCM pred, SCM str) +{ + if (scm_is_true (scm_call_1 (pred, str))) + return str; + if (!is_regular_identifier (str)) + return SCM_UNDEFINED; + str = scm_string_to_symbol (str); + if (scm_is_true (scm_call_1 (pred, str))) + return str; + return SCM_UNDEFINED; +} + bool is_regular_identifier (SCM id) { + if (!scm_is_string (id)) + return false; + string str = ly_scm2string (id); - char const *s = str.c_str (); - bool v = true; -#if 0 - isalpha (*s); - s++; -#endif - while (*s && v) - { - v = v && isalnum (*s); - s++; - } - return v; + bool middle = false; + + for (string::iterator it=str.begin(); it != str.end (); it++) + { + int c = *it & 0xff; + if ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || c > 0x7f) + middle = true; + else if (middle && (c == '-' || c == '_')) + middle = false; + else + return false; + } + return middle; } SCM