]> git.saurik.com Git - bison.git/blobdiff - data/push.c
* doc/yacc.1.in: New.
[bison.git] / data / push.c
index 3da3f72e69c3cd724be0f2fb291b2a33b7a5dbbb..b0cbeb322f42e5538bbc5c623d56be122cc6ef91 100644 (file)
@@ -1,24 +1,40 @@
-m4_divert(-1)                                                -*- C -*-
+                                                             -*- C -*-
 
 # Yacc compatible skeleton for Bison
 
-# Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
+# 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]])],
+             [m4_define([b4_push_flag], [[1]])])])
 
 m4_include(b4_pkgdatadir/[c.m4])
 
@@ -35,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)
 # ----------------------------------
@@ -132,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])[
 
@@ -148,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
@@ -185,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;
@@ -238,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
 
@@ -321,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
@@ -346,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
@@ -737,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");
     }
 }
 
@@ -1065,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], [,
@@ -1078,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);
@@ -1094,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
@@ -1138,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;
 ]])])],
@@ -1317,8 +1366,9 @@ yybackup:
     {
 ]b4_push_if([[      if (!yyps->yynew)
         {
-          YYDPRINTF ((stderr, "Return for a new token:\n"));
-          yyresult = YYPUSH_MORE;
+]b4_use_push_for_pull_if([],
+[[          YYDPRINTF ((stderr, "Return for a new token:\n"));
+]])[          yyresult = YYPUSH_MORE;
           goto yypushreturn;
         }
       yyps->yynew = 0;
@@ -1624,32 +1674,34 @@ yyreturn:
   if (yyss != yyssa)
     YYSTACK_FREE (yyss);
 #endif
-]b4_push_if([yypushreturn:])[
-#if YYERROR_VERBOSE
+]b4_push_if([[  yyps->yynew = 1;
+
+yypushreturn:
+]])[#if YYERROR_VERBOSE
   if (yymsg != yymsgbuf)
     YYSTACK_FREE (yymsg);
 #endif
   /* Make sure YYID is used.  */
   return YYID (yyresult);
-]}
+}
 
-b4_epilogue
+
+]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;
@@ -1698,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)