mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-20 01:33:03 +00:00
yacc.c: fix broken union when api.value.type=union and %defines are used
Reported by Rich Wilson. * data/c.m4 (b4_symbol_type_register): Append to b4_union_members, not b4_user_union_members. The latter invokes the former, but it is the former which is reinitialized to empty by b4_value_type_setup_union. * tests/types.at: Check it. This reveals another bug, this time in the case of glr.c parsers. * data/glr.c: Generate the header file before the implementation file, to be sure that the setup is run before what depends on it.
This commit is contained in:
5
NEWS
5
NEWS
@@ -4,6 +4,11 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
|
||||||
|
*** %define api.value.type union with %defines
|
||||||
|
|
||||||
|
The yacc.c and glr.c parsers were broken when %defines was used
|
||||||
|
together with "%define api.value.type union".
|
||||||
|
|
||||||
*** Redeclarations are reported in proper order
|
*** Redeclarations are reported in proper order
|
||||||
|
|
||||||
On
|
On
|
||||||
|
|||||||
1
THANKS
1
THANKS
@@ -112,6 +112,7 @@ Quoc Peyrot chojin@lrde.epita.fr
|
|||||||
R Blake blakers@mac.com
|
R Blake blakers@mac.com
|
||||||
Raja R Harinath harinath@cs.umn.edu
|
Raja R Harinath harinath@cs.umn.edu
|
||||||
Ralf Wildenhues Ralf.Wildenhues@gmx.de
|
Ralf Wildenhues Ralf.Wildenhues@gmx.de
|
||||||
|
Rich Wilson richaw@gmail.com
|
||||||
Richard Stallman rms@gnu.org
|
Richard Stallman rms@gnu.org
|
||||||
Rici Lake ricilake@gmail.com
|
Rici Lake ricilake@gmail.com
|
||||||
Rob Conde rob.conde@ai-solutions.com
|
Rob Conde rob.conde@ai-solutions.com
|
||||||
|
|||||||
@@ -560,15 +560,15 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
|
|||||||
# b4_symbol_type_register(SYMBOL-NUM)
|
# b4_symbol_type_register(SYMBOL-NUM)
|
||||||
# -----------------------------------
|
# -----------------------------------
|
||||||
# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag.
|
# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag.
|
||||||
# Extend the definition of %union's body with a field of that type,
|
# Extend the definition of %union's body (b4_union_members) with a
|
||||||
# and extend the symbol's "type" field to point to the field name,
|
# field of that type, and extend the symbol's "type" field to point to
|
||||||
# instead of the type name.
|
# the field name, instead of the type name.
|
||||||
m4_define([b4_symbol_type_register],
|
m4_define([b4_symbol_type_register],
|
||||||
[m4_define([b4_symbol($1, type_tag)],
|
[m4_define([b4_symbol($1, type_tag)],
|
||||||
[b4_symbol_if([$1], [has_id],
|
[b4_symbol_if([$1], [has_id],
|
||||||
[b4_symbol([$1], [id])],
|
[b4_symbol([$1], [id])],
|
||||||
[yytype_[]b4_symbol([$1], [number])])])dnl
|
[yytype_[]b4_symbol([$1], [number])])])dnl
|
||||||
m4_append([b4_user_union_members],
|
m4_append([b4_union_members],
|
||||||
m4_expand([
|
m4_expand([
|
||||||
b4_symbol_tag_comment([$1])dnl
|
b4_symbol_tag_comment([$1])dnl
|
||||||
b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
|
b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
|
||||||
|
|||||||
46
data/glr.c
46
data/glr.c
@@ -178,6 +178,39 @@ m4_if(b4_skeleton, ["glr.c"],
|
|||||||
## Output files. ##
|
## Output files. ##
|
||||||
## -------------- ##
|
## -------------- ##
|
||||||
|
|
||||||
|
# Unfortunately the order of generation between the header and the
|
||||||
|
# implementation file matters (for glr.c) because of the current
|
||||||
|
# implementation of api.value.type=union. In that case we still use a
|
||||||
|
# union for YYSTYPE, but we generate the contents of this union when
|
||||||
|
# setting up YYSTYPE. This is needed for other aspects, such as
|
||||||
|
# defining yy_symbol_value_print, since we need to now the name of the
|
||||||
|
# members of this union.
|
||||||
|
#
|
||||||
|
# To avoid this issue, just generate the header before the
|
||||||
|
# implementation file. But we should also make them more independant.
|
||||||
|
|
||||||
|
# ----------------- #
|
||||||
|
# The header file. #
|
||||||
|
# ----------------- #
|
||||||
|
|
||||||
|
# glr.cc produces its own header.
|
||||||
|
m4_if(b4_skeleton, ["glr.c"],
|
||||||
|
[b4_defines_if(
|
||||||
|
[b4_output_begin([b4_spec_defines_file])
|
||||||
|
b4_copyright([Skeleton interface for Bison GLR parsers in C],
|
||||||
|
[2002-2014])[
|
||||||
|
|
||||||
|
]b4_cpp_guard_open([b4_spec_defines_file])[
|
||||||
|
]b4_shared_declarations[
|
||||||
|
]b4_cpp_guard_close([b4_spec_defines_file])[
|
||||||
|
]b4_output_end()
|
||||||
|
])])
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------- #
|
||||||
|
# The implementation file. #
|
||||||
|
# ------------------------- #
|
||||||
|
|
||||||
b4_output_begin([b4_parser_file_name])
|
b4_output_begin([b4_parser_file_name])
|
||||||
b4_copyright([Skeleton implementation for Bison GLR parsers in C],
|
b4_copyright([Skeleton implementation for Bison GLR parsers in C],
|
||||||
[2002-2014])[
|
[2002-2014])[
|
||||||
@@ -2550,16 +2583,3 @@ m4_if(b4_prefix, [yy], [],
|
|||||||
|
|
||||||
]b4_epilogue[]dnl
|
]b4_epilogue[]dnl
|
||||||
b4_output_end()
|
b4_output_end()
|
||||||
|
|
||||||
# glr.cc produces its own header.
|
|
||||||
m4_if(b4_skeleton, ["glr.c"],
|
|
||||||
[b4_defines_if(
|
|
||||||
[b4_output_begin([b4_spec_defines_file])
|
|
||||||
b4_copyright([Skeleton interface for Bison GLR parsers in C],
|
|
||||||
[2002-2014])[
|
|
||||||
|
|
||||||
]b4_cpp_guard_open([b4_spec_defines_file])[
|
|
||||||
]b4_shared_declarations[
|
|
||||||
]b4_cpp_guard_close([b4_spec_defines_file])[
|
|
||||||
]b4_output_end()
|
|
||||||
])])
|
|
||||||
|
|||||||
@@ -61,15 +61,16 @@ AT_CLEANUP
|
|||||||
## api.value.type. ##
|
## api.value.type. ##
|
||||||
## ---------------- ##
|
## ---------------- ##
|
||||||
|
|
||||||
# AT_TEST($1: BISON-DIRECTIVES,
|
# _AT_TEST($1: BISON-DIRECTIVES,
|
||||||
# $2: MORE-BISON-DIRECTIVES,
|
# $2: MORE-BISON-DIRECTIVES,
|
||||||
# $3: PARSER-ACTION,
|
# $3: PARSER-ACTION,
|
||||||
# $4: INPUT, $5: SCANNER-ACTION,
|
# $4: INPUT,
|
||||||
# $6: RESULT)
|
# $5: SCANNER-ACTION,
|
||||||
|
# $6: RESULT)
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
# Compile the grammar and check the expected result.
|
# Compile the grammar and check the expected result.
|
||||||
# BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES.
|
# BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES.
|
||||||
m4_pushdef([AT_TEST],
|
m4_pushdef([_AT_TEST],
|
||||||
[
|
[
|
||||||
AT_SETUP([$1])
|
AT_SETUP([$1])
|
||||||
AT_KEYWORDS([api.value.type])
|
AT_KEYWORDS([api.value.type])
|
||||||
@@ -105,6 +106,25 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# AT_TEST($1: BISON-DIRECTIVES,
|
||||||
|
# $2: MORE-BISON-DIRECTIVES,
|
||||||
|
# $3: PARSER-ACTION,
|
||||||
|
# $4: INPUT,
|
||||||
|
# $5: SCANNER-ACTION,
|
||||||
|
# $6: RESULT)
|
||||||
|
# --------------------------------------
|
||||||
|
# Check with and without %defines, to avoid regressions. It turns out
|
||||||
|
# that in that case yacc.c calls the set-up of the %union twice,
|
||||||
|
# because YYSTYPE is defined once in the header, and once in the
|
||||||
|
# implementation file (eventually it'd be better to include the header
|
||||||
|
# file, but that's another story). Unfortunately running these macros
|
||||||
|
# a second time doubled the side-effects and resulted in a double
|
||||||
|
# definition of the union members.
|
||||||
|
m4_pushdef([AT_TEST],
|
||||||
|
[_AT_TEST([$1], [$2], [$3], [$4], [$5], [$6])
|
||||||
|
_AT_TEST([$1 %defines], [$2], [$3], [$4], [$5], [$6])
|
||||||
|
])
|
||||||
|
|
||||||
m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
||||||
[# A built-in type.
|
[# A built-in type.
|
||||||
AT_TEST([%skeleton "]b4_skel["
|
AT_TEST([%skeleton "]b4_skel["
|
||||||
@@ -228,3 +248,4 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
|||||||
])
|
])
|
||||||
|
|
||||||
m4_popdef([AT_TEST])
|
m4_popdef([AT_TEST])
|
||||||
|
m4_popdef([_AT_TEST])
|
||||||
|
|||||||
Reference in New Issue
Block a user