mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-16 07:43: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)
|
if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
|
||||||
YYFPRINTF (stderr, "%*s%s <empty>\n", yyindent+2, "",
|
YYFPRINTF (stderr, "%*s%s <empty>\n", yyindent+2, "",
|
||||||
yytokenName (yystos[yystates[yyi-1]->yylrState]));
|
yytokenName (yystos[yystates[yyi]->yylrState]));
|
||||||
else
|
else
|
||||||
YYFPRINTF (stderr, "%*s%s <tokens %lu .. %lu>\n", yyindent+2, "",
|
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-1]->yyposn + 1),
|
||||||
(unsigned long int) yystates[yyi]->yyposn);
|
(unsigned long int) yystates[yyi]->yyposn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1788,3 +1788,120 @@ glr-regr18.y:26.18-24: previous declaration
|
|||||||
])
|
])
|
||||||
|
|
||||||
AT_CLEANUP
|
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