-%pure_parser
+%pure-parser
%locations
#include "warn.hh"
void
-Lily_parser::parser_error (Input const *i, Lily_parser *parser, SCM *, string s)
+Lily_parser::parser_error (Input const *i, Lily_parser *parser, SCM *, const string &s)
{
parser->parser_error (*i, s);
}
%{
-#define MY_MAKE_MUSIC(x, spot) make_music_with_input (ly_symbol2scm (x), spot)
+#define MY_MAKE_MUSIC(x, spot) \
+ make_music_with_input (ly_symbol2scm (x), \
+ parser->lexer_->override_input (spot))
/* ES TODO:
- Don't use lily module, create a new module instead.
#define LOWLEVEL_MAKE_SYNTAX(proc, args) \
scm_apply_0 (proc, args)
/* Syntactic Sugar. */
-#define MAKE_SYNTAX(name, location, ...) \
- LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (parser->self_scm (), make_input (location) , ##__VA_ARGS__, SCM_UNDEFINED))
+#define MAKE_SYNTAX(name, location, ...) \
+ LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (parser->self_scm (), make_input (parser->lexer_->override_input (location)), ##__VA_ARGS__, SCM_UNDEFINED))
#define START_MAKE_SYNTAX(name, ...) \
scm_list_n (ly_lily_module_constant (name) , ##__VA_ARGS__, SCM_UNDEFINED)
#define FINISH_MAKE_SYNTAX(start, location, ...) \
- LOWLEVEL_MAKE_SYNTAX (scm_car (start), scm_cons2 (parser->self_scm (), make_input (location), scm_append_x (scm_list_2 (scm_cdr (start), scm_list_n (__VA_ARGS__, SCM_UNDEFINED)))))
+ LOWLEVEL_MAKE_SYNTAX (scm_car (start), scm_cons2 (parser->self_scm (), make_input (parser->lexer_->override_input (location)), scm_append_x (scm_list_2 (scm_cdr (start), scm_list_n (__VA_ARGS__, SCM_UNDEFINED)))))
SCM get_next_unique_context_id ();
SCM get_next_unique_lyrics_context_id ();
static Music *make_music_with_input (SCM name, Input where);
SCM check_scheme_arg (Lily_parser *parser, Input loc,
- SCM arg, SCM args, SCM pred);
+ SCM arg, SCM args, SCM pred, SCM disp = SCM_UNDEFINED);
SCM make_music_from_simple (Lily_parser *parser, Input loc, SCM pitch);
SCM loc_on_music (Input loc, SCM arg);
SCM make_chord_elements (Input loc, SCM pitch, SCM dur, SCM modification_list);
%token DOUBLE_ANGLE_OPEN "<<"
%token DOUBLE_ANGLE_CLOSE ">>"
%token E_BACKSLASH "\\"
-%token E_ANGLE_CLOSE "\\>"
-%token E_CHAR "\\C[haracter]"
-%token E_CLOSE "\\)"
%token E_EXCLAMATION "\\!"
-%token E_BRACKET_OPEN "\\["
-%token E_OPEN "\\("
-%token E_BRACKET_CLOSE "\\]"
-%token E_ANGLE_OPEN "\\<"
%token E_PLUS "\\+"
-%token E_TILDE "\\~"
%token EXTENDER "__"
/*
%token HYPHEN "--"
%token CHORDMODIFIERS
-%token LYRIC_MARKUP
%token MULTI_MEASURE_REST
%token EVENT_IDENTIFIER
%token EVENT_FUNCTION
%token FRACTION
-%token LYRICS_STRING
%token LYRIC_ELEMENT
%token MARKUP_FUNCTION
%token MARKUP_LIST_FUNCTION
{
$$ = parser->lexer_->eval_scm_token ($1);
}
- | full_markup
| full_markup_list
| context_modification
| score_block
*/
assignment_id:
STRING { $$ = $1; }
- | LYRICS_STRING { $$ = $1; }
;
assignment:
| output_def
| context_def_spec_block
| music_assign
- | post_event_nofinger
+ | post_event_nofinger post_events
+ {
+ $$ = scm_reverse_x ($2, SCM_EOL);
+ if (Music *m = unsmob_music ($1))
+ {
+ if (m->is_mus_type ("post-event-wrapper"))
+ $$ = scm_append
+ (scm_list_2 (m->get_property ("elements"),
+ $$));
+ else
+ $$ = scm_cons ($1, $$);
+ }
+ if (scm_is_pair ($$)
+ && scm_is_null (scm_cdr ($$)))
+ $$ = scm_car ($$);
+ else
+ {
+ Music * m = MY_MAKE_MUSIC ("PostEvents", @$);
+ m->set_property ("elements", $$);
+ $$ = m->unprotect ();
+ }
+ }
| number_expression
| FRACTION
| string
context_mod_arg:
embedded_scm
- | composite_music
+ |
+ {
+ SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
+ parser->lexer_->push_note_state (nn);
+ }
+ composite_music
+ {
+ parser->lexer_->pop_state ();
+ $$ = $2;
+ }
;
context_mod_embedded:
music_embedded:
music
- | embedded_scm
{
- if (unsmob_music ($1)
- || scm_is_eq ($1, SCM_UNSPECIFIED))
+ if (unsmob_music ($1)->is_mus_type ("post-event")) {
+ parser->parser_error (@1, _ ("unexpected post-event"));
+ $$ = SCM_UNSPECIFIED;
+ }
+ }
+ | music_embedded_backup
+ {
+ $$ = $1;
+ }
+ | music_embedded_backup BACKUP lyric_element_music
+ {
+ $$ = $3;
+ }
+ ;
+
+music_embedded_backup:
+ embedded_scm
+ {
+ if (scm_is_eq ($1, SCM_UNSPECIFIED))
$$ = $1;
- else
- {
+ else if (Music *m = unsmob_music ($1)) {
+ if (m->is_mus_type ("post-event")) {
+ parser->parser_error
+ (@1, _ ("unexpected post-event"));
+ $$ = SCM_UNSPECIFIED;
+ } else
+ $$ = $1;
+ } else if (parser->lexer_->is_lyric_state ()
+ && Text_interface::is_markup ($1))
+ MYBACKUP (LYRIC_ELEMENT, $1, @1);
+ else {
@$.warning (_ ("Ignoring non-music expression"));
- $$ = SCM_UNSPECIFIED;
+ $$ = $1;
}
}
;
else {
Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
t->set_property ("digit", $5);
- $$ = t->unprotect ();
- if (scm_is_true (scm_call_1 ($2, $$)))
- $$ = scm_cons ($$, $3);
- else
- $$ = check_scheme_arg (parser, @4, n, $3, $2);
+ $$ = check_scheme_arg (parser, @4, t->unprotect (),
+ $3, $2, n);
}
}
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist SCM_IDENTIFIER
{
- SCM res = try_string_variants ($2, $4);
- if (SCM_UNBNDP (res))
- $$ = check_scheme_arg (parser, @4, $4, $3, $2);
- else
- $$ = scm_cons (res, $3);
+ $$ = check_scheme_arg (parser, @4,
+ try_string_variants ($2, $4),
+ $3, $2, $4);
}
| EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
{
- SCM res = try_string_variants ($2, $4);
- if (SCM_UNBNDP (res))
- $$ = check_scheme_arg (parser, @4, $4, $3, $2);
- else
- $$ = scm_cons (res, $3);
- }
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING
- {
- SCM res = try_string_variants ($2, $4);
- if (SCM_UNBNDP (res))
- $$ = check_scheme_arg (parser, @4, $4, $3, $2);
- else
- $$ = scm_cons (res, $3);
+ $$ = check_scheme_arg (parser, @4,
+ try_string_variants ($2, $4),
+ $3, $2, $4);
}
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist full_markup
{
$$ = check_scheme_arg (parser, @4, $4, $3, $2);
}
symbol_list_element:
STRING
- | LYRICS_STRING
| embedded_scm_bare
;
(scm_call_1
($2, make_music_from_simple
(parser, @4, $4))))
- MYREPARSE (@4, $2, LYRICS_STRING, $4);
+ MYREPARSE (@4, $2, STRING, $4);
else
MYREPARSE (@4, $2, SCM_ARG, $4);
}
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
{
$$ = $3;
SCM res = try_string_variants ($2, $4);
(scm_call_1
($2, make_music_from_simple
(parser, @4, $4))))
- MYREPARSE (@4, $2, LYRICS_STRING, $4);
+ MYREPARSE (@4, $2, STRING, $4);
else
MYREPARSE (@4, $2, SCM_ARG, $4);
}
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
- {
- $$ = $3;
- SCM res = try_string_variants ($2, $4);
- if (!SCM_UNBNDP (res))
- if (scm_is_pair (res))
- MYREPARSE (@4, $2, SYMBOL_LIST, res);
- else
- MYREPARSE (@4, $2, SCM_ARG, res);
- else
- MYREPARSE (@4, $2, SCM_ARG, $4);
- }
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist full_markup
{
$$ = $3;
if (scm_is_true (scm_call_1 ($2, $4)))
(scm_call_1
($2, make_music_from_simple
(parser, @4, $4))))
- MYREPARSE (@4, $2, LYRICS_STRING, $4);
+ MYREPARSE (@4, $2, STRING, $4);
else
MYREPARSE (@4, $2, SCM_ARG, $4);
}
MYBACKUP (EVENT_IDENTIFIER, $4, @4);
}
}
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep lyric_markup
+ | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep full_markup
{
if (scm_is_true (scm_call_1 ($2, $4)))
$$ = scm_cons ($4, $3);
MYBACKUP (STRING, $4, @4);
}
}
- | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep LYRICS_STRING
- {
- SCM res = try_string_variants ($2, $4);
- if (!SCM_UNBNDP (res))
- if (scm_is_pair (res)) {
- $$ = $3;
- MYREPARSE (@4, $2, SYMBOL_LIST, res);
- }
- else
- $$ = scm_cons (res, $3);
- else {
- $$ = scm_cons (loc_on_music (@3, $1), $3);
- MYBACKUP (LYRICS_STRING, $4, @4);
- }
- }
| EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup BACKUP
{
$$ = scm_cons ($1, $3);
MYREPARSE (@3, $1, SCM_ARG, $3);
}
| EXPECT_SCM function_arglist_optional STRING
- {
- $$ = $2;
- SCM res = try_string_variants ($1, $3);
- if (!SCM_UNBNDP (res))
- if (scm_is_pair (res))
- MYREPARSE (@3, $1, SYMBOL_LIST, res);
- else
- MYREPARSE (@3, $1, SCM_ARG, res);
- else
- // This is going to flag a syntax error, we
- // know the predicate to be false.
- MYREPARSE (@3, $1, SCM_ARG, $3);
- }
- | EXPECT_SCM function_arglist_optional LYRICS_STRING
{
$$ = $2;
SCM res = try_string_variants ($1, $3);
// know the predicate to be false.
MYREPARSE (@3, $1, SCM_ARG, $3);
}
- | EXPECT_SCM function_arglist_optional lyric_markup
+ | EXPECT_SCM function_arglist_optional full_markup
{
$$ = $2;
if (scm_is_true (scm_call_1 ($1, $3)))
;
complex_music_prefix:
- CONTEXT simple_string optional_id optional_context_mod {
+ CONTEXT symbol optional_id optional_context_mod {
Context_mod *ctxmod = unsmob_context_mod ($4);
SCM mods = SCM_EOL;
if (ctxmod)
mods = ctxmod->get_mods ();
$$ = START_MAKE_SYNTAX ("context-specification", $2, $3, mods, SCM_BOOL_F);
}
- | NEWCONTEXT simple_string optional_id optional_context_mod {
+ | NEWCONTEXT symbol optional_id optional_context_mod {
Context_mod *ctxmod = unsmob_context_mod ($4);
SCM mods = SCM_EOL;
if (ctxmod)
;
property_operation:
- STRING '=' scalar {
- $$ = scm_list_3 (ly_symbol2scm ("assign"),
- scm_string_to_symbol ($1), $3);
+ symbol '=' scalar {
+ $$ = scm_list_3 (ly_symbol2scm ("assign"), $1, $3);
}
- | UNSET simple_string {
- $$ = scm_list_2 (ly_symbol2scm ("unset"),
- scm_string_to_symbol ($2));
+ | UNSET symbol {
+ $$ = scm_list_2 (ly_symbol2scm ("unset"), $2);
}
| OVERRIDE property_path '=' scalar {
if (scm_ilength ($2) < 2) {
}
}
| REVERT revert_arg {
- $$ = scm_list_3 (ly_symbol2scm ("pop"),
- scm_car ($2),
- scm_cdr ($2));
+ $$ = scm_cons (ly_symbol2scm ("pop"), $2);
}
;
// \revert Accidental.color
revert_arg:
+ revert_arg_backup BACKUP symbol_list_arg
+ {
+ $$ = $3;
+ }
+ ;
+
+revert_arg_backup:
revert_arg_part
{
if (scm_is_null ($1)
else
MYBACKUP (SYMBOL_LIST, scm_reverse_x ($1, SCM_EOL), @1);
}
- | revert_arg BACKUP symbol_list_arg
- {
- $$ = $3;
- }
;
// revert_arg_part delivers results in reverse
revert_arg_part:
symbol_list_part
- | revert_arg BACKUP SCM_ARG '.' symbol_list_part
+ | revert_arg_backup BACKUP SCM_ARG '.' symbol_list_part
{
$$ = scm_append_x (scm_list_2 ($5, $3));
}
- | revert_arg BACKUP SCM_ARG symbol_list_part
+ | revert_arg_backup BACKUP SCM_ARG symbol_list_part
{
$$ = scm_append_x (scm_list_2 ($4, $3));
}
$$ = $1;
}
| full_markup
- | string '+' string {
- if (!scm_is_string ($1)) {
- parser->parser_error (@1, (_ ("simple string expected")));
- $1 = scm_string (SCM_EOL);
- }
- if (!scm_is_string ($3)) {
- parser->parser_error (@3, (_ ("simple string expected")));
- $3 = scm_string (SCM_EOL);
- }
- $$ = scm_string_append (scm_list_2 ($1, $3));
- }
;
simple_string: STRING {
$$ = $1;
}
- | LYRICS_STRING {
- $$ = $1;
- }
| embedded_scm_bare
{
if (scm_is_string ($1)) {
}
;
+symbol:
+ STRING {
+ $$ = scm_string_to_symbol ($1);
+ }
+ | embedded_scm_bare
+ {
+ // This is a bit of overkill but makes the same
+ // routine responsible for all symbol interpretations.
+ $$ = try_string_variants (ly_lily_module_constant ("symbol?"),
+ $1);
+ if (SCM_UNBNDP ($$))
+ {
+ parser->parser_error (@1, (_ ("symbol expected")));
+ // Generate a unique symbol in case it is used
+ // for an assignment or similar
+ $$ = scm_make_symbol (ly_string2scm ("undefined"));
+ }
+ }
+ ;
+
scalar:
embedded_scm_arg
| SCM_IDENTIFIER
| bare_number
+ // The following is a rather defensive variant of admitting
+ // negative numbers: the grammar would permit number_factor or
+ // even number_expression. However, function arguments allow
+ // only this simple kind of negative number, so to have things
+ // like \tweak and \override behave reasonably similar, it
+ // makes sense to rule out things like -- which are rather an
+ // accent in function argument contexts.
+ | '-' bare_number
+ {
+ $$ = scm_difference ($2, SCM_UNDEFINED);
+ }
| FRACTION
- | lyric_element
| STRING
+ | full_markup
;
scalar_closed:
embedded_scm_arg_closed
| SCM_IDENTIFIER
+ // for scalar_closed to be an actually closed (no lookahead)
+ // expression, we'd need to use bare_number_closed here. It
+ // turns out that the only use of scalar_closed in TEMPO is
+ // not of the kind requiring the full closedness criterion.
| bare_number
+ | '-' bare_number
+ {
+ $$ = scm_difference ($2, SCM_UNDEFINED);
+ }
| FRACTION
- | lyric_element
| STRING
+ | full_markup
;
command_event {
$$ = $1;
}
- | E_BRACKET_OPEN {
- Music *m = MY_MAKE_MUSIC ("LigatureEvent", @$);
- m->set_property ("span-direction", scm_from_int (START));
- $$ = m->unprotect();
- }
- | E_BRACKET_CLOSE {
- Music *m = MY_MAKE_MUSIC ("LigatureEvent", @$);
- m->set_property ("span-direction", scm_from_int (STOP));
- $$ = m->unprotect ();
- }
- | E_BACKSLASH {
- $$ = MAKE_SYNTAX ("voice-separator", @$);
- }
- | '|' {
- SCM pipe = parser->lexer_->lookup_identifier ("pipeSymbol");
-
- Music *m = unsmob_music (pipe);
- if (m)
- {
- m = m->clone ();
- m->set_spot (@$);
- $$ = m->unprotect ();
- }
- else
- $$ = MAKE_SYNTAX ("bar-check", @$);
-
- }
;
command_event:
- E_TILDE {
- $$ = MY_MAKE_MUSIC ("PesOrFlexaEvent", @$)->unprotect ();
- }
- | tempo_event {
+ tempo_event {
$$ = $1;
}
;
$$ = SCM_EOL;
}
| post_events post_event {
- unsmob_music ($2)->set_spot (@2);
- $$ = scm_cons ($2, $$);
+ $$ = $1;
+ if (Music *m = unsmob_music ($2))
+ {
+ if (m->is_mus_type ("post-event-wrapper"))
+ {
+ for (SCM p = m->get_property ("elements");
+ scm_is_pair (p);
+ p = scm_cdr (p))
+ {
+ $$ = scm_cons (scm_car (p), $$);
+ }
+ } else {
+ m->set_spot (@2);
+ $$ = scm_cons ($2, $$);
+ }
+ }
}
;
}
| script_dir music_function_call_closed {
$$ = $2;
- if (!SCM_UNBNDP ($1))
+ if (!unsmob_music ($2)->is_mus_type ("post-event")) {
+ parser->parser_error (@2, _ ("post-event expected"));
+ $$ = SCM_UNSPECIFIED;
+ } else if (!SCM_UNBNDP ($1))
{
unsmob_music ($$)->set_property ("direction", $1);
}
}
;
-direction_less_char:
- '[' {
- $$ = ly_symbol2scm ("bracketOpenSymbol");
- }
- | ']' {
- $$ = ly_symbol2scm ("bracketCloseSymbol");
- }
- | '~' {
- $$ = ly_symbol2scm ("tildeSymbol");
- }
- | '(' {
- $$ = ly_symbol2scm ("parenthesisOpenSymbol");
- }
- | ')' {
- $$ = ly_symbol2scm ("parenthesisCloseSymbol");
- }
- | E_EXCLAMATION {
- $$ = ly_symbol2scm ("escapedExclamationSymbol");
- }
- | E_OPEN {
- $$ = ly_symbol2scm ("escapedParenthesisOpenSymbol");
- }
- | E_CLOSE {
- $$ = ly_symbol2scm ("escapedParenthesisCloseSymbol");
- }
- | E_ANGLE_CLOSE {
- $$ = ly_symbol2scm ("escapedBiggerSymbol");
- }
- | E_ANGLE_OPEN {
- $$ = ly_symbol2scm ("escapedSmallerSymbol");
- }
- ;
-
direction_less_event:
- direction_less_char {
- SCM predefd = parser->lexer_->lookup_identifier_symbol ($1);
- Music *m = 0;
- if (unsmob_music (predefd))
- {
- m = unsmob_music (predefd)->clone ();
- m->set_spot (@$);
- }
- else
- {
- m = MY_MAKE_MUSIC ("Music", @$);
- }
- $$ = m->unprotect ();
- }
- | string_number_event
+ string_number_event
| EVENT_IDENTIFIER {
$$ = $1;
}
make_simple_markup ($1));
$$ = t->unprotect ();
}
- | LYRICS_STRING {
- Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$);
- t->set_property ("text",
- make_simple_markup ($1));
- $$ = t->unprotect ();
- }
| embedded_scm_closed
{
Music *m = unsmob_music ($1);
| '-' {
$$ = scm_from_locale_string ("Dash");
}
- | '|' {
- $$ = scm_from_locale_string ("Bar");
+ | '!' {
+ $$ = scm_from_locale_string ("Bang");
}
| ANGLE_CLOSE {
$$ = scm_from_locale_string ("Larger");
}
| bass_figure figured_bass_modification {
Music *m = unsmob_music ($1);
- if ($2 == ly_symbol2scm ("plus"))
- {
- m->set_property ("augmented", SCM_BOOL_T);
- }
- else if ($2 == ly_symbol2scm ("slash"))
- {
- m->set_property ("diminished", SCM_BOOL_T);
- }
- else if ($2 == ly_symbol2scm ("exclamation"))
- {
- m->set_property ("no-continuation", SCM_BOOL_T);
- }
- else if ($2 == ly_symbol2scm ("backslash"))
- {
- m->set_property ("augmented-slash", SCM_BOOL_T);
- }
+ m->set_property ($2, SCM_BOOL_T);
}
;
figured_bass_modification:
E_PLUS {
- $$ = ly_symbol2scm ("plus");
+ $$ = ly_symbol2scm ("augmented");
}
| E_EXCLAMATION {
- $$ = ly_symbol2scm ("exclamation");
+ $$ = ly_symbol2scm ("no-continuation");
}
| '/' {
- $$ = ly_symbol2scm ("slash");
+ $$ = ly_symbol2scm ("diminished");
}
| E_BACKSLASH {
- $$ = ly_symbol2scm ("backslash");
+ $$ = ly_symbol2scm ("augmented-slash");
}
;
;
lyric_element:
- lyric_markup {
+ full_markup {
+ if (!parser->lexer_->is_lyric_state ())
+ parser->parser_error (@1, _ ("markup outside of text script or \\lyricmode"));
$$ = $1;
}
- | LYRICS_STRING {
+ | STRING {
+ if (!parser->lexer_->is_lyric_state ())
+ parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode"));
$$ = $1;
}
| LYRIC_ELEMENT
UNSIGNED {
$$ = $1;
}
- | UNSIGNED '~' UNSIGNED {
+ | UNSIGNED '-' UNSIGNED {
$$ = scm_cons ($1, $3);
}
;
}
;
-/*
-This should be done more dynamically if possible.
-*/
-
-lyric_markup:
- LYRIC_MARKUP
- { parser->lexer_->push_markup_state (); }
- markup_top {
- $$ = $3;
- parser->lexer_->pop_state ();
- }
- ;
-
full_markup_list:
MARKUPLIST
{ parser->lexer_->push_markup_state (); }
;
markup_top:
- markup_list {
+ simple_markup_list {
$$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
}
- | markup_head_1_list simple_markup {
- $$ = scm_car (scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, scm_list_1 ($2)));
+ | markup_head_1_list simple_markup
+ {
+ $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
+ @2, $1, scm_list_1 ($2)));
}
| simple_markup {
$$ = $1;
;
-markup_list:
+simple_markup_list:
markup_composed_list {
$$ = $1;
}
- | markup_braced_list {
+ | markup_uncomposed_list
+ ;
+
+markup_uncomposed_list:
+ markup_braced_list {
$$ = $1;
}
| markup_command_list {
}
;
-markup_composed_list:
- markup_head_1_list markup_braced_list {
- $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
+markup_list:
+ simple_markup_list
+ | markup_score
+ {
+ $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $1));
+ }
+ ;
+
+markup_score:
+ SCORE {
+ SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
+ parser->lexer_->push_note_state (nn);
+ } '{' score_body '}' {
+ $$ = $4;
+ parser->lexer_->pop_state ();
+ }
+ ;
+markup_composed_list:
+ markup_head_1_list markup_uncomposed_list {
+ $$ = MAKE_SYNTAX ("composed-markup-list",
+ @2, $1, $2);
}
;
| markup_braced_list_body markup {
$$ = scm_cons ($2, $1);
}
- | markup_braced_list_body markup_list {
+ | markup_braced_list_body simple_markup_list {
$$ = scm_reverse_x ($2, $1);
}
;
STRING {
$$ = make_simple_markup ($1);
}
- | SCORE {
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
- } '{' score_body '}' {
- $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $4);
- parser->lexer_->pop_state ();
- }
| MARKUP_FUNCTION markup_command_basic_arguments {
$$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
}
{
$$ = $2;
}
+ | markup_score
+ {
+ $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $1);
+ }
;
markup:
- markup_head_1_list simple_markup {
- SCM mapper = ly_lily_module_constant ("map-markup-command-list");
- $$ = scm_car (scm_call_2 (mapper, $1, scm_list_1 ($2)));
+ markup_head_1_list simple_markup
+ {
+ $$ = scm_car (MAKE_SYNTAX ("composed-markup-list",
+ @2, $1, scm_list_1 ($2)));
}
| simple_markup {
$$ = $1;
} else if (Music *mus = unsmob_music (sid)) {
mus = mus->clone ();
*destination = mus->self_scm ();
- unsmob_music (*destination)->
- set_property ("origin", make_input (last_input_));
-
bool is_event = mus->is_mus_type ("post-event");
mus->unprotect ();
return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
return scm_from_locale_string (s);
}
+// check_scheme_arg checks one argument with a given predicate for use
+// in an argument list and throws a syntax error if it is unusable.
+// The argument is prepended to the argument list in any case. After
+// throwing a syntax error, the argument list is terminated with #f as
+// its last cdr in order to mark it as uncallable while not losing
+// track of its total length.
+//
+// There are a few special considerations: if optional argument disp
+// is given (otherwise it defaults to SCM_UNDEFINED), it will be used
+// instead of arg in a prospective error message. This is useful if
+// arg is not the actual argument but rather a transformation of it.
+//
+// If arg itself is SCM_UNDEFINED, the predicate is considered false
+// and an error message using disp is produced unconditionally.
+
SCM check_scheme_arg (Lily_parser *parser, Input loc,
- SCM arg, SCM args, SCM pred)
+ SCM arg, SCM args, SCM pred, SCM disp)
{
- args = scm_cons (arg, args);
- if (scm_is_true (scm_call_1 (pred, arg)))
- return args;
+ if (SCM_UNBNDP (arg))
+ args = scm_cons (disp, args);
+ else {
+ args = scm_cons (arg, args);
+ if (scm_is_true (scm_call_1 (pred, arg)))
+ return args;
+ }
scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
- MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred, arg);
+ MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred,
+ SCM_UNBNDP (disp) ? arg : disp);
scm_set_cdr_x (scm_last_pair (args), SCM_BOOL_F);
return args;
}
if (unsmob_music (simple))
return simple;
if (parser->lexer_->is_note_state ()) {
- Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
- n->set_property ("duration", parser->default_duration_.smobbed_copy ());
- if (scm_is_symbol (simple))
+ if (scm_is_symbol (simple)) {
+ Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+ n->set_property ("duration", parser->default_duration_.smobbed_copy ());
n->set_property ("drum-type", simple);
- else if (unsmob_pitch (simple))
+ return n->unprotect ();
+ }
+ if (unsmob_pitch (simple)) {
+ Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+ n->set_property ("duration", parser->default_duration_.smobbed_copy ());
n->set_property ("pitch", simple);
- else {
- n->unprotect ();
- return simple;
+ return n->unprotect ();
}
- return n->unprotect ();
+ return simple;
} else if (parser->lexer_->is_lyric_state ()) {
if (Text_interface::is_markup (simple))
return MAKE_SYNTAX ("lyric-event", loc, simple,