X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fparser.yy;h=13f071a2881286008e95e752b23fa638698ed9f9;hb=c6911c343c9eb17831220c416b5f100670af96e7;hp=e69f9f55175ccf2133824417cc8bb30586292dbd;hpb=2b5668b7afafe5939eb047e351adddf44bc40bb5;p=lilypond.git diff --git a/lily/parser.yy b/lily/parser.yy index e69f9f5517..13f071a288 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1,4 +1,4 @@ -/* -*- mode: c++; c-file-style: "linux" -*- */ +/* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: t -*- */ /* This file is part of LilyPond, the GNU music typesetter. @@ -27,7 +27,7 @@ * inconsistent state of indentation. */ -%code requires { +%{ #define yyerror Lily_parser::parser_error @@ -49,7 +49,7 @@ free (p); \ } while (0) -} +%} %parse-param {Lily_parser *parser} %parse-param {SCM *retval} @@ -225,6 +225,7 @@ 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 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); SCM make_chord_step (SCM step, Rational alter); @@ -232,7 +233,6 @@ SCM make_simple_markup (SCM a); bool is_duration (int t); bool is_regular_identifier (SCM id); int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser); -void set_music_properties (Music *p, SCM a); %} @@ -363,7 +363,6 @@ If we give names, Bison complains. %token FRACTION %token LYRICS_STRING %token LYRIC_ELEMENT -%token LYRIC_MARKUP_IDENTIFIER %token MARKUP_FUNCTION %token MARKUP_LIST_FUNCTION %token MARKUP_IDENTIFIER @@ -380,7 +379,6 @@ If we give names, Bison complains. %token SCM_TOKEN %token SCORE_IDENTIFIER %token STRING -%token STRING_IDENTIFIER %token TONICNAME_PITCH %left '-' '+' @@ -447,6 +445,24 @@ toplevel_expression: SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler"); scm_call_2 (proc, parser->self_scm (), $1); } + | SCM_TOKEN { + // Evaluate and ignore #xxx, as opposed to \xxx + parser->lexer_->eval_scm_token ($1); + } + | embedded_scm_active + { + SCM out = SCM_UNDEFINED; + if (Text_interface::is_markup ($1)) + out = scm_list_1 ($1); + else if (Text_interface::is_markup_list ($1)) + out = $1; + if (scm_is_pair (out)) + { + SCM proc = parser->lexer_->lookup_identifier ("toplevel-text-handler"); + scm_call_2 (proc, parser->self_scm (), out); + } else if (!scm_is_eq ($1, SCM_UNSPECIFIED)) + parser->parser_error (@1, _("bad expression type")); + } | output_def { SCM id = SCM_EOL; Output_def * od = unsmob_output_def ($1); @@ -470,10 +486,14 @@ embedded_scm_bare: | SCM_IDENTIFIER ; +embedded_scm_active: + SCM_IDENTIFIER + | scm_function_call + ; + embedded_scm_bare_arg: embedded_scm_bare | STRING - | STRING_IDENTIFIER | full_markup | full_markup_list | context_modification @@ -533,6 +553,9 @@ lilypond_header_body: /* empty */ { $$ = SCM_UNSPECIFIED; } | lilypond_header_body assignment { + } + | lilypond_header_body embedded_scm { + } ; @@ -560,7 +583,6 @@ assignment: parser->lexer_->set_identifier (path, $4); $$ = SCM_UNSPECIFIED; } - | embedded_scm { $$ = SCM_UNSPECIFIED; } ; @@ -576,7 +598,6 @@ identifier_init: | FRACTION | string | embedded_scm - | full_markup | full_markup_list | context_modification ; @@ -690,11 +711,28 @@ book_body: SCM proc = parser->lexer_->lookup_identifier ("book-text-handler"); scm_call_2 (proc, $1, $2); } + | book_body SCM_TOKEN { + // Evaluate and ignore #xxx, as opposed to \xxx + parser->lexer_->eval_scm_token ($2); + } + | book_body embedded_scm_active + { + SCM out = SCM_UNDEFINED; + if (Text_interface::is_markup ($2)) + out = scm_list_1 ($2); + else if (Text_interface::is_markup_list ($2)) + out = $2; + if (scm_is_pair (out)) + { + SCM proc = parser->lexer_->lookup_identifier ("book-text-handler"); + scm_call_2 (proc, $1, out); + } else if (!scm_is_eq ($2, SCM_UNSPECIFIED)) + parser->parser_error (@2, _("bad expression type")); + } | book_body { parser->lexer_->add_scope (unsmob_book ($1)->header_); } lilypond_header - | book_body embedded_scm { } | book_body error { Book *book = unsmob_book ($1); book->paper_ = 0; @@ -740,6 +778,24 @@ bookpart_body: SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler"); scm_call_2 (proc, $1, $2); } + | bookpart_body SCM_TOKEN { + // Evaluate and ignore #xxx, as opposed to \xxx + parser->lexer_->eval_scm_token ($2); + } + | bookpart_body embedded_scm_active + { + SCM out = SCM_UNDEFINED; + if (Text_interface::is_markup ($2)) + out = scm_list_1 ($2); + else if (Text_interface::is_markup_list ($2)) + out = $2; + if (scm_is_pair (out)) + { + SCM proc = parser->lexer_->lookup_identifier ("bookpart-text-handler"); + scm_call_2 (proc, $1, out); + } else if (!scm_is_eq ($2, SCM_UNSPECIFIED)) + parser->parser_error (@2, _("bad expression type")); + } | bookpart_body { Book *book = unsmob_book ($1); @@ -747,7 +803,6 @@ bookpart_body: book->header_ = ly_make_module (false); parser->lexer_->add_scope (book->header_); } lilypond_header - | bookpart_body embedded_scm { } | bookpart_body error { Book *book = unsmob_book ($1); book->paper_ = 0; @@ -882,6 +937,9 @@ output_def_body: } | output_def_body assignment { + } + | output_def_body embedded_scm { + } | output_def_body { @@ -965,13 +1023,9 @@ music_embedded: music_arg: simple_music { - if (unsmob_pitch ($1)) { - Music *n = MY_MAKE_MUSIC ("NoteEvent", @1); - n->set_property ("pitch", $1); - n->set_property ("duration", - parser->default_duration_.smobbed_copy ()); - $$ = n->unprotect (); - } + $$ = make_music_from_simple (parser, @1, $1); + if (!unsmob_music ($$)) + parser->parser_error (@1, _ ("music expected")); } | composite_music %prec COMPOSITE ; @@ -1082,6 +1136,7 @@ closed_music: { $$ = FINISH_MAKE_SYNTAX ($1, @$, $2); } + | music_function_call_closed ; music_bare: @@ -1858,10 +1913,16 @@ string: STRING { $$ = $1; } - | STRING_IDENTIFIER { - $$ = $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)); } ; @@ -1872,8 +1933,14 @@ simple_string: STRING { | LYRICS_STRING { $$ = $1; } - | STRING_IDENTIFIER { - $$ = $1; + | embedded_scm_bare + { + if (scm_is_string ($1)) { + $$ = $1; + } else { + parser->parser_error (@1, (_ ("simple string expected"))); + $$ = scm_string (SCM_EOL); + } } ; @@ -1896,15 +1963,12 @@ event_chord: simple_element post_events { // Let the rhythmic music iterator sort this mess out. if (scm_is_pair ($2)) { - if (unsmob_pitch ($1)) { - Music *n = MY_MAKE_MUSIC ("NoteEvent", @1); - n->set_property ("pitch", $1); - n->set_property ("duration", - parser->default_duration_.smobbed_copy ()); - $$ = n->unprotect (); - } - unsmob_music ($$)->set_property ("articulations", - scm_reverse_x ($2, SCM_EOL)); + $$ = make_music_from_simple (parser, @1, $1); + if (unsmob_music ($$)) + unsmob_music ($$)->set_property ("articulations", + scm_reverse_x ($2, SCM_EOL)); + else + parser->parser_error (@1, _("music expected")); } } | simple_chord_elements post_events { @@ -2029,7 +2093,7 @@ music_function_chord_body: // with the last argument of the event function or with the expression // for which the function call acts itself as event. -music_function_event: +music_function_call_closed: MUSIC_FUNCTION function_arglist_closed { $$ = MAKE_SYNTAX ("music-function", @$, $1, $2); @@ -2100,7 +2164,7 @@ post_event_nofinger: direction_less_event { $$ = $1; } - | script_dir music_function_event { + | script_dir music_function_call_closed { $$ = $2; if (!SCM_UNBNDP ($1)) { @@ -2308,12 +2372,30 @@ gen_text_def: t->set_property ("text", $1); $$ = t->unprotect (); } - | simple_string { + | STRING { + Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$); + t->set_property ("text", + 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_bare + { + Music *m = unsmob_music ($1); + if (m && m->is_mus_type ("post-event")) + $$ = $1; + else if (Text_interface::is_markup ($1)) { + Music *t = MY_MAKE_MUSIC ("TextScriptEvent", @$); + t->set_property ("text", $1); + $$ = t->unprotect (); + } else + parser->parser_error (@1, _ ("not an articulation")); + } ; fingering: @@ -2439,6 +2521,18 @@ bass_number: UNSIGNED { $$ = $1; } | STRING { $$ = $1; } | full_markup { $$ = $1; } + | embedded_scm_bare + { + // as an integer, it needs to be non-negative, and otherwise + // it needs to be suitable as a markup. + if (scm_is_integer ($1) + ? scm_is_true (scm_negative_p ($1)) + : !Text_interface::is_markup ($1)) + { + parser->parser_error (@1, _ ("bass number expected")); + $$ = SCM_INUM0; + } + } ; figured_bass_alteration: @@ -2819,10 +2913,7 @@ This should be done more dynamically if possible. */ lyric_markup: - LYRIC_MARKUP_IDENTIFIER { - $$ = $1; - } - | LYRIC_MARKUP + LYRIC_MARKUP { parser->lexer_->push_markup_state (); } markup_top { $$ = $3; @@ -2831,10 +2922,7 @@ lyric_markup: ; full_markup_list: - MARKUPLIST_IDENTIFIER { - $$ = $1; - } - | MARKUPLIST + MARKUPLIST { parser->lexer_->push_markup_state (); } markup_list { $$ = $3; @@ -2843,10 +2931,7 @@ full_markup_list: ; full_markup: - MARKUP_IDENTIFIER { - $$ = $1; - } - | MARKUP + MARKUP { parser->lexer_->push_markup_state (); } markup_top { $$ = $3; @@ -2882,10 +2967,7 @@ markup_scm: markup_list: - MARKUPLIST_IDENTIFIER { - $$ = $1; - } - | markup_composed_list { + markup_composed_list { $$ = $1; } | markup_braced_list { @@ -2967,15 +3049,6 @@ simple_markup: STRING { $$ = make_simple_markup ($1); } - | MARKUP_IDENTIFIER { - $$ = $1; - } - | LYRIC_MARKUP_IDENTIFIER { - $$ = $1; - } - | STRING_IDENTIFIER { - $$ = $1; - } | SCORE { SCM nn = parser->lexer_->lookup_identifier ("pitchnames"); parser->lexer_->push_note_state (nn); @@ -3031,10 +3104,7 @@ otherwise, we have to import music classes into the lexer. int Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) { - if (scm_is_string (sid)) { - *destination = sid; - return STRING_IDENTIFIER; - } else if (unsmob_book (sid)) { + if (unsmob_book (sid)) { Book *book = unsmob_book (sid)->clone (); *destination = book->self_scm (); book->unprotect (); @@ -3082,14 +3152,6 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) *destination = p->self_scm (); p->unprotect (); return OUTPUT_DEF_IDENTIFIER; - } else if (Text_interface::is_markup (sid)) { - *destination = sid; - if (is_lyric_state ()) - return LYRIC_MARKUP_IDENTIFIER; - return MARKUP_IDENTIFIER; - } else if (Text_interface::is_markup_list (sid)) { - *destination = sid; - return MARKUPLIST_IDENTIFIER; } return -1; @@ -3153,6 +3215,36 @@ is_regular_identifier (SCM id) return v; } +SCM +make_music_from_simple (Lily_parser *parser, Input loc, SCM simple) +{ + 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)) + n->set_property ("drum-type", simple); + else if (unsmob_pitch (simple)) + n->set_property ("pitch", simple); + else { + n->unprotect (); + return simple; + } + return n->unprotect (); + } else if (parser->lexer_->is_lyric_state ()) { + if (Text_interface::is_markup (simple)) + return MAKE_SYNTAX ("lyric-event", loc, simple, + parser->default_duration_.smobbed_copy ()); + } else if (parser->lexer_->is_chord_state ()) { + if (unsmob_pitch (simple)) + return make_chord_elements (loc, simple, + parser->default_duration_.smobbed_copy (), + SCM_EOL); + } + return simple; +} + Music * make_music_with_input (SCM name, Input where) { @@ -3173,14 +3265,6 @@ is_duration (int t) return t && t == 1 << intlog2 (t); } -void -set_music_properties (Music *p, SCM a) -{ - for (SCM k = a; scm_is_pair (k); k = scm_cdr (k)) - p->set_property (scm_caar (k), scm_cdar (k)); -} - - SCM make_chord_step (SCM step_scm, Rational alter) {