X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=fc9aea63be73c95966a31ebe207b12228fdff2bf;hb=288456fe3fe04dd089aa53c2fc2435ddd33b4801;hp=08e3ed7adf25dd424bd4ae5edb1b6e09ccf6930b;hpb=d06ebc90ec926e435ec00f5fb18dec838928df20;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index 08e3ed7adf..fc9aea63be 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -29,9 +29,6 @@ %{ -#define YYDEBUG 1 -#define YYERROR_VERBOSE 1 - #define yyerror Lily_parser::parser_error /* We use custom location type: Input objects */ @@ -44,6 +41,8 @@ %parse-param {Lily_parser *parser} %lex-param {Lily_parser *parser} +%error-verbose +%debug /* We use SCMs to do strings, because it saves us the trouble of deleting them. Let's hope that a stack overflow doesn't trigger a move @@ -405,6 +404,8 @@ If we give names, Bison complains. %type music_bare %type music_arg %type music_assign +%type music_embedded +%type music_or_context_def %type complex_music %type complex_music_prefix %type mode_changed_music @@ -474,7 +475,6 @@ If we give names, Bison complains. %type event_function_event %type figure_list %type figure_spec -%type fraction %type full_markup %type full_markup_list %type function_arglist @@ -496,7 +496,6 @@ If we give names, Bison complains. %type identifier_init %type lilypond %type lilypond_header -%type lilypond_header_body %type lyric_element %type lyric_element_arg %type lyric_element_music @@ -565,7 +564,7 @@ start_symbol: lilypond | EMBEDDED_LILY { SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); - parser->lexer_->push_note_state (alist_to_hashq (nn)); + parser->lexer_->push_note_state (nn); } embedded_lilypond { parser->lexer_->pop_state (); parser->lexer_->set_identifier (ly_symbol2scm ("parseStringResult"), $3); @@ -587,8 +586,10 @@ lilypond: /* empty */ { } toplevel_expression: - lilypond_header { - parser->lexer_->set_identifier (ly_symbol2scm ("$defaultheader"), $1); + { + parser->lexer_->add_scope (get_header (parser)); + } lilypond_header { + parser->lexer_->set_identifier (ly_symbol2scm ("$defaultheader"), $2); } | book_block { Book *book = $1; @@ -641,7 +642,7 @@ toplevel_expression: embedded_scm_bare: SCM_TOKEN { - $$ = parser->lexer_->eval_scm ($1); + $$ = parser->lexer_->eval_scm_token ($1); } | SCM_IDENTIFIER ; @@ -702,9 +703,13 @@ embedded_lilypond: $$ = MAKE_SYNTAX ("void-music", @$); } | identifier_init - | music music music_list { - $$ = MAKE_SYNTAX ("sequential-music", @$, - scm_cons2 ($1, $2, scm_reverse_x ($3, SCM_EOL))); + | music_embedded music_embedded music_list { + $3 = scm_reverse_x ($3, SCM_EOL); + if (unsmob_music ($2)) + $3 = scm_cons ($2, $3); + if (unsmob_music ($1)) + $3 = scm_cons ($1, $3); + $$ = MAKE_SYNTAX ("sequential-music", @$, $3); } | error { parser->error_level_ = 1; @@ -716,10 +721,7 @@ embedded_lilypond: lilypond_header_body: - { - $$ = get_header (parser); - parser->lexer_->add_scope ($$); - } + /* empty */ | lilypond_header_body assignment { } @@ -885,7 +887,7 @@ book_body: $$->paper_ = dynamic_cast (unsmob_output_def (parser->lexer_->lookup_identifier ("$defaultpaper"))->clone ()); $$->paper_->unprotect (); push_paper (parser, $$->paper_); - $$->header_ = parser->lexer_->lookup_identifier ("$defaultheader"); + $$->header_ = get_header (parser); parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$->self_scm ()); } | BOOK_IDENTIFIER { @@ -924,9 +926,10 @@ book_body: SCM proc = parser->lexer_->lookup_identifier ("book-text-handler"); scm_call_2 (proc, $$->self_scm (), $2); } - | book_body lilypond_header { - $$->header_ = $2; - } + | book_body + { + parser->lexer_->add_scope ($1->header_); + } lilypond_header | book_body embedded_scm { } | book_body error { $$->paper_ = 0; @@ -977,9 +980,12 @@ bookpart_body: SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler"); scm_call_2 (proc, $$->self_scm (), $2); } - | bookpart_body lilypond_header { - $$->header_ = $2; - } + | bookpart_body + { + if (!ly_is_module ($1->header_)) + $1->header_ = ly_make_module (false); + parser->lexer_->add_scope ($1->header_); + } lilypond_header | bookpart_body embedded_scm { } | bookpart_body error { $$->paper_ = 0; @@ -1009,9 +1015,12 @@ score_body: $$->protect (); $$->origin ()->set_spot (@$); } - | score_body lilypond_header { - $$->set_header ($2); - } + | score_body + { + if (!ly_is_module ($1->get_header ())) + $1->set_header (ly_make_module (false)); + parser->lexer_->add_scope ($1->get_header ()); + } lilypond_header | score_body output_def { if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T) { @@ -1082,6 +1091,25 @@ output_def_head_with_mode_switch: } ; +// We need this weird nonterminal because both music as well as a +// context definition can start with \context and the difference is +// only apparent after looking at the next token. If it is '{', there +// is still time to escape from notes mode. + +music_or_context_def: + music_arg + { + parser->lexer_->pop_state (); + } + | CONTEXT + { + parser->lexer_->pop_state (); + } '{' context_def_spec_body '}' + { + $$ = $4; + } + ; + output_def_body: output_def_head_with_mode_switch '{' { $$ = $1; @@ -1100,12 +1128,21 @@ output_def_body: | output_def_body assignment { } - | output_def_body context_def_spec_block { - assign_context_def ($$, $2); - } - | output_def_body music_arg { - SCM proc = parser->lexer_->lookup_identifier ("output-def-music-handler"); - scm_call_3 (proc, parser->self_scm (), $1->self_scm (), $2); + | output_def_body + { + SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); + parser->lexer_->push_note_state (nn); + } music_or_context_def + { + if (unsmob_context_def ($3)) + assign_context_def ($$, $3); + else { + + SCM proc = parser->lexer_->lookup_identifier + ("output-def-music-handler"); + scm_call_3 (proc, parser->self_scm (), + $1->self_scm (), $3); + } } | output_def_body error { @@ -1131,11 +1168,9 @@ music_list: /* empty */ { $$ = SCM_EOL; } - | music_list music { - $$ = scm_cons ($2, $1); - } - | music_list embedded_scm { - + | music_list music_embedded { + if (unsmob_music ($2)) + $$ = scm_cons ($2, $1); } | music_list error { Music *m = MY_MAKE_MUSIC("Music", @$); @@ -1157,6 +1192,21 @@ music: music_arg | lyric_element_music ; +music_embedded: + music + | embedded_scm + { + if (unsmob_music ($1) + || scm_is_eq ($1, SCM_UNSPECIFIED)) + $$ = $1; + else + { + @$.warning (_ ("Ignoring non-music expression")); + $$ = SCM_UNSPECIFIED; + } + } + ; + music_arg: simple_music { @@ -1532,11 +1582,6 @@ function_arglist_backup: $$ = check_scheme_arg (parser, @3, $3, $1, $2); } - | function_arglist_backup REPARSE fraction - { - $$ = check_scheme_arg (parser, @3, - $3, $1, $2); - } ; function_arglist: @@ -1556,7 +1601,7 @@ function_arglist_common: $$ = check_scheme_arg (parser, @3, $3, $2, $1); } - | EXPECT_SCM function_arglist_closed_optional fraction + | EXPECT_SCM function_arglist_closed_optional FRACTION { $$ = check_scheme_arg (parser, @3, $3, $2, $1); @@ -1695,7 +1740,7 @@ function_arglist_closed_common: $$ = check_scheme_arg (parser, @3, $3, $2, $1); } - | EXPECT_SCM function_arglist_closed_optional fraction + | EXPECT_SCM function_arglist_closed_optional FRACTION { $$ = check_scheme_arg (parser, @3, $3, $2, $1); @@ -1843,14 +1888,14 @@ mode_changed_music: mode_changing_head: NOTEMODE { SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); - parser->lexer_->push_note_state (alist_to_hashq (nn)); + parser->lexer_->push_note_state (nn); $$ = ly_symbol2scm ("notes"); } | DRUMMODE { SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames"); - parser->lexer_->push_note_state (alist_to_hashq (nn)); + parser->lexer_->push_note_state (nn); $$ = ly_symbol2scm ("drums"); } @@ -1863,7 +1908,7 @@ mode_changing_head: SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers"); parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn); nn = parser->lexer_->lookup_identifier ("pitchnames"); - parser->lexer_->push_chord_state (alist_to_hashq (nn)); + parser->lexer_->push_chord_state (nn); $$ = ly_symbol2scm ("chords"); } @@ -1876,7 +1921,7 @@ mode_changing_head: mode_changing_head_with_context: DRUMS { SCM nn = parser->lexer_->lookup_identifier ("drumPitchNames"); - parser->lexer_->push_note_state (alist_to_hashq (nn)); + parser->lexer_->push_note_state (nn); $$ = ly_symbol2scm ("DrumStaff"); } @@ -1889,7 +1934,7 @@ mode_changing_head_with_context: SCM nn = parser->lexer_->lookup_identifier ("chordmodifiers"); parser->lexer_->chordmodifier_tab_ = alist_to_hashq (nn); nn = parser->lexer_->lookup_identifier ("pitchnames"); - parser->lexer_->push_chord_state (alist_to_hashq (nn)); + parser->lexer_->push_chord_state (nn); $$ = ly_symbol2scm ("ChordNames"); } | LYRICS @@ -2618,13 +2663,6 @@ multiplied_duration: } ; -fraction: - FRACTION { $$ = $1; } - | UNSIGNED '/' UNSIGNED { - $$ = scm_cons ($1, $3); - } - ; - dots: /* empty */ { $$ = 0; @@ -3178,7 +3216,7 @@ simple_markup: } | SCORE { SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); - parser->lexer_->push_note_state (alist_to_hashq (nn)); + parser->lexer_->push_note_state (nn); } '{' score_body '}' { Score * sc = $4; $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), sc->self_scm ());