%merge: fix compatibility with api.value.type=union

Reported by Jot Dot.
https://lists.gnu.org/r/help-bison/2020-12/msg00014.html

* data/skeletons/glr.c, data/skeletons/glr2.cc (b4_call_merger): Use
the symbol's slot, not its type.
* examples/c/glr/c++-types.y: Use explicit per-symbol typing together
with api.value.type=union.
(yylex): Use yytoken_kind_t.
This commit is contained in:
Akim Demaille
2020-12-31 07:20:49 +01:00
parent c09f2e4c7b
commit fbe5abd23d
4 changed files with 31 additions and 13 deletions

9
TODO
View File

@@ -2,6 +2,15 @@
** glr ** glr
There is no test with "Parse on stack %ld rejected by rule %d" in it. There is no test with "Parse on stack %ld rejected by rule %d" in it.
** %merge
Tests with typed %merge: 716 717 718 740 741 742 746 747 748
716: Duplicate representation of merged trees: glr.c FAILED (glr-regression.at:517)
740: Leaked semantic values if user action cuts parse: glr.c FAILED (glr-regression.at:1230)
746: Incorrect lookahead during nondeterministic GLR: glr.c FAILED (glr-regression.at:1610)
Document typed merges.
** yyrline etc. ** yyrline etc.
Clarify that rule numbers in the skeletons are 1-based. Clarify that rule numbers in the skeletons are 1-based.

View File

@@ -152,7 +152,7 @@ m4_define([b4_rhs_location],
m4_define([b4_call_merger], m4_define([b4_call_merger],
[b4_case([$1], [b4_case([$1],
[ b4_symbol_if([$3], [has_type], [ b4_symbol_if([$3], [has_type],
[yy0->b4_symbol($3, type) = $2 (*yy0, *yy1);], [yy0->b4_symbol($3, slot) = $2 (*yy0, *yy1);],
[*yy0 = $2 (*yy0, *yy1);])])]) [*yy0 = $2 (*yy0, *yy1);])])])

View File

@@ -127,7 +127,7 @@ m4_define([b4_rhs_location],
m4_define([b4_call_merger], m4_define([b4_call_merger],
[b4_case([$1], [b4_case([$1],
[ b4_symbol_if([$3], [has_type], [ b4_symbol_if([$3], [has_type],
[yy0->b4_symbol($3, type) = $2 (*yy0, *yy1);], [yy0->b4_symbol($3, slot) = $2 (*yy0, *yy1);],
[*yy0 = $2 (*yy0, *yy1);])])]) [*yy0 = $2 (*yy0, *yy1);])])])
# b4_lex # b4_lex

View File

@@ -31,7 +31,7 @@
typedef union Node Node; typedef union Node Node;
} }
%define api.value.type {Node *} %define api.value.type union
%code %code
{ {
@@ -47,11 +47,11 @@
static Node *new_term (char *); static Node *new_term (char *);
static void free_node (Node *); static void free_node (Node *);
static char *node_to_string (Node *); static char *node_to_string (Node *);
static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1); static Node *stmtMerge (YYSTYPE x0, YYSTYPE x1);
static int location_print (FILE *yyo, YYLTYPE const * const yylocp); static int location_print (FILE *yyo, YYLTYPE const * const yylocp);
static void yyerror (YYLTYPE const * const llocp, const char *msg); static void yyerror (YYLTYPE const * const llocp, const char *msg);
static int yylex (YYSTYPE *lvalp, YYLTYPE *llocp); static yytoken_kind_t yylex (YYSTYPE *lvalp, YYLTYPE *llocp);
} }
%expect-rr 1 %expect-rr 1
@@ -65,7 +65,8 @@
%glr-parser %glr-parser
%destructor { free_node ($$); } stmt expr decl declarator TYPENAME ID %type <Node*> stmt expr decl declarator TYPENAME ID
%destructor { free_node ($$); } <Node*>
%% %%
@@ -152,7 +153,8 @@ void yyerror (YYLTYPE const * const llocp, const char *msg)
fprintf (stderr, ": %s\n", msg); fprintf (stderr, ": %s\n", msg);
} }
int yylex (YYSTYPE *lvalp, YYLTYPE *llocp) yytoken_kind_t
yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
{ {
static int lineNum = 1; static int lineNum = 1;
static int colNum = 0; static int colNum = 0;
@@ -178,7 +180,7 @@ int yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
break; break;
default: default:
{ {
int tok; yytoken_kind_t tok;
llocp->first_line = llocp->last_line = lineNum; llocp->first_line = llocp->last_line = lineNum;
llocp->first_column = colNum; llocp->first_column = colNum;
if (isalpha (c)) if (isalpha (c))
@@ -197,14 +199,21 @@ int yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
ungetc (c, stdin); ungetc (c, stdin);
buffer[i++] = 0; buffer[i++] = 0;
tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; if (isupper ((unsigned char) buffer[0]))
*lvalp = new_term (strcpy (malloc (i), buffer)); {
tok = TYPENAME;
lvalp->TYPENAME = new_term (strcpy (malloc (i), buffer));
}
else
{
tok = ID;
lvalp->ID = new_term (strcpy (malloc (i), buffer));
}
} }
else else
{ {
colNum += 1; colNum += 1;
tok = c; tok = c;
*lvalp = NULL;
} }
llocp->last_column = colNum-1; llocp->last_column = colNum-1;
return tok; return tok;
@@ -289,8 +298,8 @@ node_to_string (Node *node)
} }
static YYSTYPE static Node*
stmtMerge (YYSTYPE x0, YYSTYPE x1) stmtMerge (YYSTYPE x0, YYSTYPE x1)
{ {
return new_nterm ("<OR>(%s,%s)", x0, x1, NULL); return new_nterm ("<OR>(%s,%s)", x0.stmt, x1.stmt, NULL);
} }