]> git.saurik.com Git - bison.git/blobdiff - data/push.c
Deprecate %pure-parser and add `%define api.pure'. Discussed starting
[bison.git] / data / push.c
index bf64b23bb63943af0d541273e483c4feb17d123f..b0cbeb322f42e5538bbc5c623d56be122cc6ef91 100644 (file)
@@ -1,36 +1,40 @@
-m4_divert(-1)                                                -*- C -*-
+                                                             -*- C -*-
 
 # Yacc compatible skeleton for Bison
 
 # Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
 # 2007 Free Software Foundation, Inc.
 
-# This program is free software; you can redistribute it and/or modify
+# This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
-
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-
+#
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301  USA
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Check the value of %define api.push_pull.
+b4_percent_define_default([[api.push_pull]], [[pull]])
+b4_percent_define_check_values([[[[api.push_pull]],
+                               [[pull]], [[push]], [[both]]]])
+b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
+b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
+m4_case(b4_percent_define_get([[api.push_pull]]),
+        [pull], [m4_define([b4_push_flag], [[0]])],
+        [push], [m4_define([b4_pull_flag], [[0]])])
 
 # Handle BISON_USE_PUSH_FOR_PULL for the test suite.  So that push parsing
 # tests function as written, don't let BISON_USE_PUSH_FOR_PULL modify Bison's
 # behavior at all when push parsing is already requested.
+b4_define_flag_if([use_push_for_pull])
 b4_use_push_for_pull_if([
-  b4_push_if([
-    m4_define([b4_use_push_for_pull_flag], [[0]])
-    b4_define_flag_if([use_push_for_pull])
-  ], [
-    m4_define([b4_push_flag], [[1]])
-    b4_define_flag_if([push])
-  ])])
+  b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
+             [m4_define([b4_push_flag], [[1]])])])
 
 m4_include(b4_pkgdatadir/[c.m4])
 
@@ -47,6 +51,10 @@ m4_define_default([b4_stack_depth_init],  [200])
 ## Pure/impure interfaces.  ##
 ## ------------------------ ##
 
+b4_percent_define_default([[api.pure]], [[false]])
+b4_define_flag_if([pure])
+m4_define([b4_pure_flag],
+          [b4_percent_define_flag_if([[api.pure]], [[1]], [[0]])])
 
 # b4_yacc_pure_if(IF-TRUE, IF-FALSE)
 # ----------------------------------
@@ -144,8 +152,8 @@ m4_define([b4_rhs_location],
 
 # We do want M4 expansion after # for CPP macros.
 m4_changecom()
-m4_divert(0)dnl
-@output b4_parser_file_name
+m4_divert_push(0)dnl
+@output(b4_parser_file_name@)
 b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl '
   [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006])[
 
@@ -160,6 +168,8 @@ b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl '
    USER NAME SPACE" below.  */
 
 ]b4_identification
+
+b4_percent_code_get([[top]])[]dnl
 m4_if(b4_prefix, [yy], [],
 [[/* Substitute the variable and function names.  */
 ]b4_pull_if([[#define yyparse         ]b4_prefix[parse
@@ -197,17 +207,16 @@ m4_if(b4_prefix, [yy], [],
 # define YYTOKEN_TABLE ]b4_token_table[
 #endif
 
-]m4_ifdef([b4_requires],
-[[/* Copy the %requires blocks.  */
-]b4_user_requires])[]dnl
+]b4_percent_code_get([[requires]])[]dnl
 
 b4_token_enums_defines(b4_tokens)[
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 ]m4_ifdef([b4_stype],
 [[typedef union ]b4_union_name[
+{
 ]b4_user_stype[
-       YYSTYPE;
+} YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1]],
 [m4_if(b4_tag_seen_flag, 0,
 [[typedef int YYSTYPE;
@@ -250,14 +259,13 @@ b4_c_function_decl([[yypstate_delete]], [[void]],
                    [[[yypstate *yyps]], [[yyps]]])[
 #endif
 ]])
-m4_ifdef([b4_provides],
-[[/* Copy the %provides blocks.  */
-]b4_user_provides])[]dnl
+b4_percent_code_get([[provides]])[]dnl
 
 [/* Copy the second part of user declarations.  */
-]b4_user_post_prologue[
+]b4_user_post_prologue
+b4_percent_code_get[]dnl
 
-#ifdef short
+[#ifdef short
 # undef short
 #endif
 
@@ -333,7 +341,8 @@ typedef short int yytype_int16;
 
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
+]b4_push_if([],
+[[/* The parser invokes alloca or malloc; define the necessary symbols.  */
 
 # ifdef YYSTACK_USE_ALLOCA
 #  if YYSTACK_USE_ALLOCA
@@ -358,7 +367,8 @@ typedef short int yytype_int16;
 #  endif
 # endif
 
-# ifdef YYSTACK_ALLOC
+]])dnl
+[# ifdef YYSTACK_ALLOC
    /* Pacify GCC's `empty if-body' warning.  */
 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
 #  ifndef YYSTACK_ALLOC_MAXIMUM
@@ -749,12 +759,12 @@ do {                                                              \
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      fprintf (stderr, "   $%d = ", yyi + 1);
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
                       &]b4_rhs_value(yynrhs, yyi + 1)[
                       ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
                       b4_user_args[);
-      fprintf (stderr, "\n");
+      YYFPRINTF (stderr, "\n");
     }
 }
 
@@ -1077,7 +1087,9 @@ b4_push_if(
 {
   return yypull_parse (0]m4_ifset([b4_parse_param],
                                   [[, ]b4_c_args(b4_parse_param)])[);
-}
+}]b4_pure_if([], [[
+
+static char yypstate_allocated = 0;]])[
 
 ]b4_c_function_def([[yypull_parse]], [[int]],
   [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
@@ -1090,13 +1102,22 @@ b4_push_if(
 ]b4_locations_if([[  YYLTYPE yylloc;
 ]])])[
   if (yyps == 0)
-     yyps_local = yypstate_new ();
-   else
-     yyps_local = yyps;
-   do {
-     yychar = YYLEX;
-     yystatus =
-       yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])[);
+    {
+      yyps_local = yypstate_new ();
+      if (!yyps_local)
+        {]b4_pure_if([[
+          yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
+          if (!yypstate_allocated)
+            yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
+          return 2;
+        }
+    }
+  else
+    yyps_local = yyps;
+  do {
+    yychar = YYLEX;
+    yystatus =
+      yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])[);
   } while (yystatus == YYPUSH_MORE);
   if (yyps == 0)
     yypstate_delete (yyps_local);
@@ -1106,15 +1127,31 @@ b4_push_if(
 /* Initialize the parser data structure.  */
 ]b4_c_function_def([[yypstate_new]], [[yypstate *]])[
 {
-  yypstate *yyps = (yypstate *) malloc (sizeof *yyps);
-  yyps->yynew = 1;
+  yypstate *yyps;]b4_pure_if([], [[
+  if (yypstate_allocated)
+    {
+      yyerror (]b4_yyerror_args[YY_("cannot allocate multiple impure push-parser instances"));
+      return 0;
+    }]])[
+  yyps = (yypstate *) malloc (sizeof *yyps);
+  if (!yyps)
+    return 0;
+  yyps->yynew = 1;]b4_pure_if([], [[
+  yypstate_allocated = 1;]])[
   return yyps;
 }
 
 ]b4_c_function_def([[yypstate_delete]], [[void]],
                    [[[yypstate *yyps]], [[yyps]]])[
 {
-  free (yyps);
+#ifndef yyoverflow
+  /* If the stack was reallocated but the parse did not complete, then the
+     stack still needs to be freed.  */
+  if (!yyps->yynew && yyps->yyss != yyps->yyssa)
+    YYSTACK_FREE (yyps->yyss);
+#endif
+  free (yyps);]b4_pure_if([], [[
+  yypstate_allocated = 0;]])[
 }
 
 ]b4_pure_if([[#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs
@@ -1150,8 +1187,8 @@ b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])
 b4_c_function_def([yyparse], [int], b4_parse_param)
 #endif])[
 {
-  ]b4_pure_if([b4_declare_scanner_communication_variables])
-  b4_push_if([b4_pure_if([], [[  int yypushed_char = yychar;
+]b4_pure_if([b4_declare_scanner_communication_variables])
+b4_push_if([b4_pure_if([], [[  int yypushed_char = yychar;
   YYSTYPE yypushed_val = yylval;
   ]b4_locations_if([[YYLTYPE yypushed_loc = yylloc;
 ]])])],
@@ -1651,21 +1688,20 @@ yypushreturn:
 
 ]b4_epilogue
 b4_defines_if(
-[@output b4_spec_defines_file
+[@output(b4_spec_defines_file@)
 b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl '
   [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006])
 
-m4_ifdef([b4_requires],
-[[/* Copy the %requires blocks.  */
-]b4_user_requires])[]dnl
+b4_percent_code_get([[requires]])[]dnl
 
 b4_token_enums_defines(b4_tokens)
 
 [#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 ]m4_ifdef([b4_stype],
 [[typedef union ]b4_union_name[
+{
 ]b4_user_stype[
-       YYSTYPE;
+} YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1]],
 [m4_if(b4_tag_seen_flag, 0,
 [[typedef int YYSTYPE;
@@ -1714,7 +1750,6 @@ b4_c_function_decl([b4_prefix[pstate_delete]], [[void]],
                    [[b4_prefix[pstate *yyps]], [[yyps]]])[
 #endif
 ]])
-m4_ifdef([b4_provides],
-[[/* Copy the %provides blocks.  */
-]b4_user_provides])[]
+b4_percent_code_get([[provides]])[]dnl
 ])dnl b4_defines_if
+m4_divert_pop(0)