From 7d596384905f92f64573bd2d1378ae9041daa1fd Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 1 Jan 2007 00:42:21 +0000 Subject: [PATCH] * 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. --- ChangeLog | 24 +++++++++++++++++++ data/push.c | 11 +++++---- tests/calc.at | 4 ++-- tests/headers.at | 2 -- tests/input.at | 2 -- tests/local.at | 10 +++----- tests/torture.at | 60 +++++++++++++++++++++++++++++++++++++++++------- 7 files changed, 88 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index d622a99c..b5e86bce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2006-12-31 Joel E. Denny + + * 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 For push mode, convert yyparse from a macro to a function, invoke yylex diff --git a/data/push.c b/data/push.c index 3da3f72e..220c0616 100644 --- a/data/push.c +++ b/data/push.c @@ -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( [@output b4_spec_defines_file b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl ' diff --git a/tests/calc.at b/tests/calc.at index 069ca54d..cd37de18 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -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}]) diff --git a/tests/headers.at b/tests/headers.at index 6b170170..4168531c 100644 --- a/tests/headers.at +++ b/tests/headers.at @@ -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) diff --git a/tests/input.at b/tests/input.at index 12d620c8..5686caa4 100644 --- a/tests/input.at +++ b/tests/input.at @@ -529,9 +529,7 @@ AT_DATA([main.c], [[typedef int value; #include "input.h" -#ifndef YYPUSH_DECLS int yyparse (void); -#endif int main (void) diff --git a/tests/local.at b/tests/local.at index 45833a2f..51a35a49 100644 --- a/tests/local.at +++ b/tests/local.at @@ -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 diff --git a/tests/torture.at b/tests/torture.at index 280d79ac..fabab2df 100644 --- a/tests/torture.at +++ b/tests/torture.at @@ -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, [], [ignore]) # 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, [], [ignore]) # 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 -- 2.47.2