mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-20 09:43:03 +00:00
and Akim Demaille <akim@epita.fr>
* 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.
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
2002-06-18 Cris Bailiff <c.bailiff@awayweb.com>
|
||||||
|
and Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
|
* 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 <akim@epita.fr>
|
2002-06-17 Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
* data/m4sugar/m4sugar.m4 (m4_map): Recognize when the list of
|
* data/m4sugar/m4sugar.m4 (m4_map): Recognize when the list of
|
||||||
|
|||||||
1
THANKS
1
THANKS
@@ -9,6 +9,7 @@ Andreas Schwab schwab@suse.de
|
|||||||
Arnold Robbins arnold@skeeve.com
|
Arnold Robbins arnold@skeeve.com
|
||||||
Benoit Perrot benoit.perrot@epita.fr
|
Benoit Perrot benoit.perrot@epita.fr
|
||||||
Bruce Lilly blilly@erols.com
|
Bruce Lilly blilly@erols.com
|
||||||
|
Cris Bailiff c.bailiff+bison@awayweb.com
|
||||||
Cris van Pelt cris@amf03054.office.wxs.nl
|
Cris van Pelt cris@amf03054.office.wxs.nl
|
||||||
Daniel Hagerty hag@gnu.org
|
Daniel Hagerty hag@gnu.org
|
||||||
David J. MacKenzie djm@gnu.org
|
David J. MacKenzie djm@gnu.org
|
||||||
|
|||||||
@@ -1123,7 +1123,38 @@ yyerrlab1:
|
|||||||
|
|
||||||
/* Return failure if at end of input. */
|
/* Return failure if at end of input. */
|
||||||
if (yychar == YYEOF)
|
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",
|
YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
|
||||||
yychar, yytname[yychar1]));
|
yychar, yytname[yychar1]));
|
||||||
yydestructor (yychar1, yylval);
|
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
|
m4_map([b4_symbol_destructor], m4_defn([b4_symbol_destructors]))dnl
|
||||||
default:
|
default:
|
||||||
YYDPRINTF ((stderr, "yydestructor: unknown symbol type: %s\n",
|
YYDPRINTF ((stderr, "yydestructor: unknown symbol type: %d (%s)\n",
|
||||||
yytname[[symbol_type]]));
|
symbol_type, yytname[[symbol_type]]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
120
tests/actions.at
120
tests/actions.at
@@ -169,61 +169,100 @@ AT_DATA([[input.y]],
|
|||||||
|
|
||||||
#define YYERROR_VERBOSE 1
|
#define YYERROR_VERBOSE 1
|
||||||
#define YYDEBUG 1
|
#define YYDEBUG 1
|
||||||
/* #define YYPRINT yyprint */
|
#define YYPRINT yyprint
|
||||||
|
|
||||||
static int yylex (void);
|
|
||||||
static void yyerror (const char *msg);
|
|
||||||
static void yyprint (FILE *out, int toknum, int tokval);
|
|
||||||
%}
|
%}
|
||||||
|
%verbose
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
int ival;
|
int ival;
|
||||||
}
|
}
|
||||||
%type <ival> thing 'x'
|
%type <ival> '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 thing %d\n", $$); } thing
|
||||||
%destructor { printf ("Freeing 'x' %d\n", $$); } 'x'
|
%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:
|
input:
|
||||||
/* Nothing. */
|
/* 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:
|
line:
|
||||||
thing thing thing ';'
|
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 ';'
|
| thing thing ';'
|
||||||
{ printf ("input: thing(%d) thing(%d) ';'\n", $1, $2); }
|
{
|
||||||
|
$$ = $1;
|
||||||
|
printf ("line(%d): thing(%d) thing(%d) ';'\n", $$, $1, $2);
|
||||||
|
}
|
||||||
| thing ';'
|
| thing ';'
|
||||||
{ printf ("input: thing(%d) ';'\n", $1); }
|
{
|
||||||
|
$$ = $1;
|
||||||
|
printf ("line(%d): thing(%d) ';'\n", $$, $1);
|
||||||
|
}
|
||||||
| error ';'
|
| error ';'
|
||||||
{ printf ("input: error ';'\n"); }
|
{
|
||||||
|
$$ = -1;
|
||||||
|
printf ("line(%d): error ';'\n", $$);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
thing:
|
thing:
|
||||||
'x' { printf ("thing: 'x' (%d)\n", $1); $$ = $1; }
|
'x'
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
printf ("thing(%d): 'x'(%d)\n", $$, $1);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
%%
|
%%
|
||||||
static int
|
static int
|
||||||
yylex (void)
|
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', ';',
|
'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', ';',
|
||||||
'x', ';',
|
'x', ';',
|
||||||
'x', 'y', ';'
|
'y'
|
||||||
};
|
};
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
|
|
||||||
if (counter < (sizeof(input) / sizeof (input[0])))
|
if (counter < (sizeof(input) / sizeof (input[0])))
|
||||||
{
|
{
|
||||||
yylval.ival = counter;
|
yylval.ival = counter;
|
||||||
|
printf ("sending: '%c'(%d)\n", input[counter], counter);
|
||||||
return input[counter++];
|
return input[counter++];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return EOF;
|
{
|
||||||
|
printf ("sending: EOF\n");
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -233,10 +272,9 @@ yyerror (const char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
yyprint (FILE *out, int toknum, int tokval)
|
yyprint (FILE *out, int num, YYSTYPE val)
|
||||||
{
|
{
|
||||||
if (0 < toknum && toknum < 256)
|
fprintf (out, " = %d", val.ival);
|
||||||
fprintf (out, " = %d", tokval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -255,28 +293,42 @@ main (void)
|
|||||||
|
|
||||||
AT_CHECK([bison input.y -d -v -o input.c])
|
AT_CHECK([bison input.y -d -v -o input.c])
|
||||||
AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore])
|
AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore])
|
||||||
AT_CHECK([./input], 0,
|
AT_CHECK([./input], 1,
|
||||||
[[thing: 'x' (0)
|
[[sending: 'x'(0)
|
||||||
thing: 'x' (1)
|
thing(0): 'x'(0)
|
||||||
thing: 'x' (2)
|
sending: 'x'(1)
|
||||||
|
thing(1): 'x'(1)
|
||||||
|
sending: 'x'(2)
|
||||||
|
thing(2): 'x'(2)
|
||||||
|
sending: 'x'(3)
|
||||||
parse error, unexpected 'x', expecting ';'
|
parse error, unexpected 'x', expecting ';'
|
||||||
Freeing thing 2
|
Freeing thing 2
|
||||||
Freeing thing 1
|
Freeing thing 1
|
||||||
Freeing thing 0
|
Freeing thing 0
|
||||||
Freeing 'x' 3
|
Freeing 'x' 3
|
||||||
|
sending: 'x'(4)
|
||||||
Freeing 'x' 4
|
Freeing 'x' 4
|
||||||
|
sending: 'x'(5)
|
||||||
Freeing 'x' 5
|
Freeing 'x' 5
|
||||||
input: error ';'
|
sending: ';'(6)
|
||||||
thing: 'x' (7)
|
line(-1): error ';'
|
||||||
thing: 'x' (8)
|
sending: 'x'(7)
|
||||||
input: thing(7) thing(8) ';'
|
thing(7): 'x'(7)
|
||||||
thing: 'x' (10)
|
sending: 'x'(8)
|
||||||
input: thing(10) ';'
|
thing(8): 'x'(8)
|
||||||
thing: 'x' (12)
|
sending: ';'(9)
|
||||||
parse error, unexpected $undefined., expecting 'x' or ';'
|
line(7): thing(7) thing(8) ';'
|
||||||
Freeing thing 12
|
sending: 'x'(10)
|
||||||
input: error ';'
|
thing(10): 'x'(10)
|
||||||
Successful parse.
|
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
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user