bison-patches
[Top][All Lists]
Advanced

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

Re: push parser


From: Joel E. Denny
Subject: Re: push parser
Date: Sun, 31 Dec 2006 19:42:47 -0500 (EST)

On Tue, 26 Dec 2006, Joel E. Denny wrote:

> 1. For yacc.c, you can invoke yyparse multiple times.  For push.c's push 
> mode, I haven't thought this through.  I guess yypush_parse should set 
> yyps->yynew = 1 whenever it returns with a parse error or success.

I committed the following patch to implement this and a little cleanup.

As far as I can tell, it's time to mv push.c yacc.c.  However, that's a 
major change that I should not make without some consensus.

Once we do that, I think we should add a new maintainer-check pass that 
forces yacc.c to run in that special push mode that emulates pull mode.  
(That pass should probably use Valgrind also.)  Otherwise, we'll have to 
keep setting up that mode manually in the way I've previously described:

1. Look for this line:

  m4_include(b4_pkgdatadir/[c.m4])

Add this line afterwards:

  m4_define([b4_push_if], [$1])

2. Now look for this line:

   YYDPRINTF ((stderr, "Return for a new token:\n"));

Delete it.

Index: ChangeLog
===================================================================
RCS file: /sources/bison/bison/ChangeLog,v
retrieving revision 1.1640
diff -p -u -r1.1640 ChangeLog
--- ChangeLog   31 Dec 2006 20:29:48 -0000      1.1640
+++ ChangeLog   31 Dec 2006 23:56:05 -0000
@@ -1,5 +1,29 @@
 2006-12-31  Joel E. Denny  <address@hidden>
 
+       * data/push.c (yypush_parse): Set yynew = 1 at the end of a parse
+       (whether successful or failed) so that yypush_parse can be invoked
+       again to start a new parse using the same yypstate.
+       * tests/torture.at (AT_DATA_STACK_TORTURE): For push mode, extend to
+       check multiple yypull_parse invocations on the same yypstate.  For pull
+       mode, extend to check multiple yyparse invocations.
+       (Exploding the Stack Size with Alloca): Extend to try with
+       %push-pull-parser.
+       (Exploding the Stack Size with Malloc): Likewise.
+
+       * tests/calc.at (Simple LALR Calculator): Don't specify
+       %skeleton "push.c" since %push-pull-parser implies that now.
+       * tests/headers.at (export YYLTYPE): Don't check for the push
+       declarations.  Otherwise, this test case can't be used to see if push
+       mode can truly emulate pull mode.
+       * tests/input.at (Torturing the Scanner): Likewise.
+       * tests/local.at (AT_YACC_OR_PUSH_IF, AT_PUSH_IF): Remove.
+       (AT_YYERROR_SEES_LOC_IF): Rather than AT_YACC_OR_PUSH_IF, use
+       AT_YACC_IF, which now includes the case of push mode since %skeleton
+       need not be used for push mode.  This will be more intuitive once
+       push.c is renamed to yacc.c.
+
+2006-12-31  Joel E. Denny  <address@hidden>
+
        For push mode, convert yyparse from a macro to a function, invoke yylex
        instead of passing a yylexp argument to yypull_parse, and don't
        generate yypull_parse or yyparse unless %push-pull-parser is declared.
Index: data/push.c
===================================================================
RCS file: /sources/bison/bison/data/push.c,v
retrieving revision 1.27
diff -p -u -r1.27 push.c
--- data/push.c 31 Dec 2006 20:29:48 -0000      1.27
+++ data/push.c 31 Dec 2006 23:56:06 -0000
@@ -1624,16 +1624,19 @@ 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(
 address@hidden b4_spec_defines_file
 b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl '
Index: tests/calc.at
===================================================================
RCS file: /sources/bison/bison/tests/calc.at,v
retrieving revision 1.102
diff -p -u -r1.102 calc.at
--- tests/calc.at       31 Dec 2006 20:29:48 -0000      1.102
+++ tests/calc.at       31 Dec 2006 23:56:06 -0000
@@ -562,7 +562,7 @@ AT_CHECK_CALC_LALR([%yacc])
 AT_CHECK_CALC_LALR([%error-verbose])
 
 AT_CHECK_CALC_LALR([%pure-parser %locations])
-AT_CHECK_CALC_LALR([%push-pull-parser %pure-parser %locations %skeleton 
"push.c"])
+AT_CHECK_CALC_LALR([%push-pull-parser %pure-parser %locations])
 AT_CHECK_CALC_LALR([%error-verbose %locations])
 
 AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" 
%verbose %yacc])
@@ -571,7 +571,7 @@ AT_CHECK_CALC_LALR([%debug])
 AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix 
"calc" %verbose %yacc])
 
 AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines 
%name-prefix "calc" %verbose %yacc])
-AT_CHECK_CALC_LALR([%push-pull-parser %pure-parser %error-verbose %debug 
%locations %defines %name-prefix "calc" %verbose %yacc %skeleton "push.c"])
+AT_CHECK_CALC_LALR([%push-pull-parser %pure-parser %error-verbose %debug 
%locations %defines %name-prefix "calc" %verbose %yacc])
 
 AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines 
%name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} 
%parse-param {int *count}])
 
Index: tests/headers.at
===================================================================
RCS file: /sources/bison/bison/tests/headers.at,v
retrieving revision 1.17
diff -p -u -r1.17 headers.at
--- tests/headers.at    31 Dec 2006 20:29:48 -0000      1.17
+++ tests/headers.at    31 Dec 2006 23:56:06 -0000
@@ -118,9 +118,7 @@ AT_DATA([caller.c],
 [[#include "input.h"
 YYLTYPE *my_llocp = &my_lloc;
 
-#ifndef YYPUSH_DECLS
 int my_parse (void);
-#endif
 
 int
 main (void)
Index: tests/input.at
===================================================================
RCS file: /sources/bison/bison/tests/input.at,v
retrieving revision 1.66
diff -p -u -r1.66 input.at
--- tests/input.at      31 Dec 2006 20:29:48 -0000      1.66
+++ tests/input.at      31 Dec 2006 23:56:06 -0000
@@ -529,9 +529,7 @@ AT_DATA([main.c],
 [[typedef int value;
 #include "input.h"
 
-#ifndef YYPUSH_DECLS
 int yyparse (void);
-#endif
 
 int
 main (void)
Index: tests/local.at
===================================================================
RCS file: /sources/bison/bison/tests/local.at,v
retrieving revision 1.22
diff -p -u -r1.22 local.at
--- tests/local.at      31 Dec 2006 20:29:48 -0000      1.22
+++ tests/local.at      31 Dec 2006 23:56:06 -0000
@@ -58,10 +58,6 @@ m4_pushdef([AT_LOCATION_IF],
 [m4_bmatch([$3], [%locations], [$1], [$2])])
 m4_pushdef([AT_PURE_IF],
 [m4_bmatch([$3], [%pure-parser], [$1], [$2])])
-m4_pushdef([AT_PUSH_IF],
-[m4_bmatch([$3], [%push-parser\|%push-pull-parser], [$1], [$2])])
-m4_pushdef([AT_YACC_OR_PUSH_IF],
-[AT_YACC_IF([$1], [AT_PUSH_IF([$1], [$2])])])
 m4_pushdef([AT_PURE_AND_LOC_IF],
 [m4_bmatch([$3], [%locations.*%pure-parser\|%pure-parser.*%locations],
           [$1], [$2])])
@@ -78,9 +74,9 @@ m4_pushdef([AT_YYERROR_ARG_LOC_IF],
 # yyerror always sees the locations (when activated), except if
 # (yacc & pure & !param).  FIXME: This is wrong.  See the manual.
 m4_pushdef([AT_YYERROR_SEES_LOC_IF],
-[AT_LOCATION_IF([AT_YACC_OR_PUSH_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
-                                               [$1])],
-                                   [$1])],
+[AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
+                                       [$1])],
+                           [$1])],
                [$2])])
 
 # The interface is pure: either because %pure-parser, or because we
Index: tests/torture.at
===================================================================
RCS file: /sources/bison/bison/tests/torture.at,v
retrieving revision 1.33
diff -p -u -r1.33 torture.at
--- tests/torture.at    6 Oct 2006 06:57:00 -0000       1.33
+++ tests/torture.at    31 Dec 2006 23:56:06 -0000
@@ -367,7 +367,7 @@ mv stdout $1
 
 
 ## ------------------------ ##
-## Many lookahead tokens.  ##
+## Many lookahead tokens.   ##
 ## ------------------------ ##
 
 AT_SETUP([Many lookahead tokens])
@@ -386,8 +386,8 @@ AT_CLEANUP
 
 
 
-# AT_DATA_STACK_TORTURE(C-PROLOGUE)
-# ---------------------------------
+# AT_DATA_STACK_TORTURE(C-PROLOGUE, [BISON-DECLS])
+# ------------------------------------------------
 # A parser specialized in torturing the stack size.
 m4_define([AT_DATA_STACK_TORTURE],
 [# A grammar of parens growing the stack thanks to right recursion.
@@ -402,6 +402,7 @@ AT_DATA([input.y],
   static int yylex (void);
   static void yyerror (const char *msg);
 %}
+]$2[
 %error-verbose
 %debug
 %token WAIT_FOR_EOF
@@ -429,15 +430,36 @@ int
 main (int argc, const char **argv)
 {
   char *endp;
+  YYSTYPE yylval_init;
   if (argc != 2)
     abort ();
-  yylval = strtol (argv[1], &endp, 10);
+  yylval_init = strtol (argv[1], &endp, 10);
   if (! (argv[1] != endp
-        && 0 <= yylval && yylval <= INT_MAX
+        && 0 <= yylval_init && yylval_init <= INT_MAX
         && errno != ERANGE))
     abort ();
   yydebug = 1;
-  return yyparse ();
+  {
+    int count;
+    int status;
+]m4_bmatch([$2], [%push-],
+[[    yypstate *yyps = yypstate_new ();
+]])[    for (count = 0; count < 2; ++count)
+      {
+        int new_status;
+        yylval = yylval_init;
+]m4_bmatch([$2], [%push-],
+[[        new_status = yypull_parse (yyps);
+]],
+[[        new_status = yyparse ();
+]])[        if (count > 0 && new_status != status)
+          abort ();
+        status = new_status;
+      }
+]m4_bmatch([$2], [%push-],
+[[    yypstate_delete (yyps);
+]])[    return status;
+  }
 }
 ]])
 AT_CHECK([bison -o input.c input.y])
@@ -451,13 +473,15 @@ AT_COMPILE([input])
 
 AT_SETUP([Exploding the Stack Size with Alloca])
 
-AT_DATA_STACK_TORTURE([[
+m4_pushdef([AT_USE_ALLOCA], [[
 #if (defined __GNUC__ || defined __BUILTIN_VA_ARG_INCR \
      || defined _AIX || defined _MSC_VER || defined _ALLOCA_H)
 # define YYSTACK_USE_ALLOCA 1
 #endif
 ]])
 
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
+
 # Below the limit of 200.
 AT_PARSER_CHECK([./input 20], 0, [], [ignore])
 # Two enlargements: 2 * 2 * 200.
@@ -466,6 +490,15 @@ AT_PARSER_CHECK([./input 900], 0, [], [i
 # multiply by two starting at 200 => 5120 is the last possible).
 AT_PARSER_CHECK([./input 10000], 2, [], [ignore])
 
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
+[[%push-pull-parser
+]])
+AT_PARSER_CHECK([./input 20], 0, [], [ignore])
+AT_PARSER_CHECK([./input 900], 0, [], [ignore])
+AT_PARSER_CHECK([./input 10000], 2, [], [ignore])
+
+m4_popdef([AT_USE_ALLOCA])
+
 AT_CLEANUP
 
 
@@ -477,7 +510,9 @@ AT_CLEANUP
 
 AT_SETUP([Exploding the Stack Size with Malloc])
 
-AT_DATA_STACK_TORTURE([[#define YYSTACK_USE_ALLOCA 0]])
+m4_pushdef([AT_USE_ALLOCA], [[#define YYSTACK_USE_ALLOCA 0]])
+
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
 
 # Below the limit of 200.
 AT_PARSER_CHECK([./input 20], 0, [], [ignore])
@@ -487,4 +522,13 @@ AT_PARSER_CHECK([./input 900], 0, [], [i
 # multiply by two starting at 200 => 5120 is the possible).
 AT_PARSER_CHECK([./input 10000], 2, [], [ignore])
 
+AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
+[[%push-pull-parser
+]])
+AT_PARSER_CHECK([./input 20], 0, [], [ignore])
+AT_PARSER_CHECK([./input 900], 0, [], [ignore])
+AT_PARSER_CHECK([./input 10000], 2, [], [ignore])
+
+m4_popdef([AT_USE_ALLOCA])
+
 AT_CLEANUP




reply via email to

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