+CONST_DEC_PART:
+ CONST_DEC_LIST
+ ;
+
+CONST_DEC_LIST:
+ CONST_DEC
+ | CONST_DEC_LIST CONST_DEC
+ ;
+
+CONST_DEC:
+ { } undef_id_tok '=' const_id_tok ';'
+ ;
+%%
+]])
+
+AT_BISON_CHECK([-v input.y])
+AT_CHECK([cat input.output], 0,
+[[Grammar
+
+ 0 $accept: CONST_DEC_PART $end
+
+ 1 CONST_DEC_PART: CONST_DEC_LIST
+
+ 2 CONST_DEC_LIST: CONST_DEC
+ 3 | CONST_DEC_LIST CONST_DEC
+
+ 4 $@1: /* empty */
+
+ 5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';'
+
+
+Terminals, with rules where they appear
+
+$end (0) 0
+';' (59) 5
+'=' (61) 5
+error (256)
+undef_id_tok (258) 5
+const_id_tok (259) 5
+
+
+Nonterminals, with rules where they appear
+
+$accept (7)
+ on left: 0
+CONST_DEC_PART (8)
+ on left: 1, on right: 0
+CONST_DEC_LIST (9)
+ on left: 2 3, on right: 1 3
+CONST_DEC (10)
+ on left: 5, on right: 2 3
+$@1 (11)
+ on left: 4, on right: 5
+
+
+state 0
+
+ 0 $accept: . CONST_DEC_PART $end
+
+ $default reduce using rule 4 ($@1)
+
+ CONST_DEC_PART go to state 1
+ CONST_DEC_LIST go to state 2
+ CONST_DEC go to state 3
+ $@1 go to state 4
+
+
+state 1
+
+ 0 $accept: CONST_DEC_PART . $end
+
+ $end shift, and go to state 5
+
+
+state 2
+
+ 1 CONST_DEC_PART: CONST_DEC_LIST .
+ 3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC
+
+ undef_id_tok reduce using rule 4 ($@1)
+ $default reduce using rule 1 (CONST_DEC_PART)
+
+ CONST_DEC go to state 6
+ $@1 go to state 4
+
+
+state 3
+
+ 2 CONST_DEC_LIST: CONST_DEC .
+
+ $default reduce using rule 2 (CONST_DEC_LIST)
+
+
+state 4
+
+ 5 CONST_DEC: $@1 . undef_id_tok '=' const_id_tok ';'
+
+ undef_id_tok shift, and go to state 7
+
+
+state 5
+
+ 0 $accept: CONST_DEC_PART $end .
+
+ $default accept
+
+
+state 6
+
+ 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 yyprhs[] =
+{
+ 0, 0, 3, 5, 6, 9, 14
+};
+static const yytype_int8 yyrhs[] =
+{
+ 8, 0, -1, 9, -1, -1, 10, 11, -1, 3,
+ 4, 5, 8, -1, 6, 8, -1
+};
+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", 0
+};
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261
+};
+static const yytype_uint8 yyr1[] =
+{
+ 0, 7, 8, 9, 9, 10, 11
+};
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 0, 2, 4, 2
+};
+static const yytype_uint8 yydefact[] =
+{
+ 3, 0, 0, 2, 0, 0, 1, 3, 4, 3,
+ 6, 5
+};
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 2, 3, 4, 8
+};
+static const yytype_int8 yypact[] =
+{
+ -2, -1, 4, -8, 0, 2, -8, -2, -8, -2,
+ -8, -8
+};
+static const yytype_int8 yypgoto[] =
+{
+ -8, -7, -8, -8, -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
+};
+]])
+
+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],
+[%{
+static int yylex (AT_LALR1_CC_IF([int *], [void]));
+AT_LALR1_CC_IF([],
+[#include <stdlib.h>
+#include <stdio.h>
+static void yyerror (const char *);])
+%}
+$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
+ ;