#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);
}
embedded_lilypond:
/* empty */
{
+ // FIXME: @$ does not contain a useful source location
+ // for empty rules, and the only token in the whole
+ // production, EMBEDDED_LILY, is synthetic and also
+ // contains no source location.
$$ = MAKE_SYNTAX ("void-music", @$);
}
| identifier_init
CONTEXT '{' context_def_spec_body '}'
{
$$ = $3;
+ unsmob_context_def ($$)->origin ()->set_spot (@$);
}
;
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:
$$ = $1;
else {
parser->parser_error (@1, _ ("not a context mod"));
+ $$ = Context_mod ().smobbed_copy ();
}
}
;
context_def_spec_body:
/**/ {
$$ = Context_def::make_scm ();
- unsmob_context_def ($$)->origin ()->set_spot (@$);
}
| CONTEXT_DEF_IDENTIFIER {
$$ = $1;
- unsmob_context_def ($$)->origin ()->set_spot (@$);
}
| context_def_spec_body context_mod {
if (!SCM_UNBNDP ($2))
book_block:
BOOK '{' book_body '}' {
$$ = $3;
+ unsmob_book ($$)->origin ()->set_spot (@$);
pop_paper (parser);
parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), SCM_BOOL_F);
}
{
Book *book = new Book;
init_papers (parser);
- book->origin ()->set_spot (@$);
book->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (parser->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
book->paper_->unprotect ();
push_paper (parser, book->paper_);
parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $$);
}
| BOOK_IDENTIFIER {
- unsmob_book ($1)->origin ()->set_spot (@$);
parser->lexer_->set_identifier (ly_symbol2scm ("$current-book"), $1);
}
| book_body paper_block {
bookpart_block:
BOOKPART '{' bookpart_body '}' {
$$ = $3;
+ unsmob_book ($$)->origin ()->set_spot (@$);
parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F);
}
;
bookpart_body:
{
Book *book = new Book;
- book->origin ()->set_spot (@$);
$$ = book->unprotect ();
parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $$);
}
| BOOK_IDENTIFIER {
- unsmob_book ($1)->origin ()->set_spot (@$);
parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), $1);
}
| bookpart_body paper_block {
} '{' context_def_spec_body '}'
{
$$ = $4;
+ unsmob_context_def ($$)->origin ()->set_spot (@$);
}
;
{
$$ = $1;
}
- | WITH embedded_scm_closed
+ | WITH context_modification_arg
{
+ 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))
$$ = $2;
else {
}
;
+context_modification_arg:
+ embedded_scm_closed
+ | MUSIC_IDENTIFIER
+ ;
+
optional_context_mod:
/**/ {
$$ = SCM_EOL;
;
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) {
$$ = $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 {
}
;
+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
;
lyric_element:
full_markup {
+ if (!parser->lexer_->is_lyric_state ())
+ parser->parser_error (@1, _ ("markup outside of text script or \\lyricmode"));
$$ = $1;
}
| STRING {
+ if (!parser->lexer_->is_lyric_state ())
+ parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode"));
$$ = $1;
}
| LYRIC_ELEMENT
lyric_element_music:
lyric_element optional_notemode_duration post_events {
- if (!parser->lexer_->is_lyric_state ())
- parser->parser_error (@1, _ ("have to be in Lyric mode for lyrics"));
$$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
if (scm_is_pair ($3))
unsmob_music ($$)->set_property