+ 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC .
+
+ $default reduce using rule 3 (CONST_DEC_LIST)
+
+
+State 7
+
+ 5 CONST_DEC: $@1 undef_id_tok . '=' const_id_tok ';'
+
+ '=' shift, and go to state 8
+
+
+State 8
+
+ 5 CONST_DEC: $@1 undef_id_tok '=' . const_id_tok ';'
+
+ const_id_tok shift, and go to state 9
+
+
+State 9
+
+ 5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok . ';'
+
+ ';' shift, and go to state 10
+
+
+State 10
+
+ 5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';' .
+
+ $default reduce using rule 5 (CONST_DEC)
+]])
+
+AT_CLEANUP
+
+
+## --------------- ##
+## Web2c Actions. ##
+## --------------- ##
+
+# The generation of the mapping 'state -> action' was once wrong in
+# extremely specific situations. web2c.y exhibits this situation.
+# Below is a stripped version of the grammar. It looks like one can
+# simplify it further, but just don't: it is tuned to exhibit a bug,
+# which disapears when applying sane grammar transformations.
+#
+# It used to be wrong on yydefact only:
+#
+# static const yytype_uint8 yydefact[] =
+# {
+# - 2, 0, 1, 0, 0, 2, 3, 2, 5, 4,
+# + 2, 0, 1, 0, 0, 0, 3, 2, 5, 4,
+# 0, 0
+# };
+#
+# but let's check all the tables.
+
+
+AT_SETUP([Web2c Actions])
+
+AT_KEYWORDS([report])
+
+AT_DATA([input.y],
+[[%%
+statement: struct_stat;
+struct_stat: /* empty. */ | if else;
+if: "if" "const" "then" statement;
+else: "else" statement;
+%%
+]])
+
+AT_BISON_CHECK([-v -o input.c input.y])
+
+# Check only the tables.
+[sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c]
+
+AT_CHECK([[cat tables.c]], 0,
+[[static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6
+};
+static const yytype_uint8 yyrline[] =
+{
+ 0, 2, 2, 3, 3, 4, 5
+};
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"",
+ "\"else\"", "$accept", "statement", "struct_stat", "if", "else", YY_NULL
+};
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261
+};
+static const yytype_int8 yypact[] =
+{
+ -2, -1, 4, -8, 0, 2, -8, -2, -8, -2,
+ -8, -8
+};
+static const yytype_uint8 yydefact[] =
+{
+ 3, 0, 0, 2, 0, 0, 1, 3, 4, 3,
+ 6, 5
+};
+static const yytype_int8 yypgoto[] =
+{
+ -8, -7, -8, -8, -8
+};
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 2, 3, 4, 8
+};
+static const yytype_uint8 yytable[] =
+{
+ 10, 1, 11, 5, 6, 0, 7, 9
+};
+static const yytype_int8 yycheck[] =
+{
+ 7, 3, 9, 4, 0, -1, 6, 5
+};
+static const yytype_uint8 yystos[] =
+{
+ 0, 3, 8, 9, 10, 4, 0, 6, 11, 5,
+ 8, 8
+};
+static const yytype_uint8 yyr1[] =
+{
+ 0, 7, 8, 9, 9, 10, 11
+};
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 0, 2, 4, 2
+};
+]])
+
+AT_CLEANUP
+
+
+## ------------------------- ##
+## yycheck Bound Violation. ##
+## ------------------------- ##
+
+
+# _AT_DATA_DANCER_Y(BISON-OPTIONS)
+# --------------------------------
+# The following grammar, taken from Andrew Suffield's GPL'd implementation
+# of DGMTP, the Dancer Generic Message Transport Protocol, used to violate
+# yycheck's bounds where issuing a verbose error message. Keep this test
+# so that possible bound checking compilers could check all the skeletons.
+m4_define([_AT_DATA_DANCER_Y],
+[AT_DATA_GRAMMAR([dancer.y],
+[[%code provides
+{
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
+}
+$1
+%token ARROW INVALID NUMBER STRING DATA
+%defines
+%verbose
+%error-verbose
+/* Grammar follows */
+%%
+line: header body
+ ;
+
+header: '<' from ARROW to '>' type ':'
+ | '<' ARROW to '>' type ':'
+ | ARROW to type ':'
+ | type ':'
+ | '<' '>'
+ ;
+
+from: DATA
+ | STRING
+ | INVALID
+ ;
+
+to: DATA
+ | STRING
+ | INVALID
+ ;
+
+type: DATA
+ | STRING
+ | INVALID
+ ;
+
+body: /* empty */
+ | body member
+ ;
+
+member: STRING
+ | DATA
+ | '+' NUMBER
+ | '-' NUMBER
+ | NUMBER
+ | INVALID
+ ;
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE([":"])[
+]AT_LALR1_CC_IF(
+[int
+yyparse ()
+{
+ yy::parser parser;
+#if YYDEBUG
+ parser.set_debug_level (YYDEBUG);
+#endif
+ return parser.parse ();
+}
+])[
+
+int
+main (void)