* 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.
This commit is contained in:
Joel E. Denny
2007-01-01 00:42:21 +00:00
parent 7172e23e8f
commit 7d59638490
7 changed files with 88 additions and 25 deletions

View File

@@ -1,3 +1,27 @@
2006-12-31 Joel E. Denny <jdenny@ces.clemson.edu>
* 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 <jdenny@ces.clemson.edu> 2006-12-31 Joel E. Denny <jdenny@ces.clemson.edu>
For push mode, convert yyparse from a macro to a function, invoke yylex For push mode, convert yyparse from a macro to a function, invoke yylex

View File

@@ -1624,16 +1624,19 @@ yyreturn:
if (yyss != yyssa) if (yyss != yyssa)
YYSTACK_FREE (yyss); YYSTACK_FREE (yyss);
#endif #endif
]b4_push_if([yypushreturn:])[ ]b4_push_if([[ yyps->yynew = 1;
#if YYERROR_VERBOSE
yypushreturn:
]])[#if YYERROR_VERBOSE
if (yymsg != yymsgbuf) if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg); YYSTACK_FREE (yymsg);
#endif #endif
/* Make sure YYID is used. */ /* Make sure YYID is used. */
return YYID (yyresult); return YYID (yyresult);
]} }
b4_epilogue
]b4_epilogue
b4_defines_if( 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 ' b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl '

View File

@@ -562,7 +562,7 @@ AT_CHECK_CALC_LALR([%yacc])
AT_CHECK_CALC_LALR([%error-verbose]) AT_CHECK_CALC_LALR([%error-verbose])
AT_CHECK_CALC_LALR([%pure-parser %locations]) 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])
AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc]) 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([%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([%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}]) 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}])

View File

@@ -118,9 +118,7 @@ AT_DATA([caller.c],
[[#include "input.h" [[#include "input.h"
YYLTYPE *my_llocp = &my_lloc; YYLTYPE *my_llocp = &my_lloc;
#ifndef YYPUSH_DECLS
int my_parse (void); int my_parse (void);
#endif
int int
main (void) main (void)

View File

@@ -529,9 +529,7 @@ AT_DATA([main.c],
[[typedef int value; [[typedef int value;
#include "input.h" #include "input.h"
#ifndef YYPUSH_DECLS
int yyparse (void); int yyparse (void);
#endif
int int
main (void) main (void)

View File

@@ -58,10 +58,6 @@ m4_pushdef([AT_LOCATION_IF],
[m4_bmatch([$3], [%locations], [$1], [$2])]) [m4_bmatch([$3], [%locations], [$1], [$2])])
m4_pushdef([AT_PURE_IF], m4_pushdef([AT_PURE_IF],
[m4_bmatch([$3], [%pure-parser], [$1], [$2])]) [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_pushdef([AT_PURE_AND_LOC_IF],
[m4_bmatch([$3], [%locations.*%pure-parser\|%pure-parser.*%locations], [m4_bmatch([$3], [%locations.*%pure-parser\|%pure-parser.*%locations],
[$1], [$2])]) [$1], [$2])])
@@ -78,9 +74,9 @@ m4_pushdef([AT_YYERROR_ARG_LOC_IF],
# yyerror always sees the locations (when activated), except if # yyerror always sees the locations (when activated), except if
# (yacc & pure & !param). FIXME: This is wrong. See the manual. # (yacc & pure & !param). FIXME: This is wrong. See the manual.
m4_pushdef([AT_YYERROR_SEES_LOC_IF], m4_pushdef([AT_YYERROR_SEES_LOC_IF],
[AT_LOCATION_IF([AT_YACC_OR_PUSH_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])], [AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
[$1])], [$1])],
[$1])], [$1])],
[$2])]) [$2])])
# The interface is pure: either because %pure-parser, or because we # The interface is pure: either because %pure-parser, or because we

View File

@@ -367,7 +367,7 @@ mv stdout $1
## ------------------------ ## ## ------------------------ ##
## Many lookahead tokens. ## ## Many lookahead tokens. ##
## ------------------------ ## ## ------------------------ ##
AT_SETUP([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. # A parser specialized in torturing the stack size.
m4_define([AT_DATA_STACK_TORTURE], m4_define([AT_DATA_STACK_TORTURE],
[# A grammar of parens growing the stack thanks to right recursion. [# A grammar of parens growing the stack thanks to right recursion.
@@ -402,6 +402,7 @@ AT_DATA([input.y],
static int yylex (void); static int yylex (void);
static void yyerror (const char *msg); static void yyerror (const char *msg);
%} %}
]$2[
%error-verbose %error-verbose
%debug %debug
%token WAIT_FOR_EOF %token WAIT_FOR_EOF
@@ -429,15 +430,36 @@ int
main (int argc, const char **argv) main (int argc, const char **argv)
{ {
char *endp; char *endp;
YYSTYPE yylval_init;
if (argc != 2) if (argc != 2)
abort (); abort ();
yylval = strtol (argv[1], &endp, 10); yylval_init = strtol (argv[1], &endp, 10);
if (! (argv[1] != endp if (! (argv[1] != endp
&& 0 <= yylval && yylval <= INT_MAX && 0 <= yylval_init && yylval_init <= INT_MAX
&& errno != ERANGE)) && errno != ERANGE))
abort (); abort ();
yydebug = 1; 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]) AT_CHECK([bison -o input.c input.y])
@@ -451,13 +473,15 @@ AT_COMPILE([input])
AT_SETUP([Exploding the Stack Size with Alloca]) 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 \ #if (defined __GNUC__ || defined __BUILTIN_VA_ARG_INCR \
|| defined _AIX || defined _MSC_VER || defined _ALLOCA_H) || defined _AIX || defined _MSC_VER || defined _ALLOCA_H)
# define YYSTACK_USE_ALLOCA 1 # define YYSTACK_USE_ALLOCA 1
#endif #endif
]]) ]])
AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
# Below the limit of 200. # Below the limit of 200.
AT_PARSER_CHECK([./input 20], 0, [], [ignore]) AT_PARSER_CHECK([./input 20], 0, [], [ignore])
# Two enlargements: 2 * 2 * 200. # Two enlargements: 2 * 2 * 200.
@@ -466,6 +490,15 @@ AT_PARSER_CHECK([./input 900], 0, [], [ignore])
# multiply by two starting at 200 => 5120 is the last possible). # multiply by two starting at 200 => 5120 is the last possible).
AT_PARSER_CHECK([./input 10000], 2, [], [ignore]) 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 AT_CLEANUP
@@ -477,7 +510,9 @@ AT_CLEANUP
AT_SETUP([Exploding the Stack Size with Malloc]) 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. # Below the limit of 200.
AT_PARSER_CHECK([./input 20], 0, [], [ignore]) AT_PARSER_CHECK([./input 20], 0, [], [ignore])
@@ -487,4 +522,13 @@ AT_PARSER_CHECK([./input 900], 0, [], [ignore])
# multiply by two starting at 200 => 5120 is the possible). # multiply by two starting at 200 => 5120 is the possible).
AT_PARSER_CHECK([./input 10000], 2, [], [ignore]) 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 AT_CLEANUP