bison-patches
[Top][All Lists]
Advanced

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

[PATCH 08/11] grammar: record the kind of %define variable values


From: Akim Demaille
Subject: [PATCH 08/11] grammar: record the kind of %define variable values
Date: Thu, 4 Apr 2013 17:36:25 +0200

Provide a means to tell the difference between "keyword" values (e.g.,
%define api.pull both), "string" values (e.g., %define file.name
"foo"), and "code" values (e.g., %define api.namespace {calc}).

Suggested by Joel E. Denny.
http://lists.gnu.org/archive/html/bison-patches/2013-03/msg00016.html

* src/muscle-tab.h, src/muscle-tab.c (muscle_kind, muscle_kind_new)
(muscle_kind_string): New.
(muscle_percent_define_insert): Take the kind as new argument.
Insert it in the muscle table.
Adjust callers.
* src/getargs.c: Adjust callers.
* src/parse-gram.y: Ditto.
(content.opt): Remove, replaced by...
(value): this new non-terminal, whose semantics value is stored
in the new "value" union member.
Provide a printer.
Support values in braces in additions to keyword and string values.

fuse me
---
 src/getargs.c    |  4 +++-
 src/muscle-tab.c | 34 ++++++++++++++++++++++++++++++++--
 src/muscle-tab.h | 20 +++++++++++++++++++-
 src/parse-gram.y | 47 ++++++++++++++++++++++++++++++++++-------------
 4 files changed, 88 insertions(+), 17 deletions(-)

diff --git a/src/getargs.c b/src/getargs.c
index 0254865..e6f9d76 100644
--- a/src/getargs.c
+++ b/src/getargs.c
@@ -582,6 +582,7 @@ getargs (int argc, char *argv[])
           if (value)
             *value++ = 0;
           muscle_percent_define_insert (name, command_line_location (),
+                                        muscle_string,
                                         value ? value : "",
                                         c == 'D' ? MUSCLE_PERCENT_DEFINE_D
                                                  : MUSCLE_PERCENT_DEFINE_F);
@@ -666,7 +667,8 @@ getargs (int argc, char *argv[])
 
       case 't':
         muscle_percent_define_insert ("parse.trace",
-                                      command_line_location (), "",
+                                      command_line_location (),
+                                      muscle_keyword, "",
                                       MUSCLE_PERCENT_DEFINE_D);
         break;
 
diff --git a/src/muscle-tab.c b/src/muscle-tab.c
index 4d5dd0a..10a0a5c 100644
--- a/src/muscle-tab.c
+++ b/src/muscle-tab.c
@@ -28,6 +28,31 @@
 #include "muscle-tab.h"
 #include "quote.h"
 
+muscle_kind
+muscle_kind_new (char const *k)
+{
+  if (STREQ (k, "code"))
+    return muscle_code;
+  else if (STREQ (k, "keyword"))
+    return muscle_keyword;
+  else if (STREQ (k, "string"))
+    return muscle_string;
+  aver (0);
+}
+
+char const *
+muscle_kind_string (muscle_kind k)
+{
+  switch (k)
+    {
+    case muscle_code:    return "code";
+    case muscle_keyword: return "keyword";
+    case muscle_string:  return "string";
+    }
+  aver (0);
+}
+
+
 /* A key-value pair, along with storage that can be reclaimed when
    this pair is no longer needed.  */
 typedef struct
@@ -35,6 +60,7 @@ typedef struct
   char const *key;
   char const *value;
   char *storage;
+  muscle_kind kind;
 } muscle_entry;
 
 /* An obstack used to create some entries.  */
@@ -446,6 +472,7 @@ muscle_percent_variable_update (char const *variable, 
location variable_loc,
 
 void
 muscle_percent_define_insert (char const *var, location variable_loc,
+                              muscle_kind kind,
                               char const *value,
                               muscle_percent_define_how how)
 {
@@ -456,6 +483,8 @@ muscle_percent_define_insert (char const *var, location 
variable_loc,
   char const *syncline_name =
     UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
   char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
+  char const *kind_name =
+    UNIQSTR_CONCAT ("percent_define_kind(", variable, ")");
 
   /* Command-line options are processed before the grammar file.  */
   if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
@@ -481,6 +510,7 @@ muscle_percent_define_insert (char const *var, location 
variable_loc,
   muscle_user_name_list_grow ("percent_define_user_variables", variable,
                               variable_loc);
   MUSCLE_INSERT_INT (how_name, how);
+  MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
  end:
   free (variable);
 }
@@ -497,10 +527,10 @@ muscle_percent_define_ensure (char const *variable, 
location loc,
   /* Don't complain is VARIABLE is already defined, but be sure to set
      its value to VAL.  */
   if (!muscle_find_const (name))
-    muscle_percent_define_insert (variable, loc, val,
+    muscle_percent_define_insert (variable, loc, muscle_keyword, val,
                                   MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
   if (muscle_percent_define_flag_if (variable) != value)
-    muscle_percent_define_insert (variable, loc, val,
+    muscle_percent_define_insert (variable, loc, muscle_keyword, val,
                                   MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
 }
 
diff --git a/src/muscle-tab.h b/src/muscle-tab.h
index 30a7452..af6b615 100644
--- a/src/muscle-tab.h
+++ b/src/muscle-tab.h
@@ -24,12 +24,29 @@
 
 # include "location.h"
 
+/* The kind of value associated to this muscle, depending on the
+   syntax of the value: keyword (no delimiter, e.g., true), string
+   (double quotes, e.g., "foo.h"), or code (braces, e.g., {int}).  */
+typedef enum
+{
+  muscle_code,
+  muscle_keyword,
+  muscle_string
+} muscle_kind;
+
+/* Conversion from string.  */
+muscle_kind muscle_kind_new (char const *k);
+
+/* Conversion to string.  */
+char const *muscle_kind_string (muscle_kind k);
+
+
 /* Create the MUSCLE_TABLE, and initialize it with default values.
    Also set up the MUSCLE_OBSTACK.  */
 void muscle_init (void);
 
 /* Insert (KEY, VALUE).  If KEY already existed, overwrite the
-   previous value.  */
+   previous value.  Otherwise create as a muscle_string type.  */
 void muscle_insert (char const *key, char const *value);
 
 /* Find the value of muscle KEY.  Unlike MUSCLE_FIND, this is always
@@ -124,6 +141,7 @@ typedef enum {
    this as a user occurrence of VARIABLE by invoking
    muscle_user_name_list_grow.  */
 void muscle_percent_define_insert (char const *variable, location variable_loc,
+                                   muscle_kind kind,
                                    char const *value,
                                    muscle_percent_define_how how);
 
diff --git a/src/parse-gram.y b/src/parse-gram.y
index f03069d..b633859 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -26,7 +26,6 @@
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
-#include "muscle-tab.h"
 #include "named-ref.h"
 #include "quotearg.h"
 #include "reader.h"
@@ -179,12 +178,12 @@ static char const *char_name (char);
   char *code;
   char const *chars;
 };
-%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
+%type <chars> STRING "%{...%}" EPILOGUE braceless
 %type <code> "{...}" "%?{...}"
 %printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
          STRING
 %printer { fprintf (yyo, "{\n%s\n}", $$); }
-         braceless content.opt "{...}" "%{...%}" EPILOGUE
+         braceless "{...}" "%{...%}" EPILOGUE
 
 %union {uniqstr uniqstr;}
 %type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
@@ -288,9 +287,9 @@ prologue_declaration:
     {
       muscle_percent_define_ensure ($1, @1, true);
     }
-| "%define" variable content.opt
+| "%define" variable value
     {
-      muscle_percent_define_insert ($2, @2, $3,
+      muscle_percent_define_insert ($2, @2, $3.kind, $3.chars,
                                     MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
     }
 | "%defines"                       { defines_flag = true; }
@@ -301,7 +300,8 @@ prologue_declaration:
     }
 | "%error-verbose"
     {
-      muscle_percent_define_insert ("parse.error", @1, "verbose",
+      muscle_percent_define_insert ("parse.error", @1, muscle_keyword,
+                                    "verbose",
                                     MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
     }
 | "%expect" INT                    { expected_sr_conflicts = $2; }
@@ -634,9 +634,9 @@ named_ref.opt:
 | BRACKETED_ID   { $$ = named_ref_new($1, @1); }
 ;
 
-/*---------------------------.
-| variable and content.opt.  |
-`---------------------------*/
+/*---------------------.
+| variable and value.  |
+`---------------------*/
 
 /* The STRING form of variable is deprecated and is not M4-friendly.
    For example, M4 fails for '%define "[" "value"'.  */
@@ -646,10 +646,31 @@ variable:
 ;
 
 /* Some content or empty by default. */
-content.opt:
-  %empty    { $$ = ""; }
-| ID        { $$ = $1; }
-| STRING    { $$ = $1; }
+%code requires {#include "muscle-tab.h"};
+%union
+{
+  struct
+  {
+    char const *chars;
+    muscle_kind kind;
+  } value;
+};
+%type <value> value;
+%printer
+{
+  switch ($$.kind)
+    {
+    case muscle_code:    fprintf (yyo,  "{%s}",  $$.chars); break;
+    case muscle_keyword: fprintf (yyo,   "%s",   $$.chars); break;
+    case muscle_string:  fprintf (yyo, "\"%s\"", $$.chars); break;
+    }
+} <value>;
+
+value:
+  %empty    { $$.kind = muscle_keyword; $$.chars = ""; }
+| ID        { $$.kind = muscle_keyword; $$.chars = $1; }
+| STRING    { $$.kind = muscle_string;  $$.chars = $1; }
+| braceless { $$.kind = muscle_code;    $$.chars = $1; }
 ;
 
 
-- 
1.8.2




reply via email to

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