]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/parser.yy
Add changes entry for Mike's work on skylines (28f3294954eff1).
[lilypond.git] / lily / parser.yy
index 4eb488a37f53fed2e4a34e3a944b629e3352c49f..cda631865443a1fe04b820d56b223f4658604094 100644 (file)
@@ -194,7 +194,9 @@ while (0)
 
 %{
 
-#define MY_MAKE_MUSIC(x, spot)  make_music_with_input (ly_symbol2scm (x), spot)
+#define MY_MAKE_MUSIC(x, spot) \
+       make_music_with_input (ly_symbol2scm (x), \
+                              parser->lexer_->override_input (spot))
 
 /* ES TODO:
 - Don't use lily module, create a new module instead.
@@ -203,12 +205,12 @@ while (0)
 #define LOWLEVEL_MAKE_SYNTAX(proc, args)       \
   scm_apply_0 (proc, args)
 /* Syntactic Sugar. */
-#define MAKE_SYNTAX(name, location, ...)       \
-  LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (parser->self_scm (), make_input (location) , ##__VA_ARGS__, SCM_UNDEFINED))
+#define MAKE_SYNTAX(name, location, ...)                               \
+       LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (parser->self_scm (), make_input (parser->lexer_->override_input (location)), ##__VA_ARGS__, SCM_UNDEFINED))
 #define START_MAKE_SYNTAX(name, ...)                                   \
        scm_list_n (ly_lily_module_constant (name) , ##__VA_ARGS__, SCM_UNDEFINED)
 #define FINISH_MAKE_SYNTAX(start, location, ...)                       \
-       LOWLEVEL_MAKE_SYNTAX (scm_car (start), scm_cons2 (parser->self_scm (), make_input (location), scm_append_x (scm_list_2 (scm_cdr (start), scm_list_n (__VA_ARGS__, SCM_UNDEFINED)))))
+       LOWLEVEL_MAKE_SYNTAX (scm_car (start), scm_cons2 (parser->self_scm (), make_input (parser->lexer_->override_input (location)), scm_append_x (scm_list_2 (scm_cdr (start), scm_list_n (__VA_ARGS__, SCM_UNDEFINED)))))
 
 SCM get_next_unique_context_id ();
 SCM get_next_unique_lyrics_context_id ();
@@ -224,7 +226,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 arg, SCM args, SCM pred, SCM disp = SCM_UNDEFINED);
 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);
@@ -328,7 +330,6 @@ If we give names, Bison complains.
 %token HYPHEN "--"
 
 %token CHORDMODIFIERS
-%token LYRIC_MARKUP
 %token MULTI_MEASURE_REST
 
 
@@ -362,7 +363,6 @@ If we give names, Bison complains.
 %token EVENT_IDENTIFIER
 %token EVENT_FUNCTION
 %token FRACTION
-%token LYRICS_STRING
 %token LYRIC_ELEMENT
 %token MARKUP_FUNCTION
 %token MARKUP_LIST_FUNCTION
@@ -499,7 +499,6 @@ embedded_scm_bare_arg:
        {
                $$ = parser->lexer_->eval_scm_token ($1);
        }
-       | full_markup
        | full_markup_list
        | context_modification
        | score_block
@@ -575,7 +574,6 @@ lilypond_header:
 */
 assignment_id:
        STRING          { $$ = $1; }
-       | LYRICS_STRING { $$ = $1; }
        ;
 
 assignment:
@@ -598,7 +596,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
@@ -1021,17 +1040,42 @@ music:  music_arg
 
 music_embedded:
        music
-       | embedded_scm
        {
-               if (unsmob_music ($1)
-                   || scm_is_eq ($1, SCM_UNSPECIFIED))
-                       $$ = $1;
-               else
-               {
-                       @$.warning (_ ("Ignoring non-music expression"));
+               if (unsmob_music ($1)->is_mus_type ("post-event")) {
+                       parser->parser_error (@1, _ ("unexpected post-event"));
                        $$ = SCM_UNSPECIFIED;
                }
        }
+       | music_embedded_backup BACKUP SCM_ARG
+       {
+               $$ = $3;
+       }
+       | music_embedded_backup BACKUP lyric_element_music
+       {
+               $$ = $3;
+       }
+       ;
+
+music_embedded_backup:
+       embedded_scm_closed
+       {
+               if (scm_is_eq ($1, SCM_UNSPECIFIED))
+                       MYBACKUP (SCM_ARG, $1, @1);
+               else if (Music *m = unsmob_music ($1)) {
+                       if (m->is_mus_type ("post-event")) {
+                               parser->parser_error
+                                       (@1, _ ("unexpected post-event"));
+                               MYBACKUP (SCM_ARG, SCM_UNSPECIFIED, @1);
+                       } else
+                               MYBACKUP (SCM_ARG, $1, @1);
+               } else if (parser->lexer_->is_lyric_state ()
+                          && Text_interface::is_markup ($1))
+                       MYBACKUP (LYRIC_ELEMENT, $1, @1);
+               else {
+                       @$.warning (_ ("Ignoring non-music expression"));
+                       MYBACKUP (SCM_ARG, SCM_UNSPECIFIED, @1);
+               }
+       }
        ;
 
 music_arg:
@@ -1236,11 +1280,8 @@ function_arglist_nonbackup_common:
                else {
                        Music *t = MY_MAKE_MUSIC ("FingeringEvent", @5);
                        t->set_property ("digit", $5);
-                       $$ = t->unprotect ();
-                       if (scm_is_true (scm_call_1 ($2, $$)))
-                               $$ = scm_cons ($$, $3);
-                       else
-                               $$ = check_scheme_arg (parser, @4, n, $3, $2);
+                       $$ = check_scheme_arg (parser, @4, t->unprotect (),
+                                              $3, $2, n);
                }
                
        }
@@ -1270,29 +1311,17 @@ function_arglist_closed_nonbackup:
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist SCM_IDENTIFIER
        {
-               SCM res = try_string_variants ($2, $4);
-               if (SCM_UNBNDP (res))
-                       $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-               else
-                       $$ = scm_cons (res, $3);
+               $$ = check_scheme_arg (parser, @4,
+                                      try_string_variants ($2, $4),
+                                      $3, $2, $4);
        }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
        {
-               SCM res = try_string_variants ($2, $4);
-               if (SCM_UNBNDP (res))
-                       $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-               else
-                       $$ = scm_cons (res, $3);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING
-       {
-               SCM res = try_string_variants ($2, $4);
-               if (SCM_UNBNDP (res))
-                       $$ = check_scheme_arg (parser, @4, $4, $3, $2);
-               else
-                       $$ = scm_cons (res, $3);
+               $$ = check_scheme_arg (parser, @4,
+                                      try_string_variants ($2, $4),
+                                      $3, $2, $4);
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist full_markup
        {
                $$ = check_scheme_arg (parser, @4, $4, $3, $2);
        }
@@ -1332,7 +1361,6 @@ symbol_list_part:
 
 symbol_list_element:
        STRING
-       | LYRICS_STRING
        | embedded_scm_bare
        ;
 
@@ -1375,11 +1403,11 @@ function_arglist_nonbackup_reparse:
                         (scm_call_1
                          ($2, make_music_from_simple
                           (parser, @4, $4))))
-                       MYREPARSE (@4, $2, LYRICS_STRING, $4);
+                       MYREPARSE (@4, $2, STRING, $4);
                else
                        MYREPARSE (@4, $2, SCM_ARG, $4);
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist LYRICS_STRING
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
        {
                $$ = $3;
                SCM res = try_string_variants ($2, $4);
@@ -1392,23 +1420,11 @@ function_arglist_nonbackup_reparse:
                         (scm_call_1
                          ($2, make_music_from_simple
                           (parser, @4, $4))))
-                       MYREPARSE (@4, $2, LYRICS_STRING, $4);
+                       MYREPARSE (@4, $2, STRING, $4);
                else
                        MYREPARSE (@4, $2, SCM_ARG, $4);
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist STRING
-       {
-               $$ = $3;
-               SCM res = try_string_variants ($2, $4);
-               if (!SCM_UNBNDP (res))
-                       if (scm_is_pair (res))
-                               MYREPARSE (@4, $2, SYMBOL_LIST, res);
-                       else
-                               MYREPARSE (@4, $2, SCM_ARG, res);
-               else
-                       MYREPARSE (@4, $2, SCM_ARG, $4);
-       }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist lyric_markup
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist full_markup
        {
                $$ = $3;
                if (scm_is_true (scm_call_1 ($2, $4)))
@@ -1417,7 +1433,7 @@ function_arglist_nonbackup_reparse:
                         (scm_call_1
                          ($2, make_music_from_simple
                           (parser, @4, $4))))
-                       MYREPARSE (@4, $2, LYRICS_STRING, $4);
+                       MYREPARSE (@4, $2, STRING, $4);
                else
                        MYREPARSE (@4, $2, SCM_ARG, $4);
        }
@@ -1454,7 +1470,7 @@ function_arglist_backup:
                        MYBACKUP (EVENT_IDENTIFIER, $4, @4);
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep lyric_markup
+       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep full_markup
        {
                if (scm_is_true (scm_call_1 ($2, $4)))
                        $$ = scm_cons ($4, $3);
@@ -1584,21 +1600,6 @@ function_arglist_backup:
                        MYBACKUP (STRING, $4, @4);
                }
        }
-       | EXPECT_OPTIONAL EXPECT_SCM function_arglist_keep LYRICS_STRING
-       {
-               SCM res = try_string_variants ($2, $4);
-               if (!SCM_UNBNDP (res))
-                       if (scm_is_pair (res)) {
-                               $$ = $3;
-                               MYREPARSE (@4, $2, SYMBOL_LIST, res);
-                       }
-                       else
-                               $$ = scm_cons (res, $3);
-               else {
-                       $$ = scm_cons (loc_on_music (@3, $1), $3);
-                       MYBACKUP (LYRICS_STRING, $4, @4);
-               }
-       }
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist_backup BACKUP
        {
                $$ = scm_cons ($1, $3);
@@ -1688,20 +1689,6 @@ function_arglist_common_reparse:
                        MYREPARSE (@3, $1, SCM_ARG, $3);
        }
        | EXPECT_SCM function_arglist_optional STRING
-       {
-               $$ = $2;
-               SCM res = try_string_variants ($1, $3);
-               if (!SCM_UNBNDP (res))
-                       if (scm_is_pair (res))
-                               MYREPARSE (@3, $1, SYMBOL_LIST, res);
-                       else
-                               MYREPARSE (@3, $1, SCM_ARG, res);
-               else
-                       // This is going to flag a syntax error, we
-                       // know the predicate to be false.
-                       MYREPARSE (@3, $1, SCM_ARG, $3);
-       }
-       | EXPECT_SCM function_arglist_optional LYRICS_STRING
        {
                $$ = $2;
                SCM res = try_string_variants ($1, $3);
@@ -1719,7 +1706,7 @@ function_arglist_common_reparse:
                        // know the predicate to be false.
                        MYREPARSE (@3, $1, SCM_ARG, $3);
        }
-       | EXPECT_SCM function_arglist_optional lyric_markup
+       | EXPECT_SCM function_arglist_optional full_markup
        {
                $$ = $2;
                if (scm_is_true (scm_call_1 ($1, $3)))
@@ -2065,9 +2052,7 @@ property_operation:
                }
        }
        | REVERT revert_arg {
-               $$ = scm_list_3 (ly_symbol2scm ("pop"),
-                                scm_car ($2),
-                                scm_cdr ($2));
+               $$ = scm_cons (ly_symbol2scm ("pop"), $2);
        }
        ;
 
@@ -2095,6 +2080,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)
@@ -2103,20 +2095,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));
        }               
@@ -2316,9 +2304,6 @@ string:
 simple_string: STRING {
                $$ = $1;
        }
-       | LYRICS_STRING {
-               $$ = $1;
-       }
        | embedded_scm_bare
        {
                if (scm_is_string ($1)) {
@@ -2336,7 +2321,6 @@ scalar:
        | bare_number
        | FRACTION
        | lyric_element
-       | STRING
        ;
 
 scalar_closed:
@@ -2345,7 +2329,6 @@ scalar_closed:
        | bare_number
        | FRACTION
        | lyric_element
-       | STRING
        ;
 
 
@@ -2545,8 +2528,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, $$);
+                       }
+               }
        }
        ;
 
@@ -2556,7 +2553,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);
                }
@@ -2768,12 +2768,6 @@ gen_text_def:
                        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_closed
        {
                Music *m = unsmob_music ($1);
@@ -3105,10 +3099,10 @@ simple_chord_elements:
        ;
 
 lyric_element:
-       lyric_markup {
+       full_markup {
                $$ = $1;
        }
-       | LYRICS_STRING {
+       | STRING {
                $$ = $1;
        }
        | LYRIC_ELEMENT
@@ -3116,6 +3110,8 @@ 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
@@ -3276,19 +3272,6 @@ questions:
         }
        ;
 
-/*
-This should be done more dynamically if possible.
-*/
-
-lyric_markup:
-       LYRIC_MARKUP
-               { parser->lexer_->push_markup_state (); }
-       markup_top {
-               $$ = $3;
-               parser->lexer_->pop_state ();
-       }
-       ;
-
 full_markup_list:
        MARKUPLIST
                { parser->lexer_->push_markup_state (); }
@@ -3308,11 +3291,13 @@ full_markup:
        ;
 
 markup_top:
-       markup_list {
+       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;
@@ -3334,11 +3319,15 @@ markup_scm:
        ;
                        
 
-markup_list:
+simple_markup_list:
        markup_composed_list {
                $$ = $1;
        }
-       | markup_braced_list {
+       | markup_uncomposed_list
+       ;
+
+markup_uncomposed_list:
+       markup_braced_list {
                $$ = $1;
        }
        | markup_command_list {
@@ -3350,10 +3339,28 @@ markup_list:
        }
        ;
 
-markup_composed_list:
-       markup_head_1_list markup_braced_list {
-               $$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
+markup_list:
+       simple_markup_list
+       | markup_score
+       {
+               $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $1));
+       }
+       ;
+
+markup_score:
+       SCORE {
+               SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
+               parser->lexer_->push_note_state (nn);
+       } '{' score_body '}' {
+               $$ = $4;
+               parser->lexer_->pop_state ();
+       }
+       ;
 
+markup_composed_list:
+       markup_head_1_list markup_uncomposed_list {
+               $$ = MAKE_SYNTAX ("composed-markup-list",
+                                 @2, $1, $2);
        }
        ;
 
@@ -3368,7 +3375,7 @@ markup_braced_list_body:
        | markup_braced_list_body markup {
                $$ = scm_cons ($2, $1);
        }
-       | markup_braced_list_body markup_list {
+       | markup_braced_list_body simple_markup_list {
                $$ = scm_reverse_x ($2, $1);
        }
        ;
@@ -3417,13 +3424,6 @@ simple_markup:
        STRING {
                $$ = make_simple_markup ($1);
        }
-       | SCORE {
-               SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
-               parser->lexer_->push_note_state (nn);
-       } '{' score_body '}' {
-               $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $4);
-               parser->lexer_->pop_state ();
-       }
        | MARKUP_FUNCTION markup_command_basic_arguments {
                $$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
        }
@@ -3431,12 +3431,17 @@ simple_markup:
        {
                $$ = $2;
        }
+       | markup_score
+       {
+               $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $1);
+       }
        ;
 
 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;
@@ -3495,9 +3500,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 (last_input_));
-
                bool is_event = mus->is_mus_type ("post-event");
                mus->unprotect ();
                return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
@@ -3535,14 +3537,34 @@ get_next_unique_lyrics_context_id ()
        return scm_from_locale_string (s);
 }
 
+// check_scheme_arg checks one argument with a given predicate for use
+// in an argument list and throws a syntax error if it is unusable.
+// The argument is prepended to the argument list in any case.  After
+// throwing a syntax error, the argument list is terminated with #f as
+// its last cdr in order to mark it as uncallable while not losing
+// track of its total length.
+//
+// There are a few special considerations: if optional argument disp
+// is given (otherwise it defaults to SCM_UNDEFINED), it will be used
+// instead of arg in a prospective error message.  This is useful if
+// arg is not the actual argument but rather a transformation of it.
+//
+// If arg itself is SCM_UNDEFINED, the predicate is considered false
+// and an error message using disp is produced unconditionally.
+
 SCM check_scheme_arg (Lily_parser *parser, Input loc,
-                     SCM arg, SCM args, SCM pred)
+                     SCM arg, SCM args, SCM pred, SCM disp)
 {
-       args = scm_cons (arg, args);
-       if (scm_is_true (scm_call_1 (pred, arg)))
-               return args;
+       if (SCM_UNBNDP (arg))
+               args = scm_cons (disp, args);
+       else {
+               args = scm_cons (arg, args);
+               if (scm_is_true (scm_call_1 (pred, arg)))
+                       return args;
+       }
        scm_set_cdr_x (scm_last_pair (args), SCM_EOL);
-       MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred, arg);
+       MAKE_SYNTAX ("argument-error", loc, scm_length (args), pred,
+                    SCM_UNBNDP (disp) ? arg : disp);
        scm_set_cdr_x (scm_last_pair (args), SCM_BOOL_F);
        return args;
 }
@@ -3631,17 +3653,19 @@ 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))
+               if (scm_is_symbol (simple)) {
+                       Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+                       n->set_property ("duration", parser->default_duration_.smobbed_copy ());
                        n->set_property ("drum-type", simple);
-               else if (unsmob_pitch (simple))
+                       return n->unprotect ();
+               }
+               if (unsmob_pitch (simple)) {
+                       Music *n = MY_MAKE_MUSIC ("NoteEvent", loc);
+                       n->set_property ("duration", parser->default_duration_.smobbed_copy ());
                        n->set_property ("pitch", simple);
-               else {
-                       n->unprotect ();
-                       return simple;
+                       return n->unprotect ();
                }
-               return n->unprotect ();
+               return simple;
        } else if (parser->lexer_->is_lyric_state ()) {
                if (Text_interface::is_markup (simple))
                        return MAKE_SYNTAX ("lyric-event", loc, simple,