X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fparser.yy;h=0c814a13dd7dae08751f28a32efb403c3c853dd5;hb=99b6f3aa3558b01c9d4158b19a1f1794c534f89c;hp=2c5d8312e36ca53502eb1b89458ea6c7883e6b89;hpb=c71d1ea2a0a49f55e397bc99456586e7e0b2fd87;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index 2c5d8312e3..0c814a13dd 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -332,7 +332,6 @@ If we give names, Bison complains. %token BOOK_IDENTIFIER %token CHORD_MODIFIER %token CHORD_REPETITION -%token CONTEXT_DEF_IDENTIFIER %token CONTEXT_MOD_IDENTIFIER %token DRUM_PITCH %token PITCH_IDENTIFIER @@ -449,6 +448,17 @@ toplevel_expression: { SCM proc = parser->lexer_->lookup_identifier ("toplevel-score-handler"); scm_call_2 (proc, parser->self_scm (), $1); + } else if (Output_def * od = unsmob_output_def ($1)) { + SCM id = SCM_EOL; + + if (od->c_variable ("is-paper") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultpaper"); + else if (od->c_variable ("is-midi") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultmidi"); + else if (od->c_variable ("is-layout") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultlayout"); + + parser->lexer_->set_identifier (id, $1); } else if (!scm_is_eq ($1, SCM_UNSPECIFIED)) parser->parser_error (@1, _("bad expression type")); } @@ -675,9 +685,14 @@ identifier_init_nonumber: context_def_spec_block: CONTEXT '{' context_def_spec_body '}' - { + { $$ = $3; - unsmob_context_def ($$)->origin ()->set_spot (@$); + Context_def *td = unsmob_context_def ($$); + if (!td) { + $$ = Context_def::make_scm (); + td = unsmob_context_def ($$); + } + td->origin ()->set_spot (@$); } ; @@ -695,47 +710,54 @@ context_mod_arg: } ; -context_mod_embedded: - context_mod_arg - { - if (unsmob_music ($1)) { - SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler"); - $1 = scm_call_2 (proc, parser->self_scm (), $1); - } - if (unsmob_context_mod ($1)) - $$ = $1; - else { - parser->parser_error (@1, _ ("not a context mod")); - $$ = Context_mod ().smobbed_copy (); - } - } - ; - context_def_spec_body: /**/ { - $$ = Context_def::make_scm (); - } - | CONTEXT_DEF_IDENTIFIER { - $$ = $1; + $$ = SCM_UNSPECIFIED; } | context_def_spec_body context_mod { - if (!SCM_UNBNDP ($2)) + if (!SCM_UNBNDP ($2)) { + Context_def *td = unsmob_context_def ($$); + if (!td) { + $$ = Context_def::make_scm (); + td = unsmob_context_def ($$); + } unsmob_context_def ($$)->add_context_mod ($2); + } } | context_def_spec_body context_modification { Context_def *td = unsmob_context_def ($$); + if (!td) { + $$ = Context_def::make_scm (); + td = unsmob_context_def ($$); + } SCM new_mods = unsmob_context_mod ($2)->get_mods (); for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) { td->add_context_mod (scm_car (m)); } } - | context_def_spec_body context_mod_embedded { - Context_def *td = unsmob_context_def ($$); - SCM new_mods = unsmob_context_mod ($2)->get_mods (); - for (SCM m = new_mods; scm_is_pair (m); m = scm_cdr (m)) { - td->add_context_mod (scm_car (m)); - } + | context_def_spec_body context_mod_arg { + Context_def *td = unsmob_context_def ($1); + if (scm_is_eq ($2, SCM_UNSPECIFIED)) + ; + else if (!td && unsmob_context_def ($2)) + $$ = $2; + else { + if (!td) { + $$ = Context_def::make_scm (); + td = unsmob_context_def ($$); + } + if (unsmob_music ($2)) { + SCM proc = parser->lexer_->lookup_identifier ("context-mod-music-handler"); + $2 = scm_call_2 (proc, parser->self_scm (), $2); + } + if (Context_mod *cm = unsmob_context_mod ($2)) { + for (SCM m = cm->get_mods (); scm_is_pair (m); m = scm_cdr (m)) { + td->add_context_mod (scm_car (m)); + } + } else + parser->parser_error (@2, _ ("not a context mod")); + } } ; @@ -810,6 +832,17 @@ book_body: { SCM proc = parser->lexer_->lookup_identifier ("book-score-handler"); scm_call_2 (proc, $1, $2); + } else if (Output_def *od = unsmob_output_def ($2)) { + SCM id = SCM_EOL; + + if (od->c_variable ("is-paper") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultpaper"); + else if (od->c_variable ("is-midi") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultmidi"); + else if (od->c_variable ("is-layout") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultlayout"); + + parser->lexer_->set_identifier (id, $2); } else if (!scm_is_eq ($2, SCM_UNSPECIFIED)) parser->parser_error (@2, _("bad expression type")); } @@ -880,6 +913,17 @@ bookpart_body: { SCM proc = parser->lexer_->lookup_identifier ("bookpart-score-handler"); scm_call_2 (proc, $1, $2); + } else if (Output_def *od = unsmob_output_def ($2)) { + SCM id = SCM_EOL; + + if (od->c_variable ("is-paper") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultpaper"); + else if (od->c_variable ("is-midi") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultmidi"); + else if (od->c_variable ("is-layout") == SCM_BOOL_T) + id = ly_symbol2scm ("$defaultlayout"); + + parser->lexer_->set_identifier (id, $2); } else if (!scm_is_eq ($2, SCM_UNSPECIFIED)) parser->parser_error (@2, _("bad expression type")); } @@ -904,86 +948,98 @@ score_block: } ; -score_headers: - /* empty */ - { - $$ = SCM_EOL; - } - | score_headers - { - if (!scm_is_pair ($1) - || !ly_is_module (scm_car ($1))) - $1 = scm_cons (ly_make_module (false), $1); - parser->lexer_->add_scope (scm_car ($1)); - } lilypond_header - { - $$ = $1; - } - | score_headers output_def - { - Output_def *od = unsmob_output_def ($2); - if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T) - { - parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead")); - - } - else - { +score_body: + score_items { + if (!unsmob_score ($1)) { + parser->parser_error (@1, _("Missing music in \\score")); + $$ = (new Score)->unprotect (); if (scm_is_pair ($1) && ly_is_module (scm_car ($1))) - scm_set_cdr_x ($1, scm_cons ($2, scm_cdr ($1))); - else - $$ = scm_cons ($2, $1); + { + unsmob_score ($$)->set_header (scm_car ($1)); + $1 = scm_cdr ($1); + } + for (SCM p = scm_reverse_x ($1, SCM_EOL); + scm_is_pair (p); p = scm_cdr (p)) + { + unsmob_score ($$)-> + add_output_def (unsmob_output_def (scm_car (p))); + } } } + | score_body error { + unsmob_score ($$)->error_found_ = true; + } ; - - -score_body: - score_headers music { - SCM scorify = ly_lily_module_constant ("scorify-music"); - $$ = scm_call_2 (scorify, $2, parser->self_scm ()); +score_item: + embedded_scm + | music + | output_def + ; - if (scm_is_pair ($1) && ly_is_module (scm_car ($1))) - { - unsmob_score ($$)->set_header (scm_car ($1)); - $1 = scm_cdr ($1); - } - for (SCM p = scm_reverse_x ($1, SCM_EOL); - scm_is_pair (p); p = scm_cdr (p)) - { - unsmob_score ($$)-> - add_output_def (unsmob_output_def (scm_car (p))); - } - } - | embedded_scm_active { - if (!unsmob_score ($1)) - { - $$ = (new Score)->unprotect (); - parser->parser_error (@1, _("score expected")); - } +score_items: + /* empty */ + { + $$ = SCM_EOL; } - | score_body + | score_items score_item { - Score *score = unsmob_score ($1); - if (!ly_is_module (score->get_header ())) - score->set_header (ly_make_module (false)); - parser->lexer_->add_scope (score->get_header ()); - } lilypond_header - | score_body output_def { - Output_def *od = unsmob_output_def ($2); - if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T) - { - parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead")); - + Output_def *od = unsmob_output_def ($2); + if (od) { + if (od->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T) + { + parser->parser_error (@2, _("\\paper cannot be used in \\score, use \\layout instead")); + od = 0; + $2 = SCM_UNSPECIFIED; + } + } else if (!unsmob_score ($$)) { + if (unsmob_music ($2)) { + SCM scorify = ly_lily_module_constant ("scorify-music"); + $2 = scm_call_2 (scorify, $2, parser->self_scm ()); + } + if (unsmob_score ($2)) + { + $$ = $2; + $2 = SCM_UNSPECIFIED; + } } - else - { - unsmob_score ($1)->add_output_def (od); + Score *score = unsmob_score ($$); + if (score && scm_is_pair ($1)) { + if (ly_is_module (scm_car ($1))) + { + score->set_header (scm_car ($1)); + $1 = scm_cdr ($1); + } + for (SCM p = scm_reverse_x ($1, SCM_EOL); + scm_is_pair (p); p = scm_cdr (p)) + { + score->add_output_def (unsmob_output_def (scm_car (p))); + } } + if (od) { + if (score) + score->add_output_def (od); + else if (scm_is_pair ($$) && ly_is_module (scm_car ($$))) + scm_set_cdr_x ($$, scm_cons ($2, scm_cdr ($$))); + else + $$ = scm_cons ($2, $$); + } else if (!scm_is_eq ($2, SCM_UNSPECIFIED)) + parser->parser_error (@2, _("Spurious expression in \\score")); } - | score_body error { - unsmob_score ($$)->error_found_ = true; + | score_items + { + if (Score *score = unsmob_score ($1)) { + if (!ly_is_module (score->get_header ())) + score->set_header (ly_make_module (false)); + parser->lexer_->add_scope (score->get_header ()); + } else { + if (!scm_is_pair ($1) || !ly_is_module (scm_car ($1))) + $1 = scm_cons (ly_make_module (false), $1); + parser->lexer_->add_scope (scm_car ($1)); + } + } lilypond_header + { + $$ = $1; } ; @@ -1332,9 +1388,19 @@ context_mod_list: if (md) unsmob_context_mod ($1)->add_context_mods (md->get_mods ()); } - | context_mod_list context_mod_embedded { - unsmob_context_mod ($1)->add_context_mods - (unsmob_context_mod ($2)->get_mods ()); + | context_mod_list context_mod_arg { + if (scm_is_eq ($2, SCM_UNSPECIFIED)) + ; + else 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)) + unsmob_context_mod ($$)->add_context_mods + (unsmob_context_mod ($2)->get_mods ()); + else { + parser->parser_error (@2, _ ("not a context mod")); + } } ; @@ -1462,7 +1528,6 @@ function_arglist_nonbackup: $$ = check_scheme_arg (parser, @4, t->unprotect (), $3, $2, n); } - } | EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL { @@ -1739,7 +1804,6 @@ function_arglist_backup: parser->lexer_->push_extra_token (@4, '-'); } } - } | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' REAL { @@ -2016,7 +2080,6 @@ function_arglist_common_reparse: else MYREPARSE (@4, $1, SCM_ARG, $4); } - } | EXPECT_SCM function_arglist_optional '-' REAL { @@ -2058,6 +2121,23 @@ optional_id: } ; +// We must not have lookahead tokens parsed in lyric mode. In order +// to save confusion, we take almost the same set as permitted with +// \lyricmode and/or \lyrics. However, music identifiers are also +// allowed, and they obviously do not require switching into lyrics +// mode for parsing. + +lyric_mode_music: + { + parser->lexer_->push_lyric_state (); + } grouped_music_list + { + parser->lexer_->pop_state (); + $$ = $2; + } + | MUSIC_IDENTIFIER + ; + complex_music: music_function_call | repeated_music { $$ = $1; } @@ -2170,20 +2250,11 @@ mode_changing_head_with_context: ; new_lyrics: - ADDLYRICS { parser->lexer_->push_lyric_state (); } - /*cont */ - composite_music { - /* Can also use music at the expensive of two S/Rs similar to - \repeat \alternative */ - parser->lexer_->pop_state (); - - $$ = scm_cons ($3, SCM_EOL); + ADDLYRICS lyric_mode_music { + $$ = scm_list_1 ($2); } - | new_lyrics ADDLYRICS { - parser->lexer_->push_lyric_state (); - } composite_music { - parser->lexer_->pop_state (); - $$ = scm_cons ($4, $1); + | new_lyrics ADDLYRICS lyric_mode_music { + $$ = scm_cons ($3, $1); } ; @@ -2191,11 +2262,8 @@ re_rhythmed_music: composite_music new_lyrics { $$ = MAKE_SYNTAX ("add-lyrics", @$, $1, scm_reverse_x ($2, SCM_EOL)); } %prec COMPOSITE - | LYRICSTO simple_string { - parser->lexer_->push_lyric_state (); - } music { - parser->lexer_->pop_state (); - $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $4); + | LYRICSTO simple_string lyric_mode_music { + $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $3); } ; @@ -2289,7 +2357,7 @@ revert_arg_part: | revert_arg_backup BACKUP SCM_ARG symbol_list_part { $$ = scm_append_x (scm_list_2 ($4, $3)); - } + } ; context_def_mod: @@ -2573,6 +2641,10 @@ chord_body: { $$ = MAKE_SYNTAX ("event-chord", @$, scm_reverse_x ($2, SCM_EOL)); } + | FIGURE_OPEN figure_list FIGURE_CLOSE + { + $$ = MAKE_SYNTAX ("event-chord", @$, scm_reverse_x ($2, SCM_EOL)); + } ; chord_body_elements: @@ -2722,7 +2794,7 @@ post_event_nofinger: { $$ = $2; unsmob_music ($$)->set_property ("direction", scm_from_int (DOWN)); - } + } ; post_event: @@ -2750,7 +2822,7 @@ direction_less_event: a->set_property ("tremolo-type", $1); $$ = a->unprotect (); } - | event_function_event + | event_function_event ; direction_reqd_event: @@ -2980,12 +3052,16 @@ dots: tremolo_type: ':' { - $$ = SCM_INUM0; + $$ = scm_from_int (parser->default_tremolo_type_); } | ':' UNSIGNED { - if (SCM_UNBNDP (make_duration ($2))) + if (SCM_UNBNDP (make_duration ($2))) { parser->parser_error (@2, _ ("not a duration")); - $$ = $2; + $$ = scm_from_int (parser->default_tremolo_type_); + } else { + $$ = $2; + parser->default_tremolo_type_ = scm_to_int ($2); + } } ; @@ -3085,13 +3161,6 @@ figure_list: } ; -figure_spec: - FIGURE_OPEN figure_list FIGURE_CLOSE { - $$ = scm_reverse_x ($2, SCM_EOL); - } - ; - - optional_rest: /**/ { $$ = SCM_BOOL_F; } | REST { $$ = SCM_BOOL_T; } @@ -3113,20 +3182,20 @@ pitch_or_music: n = MY_MAKE_MUSIC ("RestEvent", @$); else n = MY_MAKE_MUSIC ("NoteEvent", @$); - + n->set_property ("pitch", $1); if (SCM_UNBNDP ($5)) n->set_property ("duration", parser->default_duration_.smobbed_copy ()); else n->set_property ("duration", $5); - + if (scm_is_number ($4)) { int q = scm_to_int ($4); n->set_property ("absolute-octave", scm_from_int (q-1)); } - + if (to_boolean ($3)) n->set_property ("cautionary", SCM_BOOL_T); if (to_boolean ($2) || to_boolean ($3)) @@ -3137,7 +3206,9 @@ pitch_or_music: $$ = n->unprotect (); } } %prec ':' - | simple_chord_elements post_events { + | new_chord post_events { + if (!parser->lexer_->is_chord_state ()) + parser->parser_error (@1, _ ("have to be in Chord mode for chords")); if (scm_is_pair ($2)) { if (unsmob_pitch ($1)) $1 = make_chord_elements (@1, @@ -3177,22 +3248,6 @@ simple_element: } ; -// Can return a single pitch rather than a list. -simple_chord_elements: - new_chord { - if (!parser->lexer_->is_chord_state ()) - parser->parser_error (@1, _ ("have to be in Chord mode for chords")); - $$ = $1; - } - | figure_spec optional_notemode_duration { - for (SCM s = $1; scm_is_pair (s); s = scm_cdr (s)) - { - unsmob_music (scm_car (s))->set_property ("duration", $2); - } - $$ = $1; - } - ; - lyric_element: full_markup { if (!parser->lexer_->is_lyric_state ()) @@ -3441,7 +3496,7 @@ markup_scm: } } BACKUP ; - + markup_list: markup_composed_list { @@ -3465,7 +3520,13 @@ markup_uncomposed_list: SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); parser->lexer_->push_note_state (nn); } '{' score_body '}' { - unsmob_score ($4)->origin ()->set_spot (@$); + Score *sc = unsmob_score ($4); + sc->origin ()->set_spot (@$); + if (sc->defs_.empty ()) { + Output_def *od = get_layout (parser); + sc->add_output_def (od); + od->unprotect (); + } $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $4)); parser->lexer_->pop_state (); } @@ -3542,7 +3603,13 @@ simple_markup: SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); parser->lexer_->push_note_state (nn); } '{' score_body '}' { - unsmob_score ($4)->origin ()->set_spot (@$); + Score *sc = unsmob_score ($4); + sc->origin ()->set_spot (@$); + if (sc->defs_.empty ()) { + Output_def *od = get_layout (parser); + sc->add_output_def (od); + od->unprotect (); + } $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $4); parser->lexer_->pop_state (); } @@ -3604,16 +3671,12 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) } else if (scm_is_number (sid)) { *destination = sid; return NUMBER_IDENTIFIER; - } else if (unsmob_context_def (sid)) { - Context_def *def= unsmob_context_def (sid)->clone (); - - *destination = def->self_scm (); - def->unprotect (); - - return CONTEXT_DEF_IDENTIFIER; + } else if (unsmob_context_def (sid)) + { + *destination = unsmob_context_def (sid)->clone ()->unprotect (); + return SCM_IDENTIFIER; } else if (unsmob_context_mod (sid)) { *destination = unsmob_context_mod (sid)->smobbed_copy (); - return CONTEXT_MOD_IDENTIFIER; } else if (Music *mus = unsmob_music (sid)) { mus = mus->clone ();