From: David Kastrup Date: Sat, 27 Aug 2011 20:23:44 +0000 (+0200) Subject: Make #{ #} accept everything an assignment accepts. X-Git-Tag: release/2.15.9-1~5^2~6^2~4 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=d8ee829c73452cc35ef17c6c22abf5b47c754c15;p=lilypond.git Make #{ #} accept everything an assignment accepts. This also makes #{ #} return a void music event, and does not create sequential music if not necessary. --- diff --git a/input/regression/display-lily-tests.ly b/input/regression/display-lily-tests.ly index a62cc103d3..848ff190d8 100644 --- a/input/regression/display-lily-tests.ly +++ b/input/regression/display-lily-tests.ly @@ -17,9 +17,7 @@ (display c out)))))) `(let* ((parser-clone (ly:parser-clone parser)) (input-str (string-trim-both ,lily-string)) - (music (car (ly:music-property (parse-string-result input-str - parser-clone) - 'elements))) + (music (ly:parse-string-expression parser-clone input-str)) (result-str (string-trim-both (music->lily-string music parser-clone)))) (cons input-str result-str)))) diff --git a/lily/include/lily-lexer.hh b/lily/include/lily-lexer.hh index 72391a0877..b87188b401 100644 --- a/lily/include/lily-lexer.hh +++ b/lily/include/lily-lexer.hh @@ -102,6 +102,7 @@ public: SCM lookup_identifier (string s); SCM lookup_identifier_symbol (SCM s); void push_extra_token (int token_type); + void push_embedded_token (); void push_chord_state (SCM tab); void push_figuredbass_state (); void push_lyric_state (); diff --git a/lily/include/lily-parser.hh b/lily/include/lily-parser.hh index 0387e2efd7..9839d38f4d 100644 --- a/lily/include/lily-parser.hh +++ b/lily/include/lily-parser.hh @@ -66,6 +66,7 @@ public: void include_string (string ly_code); void parse_file (string init, string name, string out_name); void parse_string (string ly_code); + SCM parse_string_expression (string ly_code); void parser_error (string); void parser_error (Input const &, string); void set_yydebug (bool); diff --git a/lily/lexer.ll b/lily/lexer.ll index 5743f44964..a9b1d3980e 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -182,6 +182,18 @@ BOM_UTF8 \357\273\277 return type; } +<> { + /* Generate a token without swallowing anything */ + + /* produce requested token */ + int type = extra_token_types_.back (); + extra_token_types_.pop_back (); + if (extra_token_types_.empty ()) + yy_pop_state (); + + return type; +} + /* Use the trailing context feature. Otherwise, the BOM will not be found if the file starts with an identifier definition. */ {BOM_UTF8}/.* { @@ -610,15 +622,14 @@ BOM_UTF8 \357\273\277 } } -<*><> { - if (YY_START == longcomment) - { +<> { LexerError (_ ("EOF found inside a comment").c_str ()); is_main_input_ = false; // should be safe , can't have \include in --safe. if (!close_input ()) yyterminate (); // can't move this, since it actually rets a YY_NULL } - else if (is_main_input_) + +<> { if (is_main_input_) { /* 2 = init.ly + current file. > because we're before closing, but is_main_input_ should @@ -730,6 +741,12 @@ Lily_lexer::push_extra_token (int token_type) extra_token_types_.push_back (token_type); } +void +Lily_lexer::push_embedded_token () +{ + push_extra_token (EMBEDDED_LILY); +} + void Lily_lexer::push_chord_state (SCM tab) { diff --git a/lily/lily-parser-scheme.cc b/lily/lily-parser-scheme.cc index 1107af9995..dc6b652b3d 100644 --- a/lily/lily-parser-scheme.cc +++ b/lily/lily-parser-scheme.cc @@ -207,6 +207,25 @@ LY_DEFINE (ly_parser_parse_string, "ly:parser-parse-string", return SCM_UNSPECIFIED; } +LY_DEFINE (ly_parse_string_expression, "ly:parse-string-expression", + 2, 0, 0, (SCM parser_smob, SCM ly_code), + "Parse the string @var{ly-code} with @var{parser-smob}." +" Return the contained music expression.") +{ + LY_ASSERT_SMOB (Lily_parser, parser_smob, 1); + Lily_parser *parser = unsmob_lily_parser (parser_smob); + LY_ASSERT_TYPE (scm_is_string, ly_code, 2); + + if (!parser->lexer_->is_clean ()) + { + parser->parser_error (_ ("ly:parse-string-expression is only valid with a new parser." + " Use ly:parser-include-string instead.")); + return SCM_UNSPECIFIED; + } + + return parser->parse_string_expression (ly_scm2string (ly_code)); +} + LY_DEFINE (ly_parser_include_string, "ly:parser-include-string", 2, 0, 0, (SCM parser_smob, SCM ly_code), "Include the string @var{ly-code} into the input stream" diff --git a/lily/lily-parser.cc b/lily/lily-parser.cc index ba3bd0f99b..5c1a3d358d 100644 --- a/lily/lily-parser.cc +++ b/lily/lily-parser.cc @@ -163,6 +163,36 @@ Lily_parser::parse_string (string ly_code) error_level_ = error_level_ | lexer_->error_level_; } +SCM +Lily_parser::parse_string_expression (string ly_code) +{ + // TODO: use $parser + lexer_->set_identifier (ly_symbol2scm ("parser"), + self_scm ()); + + lexer_->main_input_name_ = ""; + lexer_->is_main_input_ = true; + lexer_->new_input (lexer_->main_input_name_, ly_code, sources_); + + SCM mod = lexer_->set_current_scope (); + lexer_->push_embedded_token (); + do_yyparse (); + SCM result = lexer_->lookup_identifier_symbol (ly_symbol2scm ("$parseStringResult")); + // $parseStringResult is set in the grammar rule for embedded_lilypond + + scm_set_current_module (mod); + + if (!define_spots_.empty ()) + { + if (define_spots_.empty () + && !error_level_) + programming_error ("define_spots_ don't match, but error_level_ not set."); + } + + error_level_ = error_level_ | lexer_->error_level_; + return result; +} + void Lily_parser::include_string (string ly_code) { diff --git a/lily/parser.yy b/lily/parser.yy index c54adb7575..a744ed7192 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -277,6 +277,9 @@ If we give names, Bison complains. /* After the last argument. */ %token EXPECT_NO_MORE_ARGS; +/* An artificial token for parsing embedded Lilypond */ +%token EMBEDDED_LILY "#{" + %token BOOK_IDENTIFIER %token CHORDMODIFIER_PITCH %token CHORD_MODIFIER @@ -343,6 +346,7 @@ If we give names, Bison complains. %type context_change %type direction_less_event %type direction_reqd_event +%type embedded_lilypond %type event_chord %type gen_text_def %type music_property_def @@ -352,6 +356,7 @@ If we give names, Bison complains. %type relative_music %type simple_element %type simple_music_property_def +%type start_symbol %type string_number_event %type tempo_event @@ -396,6 +401,7 @@ If we give names, Bison complains. %type closed_function_arglist %type open_function_arglist %type identifier_init +%type lilypond %type lilypond_header %type lilypond_header_body %type lyric_element @@ -458,7 +464,18 @@ prec levels in different prods */ %% -lilypond: /* empty */ +start_symbol: + lilypond + | EMBEDDED_LILY { + SCM nn = PARSER->lexer_->lookup_identifier ("pitchnames"); + PARSER->lexer_->push_note_state (alist_to_hashq (nn)); + } embedded_lilypond { + PARSER->lexer_->pop_state (); + PARSER->lexer_->set_identifier (ly_symbol2scm ("$parseStringResult"), $3); + } + ; + +lilypond: /* empty */ { } | lilypond toplevel_expression { } | lilypond assignment { @@ -529,6 +546,21 @@ embedded_scm: | SCM_IDENTIFIER ; +embedded_lilypond: + { $$ = MAKE_SYNTAX ("void-music", @$, SCM_UNDEFINED); } + | identifier_init + | music music music_list { + $$ = MAKE_SYNTAX ("sequential-music", @$, + scm_cons2 ($1, $2, scm_reverse_x ($3, SCM_EOL))); + } + | error { + PARSER->error_level_ = 1; + } + | embedded_lilypond INVALID { + PARSER->error_level_ = 1; + } + ; + lilypond_header_body: { diff --git a/scm/parser-ly-from-scheme.scm b/scm/parser-ly-from-scheme.scm index b86392623f..a17edb63f9 100644 --- a/scm/parser-ly-from-scheme.scm +++ b/scm/parser-ly-from-scheme.scm @@ -28,14 +28,6 @@ (char->integer #\0))))) (string->list (number->string var-idx))))))))) -(define-public (parse-string-result str parser) - "Parse @var{str}, which is supposed to contain a music expression." - - (ly:parser-parse-string - parser - (format #f "parseStringResult = \\notemode { ~a }" str)) - (ly:parser-lookup parser 'parseStringResult)) - (define-public (read-lily-expression chr port) "Read a lilypond music expression enclosed within @code{#@}} and @code{#@}} from @var{port} and return the corresponding Scheme music expression. @@ -93,6 +85,6 @@ symbols. @code{$$} may be used to simply write a @samp{$} character itself." ,@(map (lambda (binding) `(ly:parser-define! parser-clone ',(car binding) ,(cdr binding))) (reverse bindings)) - (parse-string-result ,lily-string parser-clone))))) + (ly:parse-string-expression parser-clone ,lily-string))))) (read-hash-extend #\{ read-lily-expression)