]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
parser: do not convert $ and @ in code values of %define variables
[bison.git] / src / parse-gram.y
index ebcd31b3a87f001b047a45e6410e5625a2f0f042..9a266251d8111c497380a72d3b380302132d5bda 100644 (file)
@@ -1,4 +1,4 @@
-%{/* Bison Grammar Parser                             -*- C -*-
+/* Bison Grammar Parser                             -*- C -*-
 
    Copyright (C) 2002-2013 Free Software Foundation, Inc.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#include <config.h>
-#include "system.h"
-
-#include "c-ctype.h"
-#include "complain.h"
-#include "conflicts.h"
-#include "files.h"
-#include "getargs.h"
-#include "gram.h"
-#include "named-ref.h"
-#include "quotearg.h"
-#include "reader.h"
-#include "symlist.h"
-#include "symtab.h"
-#include "scan-gram.h"
-#include "scan-code.h"
-#include "xmemdup0.h"
-
-#define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
-static YYLTYPE lloc_default (YYLTYPE const *, int);
-
-#define YY_LOCATION_PRINT(File, Loc) \
-          location_print (Loc, File)
-
-static void version_check (location const *loc, char const *version);
-
-static void gram_error (location const *, char const *);
-
-/* A string that describes a char (e.g., 'a' -> "'a'").  */
-static char const *char_name (char);
-%}
+%code requires
+{
+  #include "symlist.h"
+  #include "symtab.h"
+}
 
 %code
 {
+  #include <config.h>
+  #include "system.h"
+
+  #include "c-ctype.h"
+  #include "complain.h"
+  #include "conflicts.h"
+  #include "files.h"
+  #include "getargs.h"
+  #include "gram.h"
+  #include "named-ref.h"
+  #include "quotearg.h"
+  #include "reader.h"
+  #include "scan-gram.h"
+  #include "scan-code.h"
+  #include "xmemdup0.h"
+
   static int current_prec = 0;
   static location current_lhs_location;
   static named_ref *current_lhs_named_ref;
@@ -61,20 +51,37 @@ static char const *char_name (char);
   /** Set the new current left-hand side symbol, possibly common
    * to several right-hand side parts of rule.
    */
-  static
-  void
-  current_lhs (symbol *sym, location loc, named_ref *ref)
-  {
-    current_lhs_symbol = sym;
-    current_lhs_location = loc;
-    /* In order to simplify memory management, named references for lhs
-       are always assigned by deep copy into the current symbol_list
-       node.  This is because a single named-ref in the grammar may
-       result in several uses when the user factors lhs between several
-       rules using "|".  Therefore free the parser's original copy.  */
-    free (current_lhs_named_ref);
-    current_lhs_named_ref = ref;
-  }
+  static void current_lhs (symbol *sym, location loc, named_ref *ref);
+
+  #define YYLLOC_DEFAULT(Current, Rhs, N)         \
+    (Current) = lloc_default (Rhs, N)
+  static YYLTYPE lloc_default (YYLTYPE const *, int);
+
+  #define YY_LOCATION_PRINT(File, Loc)            \
+    location_print (Loc, File)
+
+  /* Strip initial '{' and final '}' (must be first and last characters).
+     Return the result.  */
+  static char *strip_braces (char *code);
+
+  /* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
+     code_props_symbol_action_init.  Call
+     gram_scanner_last_string_free to release the latest string from
+     the scanner (should be CODE). */
+  static char const *translate_code (char *code, location loc, bool plain);
+
+  /* Convert CODE by calling code_props_plain_init after having
+     stripped the first and last characters (expected to be '{', and
+     '}').  Call gram_scanner_last_string_free to release the latest
+     string from the scanner (should be CODE). */
+  static char const *translate_code_braceless (char *code, location loc);
+
+  static void version_check (location const *loc, char const *version);
+
+  static void gram_error (location const *, char const *);
+
+  /* A string that describes a char (e.g., 'a' -> "'a'").  */
+  static char const *char_name (char);
 
   #define YYTYPE_INT16 int_fast16_t
   #define YYTYPE_INT8 int_fast8_t
@@ -82,7 +89,7 @@ static char const *char_name (char);
   #define YYTYPE_UINT8 uint_fast8_t
 }
 
-%define api.prefix "gram_"
+%define api.prefix {gram_}
 %define api.pure full
 %define locations
 %define parse.error verbose
@@ -171,19 +178,10 @@ static char const *char_name (char);
 %type <character> CHAR
 %printer { fputs (char_name ($$), yyo); } CHAR
 
-/* braceless is not to be used for rule or symbol actions, as it
-   calls code_props_plain_init.  */
-%union
-{
-  char *code;
-  char const *chars;
-};
-%type <chars> STRING "%{...%}" EPILOGUE braceless
-%type <code> "{...}" "%?{...}"
-%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
-         STRING
-%printer { fprintf (yyo, "{\n%s\n}", $$); }
-         braceless "{...}" "%{...%}" EPILOGUE
+%union {char *code;};
+%type <code> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING
+%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } STRING
+%printer { fprintf (yyo, "{\n%s\n}", $$); } <code>
 
 %union {uniqstr uniqstr;}
 %type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
@@ -275,12 +273,8 @@ prologue_declaration:
   grammar_declaration
 | "%{...%}"
     {
-      code_props plain_code;
-      code_props_plain_init (&plain_code, $1, @1);
-      code_props_translate_code (&plain_code);
-      gram_scanner_last_string_free ();
       muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
-                        plain_code.code, @1);
+                        translate_code ($1, @1, true), @1);
       code_scanner_last_string_free ();
     }
 | "%<flag>"
@@ -314,11 +308,7 @@ prologue_declaration:
     }
 | "%initial-action" "{...}"
     {
-      code_props action;
-      code_props_symbol_action_init (&action, $2, @2);
-      code_props_translate_code (&action);
-      gram_scanner_last_string_free ();
-      muscle_code_grow ("initial_action", action.code, @2);
+      muscle_code_grow ("initial_action", translate_code ($2, @2, false), @2);
       code_scanner_last_string_free ();
     }
 | "%language" STRING            { language_argmatch ($2, grammar_prio, @1); }
@@ -395,16 +385,17 @@ grammar_declaration:
     {
       default_prec = false;
     }
-| "%code" braceless
+| "%code" "{...}"
     {
       /* Do not invoke muscle_percent_code_grow here since it invokes
          muscle_user_name_list_grow.  */
-      muscle_code_grow ("percent_code()", $2, @2);
+      muscle_code_grow ("percent_code()",
+                        translate_code_braceless ($2, @2), @2);
       code_scanner_last_string_free ();
     }
-| "%code" ID braceless
+| "%code" ID "{...}"
     {
-      muscle_percent_code_grow ($2, @2, $3, @3);
+      muscle_percent_code_grow ($2, @2, translate_code_braceless ($3, @3), @3);
       code_scanner_last_string_free ();
     }
 ;
@@ -429,10 +420,10 @@ union_name:
 ;
 
 grammar_declaration:
-  "%union" union_name braceless
+  "%union" union_name "{...}"
     {
       union_seen = true;
-      muscle_code_grow ("union_members", $3, @3);
+      muscle_code_grow ("union_members", translate_code_braceless ($3, @3), @3);
       code_scanner_last_string_free ();
     }
 ;
@@ -667,27 +658,10 @@ variable:
 } <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; }
-;
-
-
-/*------------.
-| braceless.  |
-`------------*/
-
-braceless:
-  "{...}"
-    {
-      code_props plain_code;
-      $1[strlen ($1) - 1] = '\0';
-      code_props_plain_init (&plain_code, $1+1, @1);
-      code_props_translate_code (&plain_code);
-      gram_scanner_last_string_free ();
-      $$ = plain_code.code;
-    }
+  %empty  { $$.kind = muscle_keyword; $$.chars = ""; }
+| ID      { $$.kind = muscle_keyword; $$.chars = $1; }
+| STRING  { $$.kind = muscle_string;  $$.chars = $1; }
+| "{...}" { $$.kind = muscle_code;    $$.chars = strip_braces ($1); }
 ;
 
 
@@ -732,11 +706,7 @@ epilogue.opt:
   %empty
 | "%%" EPILOGUE
     {
-      code_props plain_code;
-      code_props_plain_init (&plain_code, $2, @2);
-      code_props_translate_code (&plain_code);
-      gram_scanner_last_string_free ();
-      muscle_code_grow ("epilogue", plain_code.code, @2);
+      muscle_code_grow ("epilogue", translate_code ($2, @2, true), @2);
       code_scanner_last_string_free ();
     }
 ;
@@ -772,6 +742,33 @@ lloc_default (YYLTYPE const *rhs, int n)
   return loc;
 }
 
+static
+char *strip_braces (char *code)
+{
+  code[strlen(code) - 1] = 0;
+  return code + 1;
+}
+
+static
+char const *
+translate_code (char *code, location loc, bool plain)
+{
+  code_props plain_code;
+  if (plain)
+    code_props_plain_init (&plain_code, code, loc);
+  else
+    code_props_symbol_action_init (&plain_code, code, loc);
+  code_props_translate_code (&plain_code);
+  gram_scanner_last_string_free ();
+  return plain_code.code;
+}
+
+static
+char const *
+translate_code_braceless (char *code, location loc)
+{
+  return translate_code (strip_braces (code), loc, true);
+}
 
 static void
 add_param (param_type type, char *decl, location loc)
@@ -854,3 +851,18 @@ char_name (char c)
       return quotearg_style (escape_quoting_style, buf);
     }
 }
+
+static
+void
+current_lhs (symbol *sym, location loc, named_ref *ref)
+{
+  current_lhs_symbol = sym;
+  current_lhs_location = loc;
+  /* In order to simplify memory management, named references for lhs
+     are always assigned by deep copy into the current symbol_list
+     node.  This is because a single named-ref in the grammar may
+     result in several uses when the user factors lhs between several
+     rules using "|".  Therefore free the parser's original copy.  */
+  free (current_lhs_named_ref);
+  current_lhs_named_ref = ref;
+}