X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=23c024e9b7e590c42327b4ab69f972a0e76309ac;hb=cff11827495c69276d36a12dbbc9097f6c5887b2;hp=25b7cd86c3e95f1ec6da4379b9fb6db3575fca6a;hpb=4f73dc31d42627f022d5efc9b241571c0ea1d4cb;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index 25b7cd86c3..23c024e9b7 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -265,6 +265,7 @@ int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser); %token DESCRIPTION "\\description" %token DRUMMODE "\\drummode" %token DRUMS "\\drums" +%token ETC "\\etc" %token FIGUREMODE "\\figuremode" %token FIGURES "\\figures" %token HEADER "\\header" @@ -509,6 +510,7 @@ embedded_scm_bare_arg: $$ = parser->lexer_->eval_scm_token ($1, @1); } | FRACTION + | partial_markup | full_markup_list | context_modification | score_block @@ -691,8 +693,70 @@ identifier_init_nonumber: | FRACTION | string | embedded_scm + | partial_markup | full_markup_list | context_modification + | partial_function ETC + { + $$ = MAKE_SYNTAX (partial_music_function, @$, + scm_reverse_x ($1, SCM_EOL)); + } + ; + +// Partial functions +partial_function: + MUSIC_FUNCTION function_arglist_partial + { + $$ = scm_acons ($1, $2, SCM_EOL); + } + | EVENT_FUNCTION function_arglist_partial + { + $$ = scm_acons ($1, $2, SCM_EOL); + } + | SCM_FUNCTION function_arglist_partial + { + $$ = scm_acons ($1, $2, SCM_EOL); + } + | OVERRIDE grob_prop_path '=' + { + $$ = scm_acons (Lily::property_override, scm_list_1 ($2), SCM_EOL); + } + | SET context_prop_spec '=' + { + $$ = scm_acons (Lily::property_set, scm_list_1 ($2), SCM_EOL); + } + | MUSIC_FUNCTION EXPECT_SCM function_arglist_optional partial_function + { + $$ = scm_acons ($1, $3, $4); + } + | EVENT_FUNCTION EXPECT_SCM function_arglist_optional partial_function + { + $$ = scm_acons ($1, $3, $4); + } + | SCM_FUNCTION EXPECT_SCM function_arglist_optional partial_function + { + $$ = scm_acons ($1, $3, $4); + } + | OVERRIDE grob_prop_path '=' partial_function + { + $$ = scm_acons (Lily::property_override, scm_list_1 ($2), $4); + } + | SET context_prop_spec '=' partial_function + { + $$ = scm_acons (Lily::property_set, scm_list_1 ($2), $4); + } + | MUSIC_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function + { + $$ = scm_acons ($1, $4, $5); + } + | EVENT_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function + { + $$ = scm_acons ($1, $4, $5); + } + | SCM_FUNCTION EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup partial_function + { + $$ = scm_acons ($1, $4, $5); + } ; context_def_spec_block: @@ -2004,6 +2068,56 @@ function_arglist_skip_nonbackup: } ; +// Partial function arglists are returned just in their incomplete +// state: when combined with the music function, the missing parts of +// the signature can be reconstructed +// +// To serve as a partial arglist, the argument list must absolutely +// _not_ be in "skipping optional arguments" mode since then there is +// some backup token that has nowhere to go before \etc. +// +// So we can skim off an arbitrary number of arguments from the end of +// the argument list. The argument list remaining afterwards has to +// be in not-skipping-optional-arguments mode. + +function_arglist_partial: + EXPECT_SCM function_arglist_optional + { + $$ = $2; + } + | EXPECT_SCM function_arglist_partial_optional + { + $$ = $2; + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup + { + $$ = $3; + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial + { + $$ = $3; + } + ; + +function_arglist_partial_optional: + EXPECT_SCM function_arglist_optional + { + $$ = $2; + } + | EXPECT_SCM function_arglist_partial_optional + { + $$ = $2; + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup + { + $$ = $3; + } + | EXPECT_OPTIONAL EXPECT_SCM function_arglist_partial_optional + { + $$ = $3; + } + ; + function_arglist_common: EXPECT_NO_MORE_ARGS { $$ = SCM_EOL; @@ -3509,11 +3623,24 @@ full_markup_list: } ; -full_markup: +markup_mode: MARKUP - { parser->lexer_->push_markup_state (); } - markup_top { - $$ = $3; + { + parser->lexer_->push_markup_state (); + } + ; + +full_markup: + markup_mode markup_top { + $$ = $2; + parser->lexer_->pop_state (); + } + ; + +partial_markup: + markup_mode markup_head_1_list ETC + { + $$ = MAKE_SYNTAX (partial_markup, @2, $2); parser->lexer_->pop_state (); } ;