mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
glr: fix ambiguity reports.
Fix a regression introduced in commit
783aa653f4.
* tests/glr-regression.at (Ambiguity reports): New.
* data/glr.c (yyreportTree): Fix an offset error.
This commit is contained in:
@@ -1727,10 +1727,10 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
|
||||
{
|
||||
if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
|
||||
YYFPRINTF (stderr, "%*s%s <empty>\n", yyindent+2, "",
|
||||
yytokenName (yystos[yystates[yyi-1]->yylrState]));
|
||||
yytokenName (yystos[yystates[yyi]->yylrState]));
|
||||
else
|
||||
YYFPRINTF (stderr, "%*s%s <tokens %lu .. %lu>\n", yyindent+2, "",
|
||||
yytokenName (yystos[yystates[yyi-1]->yylrState]),
|
||||
yytokenName (yystos[yystates[yyi]->yylrState]),
|
||||
(unsigned long int) (yystates[yyi-1]->yyposn + 1),
|
||||
(unsigned long int) yystates[yyi]->yyposn);
|
||||
}
|
||||
|
||||
@@ -1788,3 +1788,120 @@ glr-regr18.y:26.18-24: previous declaration
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------- ##
|
||||
## Ambiguity reports. ##
|
||||
## ------------------- ##
|
||||
|
||||
AT_SETUP([Ambiguity reports])
|
||||
|
||||
AT_DATA_GRAMMAR([input.y],
|
||||
[[
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
static void yyerror (char const *);
|
||||
static int yylex (void);
|
||||
%}
|
||||
|
||||
%debug
|
||||
%glr-parser
|
||||
|
||||
%%
|
||||
start:
|
||||
'a' b 'c' d
|
||||
| 'a' b 'c' d
|
||||
;
|
||||
b: 'b';
|
||||
d: /* nada. */;
|
||||
%%
|
||||
|
||||
static int
|
||||
yylex (void)
|
||||
{
|
||||
static char const input[] = "abc";
|
||||
static size_t toknum;
|
||||
if (! (toknum < sizeof input))
|
||||
abort ();
|
||||
return input[toknum++];
|
||||
}
|
||||
|
||||
static void
|
||||
yyerror (char const *msg)
|
||||
{
|
||||
fprintf (stderr, "%s\n", msg);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
yydebug = 1;
|
||||
return !!yyparse ();
|
||||
}
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[-o input.c input.y]], 0, [],
|
||||
[input.y: conflicts: 1 reduce/reduce
|
||||
])
|
||||
AT_COMPILE([input])
|
||||
|
||||
AT_PARSER_CHECK([[./input]], 1, [],
|
||||
[Starting parse
|
||||
Entering state 0
|
||||
Reading a token: Next token is token 'a' ()
|
||||
Shifting token 'a' ()
|
||||
Entering state 1
|
||||
Reading a token: Next token is token 'b' ()
|
||||
Shifting token 'b' ()
|
||||
Entering state 3
|
||||
Reducing stack 0 by rule 3 (line 25):
|
||||
$1 = token 'b' ()
|
||||
-> $$ = nterm b ()
|
||||
Entering state 4
|
||||
Reading a token: Next token is token 'c' ()
|
||||
Shifting token 'c' ()
|
||||
Entering state 6
|
||||
Reducing stack 0 by rule 4 (line 26):
|
||||
-> $$ = nterm d ()
|
||||
Entering state 7
|
||||
Reading a token: Now at end of input.
|
||||
Stack 0 Entering state 7
|
||||
Now at end of input.
|
||||
Splitting off stack 1 from 0.
|
||||
Reduced stack 1 by rule #2; action deferred. Now in state 2.
|
||||
Stack 1 Entering state 2
|
||||
Now at end of input.
|
||||
Reduced stack 0 by rule #1; action deferred. Now in state 2.
|
||||
Merging stack 0 into stack 1.
|
||||
Stack 1 Entering state 2
|
||||
Now at end of input.
|
||||
Removing dead stacks.
|
||||
Rename stack 1 -> 0.
|
||||
On stack 0, shifting token $end ()
|
||||
Stack 0 now in state #5
|
||||
Ambiguity detected.
|
||||
Option 1,
|
||||
start -> <Rule 1, tokens 1 .. 3>
|
||||
'a' <tokens 1 .. 1>
|
||||
b <tokens 2 .. 2>
|
||||
'c' <tokens 3 .. 3>
|
||||
d <empty>
|
||||
|
||||
Option 2,
|
||||
start -> <Rule 2, tokens 1 .. 3>
|
||||
'a' <tokens 1 .. 1>
|
||||
b <tokens 2 .. 2>
|
||||
'c' <tokens 3 .. 3>
|
||||
d <empty>
|
||||
|
||||
syntax is ambiguous
|
||||
Cleanup: popping token $end ()
|
||||
Cleanup: popping unresolved nterm start ()
|
||||
Cleanup: popping nterm d ()
|
||||
Cleanup: popping token 'c' ()
|
||||
Cleanup: popping nterm b ()
|
||||
Cleanup: popping token 'a' ()
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
Reference in New Issue
Block a user