+[[%code bad {}
+%code q {}
+%code q {}
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [],
+[[input-c++-glr.y:1.7-9: %code qualifier `bad' is not used
+input-c++-glr.y:2.7: %code qualifier `q' is not used
+input-c++-glr.y:3.7: %code qualifier `q' is not used
+]])
+
+AT_DATA([special-char-@@.y],
+[[%code bad {}
+%code q {}
+%code q {}
+%%
+start: ;
+]])
+AT_BISON_CHECK([[special-char-@@.y]], [[1]], [],
+[[special-char-@@.y:1.7-9: %code qualifier `bad' is not used
+special-char-@@.y:2.7: %code qualifier `q' is not used
+special-char-@@.y:3.7: %code qualifier `q' is not used
+]])
+
+AT_DATA([special-char-@:>@.y],
+[[%code bad {}
+%code q {}
+%code q {}
+%%
+start: ;
+]])
+AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [],
+[[special-char-@:>@.y:1.7-9: %code qualifier `bad' is not used
+special-char-@:>@.y:2.7: %code qualifier `q' is not used
+special-char-@:>@.y:3.7: %code qualifier `q' is not used
+]])
+
+AT_CLEANUP
+
+
+## ---------------- ##
+## %define errors. ##
+## ---------------- ##
+
+AT_SETUP([%define errors])
+
+AT_DATA([input-redefined.y],
+[[%define var "value1"
+%define var "value1"
+ %define var "value2"
+%define special1 "@:>@"
+%define special2 "@<:@"
+%%
+start: ;
+]])
+
+AT_BISON_CHECK([[input-redefined.y]], [[1]], [],
+[[input-redefined.y:2.9-11: %define variable `var' redefined
+input-redefined.y:1.9-11: previous definition
+input-redefined.y:3.10-12: %define variable `var' redefined
+input-redefined.y:2.9-11: previous definition
+]])
+
+AT_DATA([input-unused.y],
+[[%define var "value"
+%%
+start: ;
+]])
+
+AT_BISON_CHECK([[input-unused.y]], [[1]], [],
+[[input-unused.y:1.9-11: %define variable `var' is not used
+]])
+
+AT_CLEANUP
+
+
+## ----------------------------------- ##
+## %define, --define, --force-define. ##
+## ----------------------------------- ##
+
+AT_SETUP([[%define, --define, --force-define]])
+
+AT_DATA([[skel.c]],
+[[m4@&t@_divert_push(0)@
+@output(b4_parser_file_name@)@
+[var-dd: ]b4_percent_define_get([[var-dd]])[
+var-ff: ]b4_percent_define_get([[var-ff]])[
+var-dfg: ]b4_percent_define_get([[var-dfg]])[
+var-fd: ]b4_percent_define_get([[var-fd]])
+m4@&t@_divert_pop(0)
+]])
+AT_DATA([[input.y]],
+[[%define var-dfg "gram"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \
+ -Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \
+ -Dvar-dfg=cmd-d -Fvar-dfg=cmd-f \
+ -Fvar-fd=cmd-f -Dvar-fd=cmd-d \
+ --skeleton ./skel.c input.y]])
+AT_CHECK([[cat input.tab.c]], [[0]],
+[[var-dd: cmd-d2
+var-ff: cmd-f2
+var-dfg: cmd-f
+var-fd: cmd-d
+]])
+
+AT_DATA([[input-dg.y]],
+[[%define var "gram"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
+[[input-dg.y:1.9-11: %define variable `var' redefined
+<command line>:2: previous definition
+]])
+
+AT_DATA([[input-unused.y]],
+[[%%
+start: ;
+]])
+AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [],
+[[<command line>:2: %define variable `unused-d' is not used
+<command line>:3: %define variable `unused-f' is not used
+]])
+
+AT_CLEANUP
+
+## --------------------------- ##
+## %define Boolean variables. ##
+## --------------------------- ##
+
+AT_SETUP([[%define Boolean variables]])
+
+AT_DATA([Input.y],
+[[%language "Java"
+%define public "maybe"
+%define parser_class_name "Input"
+%%
+start: ;
+]])
+
+AT_BISON_CHECK([[Input.y]], [1], [],
+[[Input.y:2.9-14: invalid value for %define Boolean variable `public'
+]])
+
+AT_CLEANUP
+
+## ------------------------ ##
+## %define enum variables. ##
+## ------------------------ ##
+
+AT_SETUP([[%define enum variables]])
+
+# Front-end.
+AT_DATA([[input.y]],
+[[%define lr.default-reductions bogus
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [[1]], [[]],
+[[input.y:1.9-29: invalid value for %define variable `lr.default-reductions': `bogus'
+input.y:1.9-29: accepted value: `all'
+input.y:1.9-29: accepted value: `consistent'
+input.y:1.9-29: accepted value: `accepting'
+]])
+
+# Back-end.
+AT_DATA([[input.y]],
+[[%define api.push-pull neither
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [1], [],
+[[input.y:1.9-21: invalid value for %define variable `api.push-pull': `neither'
+input.y:1.9-21: accepted value: `pull'
+input.y:1.9-21: accepted value: `push'
+input.y:1.9-21: accepted value: `both'
+]])
+
+AT_CLEANUP
+
+## -------------------------------- ##
+## %define backward compatibility. ##
+## -------------------------------- ##
+
+AT_SETUP([[%define backward compatibility]])
+
+# The error messages tell us whether underscores in these variables are
+# being converted to dashes.
+
+AT_DATA([[input.y]],
+[[%define api.push_pull "neither"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [1], [],
+[[input.y:1.9-21: invalid value for %define variable `api.push-pull': `neither'
+input.y:1.9-21: accepted value: `pull'
+input.y:1.9-21: accepted value: `push'
+input.y:1.9-21: accepted value: `both'
+]])
+
+AT_DATA([[input.y]],
+[[%define lr.keep_unreachable_states maybe
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [1], [],
+[[input.y:1.9-34: invalid value for %define Boolean variable `lr.keep-unreachable-states'
+]])
+
+AT_DATA([[input.y]],
+[[%define namespace "foo"
+%define api.namespace "foo"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [1], [],
+[[input.y:2.9-21: %define variable `api.namespace' redefined
+input.y:1.9-17: previous definition
+]])
+
+AT_DATA([[input.y]],
+[[%define foo_bar "baz"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [[1]], [],
+[[input.y:1.9-15: %define variable `foo_bar' is not used
+]])
+
+AT_CLEANUP
+
+## ------------------------- ##
+## Unused %define api.pure. ##
+## ------------------------- ##
+
+AT_SETUP([[Unused %define api.pure]])
+
+# AT_CHECK_API_PURE(DECLS, VALUE)
+# -------------------------------
+# Make sure Bison reports that `%define api.pure VALUE' is unused when DECLS
+# are specified.
+m4_define([AT_CHECK_API_PURE],
+[
+AT_DATA([[input.y]],
+[[%define api.pure ]$2[
+]$1[
+%%
+start: ;
+]])
+
+AT_BISON_CHECK([[input.y]], [[1]], [],
+[[input.y:1.9-16: %define variable `api.pure' is not used
+]])
+])
+
+AT_CHECK_API_PURE([[%language "c++" %defines]], [[]])
+AT_CHECK_API_PURE([[%language "c++" %defines]], [[false]])
+AT_CHECK_API_PURE([[%language "c++" %defines %glr-parser]], [[""]])
+AT_CHECK_API_PURE([[%language "c++" %defines %glr-parser]], [[false]])
+AT_CHECK_API_PURE([[%language "java"]], [[true]])
+AT_CHECK_API_PURE([[%language "java"]], [[false]])
+
+AT_CLEANUP
+
+## -------------------------------- ##
+## C++ namespace reference errors. ##
+## -------------------------------- ##
+
+AT_SETUP([[C++ namespace reference errors]])
+
+# AT_CHECK_NAMESPACE_ERROR(NAMESPACE-DECL, ERROR, [ERROR], ...)
+# -------------------------------------------------------------
+# Make sure Bison reports all ERROR's for %define namespace "NAMESPACE-DECL".
+m4_define([AT_CHECK_NAMESPACE_ERROR],
+[
+AT_DATA([[input.y]],
+[[%language "C++"
+%defines
+%define api.namespace "]$1["