lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 08/16] Allow property and grob paths to be constructed from strin


From: David Kastrup
Subject: [PATCH 08/16] Allow property and grob paths to be constructed from strings
Date: Tue, 9 Oct 2012 20:59:53 +0200

---
 lily/parser.yy |  242 ++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 175 insertions(+), 67 deletions(-)

diff --git a/lily/parser.yy b/lily/parser.yy
index 270961f..6a087d8 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -381,6 +381,7 @@ If we give names, Bison complains.
 %token SCM_TOKEN
 %token SCORE_IDENTIFIER
 %token STRING
+%token SYMBOL_LIST
 %token TONICNAME_PITCH
 
 %left '-' '+'
@@ -1158,6 +1159,34 @@ grouped_music_list:
  MUSIC_FUNCTION EXPECT_PITCH EXPECT_SCM EXPECT_SCM EXPECT_NO_MORE_ARGS
 and this rule returns the reversed list of arguments. */
 
+/* Function argument lists come in a number of flavors.  Whenever
+ * LilyPond has to pick between different flavors, the decision is
+ * either made because of tokens it has already seen, or it is
+ * postponed until tokens suitable for making the decision come up.
+ * For postponing decisions, it may be necessary that the competing
+ * rules are written in a way making them compatible until a decision
+ * can be made.  Sometimes this is done by putting common traits into
+ * a separate "common" rule set.
+ *
+ * function_arglist: a full argument list.  Optional arguments at the
+ * end of the list can only be skipped by writing \default in their
+ * place.
+ *
+ * function_arglist_backup: an argument list ending in an optional
+ * argument that may be skipped depending on its predicate.
+ *
+ * function_arglist_skip: an argument list _not_ ending in an optional
+ * argument that is actually taken.
+ *
+ * function_arglist_nonbackup: an argument list ending in an optional
+ * argument that may not be skipped because it is in end position and
+ * has not been shortcircuited with \default.
+ *
+ * function_arglist* / function_arglist_closed*: The closed variants
+ * don't end in simple music expressions that might still accept
+ * things like a duration or a postevent.
+ */
+
 function_arglist_skip:
        function_arglist_common
        | EXPECT_OPTIONAL EXPECT_PITCH function_arglist_skip
@@ -1260,6 +1289,46 @@ function_arglist_closed_nonbackup:
        }
        ;
 
+symbol_list_arg:
+       SYMBOL_LIST
+       | SYMBOL_LIST '.' symbol_list_rev
+       {
+               $$ = scm_append (scm_list_2 ($1, scm_reverse_x ($3, SCM_EOL)));
+       }
+       ;
+
+symbol_list_rev:
+       symbol_list_part
+       | symbol_list_rev '.' symbol_list_part
+       {
+               $$ = scm_append_x (scm_list_2 ($3, $1));
+       }
+       ;
+
+symbol_list_part:
+       symbol_list_element
+       {
+               SCM sym_l_p = ly_lily_module_constant ("symbol-list?");
+               if (scm_is_true (scm_call_1 (sym_l_p, $1)))
+                       $$ = scm_reverse ($1);
+               else {
+                       $$ = try_string_variants (sym_l_p, $1);
+                       if (SCM_UNBNDP ($$)) {
+                               parser->parser_error (@1, _("not a symbol"));
+                               $$ = SCM_EOL;
+                       }
+               }
+       }
+       ;
+
+
+symbol_list_element:
+       STRING
+       | LYRICS_STRING
+       | embedded_scm_bare
+       ;
+
+
 function_arglist_nonbackup:
        function_arglist_nonbackup_common
        | EXPECT_OPTIONAL EXPECT_SCM function_arglist embedded_scm_arg
@@ -1270,14 +1339,6 @@ function_arglist_nonbackup:
        {
                $$ = check_scheme_arg (parser, @4, $4, $3, $2);
        }
-       | 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);
-       }
        | function_arglist_nonbackup_reparse REPARSE SCM_ARG
        {
                $$ = check_scheme_arg (parser, @3, $3, $1, $2);
@@ -1286,6 +1347,10 @@ function_arglist_nonbackup:
        {
                $$ = check_scheme_arg (parser, @3, $3, $1, $2);
        }
+       | function_arglist_nonbackup_reparse REPARSE symbol_list_arg
+       {
+               $$ = check_scheme_arg (parser, @3, $3, $1, $2);
+       }
        ;
 
 function_arglist_nonbackup_reparse:
@@ -1294,7 +1359,10 @@ function_arglist_nonbackup_reparse:
                $$ = $3;
                SCM res = try_string_variants ($2, $4);
                if (!SCM_UNBNDP (res))
-                       MYREPARSE (@4, $2, SCM_ARG, res);
+                       if (scm_is_pair (res))
+                               MYREPARSE (@4, $2, SYMBOL_LIST, res);
+                       else
+                               MYREPARSE (@4, $2, SCM_ARG, res);
                else if (scm_is_true
                         (scm_call_1
                          ($2, make_music_from_simple
@@ -1308,7 +1376,10 @@ function_arglist_nonbackup_reparse:
                $$ = $3;
                SCM res = try_string_variants ($2, $4);
                if (!SCM_UNBNDP (res))
-                       MYREPARSE (@4, $2, SCM_ARG, res);
+                       if (scm_is_pair (res))
+                               MYREPARSE (@4, $2, SYMBOL_LIST, res);
+                       else
+                               MYREPARSE (@4, $2, SCM_ARG, res);
                else if (scm_is_true
                         (scm_call_1
                          ($2, make_music_from_simple
@@ -1317,6 +1388,18 @@ function_arglist_nonbackup_reparse:
                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
        {
                $$ = $3;
@@ -1467,7 +1550,12 @@ function_arglist_backup:
        {
                SCM res = try_string_variants ($2, $4);
                if (!SCM_UNBNDP (res))
-                       $$ = scm_cons (res, $3);
+                       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 (SCM_IDENTIFIER, $4, @4);
@@ -1477,7 +1565,12 @@ function_arglist_backup:
        {
                SCM res = try_string_variants ($2, $4);
                if (!SCM_UNBNDP (res))
-                       $$ = scm_cons (res, $3);
+                       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 (STRING, $4, @4);
@@ -1487,7 +1580,12 @@ function_arglist_backup:
        {
                SCM res = try_string_variants ($2, $4);
                if (!SCM_UNBNDP (res))
-                       $$ = scm_cons (res, $3);
+                       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);
@@ -1503,6 +1601,10 @@ function_arglist_backup:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $1, $2);
        }
+       | function_arglist_backup REPARSE symbol_list_arg
+       {
+               $$ = check_scheme_arg (parser, @3, $3, $1, $2);
+       }
        ;
 
 function_arglist:
@@ -1537,17 +1639,6 @@ function_arglist_common:
                SCM n = scm_difference ($4, SCM_UNDEFINED);
                $$ = check_scheme_arg (parser, @4, n, $2, $1);
        }
-       | EXPECT_SCM function_arglist_optional STRING
-       {
-               SCM res = try_string_variants ($1, $3);
-               if (!SCM_UNBNDP (res))
-                       $$ = scm_cons ($3, $2);
-               else
-                       // This is going to flag a syntax error, we
-                       // know the predicate to be false.
-                       $$ = check_scheme_arg (parser, @3,
-                                              $3, $2, $1);
-       }
        | function_arglist_common_reparse REPARSE SCM_ARG
        {
                $$ = check_scheme_arg (parser, @3,
@@ -1563,6 +1654,10 @@ function_arglist_common:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $1, $2);
        }
+       | function_arglist_common_reparse REPARSE symbol_list_arg
+       {
+               $$ = check_scheme_arg (parser, @3, $3, $1, $2);
+       }
        ;
 
 function_arglist_common_reparse:
@@ -1571,25 +1666,45 @@ function_arglist_common_reparse:
                $$ = $2;
                SCM res = try_string_variants ($1, $3);
                if (!SCM_UNBNDP (res))
-                       MYREPARSE (@3, $1, SCM_ARG, res);
+                       if (scm_is_pair (res))
+                               MYREPARSE (@3, $1, SYMBOL_LIST, res);
+                       else
+                               MYREPARSE (@3, $1, SCM_ARG, res);
                else if (scm_is_true
-                          (scm_call_1
-                           ($1, make_music_from_simple (parser, @3, $3))))
+                        (scm_call_1
+                         ($1, make_music_from_simple (parser, @3, $3))))
                        MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
                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 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);
                if (!SCM_UNBNDP (res))
-                       MYREPARSE (@3, $1, SCM_ARG, res);
+                       if (scm_is_pair (res))
+                               MYREPARSE (@3, $1, SYMBOL_LIST, res);
+                       else
+                               MYREPARSE (@3, $1, SCM_ARG, res);
                else if (scm_is_true
-                          (scm_call_1
-                           ($1, make_music_from_simple (parser, @3, $3))))
+                        (scm_call_1
+                         ($1, make_music_from_simple (parser, @3, $3))))
                        MYREPARSE (@3, $1, LYRIC_ELEMENT, $3);
                else
                        // This is going to flag a syntax error, we
@@ -1599,10 +1714,6 @@ function_arglist_common_reparse:
        | EXPECT_SCM function_arglist_optional lyric_markup
        {
                $$ = $2;
-               // We check how the predicate thinks about the
-               // unmodified lyric element.  If it would be accepted
-               // in this form, we don't try interpreting is as lyric
-               // music.
                if (scm_is_true (scm_call_1 ($1, $3)))
                        MYREPARSE (@3, $1, SCM_ARG, $3);
                else if (scm_is_true
@@ -1672,17 +1783,6 @@ function_arglist_closed_common:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $2, $1);
        }
-       | EXPECT_SCM function_arglist_optional STRING
-       {
-               SCM res = try_string_variants ($1, $3);
-               if (!SCM_UNBNDP (res))
-                       $$ = scm_cons ($3, $2);
-               else
-                       // This is going to flag a syntax error, we
-                       // know the predicate to be false.
-                       $$ = check_scheme_arg (parser, @3,
-                                              $3, $2, $1);
-       }
        | function_arglist_common_reparse REPARSE SCM_ARG
        {
                $$ = check_scheme_arg (parser, @3,
@@ -1693,6 +1793,10 @@ function_arglist_closed_common:
                $$ = check_scheme_arg (parser, @3,
                                       $3, $1, $2);
        }
+       | function_arglist_common_reparse REPARSE symbol_list_arg
+       {
+               $$ = check_scheme_arg (parser, @3, $3, $1, $2);
+       }
        ;
 
 function_arglist_optional:
@@ -1923,19 +2027,13 @@ context_change:
        ;
 
 
-property_path_revved:
-       embedded_scm_closed {
-               $$ = scm_cons ($1, SCM_EOL);
-       }
-       | property_path_revved embedded_scm_closed {
-               $$ = scm_cons ($2, $1);
-       }
-       ;
-
 property_path:
-       property_path_revved  {
+       symbol_list_rev  {
                $$ = scm_reverse_x ($1, SCM_EOL);
        }
+       | symbol_list_rev property_path {
+               $$ = scm_reverse_x ($1, $2);
+       }
        ;
 
 property_operation:
@@ -1994,18 +2092,19 @@ context_mod:
        ;
 
 context_prop_spec:
-       simple_string {
-               if (!is_regular_identifier ($1))
+       symbol_list_rev
+       {
+               switch (scm_to_int (scm_length ($1)))
                {
-                       @$.error (_("Grob name should be alphanumeric"));
+               case 1:
+                       $$ = scm_cons (ly_symbol2scm ("Bottom"), $1);
+                       break;
+               case 2:
+                       $$ = scm_reverse_x ($1, SCM_EOL);
+                       break;
+               default:
+                       @$.error (_("wrong Grob path length"));
                }
-
-               $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
-                       scm_string_to_symbol ($1));
-       }
-       | simple_string '.' simple_string {
-               $$ = scm_list_2 (scm_string_to_symbol ($1),
-                       scm_string_to_symbol ($3));
        }
        ;
 
@@ -3316,9 +3415,18 @@ try_string_variants (SCM pred, SCM str)
 {
        if (scm_is_true (scm_call_1 (pred, str)))
                return str;
-       if (!is_regular_identifier (str))
+       if (scm_is_string (str))
+       {
+               if (!is_regular_identifier (str))
+                       return SCM_UNDEFINED;
+
+               str = scm_string_to_symbol (str);
+               if (scm_is_true (scm_call_1 (pred, str)))
+                       return str;
+       } else if (!scm_is_symbol (str))
                return SCM_UNDEFINED;
-       str = scm_string_to_symbol (str);
+
+       str = scm_list_1 (str);
        if (scm_is_true (scm_call_1 (pred, str)))
                return str;
        return SCM_UNDEFINED;
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]