]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
Merge branch 'translation' into staging
[lilypond.git] / lily / parser.yy
index 89123a5e5bee635ada7d01d29fffb13efbbbe4b8..a99dffcf3889056a2e4e01d128fd67639acc1bf4 100644 (file)
@@ -157,7 +157,7 @@ using namespace std;
 #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);
 }
@@ -523,6 +523,10 @@ scm_function_call:
 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
@@ -622,12 +626,22 @@ context_def_spec_block:
        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:
@@ -641,6 +655,7 @@ context_mod_embedded:
                        $$ = $1;
                else {
                        parser->parser_error (@1, _ ("not a context mod"));
+                       $$ = Context_mod ().smobbed_copy ();
                }
        }
        ;
@@ -649,11 +664,9 @@ context_mod_embedded:
 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))
@@ -680,6 +693,7 @@ context_def_spec_body:
 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);
        }
@@ -692,7 +706,6 @@ book_body:
        {
                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_);
@@ -701,7 +714,6 @@ book_body:
                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 {
@@ -761,6 +773,7 @@ book_body:
 bookpart_block:
        BOOKPART '{' bookpart_body '}' {
                $$ = $3;
+               unsmob_book ($$)->origin ()->set_spot (@$);
                parser->lexer_->set_identifier (ly_symbol2scm ("$current-bookpart"), SCM_BOOL_F);
        }
        ;
@@ -768,12 +781,10 @@ bookpart_block:
 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 {
@@ -936,16 +947,7 @@ output_def_head_with_mode_switch:
 
 music_or_context_def:
        music_arg
-       {
-               parser->lexer_->pop_state ();
-       }
-       | CONTEXT
-       {
-               parser->lexer_->pop_state ();
-       } '{' context_def_spec_body '}'
-       {
-               $$ = $4;
-       }
+       | context_def_spec_block
        ;
 
 output_def_body:
@@ -972,6 +974,7 @@ output_def_body:
                parser->lexer_->push_note_state (nn);
        } music_or_context_def
        {
+               parser->lexer_->pop_state ();
                if (unsmob_context_def ($3))
                        assign_context_def (unsmob_output_def ($1), $3);
                else {
@@ -1121,7 +1124,11 @@ simple_music:
        ;
 
 context_modification:
-        WITH { parser->lexer_->push_initial_state (); } '{' context_mod_list '}'
+        WITH
+       {
+               SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
+               parser->lexer_->push_note_state (nn);
+       } '{' context_mod_list '}'
         {
                 parser->lexer_->pop_state ();
                 $$ = $4;
@@ -1134,8 +1141,12 @@ context_modification:
         {
                 $$ = $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 {
@@ -1145,6 +1156,11 @@ context_modification:
        }
         ;
 
+context_modification_arg:
+       embedded_scm_closed
+       | MUSIC_IDENTIFIER
+       ;
+
 optional_context_mod:
         /**/ {
             $$ = SCM_EOL;
@@ -1877,14 +1893,14 @@ complex_music:
        ;
 
 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)
@@ -2024,13 +2040,11 @@ property_path:
        ;
 
 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) {
@@ -2280,17 +2294,6 @@ string:
                $$ = $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 {
@@ -2307,20 +2310,61 @@ 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
        ;
 
 
@@ -3000,9 +3044,13 @@ simple_chord_elements:
 
 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
@@ -3010,8 +3058,6 @@ 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