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.
** 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
On
R Blake blakers@mac.com
Raja R Harinath harinath@cs.umn.edu
Ralf Wildenhues Ralf.Wildenhues@gmx.de
+Rich Wilson richaw@gmail.com
Richard Stallman rms@gnu.org
Rici Lake ricilake@gmail.com
Rob Conde rob.conde@ai-solutions.com
# b4_symbol_type_register(SYMBOL-NUM)
# -----------------------------------
# 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,
-# and extend the symbol's "type" field to point to the field name,
-# instead of the type name.
+# Extend the definition of %union's body (b4_union_members) with a
+# field of that type, and extend the symbol's "type" field to point to
+# the field name, instead of the type name.
m4_define([b4_symbol_type_register],
[m4_define([b4_symbol($1, type_tag)],
[b4_symbol_if([$1], [has_id],
[b4_symbol([$1], [id])],
[yytype_[]b4_symbol([$1], [number])])])dnl
-m4_append([b4_user_union_members],
+m4_append([b4_union_members],
m4_expand([
b4_symbol_tag_comment([$1])dnl
b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
## 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_copyright([Skeleton implementation for Bison GLR parsers in C],
[2002-2014])[
]b4_epilogue[]dnl
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()
-])])
## api.value.type. ##
## ---------------- ##
-# AT_TEST($1: BISON-DIRECTIVES,
-# $2: MORE-BISON-DIRECTIVES,
-# $3: PARSER-ACTION,
-# $4: INPUT, $5: SCANNER-ACTION,
-# $6: RESULT)
+# _AT_TEST($1: BISON-DIRECTIVES,
+# $2: MORE-BISON-DIRECTIVES,
+# $3: PARSER-ACTION,
+# $4: INPUT,
+# $5: SCANNER-ACTION,
+# $6: RESULT)
# --------------------------------------
# Compile the grammar and check the expected result.
# BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES.
-m4_pushdef([AT_TEST],
+m4_pushdef([_AT_TEST],
[
AT_SETUP([$1])
AT_KEYWORDS([api.value.type])
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]],
[# A built-in type.
AT_TEST([%skeleton "]b4_skel["
])
m4_popdef([AT_TEST])
+m4_popdef([_AT_TEST])