%token BOOK_IDENTIFIER
%token CHORD_MODIFIER
%token CHORD_REPETITION
-%token CONTEXT_DEF_IDENTIFIER
%token CONTEXT_MOD_IDENTIFIER
%token DRUM_PITCH
%token PITCH_IDENTIFIER
{
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"));
}
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 (@$);
}
;
}
;
-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"));
+ }
}
;
{
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"));
}
{
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"));
}
}
;
-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;
}
;
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"));
+ }
}
;
$$ = check_scheme_arg (parser, @4, t->unprotect (),
$3, $2, n);
}
-
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist_nonbackup '-' REAL
{
$$ = scm_cons ($4, $3);
else {
$$ = scm_cons (loc_on_music (@3, $1), $3);
- MYBACKUP (LYRIC_ELEMENT, $4, @4);
+ MYBACKUP (SCM_IDENTIFIER, $4, @4);
}
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup UNSIGNED
parser->lexer_->push_extra_token (@4, '-');
}
}
-
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup '-' REAL
{
else
MYREPARSE (@4, $1, SCM_ARG, $4);
}
-
}
| EXPECT_SCM function_arglist_optional '-' REAL
{
}
;
+// 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; }
;
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);
}
;
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);
}
;
| revert_arg_backup BACKUP SCM_ARG symbol_list_part
{
$$ = scm_append_x (scm_list_2 ($4, $3));
- }
+ }
;
context_def_mod:
{
$$ = 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:
{
$$ = $2;
unsmob_music ($$)->set_property ("direction", scm_from_int (DOWN));
- }
+ }
;
post_event:
a->set_property ("tremolo-type", $1);
$$ = a->unprotect ();
}
- | event_function_event
+ | event_function_event
;
direction_reqd_event:
if (!scm_is_eq (SCM_INUM0, $2))
{
Pitch p = *unsmob_pitch ($1);
- p = p.transposed (Pitch (scm_to_int ($2),0,0));
+ p = p.transposed (Pitch (scm_to_int ($2), 0));
$$ = p.smobbed_copy ();
}
}
if (!scm_is_eq (SCM_INUM0, $2))
{
Pitch p = *unsmob_pitch ($1);
- p = p.transposed (Pitch (scm_to_int ($2),0,0));
+ p = p.transposed (Pitch (scm_to_int ($2), 0));
$$ = p.smobbed_copy ();
}
}
if (!scm_is_eq (SCM_INUM0, $2))
{
Pitch p = *unsmob_pitch ($1);
- p = p.transposed (Pitch (scm_to_int ($2),0,0));
+ p = p.transposed (Pitch (scm_to_int ($2), 0));
$$ = p.smobbed_copy ();
}
}
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);
+ }
}
;
}
;
-figure_spec:
- FIGURE_OPEN figure_list FIGURE_CLOSE {
- $$ = scm_reverse_x ($2, SCM_EOL);
- }
- ;
-
-
optional_rest:
/**/ { $$ = SCM_BOOL_F; }
| REST { $$ = SCM_BOOL_T; }
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))
$$ = 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,
}
;
-// 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 ())
}
} BACKUP
;
-
+
markup_list:
markup_composed_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 ();
}
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 ();
}
} 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 ();