From 5719c1092fec376fe02ecbd7f82bf2263e513959 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 18 Jun 2002 09:12:58 +0000 Subject: [PATCH] and Akim Demaille * data/bison.simple.new (yyerrlab1): Be sure to pop and destroy what's left on the stack when the error recovery hits EOF. * tests/actions.at (Destructors): Complete to exercise this case. --- ChangeLog | 7 +++ THANKS | 1 + data/bison.simple | 37 ++++++++++++-- tests/actions.at | 120 +++++++++++++++++++++++++++++++++------------- 4 files changed, 128 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index e83fe2ac..96774cbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-06-18 Cris Bailiff + and Akim Demaille + + * data/bison.simple.new (yyerrlab1): Be sure to pop and destroy + what's left on the stack when the error recovery hits EOF. + * tests/actions.at (Destructors): Complete to exercise this case. + 2002-06-17 Akim Demaille * data/m4sugar/m4sugar.m4 (m4_map): Recognize when the list of diff --git a/THANKS b/THANKS index 292b58c5..8bf7741e 100644 --- a/THANKS +++ b/THANKS @@ -9,6 +9,7 @@ Andreas Schwab schwab@suse.de Arnold Robbins arnold@skeeve.com Benoit Perrot benoit.perrot@epita.fr Bruce Lilly blilly@erols.com +Cris Bailiff c.bailiff+bison@awayweb.com Cris van Pelt cris@amf03054.office.wxs.nl Daniel Hagerty hag@gnu.org David J. MacKenzie djm@gnu.org diff --git a/data/bison.simple b/data/bison.simple index 80314c0c..7b48459a 100644 --- a/data/bison.simple +++ b/data/bison.simple @@ -1123,7 +1123,38 @@ yyerrlab1: /* Return failure if at end of input. */ if (yychar == YYEOF) - YYABORT; + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyssp > yyss) + { +#if YYDEBUG + if (yydebug) + { + if (yystos[*yyssp] < YYNTOKENS) + { + YYFPRINTF (stderr, "Error: popping token %d (%s", + yytoknum[yystos[*yyssp]], + yytname[yystos[*yyssp]]); +# ifdef YYPRINT + YYPRINT (stderr, yytoknum[yystos[*yyssp]], *yyvsp); +# endif + YYFPRINTF (stderr, ")\n"); + } + else + { + YYFPRINTF (stderr, "Error: popping nonterminal (%s)\n", + yytname[yystos[*yyssp]]); + } + } +#endif + yydestructor (yystos[*yyssp], *yyvsp); + YYPOPSTACK; + } + YYABORT; + } + YYDPRINTF ((stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1])); yydestructor (yychar1, yylval); @@ -1263,8 +1294,8 @@ yydestructor (int symbol_type, YYSTYPE symbol_value) { m4_map([b4_symbol_destructor], m4_defn([b4_symbol_destructors]))dnl default: - YYDPRINTF ((stderr, "yydestructor: unknown symbol type: %s\n", - yytname[[symbol_type]])); + YYDPRINTF ((stderr, "yydestructor: unknown symbol type: %d (%s)\n", + symbol_type, yytname[[symbol_type]])); break; } } diff --git a/tests/actions.at b/tests/actions.at index 2c614874..8da9d3ea 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -169,61 +169,100 @@ AT_DATA([[input.y]], #define YYERROR_VERBOSE 1 #define YYDEBUG 1 -/* #define YYPRINT yyprint */ - -static int yylex (void); -static void yyerror (const char *msg); -static void yyprint (FILE *out, int toknum, int tokval); +#define YYPRINT yyprint %} - +%verbose %union { int ival; } -%type thing 'x' +%type 'x' thing line input +%destructor { printf ("Freeing input %d\n", $$); } input +%destructor { printf ("Freeing line %d\n", $$); } line %destructor { printf ("Freeing thing %d\n", $$); } thing %destructor { printf ("Freeing 'x' %d\n", $$); } 'x' +%{ +static int yylex (void); +static void yyerror (const char *msg); +static void yyprint (FILE *out, int num, YYSTYPE val); +%} + + %% input: /* Nothing. */ -| input line + { + $$ = 0; + printf ("input(%d): /* Nothing */';'\n", $$); + } +| line input /* Right recursive to load the stack so that popping at + EOF can be exercised. */ + { + $$ = 2; + printf ("input(%d): line(%d) input(%d)';'\n", $$, $1, $2); + } ; line: thing thing thing ';' - { printf ("input: thing(%d) thing(%d) thing(%d) ';'\n", $1, $2, $3); } + { + $$ = $1; + printf ("line(%d): thing(%d) thing(%d) thing(%d) ';'\n", $$, $1, $2, $3); + } | thing thing ';' - { printf ("input: thing(%d) thing(%d) ';'\n", $1, $2); } + { + $$ = $1; + printf ("line(%d): thing(%d) thing(%d) ';'\n", $$, $1, $2); + } | thing ';' - { printf ("input: thing(%d) ';'\n", $1); } + { + $$ = $1; + printf ("line(%d): thing(%d) ';'\n", $$, $1); + } | error ';' - { printf ("input: error ';'\n"); } + { + $$ = -1; + printf ("line(%d): error ';'\n", $$); + } ; thing: - 'x' { printf ("thing: 'x' (%d)\n", $1); $$ = $1; } + 'x' + { + $$ = $1; + printf ("thing(%d): 'x'(%d)\n", $$, $1); + } ; %% static int yylex (void) { - static const int input[] = + static const unsigned int input[] = { + /* Exericise the discarding of stack top and input until `error' + can be reduced. */ 'x', 'x', 'x', 'x', 'x', 'x', ';', + + /* Load the stack and provoke an error that cannot be caught be + the grammar, and check that the stack is cleared. */ 'x', 'x', ';', 'x', ';', - 'x', 'y', ';' + 'y' }; static int counter = 0; if (counter < (sizeof(input) / sizeof (input[0]))) { yylval.ival = counter; + printf ("sending: '%c'(%d)\n", input[counter], counter); return input[counter++]; } else - return EOF; + { + printf ("sending: EOF\n"); + return EOF; + } } static void @@ -233,10 +272,9 @@ yyerror (const char *msg) } static void -yyprint (FILE *out, int toknum, int tokval) +yyprint (FILE *out, int num, YYSTYPE val) { - if (0 < toknum && toknum < 256) - fprintf (out, " = %d", tokval); + fprintf (out, " = %d", val.ival); } int @@ -255,28 +293,42 @@ main (void) AT_CHECK([bison input.y -d -v -o input.c]) AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore]) -AT_CHECK([./input], 0, -[[thing: 'x' (0) -thing: 'x' (1) -thing: 'x' (2) +AT_CHECK([./input], 1, +[[sending: 'x'(0) +thing(0): 'x'(0) +sending: 'x'(1) +thing(1): 'x'(1) +sending: 'x'(2) +thing(2): 'x'(2) +sending: 'x'(3) parse error, unexpected 'x', expecting ';' Freeing thing 2 Freeing thing 1 Freeing thing 0 Freeing 'x' 3 +sending: 'x'(4) Freeing 'x' 4 +sending: 'x'(5) Freeing 'x' 5 -input: error ';' -thing: 'x' (7) -thing: 'x' (8) -input: thing(7) thing(8) ';' -thing: 'x' (10) -input: thing(10) ';' -thing: 'x' (12) -parse error, unexpected $undefined., expecting 'x' or ';' -Freeing thing 12 -input: error ';' -Successful parse. +sending: ';'(6) +line(-1): error ';' +sending: 'x'(7) +thing(7): 'x'(7) +sending: 'x'(8) +thing(8): 'x'(8) +sending: ';'(9) +line(7): thing(7) thing(8) ';' +sending: 'x'(10) +thing(10): 'x'(10) +sending: ';'(11) +line(10): thing(10) ';' +sending: 'y'(12) +parse error, unexpected $undefined., expecting $ or error or 'x' +sending: EOF +Freeing line 10 +Freeing line 7 +Freeing line -1 +Parsing FAILED. ]]) AT_CLEANUP -- 2.47.2