mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
* 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:
24
ChangeLog
24
ChangeLog
@@ -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
|
||||||
|
|||||||
11
data/push.c
11
data/push.c
@@ -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 '
|
||||||
|
|||||||
@@ -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}])
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user