%union: fix the support for named %union

Bison supports a union tag, for obscure reasons.  But it does a poor
job at it, especially since Bison 3.0.
Reported by Stephen Cameron and Tobias Frost.

It did not ensure that the name was not given several times.  An easy
way to do this is to make the %union tag be handled as a %define
variable, as they cannot be defined several times.

Since Bison 3.0, the synclines were wrongly placed, resulting in
invalid code.  Addressing this issue, because of the way the union tag
was stored (as a code muscle), would have been tedious.  Unless we
rather define the %union tag as a %percent variable, whose synclines
are easier to manipulate.

So replace the b4_union_name muscle by the api.value.union.name
%define variable, document, and check.

* data/bison.m4: Make sure that api.value.union.name has a keyword value.
* data/c++.m4: Make sure that api.value.union.name is not defined.
* data/c.m4 (b4_union_name): No longer use it, use api.value.union.name.
* doc/bison.texi (%define Summary): Document it.
* src/parse-gram.y (union_name): No longer define b4_uion_name, but
api.value.union.name.
* tests/input.at (Redefined %union name): New.
* tests/synclines.at (%union name syncline): New.
* tests/types.at: Check named %unions.
This commit is contained in:
Akim Demaille
2015-01-04 14:16:23 +01:00
parent 3209eb1c4c
commit 827bc59ca1
12 changed files with 363 additions and 212 deletions

View File

@@ -197,18 +197,23 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
AT_VAL.fval = .2f],
[10 0.2])
# A %union.
AT_TEST([%skeleton "]b4_skel["
%union { float fval; int ival; };],
[%token <ival> '1';
%token <fval> '2';],
['1' '2' { printf ("%d %2.1f\n", $1, $2); }],
["12"],
[if (res == '1')
AT_VAL.ival = 10;
else
AT_VAL.fval = 0.2f],
[10 0.2])
# A %union and a named %union. In C++ named %union is an error.
m4_foreach([b4_union],
[m4_bmatch(b4_skel, [\.cc$],
[[%union]],
[[%union], [%union foo],
[%define api.value.union.name foo; %union]])],
[AT_TEST([%skeleton "]b4_skel["
]b4_union[ { float fval; int ival; };],
[%token <ival> '1';
%token <fval> '2';],
['1' '2' { printf ("%d %2.1f\n", $1, $2); }],
["12"],
[if (res == '1')
AT_VAL.ival = 10;
else
AT_VAL.fval = 0.2f],
[10 0.2])])
# A Bison-defined union.
# The tokens names are not available directly in C++, we use their
@@ -249,3 +254,22 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
m4_popdef([AT_TEST])
m4_popdef([_AT_TEST])
## ------------------- ##
## C++: Named %union. ##
## ------------------- ##
m4_foreach([b4_skel], [[lalr1.cc], [glr.cc]],
[AT_SETUP([b4_skel: Named %union])
AT_DATA([input.y],
[%skeleton "]b4_skel["
%union foo { float fval; int ival; };
%%
exp: %empty;
])
AT_BISON_CHECK([input.y], 1, [],
[[input.y:2.8-10: error: named %union is invalid in C++
]])
AT_CLEANUP
])