%token MUSIC_IDENTIFIER
%token NOTENAME_PITCH
%token NUMBER_IDENTIFIER
-%token OUTPUT_DEF_IDENTIFIER
%token REAL
%token RESTNAME
%token SCM_ARG
output_def:
output_def_body '}' {
- $$ = $1;
+ if (scm_is_pair ($1))
+ $$ = scm_car ($1);
parser->lexer_->remove_scope ();
parser->lexer_->pop_state ();
output_def_body:
output_def_head_with_mode_switch '{' {
- $$ = $1;
- unsmob_output_def ($$)->input_origin_.set_spot (@$);
- }
- | output_def_head_with_mode_switch '{' OUTPUT_DEF_IDENTIFIER {
- Output_def *o = unsmob_output_def ($3);
- o->input_origin_.set_spot (@$);
- $$ = o->self_scm ();
- parser->lexer_->remove_scope ();
- parser->lexer_->add_scope (o->scope_);
+ unsmob_output_def ($1)->input_origin_.set_spot (@$);
+ // This is a stupid trick to mark the beginning of the
+ // body for deciding whether to allow
+ // embedded_scm_active to have an output definition
+ $$ = scm_list_1 ($1);
}
| output_def_body assignment {
-
+ if (scm_is_pair ($1))
+ $$ = scm_car ($1);
}
- | output_def_body embedded_scm {
-
+ | output_def_body embedded_scm_active
+ {
+ // We don't switch into note mode for Scheme functions
+ // here. Does not seem warranted/required in output
+ // definitions.
+ if (scm_is_pair ($1))
+ {
+ Output_def *o = unsmob_output_def ($2);
+ if (o) {
+ o->input_origin_.set_spot (@$);
+ $1 = o->self_scm ();
+ parser->lexer_->remove_scope ();
+ parser->lexer_->add_scope (o->scope_);
+ $2 = SCM_UNSPECIFIED;
+ } else
+ $1 = scm_car ($1);
+ }
+ if (unsmob_context_def ($2))
+ assign_context_def (unsmob_output_def ($1), $2);
+ // Seems unlikely, but let's be complete:
+ else if (unsmob_music ($2))
+ {
+ SCM proc = parser->lexer_->lookup_identifier
+ ("output-def-music-handler");
+ scm_call_3 (proc, parser->self_scm (),
+ $1, $2);
+ } else if (!scm_is_eq ($2, SCM_UNSPECIFIED))
+ parser->parser_error (@2, _("bad expression type"));
+ $$ = $1;
+ }
+ | output_def_body SCM_TOKEN {
+ if (scm_is_pair ($1))
+ $$ = scm_car ($1);
+ // Evaluate and ignore #xxx, as opposed to \xxx
+ parser->lexer_->eval_scm_token ($2, @2);
}
| output_def_body
{
+ if (scm_is_pair ($1))
+ $1 = scm_car ($1);
SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
parser->lexer_->push_note_state (nn);
} music_or_context_def
scm_call_3 (proc, parser->self_scm (),
$1, $3);
}
+ $$ = $1;
}
| output_def_body error {
}
;
+// 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);
}
;
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);
+ }
}
;
*destination = unsmob_duration (sid)->smobbed_copy ();
return DURATION_IDENTIFIER;
} else if (unsmob_output_def (sid)) {
- Output_def *p = unsmob_output_def (sid);
- p = p->clone ();
-
- *destination = p->self_scm ();
- p->unprotect ();
- return OUTPUT_DEF_IDENTIFIER;
+ *destination = unsmob_output_def (sid)->clone ()->unprotect ();
+ return SCM_IDENTIFIER;
} else if (unsmob_score (sid)) {
*destination = unsmob_score (sid)->clone ()->unprotect ();
return SCM_IDENTIFIER;