]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
Use double ; in comment (single ; sometimes cause trouble)
[lilypond.git] / lily / parser.yy
index 478d05377540e10033d55fb569792645d35e3612..a1e1a9f080704571d1b9568ea5a91581726c605e 100644 (file)
@@ -113,7 +113,7 @@ or
 
 
 
-%pure_parser
+%pure-parser
 %locations
 
 
@@ -309,16 +309,8 @@ int yylex (YYSTYPE *s, YYLTYPE *loc, Lily_parser *parser);
 %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 "__"
 
 /*
@@ -596,7 +588,28 @@ identifier_init:
        | 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
@@ -614,7 +627,16 @@ context_def_spec_block:
 
 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:
@@ -1025,7 +1047,18 @@ music_embedded:
                        $$ = SCM_UNSPECIFIED;
                }
        }
-       | embedded_scm
+       | 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;
@@ -1036,9 +1069,12 @@ music_embedded:
                                $$ = SCM_UNSPECIFIED;
                        } else
                                $$ = $1;
-               } else {
+               } 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;
                }
        }
        ;
@@ -1850,14 +1886,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)
@@ -1997,13 +2033,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) {
@@ -2045,6 +2079,13 @@ property_operation:
 // \revert Accidental.color
 
 revert_arg:
+       revert_arg_backup BACKUP symbol_list_arg
+       {
+               $$ = $3;
+       }
+       ;
+
+revert_arg_backup:
        revert_arg_part
        {
                if (scm_is_null ($1)
@@ -2053,20 +2094,16 @@ revert_arg:
                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));
        }               
@@ -2250,17 +2287,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 {
@@ -2277,20 +2303,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
        ;
 
 
@@ -2446,40 +2513,10 @@ command_element:
        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;
        }
        ;
@@ -2490,8 +2527,22 @@ post_events:
                $$ = 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, $$);
+                       }
+               }
        }
        ;
 
@@ -2501,7 +2552,10 @@ post_event_nofinger:
        }
        | 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);
                }
@@ -2559,55 +2613,8 @@ string_number_event:
        }
        ;
 
-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;
        }
@@ -2745,8 +2752,8 @@ script_abbreviation:
        | '-'           {
                $$ = scm_from_locale_string ("Dash");
        }
-       | '|'           {
-               $$ = scm_from_locale_string ("Bar");
+       | '!'           {
+               $$ = scm_from_locale_string ("Bang");
        }
        | ANGLE_CLOSE   {
                $$ = scm_from_locale_string ("Larger");
@@ -2903,38 +2910,23 @@ bass_figure:
        }
        | 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");
        }
        ;
 
@@ -3045,9 +3037,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
@@ -3055,8 +3051,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
@@ -3133,7 +3127,7 @@ tempo_range:
        UNSIGNED {
                $$ = $1;
        }
-       | UNSIGNED '~' UNSIGNED {
+       | UNSIGNED '-' UNSIGNED {
                $$ = scm_cons ($1, $3);
        }
        ;
@@ -3239,8 +3233,10 @@ markup_top:
        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;
@@ -3266,7 +3262,11 @@ simple_markup_list:
        markup_composed_list {
                $$ = $1;
        }
-       | markup_braced_list {
+       | markup_uncomposed_list
+       ;
+
+markup_uncomposed_list:
+       markup_braced_list {
                $$ = $1;
        }
        | markup_command_list {
@@ -3297,9 +3297,9 @@ markup_score:
        ;
 
 markup_composed_list:
-       markup_head_1_list markup_braced_list {
-               $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
-
+       markup_head_1_list markup_uncomposed_list {
+               $$ = MAKE_SYNTAX ("composed-markup-list",
+                                 @2, $1, $2);
        }
        ;
 
@@ -3377,9 +3377,10 @@ simple_markup:
        ;
 
 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;
@@ -3438,10 +3439,6 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
        } else if (Music *mus = unsmob_music (sid)) {
                mus = mus->clone ();
                *destination = mus->self_scm ();
-               unsmob_music (*destination)->
-                       set_property ("origin",
-                                     make_input (override_input (last_input_)));
-
                bool is_event = mus->is_mus_type ("post-event");
                mus->unprotect ();
                return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;