Implement %define api.prefix and %name-prefix (nearly the same but not quite)
authorNick Downing <downing.nick@gmail.com>
Sun, 29 Jul 2018 10:32:57 +0000 (20:32 +1000)
committerNick Downing <downing.nick@gmail.com>
Sun, 29 Jul 2018 10:32:57 +0000 (20:32 +1000)
ast.py
bison_lr1dfa.py
skel/y.tab.c.patch

diff --git a/ast.py b/ast.py
index eb63314..9fd42b1 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -1510,9 +1510,18 @@ class PYACC(element.Element):
         name_to_tag
       ):
         name = self[0].get_text()
-        value = self[1].get_text() if len(self) >= 2 else ''
+        value = (
+          ''
+        if len(self) < 2 else
+          self[1][0].get_text()
+        if isinstance(self[1], PYACC.String) else
+          self[1].get_text()[1:-1] # fix this later
+        if isinstance(self[1], PYACC.BracedCode) else
+          self[1].get_text() # ID
+        )
         if name == 'api.prefix':
-          section.api_prefix = value
+          section.type_prefix = value.upper()
+          section.name_prefix = value
         elif name == 'api.pure':
           if value == 'full':
             section.api_pure = 2
@@ -1945,7 +1954,17 @@ class PYACC(element.Element):
         self.repr_serialize(params)
         return 'ast.PYACC.Section1.NamePrefix({0:s})'.format(', '.join(params))
       # GENERATE END
-
+      def post_process(
+        self,
+        pyacc,
+        section,
+        character_to_symbol,
+        name_to_symbol,
+        string_to_symbol,
+        name_to_tag
+      ):
+        section.name_prefix = self[0][0].get_text()
     class NonDeterministicParser(Item):
       # GENERATE ELEMENT() BEGIN
       def __init__(
@@ -2260,14 +2279,15 @@ class PYACC(element.Element):
         return 'ast.PYACC.Section1.YACC({0:s})'.format(', '.join(params))
       # GENERATE END
 
-    # GENERATE ELEMENT(str api_prefix, int api_pure, bool locations, bool error_verbose, str parse_lac, bool debug, bool defines, int expect, bool verbose) BEGIN
+    # GENERATE ELEMENT(str type_prefix, str name_prefix, int api_pure, bool locations, bool error_verbose, str parse_lac, bool debug, bool defines, int expect, bool verbose) BEGIN
     def __init__(
       self,
       tag = 'PYACC_Section1',
       attrib = {},
       text = '',
       children = [],
-      api_prefix = '',
+      type_prefix = '',
+      name_prefix = '',
       api_pure = -1,
       locations = False,
       error_verbose = False,
@@ -2284,7 +2304,8 @@ class PYACC(element.Element):
         text,
         children
       )
-      self.api_prefix = api_prefix
+      self.type_prefix = type_prefix
+      self.name_prefix = name_prefix
       self.api_pure = (
         element.deserialize_int(api_pure)
       if isinstance(api_pure, str) else
@@ -2323,7 +2344,8 @@ class PYACC(element.Element):
       )
     def serialize(self, ref_list):
       PYACC.Section1Or2.serialize(self, ref_list)
-      self.set('api_prefix', element.serialize_str(self.api_prefix))
+      self.set('type_prefix', element.serialize_str(self.type_prefix))
+      self.set('name_prefix', element.serialize_str(self.name_prefix))
       self.set('api_pure', element.serialize_int(self.api_pure))
       self.set('locations', element.serialize_bool(self.locations))
       self.set('error_verbose', element.serialize_bool(self.error_verbose))
@@ -2334,7 +2356,8 @@ class PYACC(element.Element):
       self.set('verbose', element.serialize_bool(self.verbose))
     def deserialize(self, ref_list):
       PYACC.Section1Or2.deserialize(self, ref_list)
-      self.api_prefix = element.deserialize_str(self.get('api_prefix', ''))
+      self.type_prefix = element.deserialize_str(self.get('type_prefix', ''))
+      self.name_prefix = element.deserialize_str(self.get('name_prefix', ''))
       self.api_pure = element.deserialize_int(self.get('api_pure', '-1'))
       self.locations = element.deserialize_bool(self.get('locations', 'false'))
       self.error_verbose = element.deserialize_bool(self.get('error_verbose', 'false'))
@@ -2348,7 +2371,8 @@ class PYACC(element.Element):
         self,
         Section1 if factory is None else factory
       )
-      result.api_prefix = self.api_prefix
+      result.type_prefix = self.type_prefix
+      result.name_prefix = self.name_prefix
       result.api_pure = self.api_pure
       result.locations = self.locations
       result.error_verbose = self.error_verbose
@@ -2360,9 +2384,13 @@ class PYACC(element.Element):
       return result
     def repr_serialize(self, params):
       PYACC.Section1Or2.repr_serialize(self, params)
-      if self.api_prefix != '':
+      if self.type_prefix != '':
+        params.append(
+          'type_prefix = {0:s}'.format(repr(self.type_prefix))
+        )
+      if self.name_prefix != '':
         params.append(
-          'api_prefix = {0:s}'.format(repr(self.api_prefix))
+          'name_prefix = {0:s}'.format(repr(self.name_prefix))
         )
       if self.api_pure != -1:
         params.append(
@@ -2409,7 +2437,8 @@ class PYACC(element.Element):
       string_to_symbol,
       name_to_tag
     ):
-      self.api_prefix = ''
+      self.type_prefix = 'YY'
+      self.name_prefix = 'yy'
       self.api_pure = 0
       self.locations = False
       self.error_verbose = False
@@ -2426,8 +2455,10 @@ class PYACC(element.Element):
         string_to_symbol,
         name_to_tag
       )
-      if len(self.api_prefix):
-        sys.stderr.write('warning: ignoring %define api.prefix\n')
+      #if self.type_prefix != 'YY':
+      #  sys.stderr.write('warning: ignoring %define api.prefix\n')
+      #if self.name_prefix != 'yy':
+      #  sys.stderr.write('warning: ignoring %name-prefix\n')
       #if self.api_pure != 0:
       #  sys.stderr.write('warning: ignoring %define api.pure\n')
       #if self.locations:
index b3d3214..a7b0477 100644 (file)
@@ -346,6 +346,62 @@ def generate(pyacc, skel_file, out_file, defines_file = None):
                 pyacc[0].api_pure
               )
             )
+          elif line == '/* GENERATE TYPEPREFIX */\n':
+            fout.write(
+              '''/* GENERATE TYPEPREFIX BEGIN */
+{0:s}/* GENERATE TYPEPREFIX END */
+'''.format(
+                  '''/* Substitute the type names.  */
+{0:s}'''.format(
+                    ''.join(
+                      [
+                        '#define YY{0:s} {1:s}{2:s}\n'.format(
+                          i,
+                          pyacc[0].type_prefix,
+                          i
+                        )
+                        for i in (
+                          ['STYPE'] +
+                          (['LTYPE'] if pyacc[0].locations else [])
+                        )
+                      ]
+                    )
+                  )
+                if pyacc[0].type_prefix != 'YY' else
+                  ''
+              )
+            )
+          elif line == '/* GENERATE NAMEPREFIX */\n':
+            fout.write(
+              '''/* GENERATE NAMEPREFIX BEGIN */
+{0:s}/* GENERATE NAMEPREFIX END */
+'''.format(
+                  '''/* Substitute the variable and function names.  */
+{0:s}'''.format(
+                    ''.join(
+                      [
+                        '#define yy{0:s} {1:s}{2:s}\n'.format(
+                          i,
+                          pyacc[0].name_prefix,
+                          i
+                        )
+                        for i in (
+                          # note: nerrs is actually pure but do what bison does
+                          ['parse', 'lex', 'error', 'debug', 'nerrs'] +
+                          (
+                            []
+                          if pyacc[0].api_pure else
+                            ['lval', 'char'] +
+                            (['lloc'] if pyacc[0].locations else [])
+                          )
+                        )
+                      ]
+                    )
+                  )
+                if pyacc[0].name_prefix != 'yy' else
+                  ''
+              )
+            )
           elif line == '/* GENERATE SECTION1TOP */\n':
             fout.write(
               '''/* GENERATE SECTION1TOP BEGIN */
index e2a1a8b..57368cb 100644 (file)
@@ -1,5 +1,5 @@
---- y.tab.c.orig       2018-07-29 19:39:22.183720400 +1000
-+++ y.tab.c    2018-07-29 19:40:01.175721429 +1000
+--- y.tab.c.orig       2018-07-29 20:02:05.723756386 +1000
++++ y.tab.c    2018-07-29 20:32:07.283803932 +1000
 @@ -50,7 +50,7 @@
  #define YYSKELETON_NAME "yacc.c"
  
@@ -9,12 +9,14 @@
  
  /* Push parsers.  */
  #define YYPUSH 0
-@@ -58,11 +58,11 @@
+@@ -58,11 +58,15 @@
  /* Pull parsers.  */
  #define YYPULL 1
  
--
--
++/* GENERATE TYPEPREFIX */
++/* GENERATE NAMEPREFIX */
 +/* GENERATE SECTION1TOP */
  
  /* Copy the first part of user declarations.  */
@@ -23,7 +25,7 @@
  
  # ifndef YY_NULLPTR
  #  if defined __cplusplus && 201103L <= __cplusplus
-@@ -73,21 +73,14 @@
+@@ -73,21 +77,14 @@
  # endif
  
  /* Enabling verbose error messages.  */
@@ -47,7 +49,7 @@
  #if YYDEBUG
  extern int yydebug;
  #endif
-@@ -97,28 +90,26 @@
+@@ -97,28 +94,26 @@
  # define YYTOKENTYPE
    enum yytokentype
    {
 -
 -/* Value type.  */
 -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-+/* GENERATE TOKENS */
+-
 -union YYSTYPE
 -{
 - /* something */ 
--
++/* GENERATE TOKENS */
 -};
 +/* GENERATE SECTION1REQUIRES */
  
@@ -88,7 +90,7 @@
  
  int yyparse (void);
  
-@@ -126,6 +117,7 @@
+@@ -126,6 +121,7 @@
  
  /* Copy the second part of user declarations.  */
  
@@ -96,7 +98,7 @@
  
  #ifdef short
  # undef short
-@@ -306,13 +298,20 @@
+@@ -306,13 +302,20 @@
  
  #if (! defined yyoverflow \
       && (! defined __cplusplus \
  };
  
  /* The size of the maximum gap between one aligned stack and the next.  */
-@@ -320,9 +319,15 @@
+@@ -320,9 +323,15 @@
  
  /* The size of an array large to enough to hold all stacks, each with
     N elements.  */
  
  # define YYCOPY_NEEDED 1
  
-@@ -364,155 +369,7 @@
+@@ -364,155 +373,7 @@
  # endif
  #endif /* !YYCOPY_NEEDED */
  
  
  #define yyerrok         (yyerrstatus = 0)
  #define yyclearin       (yychar = YYEMPTY)
-@@ -526,7 +383,25 @@
+@@ -526,7 +387,25 @@
  
  #define YYRECOVERING()  (!!yyerrstatus)
  
  do                                                              \
    if (yychar == YYEMPTY)                                        \
      {                                                           \
-@@ -542,12 +417,39 @@
+@@ -542,12 +421,39 @@
        YYERROR;                                                  \
      }                                                           \
  while (0)
 +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
 +   If N is 0, then set CURRENT to the empty location which ends
 +   the previous symbol: RHS[0] (always defined).  */
++
 +# ifndef YYLLOC_DEFAULT
 +#  define YYLLOC_DEFAULT(Current, Rhs, N)                               \
 +    do                                                                  \
 +        }                                                               \
 +    while (0)
 +# endif
-+
 +# define YYRHSLOC(Rhs, K) ((Rhs)[K])
 +#endif
  
  /* Enable debugging if requested.  */
  #if YYDEBUG
-@@ -563,13 +465,64 @@
+@@ -563,13 +469,64 @@
      YYFPRINTF Args;                             \
  } while (0)
  
  do {                                                                      \
    if (yydebug)                                                            \
      {                                                                     \
-@@ -579,12 +532,29 @@
+@@ -579,12 +536,29 @@
        YYFPRINTF (stderr, "\n");                                           \
      }                                                                     \
  } while (0)
  static void
  yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
  {
-@@ -592,18 +562,32 @@
+@@ -592,18 +566,32 @@
    YYUSE (yyo);
    if (!yyvaluep)
      return;
  static void
  yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
  {
-@@ -613,6 +597,7 @@
+@@ -613,6 +601,7 @@
    yy_symbol_value_print (yyoutput, yytype, yyvaluep);
    YYFPRINTF (yyoutput, ")");
  }
  
  /*------------------------------------------------------------------.
  | yy_stack_print -- Print the state stack from its BOTTOM up to its |
-@@ -642,6 +627,33 @@
+@@ -642,6 +631,33 @@
  | Report that the YYRULE is going to be reduced.  |
  `------------------------------------------------*/
  
  static void
  yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
  {
-@@ -662,11 +674,12 @@
+@@ -662,11 +678,12 @@
      }
  }
  
  
  /* Nonzero means print parse trace.  It is left uninitialized so that
     multiple parsers can coexist.  */
-@@ -923,10 +936,12 @@
+@@ -923,10 +940,12 @@
  | Release the memory associated to this symbol.  |
  `-----------------------------------------------*/
  
    if (!yymsg)
      yymsg = "Deleting";
    YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-@@ -935,18 +950,38 @@
+@@ -935,18 +954,38 @@
    YYUSE (yytype);
    YY_IGNORE_MAYBE_UNINITIALIZED_END
  }
  
  /*----------.
  | yyparse.  |
-@@ -955,6 +990,27 @@
+@@ -955,6 +994,27 @@
  int
  yyparse (void)
  {
      int yystate;
      /* Number of tokens to shift before error messages enabled.  */
      int yyerrstatus;
-@@ -962,6 +1018,7 @@
+@@ -962,6 +1022,7 @@
      /* The stacks and their tools:
         'yyss': related to states.
         'yyvs': related to semantic values.
  
         Refer to the stacks through separate pointers, to allow yyoverflow
         to reallocate them elsewhere.  */
-@@ -976,6 +1033,16 @@
+@@ -976,6 +1037,16 @@
      YYSTYPE *yyvs;
      YYSTYPE *yyvsp;
  
      YYSIZE_T yystacksize;
  
    int yyn;
-@@ -985,6 +1052,9 @@
+@@ -985,6 +1056,9 @@
    /* The variables used to return semantic value and location from the
       action routines.  */
    YYSTYPE yyval;
  
  #if YYERROR_VERBOSE
    /* Buffer for error messages, and its allocated size.  */
-@@ -993,7 +1063,11 @@
+@@ -993,7 +1067,11 @@
    YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
  #endif
  
  
    /* The number of symbols on the RHS of the reduced rule.
       Keep to zero when no symbol should be popped.  */
-@@ -1001,6 +1075,9 @@
+@@ -1001,6 +1079,9 @@
  
    yyssp = yyss = yyssa;
    yyvsp = yyvs = yyvsa;
    yystacksize = YYINITDEPTH;
  
    YYDPRINTF ((stderr, "Starting parse\n"));
-@@ -1075,6 +1152,9 @@
+@@ -1075,6 +1156,9 @@
  
        yyssp = yyss + yysize - 1;
        yyvsp = yyvs + yysize - 1;
  
        YYDPRINTF ((stderr, "Stack size increased to %lu\n",
                    (unsigned long int) yystacksize));
-@@ -1109,7 +1189,15 @@
+@@ -1109,7 +1193,15 @@
    if (yychar == YYEMPTY)
      {
        YYDPRINTF ((stderr, "Reading a token: "));
      }
  
    if (yychar <= YYEOF)
-@@ -1152,7 +1240,9 @@
+@@ -1152,7 +1244,9 @@
    YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
    *++yyvsp = yylval;
    YY_IGNORE_MAYBE_UNINITIALIZED_END
    goto yynewstate;
  
  
-@@ -1183,18 +1273,14 @@
+@@ -1183,18 +1277,14 @@
       GCC warning that YYVAL may be used uninitialized.  */
    yyval = yyvsp[1-yylen];
  
  
        default: break;
      }
-@@ -1216,6 +1302,9 @@
+@@ -1216,6 +1306,9 @@
    YY_STACK_PRINT (yyss, yyssp);
  
    *++yyvsp = yyval;
  
    /* Now 'shift' the result of the reduction.  Determine what state
       that goes to, based on the state we popped back to and the rule
-@@ -1245,7 +1334,11 @@
+@@ -1245,7 +1338,11 @@
      {
        ++yynerrs;
  #if ! YYERROR_VERBOSE
  #else
  # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
                                          yyssp, yytoken)
-@@ -1272,7 +1365,11 @@
+@@ -1272,7 +1369,11 @@
                  yymsgp = yymsg;
                }
            }
          if (yysyntax_error_status == 2)
            goto yyexhaustedlab;
        }
-@@ -1280,7 +1377,9 @@
+@@ -1280,7 +1381,9 @@
  #endif
      }
  
  
    if (yyerrstatus == 3)
      {
-@@ -1295,8 +1394,13 @@
+@@ -1295,8 +1398,13 @@
          }
        else
          {
            yychar = YYEMPTY;
          }
      }
-@@ -1317,6 +1421,9 @@
+@@ -1317,6 +1425,9 @@
    if (/*CONSTCOND*/ 0)
       goto yyerrorlab;
  
    /* Do not reclaim the symbols of the rule whose action triggered
       this YYERROR.  */
    YYPOPSTACK (yylen);
-@@ -1350,9 +1457,14 @@
+@@ -1350,9 +1461,14 @@
        if (yyssp == yyss)
          YYABORT;
  
        YYPOPSTACK (1);
        yystate = *yyssp;
        YY_STACK_PRINT (yyss, yyssp);
-@@ -1362,6 +1474,13 @@
+@@ -1362,6 +1478,13 @@
    *++yyvsp = yylval;
    YY_IGNORE_MAYBE_UNINITIALIZED_END
  
  
    /* Shift the error token.  */
    YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-@@ -1389,7 +1508,11 @@
+@@ -1389,7 +1512,11 @@
  | yyexhaustedlab -- memory exhaustion comes here.  |
  `-------------------------------------------------*/
  yyexhaustedlab:
    yyresult = 2;
    /* Fall through.  */
  #endif
-@@ -1400,8 +1523,13 @@
+@@ -1400,8 +1527,13 @@
        /* Make sure we have latest lookahead translation.  See comments at
           user semantic actions for why this is necessary.  */
        yytoken = YYTRANSLATE (yychar);
      }
    /* Do not reclaim the symbols of the rule whose action triggered
       this YYABORT or YYACCEPT.  */
-@@ -1409,8 +1537,13 @@
+@@ -1409,8 +1541,13 @@
    YY_STACK_PRINT (yyss, yyssp);
    while (yyssp != yyss)
      {
        YYPOPSTACK (1);
      }
  #ifndef yyoverflow
-@@ -1423,3 +1556,5 @@
+@@ -1423,3 +1560,5 @@
  #endif
    return yyresult;
  }