]> git.saurik.com Git - bison.git/commitdiff
Merge remote-tracking branch 'origin/maint'
authorAkim Demaille <akim@lrde.epita.fr>
Thu, 28 Jun 2012 13:29:18 +0000 (15:29 +0200)
committerAkim Demaille <akim@lrde.epita.fr>
Thu, 28 Jun 2012 13:42:00 +0000 (15:42 +0200)
* origin/maint:
  tests: use the generalized default yylex.
  tests: AT_YYERROR_DEFINE: prepare for list of ints.
  skeletons: no longer define YYLSP_NEEDED.
  c++: do not export YYTOKEN_TABLE and YYERROR_VERBOSE.

Conflicts:
data/c.m4
data/glr.cc
data/lalr1.cc
doc/bison.texi
tests/regression.at

12 files changed:
1  2 
NEWS
data/bison.m4
data/c.m4
data/glr.c
data/glr.cc
data/lalr1.cc
data/yacc.c
src/output.c
tests/actions.at
tests/conflicts.at
tests/local.at
tests/regression.at

diff --combined NEWS
index 41e685196e2558c0dab97d8b89fa2f6651cc7f72,33fac14571f23f3bb5d93d826a204319f0c91fec..e1373657b4993abb3e5959c197713f510e05bc75
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -2,117 -2,6 +2,117 @@@ GNU Bison NEW
  
  * Noteworthy changes in release ?.? (????-??-??) [?]
  
 +** Warnings about useless semantic types
 +
 +  Bison now warns about useless (uninhabited) semantic types.  Since
 +  semantic types are not declared to Bison (they are defined in the opaque
 +  %union structure), it is %printer/%destructor directives about useless
 +  types that trigger the warning:
 +
 +    %token <type1> term
 +    %type  <type2> nterm
 +    %printer    {} <type1> <type3>
 +    %destructor {} <type2> <type4>
 +    %%
 +    nterm: term { $$ = $1; };
 +
 +    3.28-34: warning: type <type3> is used, but is not associated to any symbol
 +    4.28-34: warning: type <type4> is used, but is not associated to any symbol
 +
 +** Warnings about undeclared symbols
 +
 +  Bison used to raise an error for %printer and %destructor directives for
 +  undefined symbols.
 +
 +    %printer    {} symbol1
 +    %destructor {} symbol2
 +    %%
 +    exp: "a";
 +
 +  This is now only a warning.
 +
 +** Warnings about useless destructors or printers
 +
 +  Bison now warns about useless destructors or printers.  In the following
 +  example, the printer for <type1>, and the destructor for <type2> are
 +  useless: all symbols of <type1> (token1) already have a printer, and all
 +  symbols of type <type2> (token2) already have a destructor.
 +
 +    %token <type1> token1
 +           <type2> token2
 +           <type3> token3
 +           <type4> token4
 +    %printer    {} token1 <type1> <type3>
 +    %destructor {} token2 <type2> <type4>
 +
 +** Additional yylex/yyparse arguments
 +
 +  The new directive %param declares additional arguments to both yylex and
 +  yyparse.  The %lex-param, %parse-param, and %param directives support one
 +  or more arguments.  Instead of
 +
 +    %lex-param   {arg1_type *arg1}
 +    %lex-param   {arg2_type *arg2}
 +    %parse-param {arg1_type *arg1}
 +    %parse-param {arg2_type *arg2}
 +
 +  one may now declare
 +
 +    %param {arg1_type *arg1} {arg2_type *arg2}
 +
 +** Java skeleton improvements
 +
 +  The constants for token names were moved to the Lexer interface.
 +  Also, it is possible to add code to the parser's constructors using
 +  "%code init" and "%define init_throws".
 +
 +** C++ skeleton improvements
 +
 +  The C++ parser features a syntax_error exception, which can be
 +  thrown from the scanner or from user rules to raise syntax errors.
 +  This facilitates reporting errors caught in sub-functions (e.g.,
 +  rejecting too large integral literals from a conversion function
 +  used by the scanner, or rejecting invalid combinations from a
 +  factory invoked by the user actions).
 +
 +** Variable api.tokens.prefix
 +
 +  The variable api.tokens.prefix changes the way tokens are identified in
 +  the generated files.  This is especially useful to avoid collisions
 +  with identifiers in the target language.  For instance
 +
 +    %token FILE for ERROR
 +    %define api.tokens.prefix "TOK_"
 +    %%
 +    start: FILE for ERROR;
 +
 +  will generate the definition of the symbols TOK_FILE, TOK_for, and
 +  TOK_ERROR in the generated sources.  In particular, the scanner must
 +  use these prefixed token names, although the grammar itself still
 +  uses the short names (as in the sample rule given above).
 +
 +** Variable api.namespace
 +
 +  The "namespace" variable is renamed "api.namespace".  Backward
 +  compatibility is ensured, but upgrading is recommended.
 +
 +** Variable parse.error
 +
 +  The variable error controls the verbosity of error messages.  The
 +  use of the %error-verbose directive is deprecated in favor of
 +  %define parse.error "verbose".
 +
 +** Semantic predicates
 +
 +  The new, experimental, semantic-predicate feature allows actions of
 +  the form %?{ BOOLEAN-EXPRESSION }, which cause syntax errors (as for
 +  YYERROR) if the expression evaluates to 0, and are evaluated immediately
 +  in GLR parsers, rather than being deferred.  The result is that they
 +  allow the programmer to prune possible parses based on the values of
 +  runtime expressions.
 +
 +* Noteworthy changes in release ?.? (????-??-??) [?]
 +
  ** Future changes
  
    The next major release of Bison will drop support for the following
    generated for C supprt ISO C90, and are tested with ISO C99 and ISO C11
    compilers.
  
- *** Deprecated features
+ *** Features deprecated since Bison 1.875
  
-   The definitions of yystype and yyltype will be removed, as announced since
-   Bison 1.875.  Use YYSTYPE and YYLTYPE only.
+   The definitions of yystype and yyltype will be removed; use YYSTYPE and
+   YYLTYPE.
  
-   YYPARSE_PARAM and YYLEX_PARAM, which were deprecated in favor of
-   %parse-param and %lex-param (introduced in Bison 1.875), will no longer be
-   supported.
+   YYPARSE_PARAM and YYLEX_PARAM, deprecated in favor of %parse-param and
+   %lex-param, will no longer be supported.
+   Support for the preprocessor symbol YYERROR_VERBOSE will be removed, use
+   %error-verbose.
  
  *** The generated header will be included (yacc.c)
  
    because existing versions of ylwrap (e.g., Automake 1.12.1) do not support
    it.
  
- ** Headers (yacc.c, glr.c, glr.cc)
+ ** Headers
  
- *** Guards
+ *** Guards (yacc.c, glr.c, glr.cc)
  
    The generated headers are now guarded, as is already the case for C++
    parsers (lalr1.cc).  For intance, with --defines=foo.h:
      ...
      #endif /* !YY_FOO_H  */
  
- *** New declarations
+ *** New declarations (yacc.c, glr.c)
  
    The generated header now declares yydebug and yyparse.  Both honor
    --name-prefix=bar_, and yield
    in order to facilitate the inclusion of several parser headers inside a
    single compilation unit.
  
+ *** Exported symbols in C++
+   The symbols YYTOKEN_TABLE and YYERROR_VERBOSE, which were defined in the
+   header, are removed, as they prevent the possibility of including several
+   generated headers from a single compilation unit.
+ *** YYLSP_NEEDED
+   For the same reasons, the undocumented and unused macro YYLSP_NEEDED is no
+   longer defined.
  * Noteworthy changes in release 2.5.1 (2012-06-05) [stable]
  
  ** Future changes:
diff --combined data/bison.m4
index 37bc012f58f9f1822cbba76389ccbc1255b751ce,a5c1ee7376717fa50428eeb9e71bc6abf476867e..5fc4f5573b43c618485ef17264825526da180b0c
  ## Identification.  ##
  ## ---------------- ##
  
 -# b4_copyright(TITLE, YEARS)
 -# --------------------------
 +# b4_copyright(TITLE, [YEARS])
 +# ----------------------------
 +# If YEARS are not defined, use b4_copyright_years.
  m4_define([b4_copyright],
  [b4_comment([A Bison parser, made by GNU Bison b4_version.])
  
  b4_comment([$1
  
 -m4_text_wrap([Copyright (C) $2 Free Software Foundation, Inc.], [   ])
 +]m4_dquote(m4_text_wrap([Copyright (C)
 +]m4_ifval([$2], [[$2]], [m4_defn([b4_copyright_years])])[
 +Free Software Foundation, Inc.]))[
  
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
@@@ -212,87 -209,6 +212,87 @@@ m4_define([b4_ints_in]
  [m4_eval([$3 <= $1 && $1 <= $4 && $3 <= $2 && $2 <= $4])])
  
  
 +# b4_subtract(LHS, RHS)
 +# ---------------------
 +# Evaluate LHS - RHS if they are integer literals, otherwise expand
 +# to (LHS) - (RHS).
 +m4_define([b4_subtract],
 +[m4_bmatch([$1$2], [^[0123456789]*$],
 +           [m4_eval([$1 - $2])],
 +           [($1) - ($2)])])
 +
 +# b4_args(ARG1, ...)
 +# _b4_args(ARG1, ...)
 +# -------------------
 +# Join with comma, skipping empty arguments.
 +# b4_args calls itself recursively until it sees the first non-empty
 +# argument, then calls _b4_args which prepends each non-empty argument
 +# with a comma.
 +m4_define([b4_args],
 +[m4_if([$#$1],
 +       [1], [],
 +       [m4_ifval([$1],
 +                 [$1[]_$0(m4_shift($@))],
 +                 [$0(m4_shift($@))])])])
 +
 +# _b4_args(ARGS1, ...)
 +# --------------------
 +m4_define([_b4_args],
 +[m4_if([$#$1],
 +       [1], [],
 +       [m4_ifval([$1], [, $1])[]$0(m4_shift($@))])])
 +
 +
 +
 +
 +# b4_integral_parser_tables_map(MACRO)
 +# -------------------------------------
 +# Map MACRO on all the integral tables.  MACRO is expected to have
 +# the signature MACRO(TABLE-NAME, CONTENT, COMMENT).
 +m4_define([b4_integral_parser_tables_map],
 +[$1([pact], [b4_pact],
 +    [[YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
 +STATE-NUM.]])
 +
 +$1([defact], [b4_defact],
 +   [[YYDEFACT[S] -- default reduction number in state S.  Performed when
 +YYTABLE does not specify something else to do.  Zero means the default
 +is an error.]])
 +
 +$1([pgoto], [b4_pgoto], [[YYPGOTO[NTERM-NUM].]])
 +
 +$1([defgoto], [b4_defgoto], [[YYDEFGOTO[NTERM-NUM].]])
 +
 +$1([table], [b4_table],
 +   [[YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
 +positive, shift that token.  If negative, reduce the rule which
 +number is the opposite.  If YYTABLE_NINF, syntax error.]])
 +
 +$1([check], [b4_check])
 +
 +$1([stos], [b4_stos],
 +   [[STOS_[STATE-NUM] -- The (internal number of the) accessing
 +symbol of state STATE-NUM.]])
 +
 +$1([r1], [b4_r1],
 +   [[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]])
 +
 +$1([r2], [b4_r2],
 +   [[YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.]])
 +])
 +
 +
 +# b4_parser_tables_declare
 +# b4_parser_tables_define
 +# ------------------------
 +# Define/declare the (deterministic) parser tables.
 +m4_define([b4_parser_tables_declare],
 +[b4_integral_parser_tables_map([b4_integral_parser_table_declare])])
 +
 +m4_define([b4_parser_tables_define],
 +[b4_integral_parser_tables_map([b4_integral_parser_table_define])])
 +
 +
  
  ## ------------------ ##
  ## Decoding options.  ##
  m4_define([b4_flag_if],
  [m4_case(b4_$1_flag,
           [0], [$3],
 -       [1], [$2],
 -       [m4_fatal([invalid $1 value: ]$1)])])
 +         [1], [$2],
 +         [m4_fatal([invalid $1 value: ]$1)])])
  
  
  # b4_define_flag_if(FLAG)
@@@ -317,9 -233,9 +317,9 @@@ m4_define([b4_define_flag_if]
  
  # _b4_define_flag_if($1, $2, FLAG)
  # --------------------------------
- # This macro works around the impossibility to define macros
- # inside macros, because issuing `[$1]' is not possible in M4 :(.
- # This sucks hard, GNU M4 should really provide M5 like $$1.
+ # Work around the impossibility to define macros inside macros,
+ # because issuing `[$1]' is not possible in M4.  GNU M4 should provide
+ # $$1 a la M5/TeX.
  m4_define([_b4_define_flag_if],
  [m4_if([$1$2], $[1]$[2], [],
         [m4_fatal([$0: Invalid arguments: $@])])dnl
@@@ -331,120 -247,20 +331,124 @@@ m4_define([b4_$3_if]
  # -----------------------------
  # Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
  b4_define_flag_if([defines])            # Whether headers are requested.
 -b4_define_flag_if([error_verbose])      # Whether error are verbose.
  b4_define_flag_if([glr])                # Whether a GLR parser is requested.
 -b4_define_flag_if([locations])          # Whether locations are tracked.
  b4_define_flag_if([nondeterministic])   # Whether conflicts should be handled.
+ b4_define_flag_if([token_table])        # Whether yytoken_table is demanded.
  b4_define_flag_if([yacc])               # Whether POSIX Yacc is emulated.
  
+ # yytoken_table is needed to support verbose errors.
+ b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
  
 -## ------------------------- ##
 -## Assigning token numbers.  ##
 -## ------------------------- ##
 +## --------- ##
 +## Symbols.  ##
 +## --------- ##
 +
 +# b4_symbol_(NUM, FIELD)
 +# ----------------------
 +# Recover a FIELD about symbol #NUM.  Thanks to m4_indir, fails if
 +# undefined.
 +m4_define([b4_symbol_],
 +[m4_indir([b4_symbol($1, $2)])])
 +
 +
 +# b4_symbol(NUM, FIELD)
 +# ---------------------
 +# Recover a FIELD about symbol #NUM.  Thanks to m4_indir, fails if
 +# undefined.  If FIELD = id, prepend the prefix.
 +m4_define([b4_symbol],
 +[m4_case([$2],
 +         [id],    [m4_do([b4_percent_define_get([api.tokens.prefix])],
 +                         [b4_symbol_([$1], [id])])],
 +         [b4_symbol_($@)])])
 +
 +
 +# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE)
 +# -------------------------------------------
 +# If FIELD about symbol #NUM is 1 expand IF-TRUE, if is 0, expand IF-FALSE.
 +# Otherwise an error.
 +m4_define([b4_symbol_if],
 +[m4_case(b4_symbol([$1], [$2]),
 +         [1], [$3],
 +         [0], [$4],
 +         [m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])])
 +
 +
 +# b4_symbol_action_location(SYMBOL-NUM, KIND)
 +# -------------------------------------------
 +# Report the location of the KIND action as FILE:LINE.
 +m4_define([b4_symbol_action_location],
 +[b4_symbol([$1], [$2_file]):b4_syncline([b4_symbol([$1], [$2_line])])])
 +
 +
 +# b4_symbol_action(SYMBOL-NUM, KIND)
 +# ----------------------------------
 +# Run the action KIND (destructor or printer) for SYMBOL-NUM.
 +# Same as in C, but using references instead of pointers.
 +m4_define([b4_symbol_action],
 +[b4_symbol_if([$1], [has_$2],
 +[m4_pushdef([b4_dollar_dollar],
 +    [b4_symbol_value([(*yyvaluep)],
 +                     b4_symbol_if([$1], [has_type],
 +                                  [b4_symbol([$1], [type])]))])dnl
 +m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl
 +      b4_symbol_case_([$1])
 +b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
 +        b4_symbol([$1], [$2])
 +b4_syncline([@oline@], [@ofile@])
 +        break;
 +
 +m4_popdef([b4_at_dollar])dnl
 +m4_popdef([b4_dollar_dollar])dnl
 +])])
 +
 +
 +# b4_symbol_destructor(SYMBOL-NUM)
 +# b4_symbol_printer(SYMBOL-NUM)
 +# --------------------------------
 +m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
 +m4_define([b4_symbol_printer],    [b4_symbol_action([$1], [printer])])
 +
 +
 +# b4_symbol_case_(SYMBOL-NUM)
 +# ---------------------------
 +# Issue a "case NUM" for SYMBOL-NUM.
 +m4_define([b4_symbol_case_],
 +[      case b4_symbol([$1], [number]): // b4_symbol([$1], [tag])
 +])
 +
 +
 +# b4_symbol_foreach(MACRO)
 +# ------------------------
 +# Invoke MACRO(SYMBOL-NUM) for each SYMBOL-NUM.
 +m4_define([b4_symbol_foreach],
 +          [m4_map([$1], m4_defn([b4_symbol_numbers]))])
 +
 +
 +## ------- ##
 +## Types.  ##
 +## ------- ##
 +
 +# b4_type_action_(NUMS)
 +# ---------------------
 +# Run actions for the symbol NUMS that all have the same type-name.
 +# Skip NUMS that have no type-name.
 +m4_define([b4_type_action_],
 +[b4_symbol_if([$1], [has_type],
 +[m4_map([b4_symbol_case_], [$@])[]dnl
 +        b4_dollar_dollar([b4_symbol([$1], [number])],
 +                         [b4_symbol([$1], [tag])],
 +                         [b4_symbol([$1], [type])]);
 +        break;
 +
 +])])
 +
 +# b4_type_foreach(MACRO)
 +# ----------------------
 +# Invoke MACRO(SYMBOL-NUMS) for each set of SYMBOL-NUMS for each type set.
 +m4_define([b4_type_foreach],
 +          [m4_map([$1], m4_defn([b4_type_names]))])
 +
  
  
  ## ----------- ##
@@@ -462,8 -278,8 +466,8 @@@ m4_define([b4_basename]
  # b4_syncline(LINE, FILE)
  # -----------------------
  m4_define([b4_syncline],
 -[b4_flag_if([synclines], [
 -b4_sync_end([__line__], [b4_basename(m4_quote(__file__))])
 +[b4_flag_if([synclines],
 +[b4_sync_end([__line__], [b4_basename(m4_quote(__file__))])
  b4_sync_start([$1], [$2])])])
  
  m4_define([b4_sync_end], [b4_comment([Line $1 of $2])])
@@@ -552,6 -368,7 +556,6 @@@ m4_popdef([b4_end])dn
  
  
  
 -
  ## --------------------- ##
  ## b4_percent_define_*.  ##
  ## --------------------- ##
@@@ -581,6 -398,7 +585,6 @@@ m4_ifdef([b4_percent_define(]$1[)]
           [m4_indir([b4_percent_define(]$1[)])],
           [$2])])
  
 -
  # b4_percent_define_get_loc(VARIABLE)
  # -----------------------------------
  # Mimic muscle_percent_define_get_loc in ../src/muscle-tab.h exactly.  That is,
@@@ -629,14 -447,8 +633,14 @@@ m4_define([b4_percent_define_get_syncli
  #   b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]])
  m4_define([b4_percent_define_ifdef],
  [m4_ifdef([b4_percent_define(]$1[)],
 -        [m4_define([b4_percent_define_bison_variables(]$1[)])$2],
 -        [$3])])
 +          [b4_percent_define_use([$1])$2],
 +          [$3])])
 +
 +
 +## --------- ##
 +## Options.  ##
 +## --------- ##
 +
  
  # b4_percent_define_flag_if(VARIABLE, IF-TRUE, [IF-FALSE])
  # --------------------------------------------------------
@@@ -661,7 -473,6 +665,7 @@@ m4_define([b4_percent_define_flag_if]
                             [[b4_percent_define_flag_if($1)]])])],
    [b4_fatal([[b4_percent_define_flag_if: undefined %%define variable '%s']], [$1])])])
  
 +
  # b4_percent_define_default(VARIABLE, DEFAULT)
  # --------------------------------------------
  # Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly.  That is,
@@@ -680,20 -491,6 +684,20 @@@ m4_define([b4_percent_define_default]
                          [[<skeleton default value>:-1.-1]]]])dnl
              m4_define([b4_percent_define_syncline(]$1[)], [[]])])])
  
 +
 +# b4_percent_define_if_define(VARIABLE)
 +# -------------------------------------
 +# Define b4_VARIABLE_if that executes its $1 or $2 depending whether
 +# VARIABLE was %defined.  The characters `.' and `-' in VARIABLE are mapped
 +# to `_'.
 +m4_define([b4_percent_define_if_define_],
 +[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
 +           [b4_percent_define_flag_if([$1], [$2], [$3])])])
 +m4_define([b4_percent_define_if_define],
 +[b4_percent_define_default([[$1]], [[false]])
 +b4_percent_define_if_define_([$1], $[1], $[2])])
 +
 +
  # b4_percent_define_check_values(VALUES)
  # --------------------------------------
  # Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
@@@ -765,42 -562,7 +769,42 @@@ m4_popdef([b4_macro_name])]
  m4_define([b4_percent_code_ifdef],
  [m4_ifdef([b4_percent_code(]$1[)],
            [m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])$2],
 -        [$3])])
 +          [$3])])
 +
 +
 +## ------------------ ##
 +## Common variables.  ##
 +## ------------------ ##
 +
 +# Default values for %define.
 +# ---------------------------
 +# If the api.tokens.prefix, it is empty.
 +m4_percent_define_default([[api.tokens.prefix]], [[]])
 +
 +# b4_parse_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
 +# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT])
 +# b4_lex_symbol_if([IF-YYLEX-RETURNS-A-COMPLETE-SYMBOL], [IF-NOT])
 +# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
 +# ----------------------------------------------
 +b4_percent_define_if_define([lex_symbol])
 +b4_percent_define_if_define([locations])     # Whether locations are tracked.
 +b4_percent_define_if_define([parse.assert])
 +b4_percent_define_if_define([parse.trace])
 +b4_percent_define_if_define([variant])
 +
 +
 +# b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT])
 +# ------------------------------------------------------
 +# Map %define parse.error "(simple|verbose)" to b4_error_verbose_if and
 +# b4_error_verbose_flag.
 +b4_percent_define_default([[parse.error]], [[simple]])
 +b4_percent_define_check_values([[[[parse.error]],
 +                                 [[simple]], [[verbose]]]])
 +m4_define([b4_error_verbose_flag],
 +          [m4_case(b4_percent_define_get([[parse.error]]),
 +                   [simple],  [[0]],
 +                   [verbose], [[1]])])
 +b4_define_flag_if([error_verbose])
  
  
  ## ----------------------------------------------------------- ##
diff --combined data/c.m4
index 9bd8295614edd47b2a2e244281b0c322e43d6e9b,1f266a4713f361a82e5938f7c96a6a4af11e2fed..f7179e91d8eae86ade9bbc7c8dff4c4040964ba5
+++ b/data/c.m4
@@@ -48,34 -48,11 +48,34 @@@ m4_define([b4_cpp_guard_close]
  ## Identification.  ##
  ## ---------------- ##
  
 -# b4_comment(TEXT)
 -# ----------------
 -m4_define([b4_comment], [/* m4_bpatsubst([$1], [
 -], [
 -   ])  */])
 +# b4_comment_(TEXT, OPEN, CONTINUE, END)
 +# -------------------------------------
 +# Put TEXT in comment.  Avoid trailing spaces: don't indent empty lines.
 +# Avoid adding indentation to the first line, as the indentation comes
 +# from OPEN.  That's why we don't patsubst([$1], [^\(.\)], [   \1]).
 +#
 +# Prefix all the output lines with PREFIX.
 +m4_define([b4_comment_], [$2[]m4_bpatsubst([$1], [
 +\(.\)], [
 +$3\1])$4])
 +
 +
 +# b4_c_comment(TEXT, [PREFIX])
 +# ----------------------------
 +# Put TEXT in comment.  Avoid trailing spaces: don't indent empty lines.
 +# Avoid adding indentation to the first line, as the indentation comes
 +# from "/*".  That's why we don't patsubst([$1], [^\(.\)], [   \1]).
 +#
 +# Prefix all the output lines with PREFIX.
 +m4_define([b4_c_comment],
 +[b4_comment_([$1], [$2/* ], [$2   ], [$2  */])])
 +
 +
 +# b4_comment(TEXT, [PREFIX])
 +# --------------------------
 +# By default, C comments.
 +m4_define([b4_comment], [b4_c_comment($@)])
 +
  
  # b4_identification
  # -----------------
@@@ -100,9 -77,6 +100,6 @@@ m4_define([b4_identification]
  
  /* Pull parsers.  */
  #define YYPULL ]b4_pull_flag])[
- /* Using locations.  */
- #define YYLSP_NEEDED ]b4_locations_if([1], [0])[
  ]])
  
  
@@@ -147,13 -121,11 +144,13 @@@ m4_popdef([$2])dn
  m4_popdef([$1])dnl
  ])])
  
 -# b4_parse_param_use
 -# ------------------
 -# `YYUSE' all the parse-params.
 +# b4_parse_param_use([VAL], [LOC])
 +# --------------------------------
 +# `YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
  m4_define([b4_parse_param_use],
 -[b4_parse_param_for([Decl], [Formal], [  YYUSE (Formal);
 +[m4_ifvaln([$1], [  YYUSE([$1]);])dnl
 +b4_locations_if([m4_ifvaln([$2], [  YYUSE ([$2]);])])dnl
 +b4_parse_param_for([Decl], [Formal], [  YYUSE (Formal);
  ])dnl
  ])
  
@@@ -175,7 -147,7 +172,7 @@@ m4_define([b4_int_type]
  
         m4_eval([0 <= $1]),                [1], [unsigned int],
  
 -                                             [int])])
 +                                               [int])])
  
  
  # b4_int_type_for(NAME)
@@@ -224,16 -196,6 +221,16 @@@ m4_define([b4_null_define]
  # Return a null pointer constant.
  m4_define([b4_null], [YY_NULL])
  
 +# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
 +# -------------------------------------------------------------
 +# Define "yy<TABLE-NAME>" which contents is CONTENT.
 +m4_define([b4_integral_parser_table_define],
 +[m4_ifvaln([$3], [b4_c_comment([$3], [  ])])dnl
 +static const b4_int_type_for([$2]) yy$1[[]] =
 +{
 +  $2
 +};dnl
 +])
  
  
  ## ------------------------- ##
  # -----------------------------------------
  # Output the definition of this token as #define.
  m4_define([b4_token_define],
 -[#define $1 $2
 +[#define b4_percent_define_get([api.tokens.prefix])$1 $2
  ])
  
  
@@@ -262,7 -224,7 +259,7 @@@ m4_map([b4_token_define], [$@])]
  # ---------------------------------------
  # Output the definition of this token as an enum.
  m4_define([b4_token_enum],
 -[$1 = $2])
 +[b4_percent_define_get([api.tokens.prefix])$1 = $2])
  
  
  # b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
@@@ -278,7 -240,7 +275,7 @@@ m4_define([b4_token_enums]
     enum yytokentype {
  m4_map_sep([     b4_token_enum], [,
  ],
 -         [$@])
 +           [$@])
     };
  #endif
  ])])
@@@ -293,21 -255,6 +290,21 @@@ m4_define([b4_token_enums_defines]
  ])
  
  
 +## ----------------- ##
 +## Semantic Values.  ##
 +## ----------------- ##
 +
 +
 +# b4_symbol_value(VAL, [TYPE])
 +# ----------------------------
 +# Given a semantic value VAL ($$, $1 etc.), extract its value of type
 +# TYPE if TYPE is given, otherwise just return VAL.  The result can be
 +# used safetly, it is put in parens to avoid nasty precedence issues.
 +# TYPE is *not* put in braces, provide some if needed.
 +m4_define([b4_symbol_value],
 +[($1[]m4_ifval([$2], [.$2]))])
 +
 +
  
  ## --------------------------------------------- ##
  ## Defining C functions in both K&R and ANSI-C.  ##
@@@ -357,7 -304,7 +354,7 @@@ $1 (b4_c_ansi_formals(m4_shift2($@)))[]
  m4_define([b4_c_ansi_formals],
  [m4_if([$#], [0], [void],
         [$#$1], [1], [void],
 -             [m4_map_sep([b4_c_ansi_formal], [, ], [$@])])])
 +               [m4_map_sep([b4_c_ansi_formal], [, ], [$@])])])
  
  m4_define([b4_c_ansi_formal],
  [$1])
@@@ -378,9 -325,9 +375,9 @@@ m4_define([b4_c_knr_formal_name]
  # Output the K&R argument declarations.
  m4_define([b4_c_knr_formal_decls],
  [m4_map_sep([b4_c_knr_formal_decl],
 -          [
 +            [
  ],
 -          [$@])])
 +            [$@])])
  
  m4_define([b4_c_knr_formal_decl],
  [    $1;])
  # -----------------------------------------------------------
  # Declare the function NAME.
  m4_define([b4_c_function_decl],
 -[#if defined __STDC__ || defined __cplusplus
 +[#if b4_c_modern
  b4_c_ansi_function_decl($@)
  #else
  $2 $1 ();
@@@ -455,17 -402,24 +452,17 @@@ m4_define([b4_sync_start], [[#]line $1 
  m4_define([b4_case],
  [  case $1:
  $2
 +b4_syncline([@oline@], [@ofile@])
      break;])
  
 -# b4_symbol_actions(FILENAME, LINENO,
 -#                   SYMBOL-TAG, SYMBOL-NUM,
 -#                   SYMBOL-ACTION, SYMBOL-TYPENAME)
 -# -------------------------------------------------
 -m4_define([b4_symbol_actions],
 -[m4_pushdef([b4_dollar_dollar],
 -   [m4_ifval([$6], [(yyvaluep->$6)], [(*yyvaluep)])])dnl
 -m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl
 -      case $4: /* $3 */
 -b4_syncline([$2], [$1])
 -      $5;
 +
 +# b4_predicate_case(LABEL, CONDITIONS)
 +# ------------------------------------
 +m4_define([b4_predicate_case],
 +[  case $1:
 +    if (! ($2)) YYERROR;
  b4_syncline([@oline@], [@ofile@])
 -      break;
 -m4_popdef([b4_at_dollar])dnl
 -m4_popdef([b4_dollar_dollar])dnl
 -])
 +    break;])
  
  
  # b4_yydestruct_generate(FUNCTION-DECLARATOR)
@@@ -487,16 -441,20 +484,16 @@@ m4_define_default([b4_yydestruct_genera
  b4_locations_if(            [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl
  m4_ifset([b4_parse_param], [, b4_parse_param]))[
  {
 -  YYUSE (yyvaluep);
 -]b4_locations_if([  YYUSE (yylocationp);
 -])dnl
 -b4_parse_param_use[]dnl
 -[
 -  if (!yymsg)
 +]b4_parse_param_use([yyvaluep], [yylocationp])dnl
 +[  if (!yymsg)
      yymsg = "Deleting";
    YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
  
    switch (yytype)
      {
 -]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[
 -      default:
 -      break;
 +]b4_symbol_foreach([b4_symbol_destructor])dnl
 +[      default:
 +        break;
      }
  }]dnl
  ])
@@@ -516,28 -474,30 +513,28 @@@ m4_define_default([b4_yy_symbol_print_g
  /*ARGSUSED*/
  ]$1([yy_symbol_value_print],
      [static void],
 -             [[FILE *yyoutput],                       [yyoutput]],
 -             [[int yytype],                           [yytype]],
 -             [[YYSTYPE const * const yyvaluep],       [yyvaluep]][]dnl
 +               [[FILE *yyoutput],                       [yyoutput]],
 +               [[int yytype],                           [yytype]],
 +               [[YYSTYPE const * const yyvaluep],       [yyvaluep]][]dnl
  b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
  m4_ifset([b4_parse_param], [, b4_parse_param]))[
  {
    FILE *yyo = yyoutput;
 -  YYUSE (yyo);
 -  if (!yyvaluep)
 -    return;
 -]b4_locations_if([  YYUSE (yylocationp);
 -])dnl
 -b4_parse_param_use[]dnl
 -[# ifdef YYPRINT
 +]b4_parse_param_use([yyo], [yylocationp])dnl
 +[  if (!yyvaluep)
 +    return;]
 +dnl glr.c does not feature yytoknum.
 +m4_if(b4_skeleton, ["yacc.c"],
 +[[# ifdef YYPRINT
    if (yytype < YYNTOKENS)
      YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
 -# else
 -  YYUSE (yyoutput);
  # endif
 -  switch (yytype)
 +]])dnl
 +[  switch (yytype)
      {
 -]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
 +]b4_symbol_foreach([b4_symbol_printer])dnl
  [      default:
 -      break;
 +        break;
      }
  }
  
  
  ]$1([yy_symbol_print],
      [static void],
 -             [[FILE *yyoutput],                       [yyoutput]],
 -             [[int yytype],                           [yytype]],
 -             [[YYSTYPE const * const yyvaluep],       [yyvaluep]][]dnl
 +               [[FILE *yyoutput],                       [yyoutput]],
 +               [[int yytype],                           [yytype]],
 +               [[YYSTYPE const * const yyvaluep],       [yyvaluep]][]dnl
  b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
  m4_ifset([b4_parse_param], [, b4_parse_param]))[
  {
@@@ -613,7 -573,7 +610,7 @@@ b4_pure_if([], [[extern YYSTYPE ]b4_pre
  m4_define([b4_declare_yydebug],
  [[/* Enabling traces.  */
  #ifndef YYDEBUG
 -# define YYDEBUG ]b4_debug_flag[
 +# define YYDEBUG ]b4_parse_trace_if([1], [0])[
  #endif
  #if YYDEBUG
  extern int ]b4_prefix[debug;
diff --combined data/glr.c
index 3d4120cc701b87e5cd02fa7494b01c52dc0a31b8,699d7304819b61bd1a3b3fd0dd7f00cee865cfcd..2aa12b50d686716d14b1b4636b1bfe053ad2cc99
@@@ -123,15 -123,7 +123,15 @@@ m4_define([b4_locuser_args]
  # --------------------
  # Expansion of $<TYPE>$.
  m4_define([b4_lhs_value],
 -[((*yyvalp)[]m4_ifval([$1], [.$1]))])
 +[b4_symbol_value([(*yyvalp)], [$1])])
 +
 +
 +# b4_rhs_data(RULE-LENGTH, NUM)
 +# -----------------------------
 +# Expand to the semantic stack place that contains value and location
 +# of symbol number NUM in a rule of length RULE-LENGTH.
 +m4_define([b4_rhs_data],
 +[((yyGLRStackItem const *)yyvsp)@{YYFILL (b4_subtract([$2], [$1]))@}.yystate])
  
  
  # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
  # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
  # symbols on RHS.
  m4_define([b4_rhs_value],
 -[(((yyGLRStackItem const *)yyvsp)@{YYFILL (($2) - ($1))@}.yystate.yysemantics.yysval[]m4_ifval([$3], [.$3]))])
 +[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3])])
  
  
  
@@@ -159,7 -151,7 +159,7 @@@ m4_define([b4_lhs_location]
  # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
  # on RHS.
  m4_define([b4_rhs_location],
 -[(((yyGLRStackItem const *)yyvsp)@{YYFILL (($2) - ($1))@}.yystate.yyloc)])
 +[(b4_rhs_data([$1], [$2]).yyloc)])
  
  
  ## -------------- ##
@@@ -213,21 -205,16 +213,16 @@@ b4_percent_code_get([[top]])
  ]b4_null_define[
  
  ]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]],
 -               [b4_shared_declarations])[
 +              [b4_shared_declarations])[
  
  /* Enabling verbose error messages.  */
  #ifdef YYERROR_VERBOSE
  # undef YYERROR_VERBOSE
  # define YYERROR_VERBOSE 1
  #else
 -# define YYERROR_VERBOSE ]b4_error_verbose_flag[
 +# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
  #endif
  
- /* Enabling the token table.  */
- #ifndef YYTOKEN_TABLE
- # define YYTOKEN_TABLE ]b4_token_table[
- #endif
  /* Default (constant) value used for initialization for null
     right-hand sides.  Unlike the standard yacc.c template,
     here we set the default value of $$ to a zeroed-out value.
@@@ -355,6 -342,19 +350,6 @@@ static const ]b4_int_type_for([b4_trans
  };
  
  #if YYDEBUG
 -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
 -   YYRHS.  */
 -static const ]b4_int_type_for([b4_prhs])[ yyprhs[] =
 -{
 -  ]b4_prhs[
 -};
 -
 -/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 -static const ]b4_int_type_for([b4_rhs])[ yyrhs[] =
 -{
 -  ]b4_rhs[
 -};
 -
  /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
  static const ]b4_int_type_for([b4_rline])[ yyrline[] =
  {
  };
  #endif
  
- #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+ #if YYDEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
  /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
     First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
  static const char *const yytname[] =
  };
  #endif
  
 -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 -static const ]b4_int_type_for([b4_r1])[ yyr1[] =
 -{
 -  ]b4_r1[
 -};
 +#define YYPACT_NINF ]b4_pact_ninf[
 +#define YYTABLE_NINF ]b4_table_ninf[
  
 -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 -static const ]b4_int_type_for([b4_r2])[ yyr2[] =
 -{
 -  ]b4_r2[
 -};
 +]b4_parser_tables_define[
  
  /* YYDPREC[RULE-NUM] -- Dynamic precedence of rule #RULE-NUM (0 if none).  */
  static const ]b4_int_type_for([b4_dprec])[ yydprec[] =
@@@ -388,11 -395,41 +383,11 @@@ static const ]b4_int_type_for([b4_merge
    ]b4_merger[
  };
  
 -/* YYDEFACT[S] -- default reduction number in state S.  Performed when
 -   YYTABLE doesn't specify something else to do.  Zero means the default
 -   is an error.  */
 -static const ]b4_int_type_for([b4_defact])[ yydefact[] =
 +/* YYIMMEDIATE[RULE-NUM] -- True iff rule #RULE-NUM is not to be deferred, as
 +   in the case of predicates.  */
 +static const yybool yyimmediate[] =
  {
 -  ]b4_defact[
 -};
 -
 -/* YYPDEFGOTO[NTERM-NUM].  */
 -static const ]b4_int_type_for([b4_defgoto])[ yydefgoto[] =
 -{
 -  ]b4_defgoto[
 -};
 -
 -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
 -   STATE-NUM.  */
 -#define YYPACT_NINF ]b4_pact_ninf[
 -static const ]b4_int_type_for([b4_pact])[ yypact[] =
 -{
 -  ]b4_pact[
 -};
 -
 -/* YYPGOTO[NTERM-NUM].  */
 -static const ]b4_int_type_for([b4_pgoto])[ yypgoto[] =
 -{
 -  ]b4_pgoto[
 -};
 -
 -/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
 -   positive, shift that token.  If negative, reduce the rule which
 -   number is the opposite.  If YYTABLE_NINF, syntax error.  */
 -#define YYTABLE_NINF ]b4_table_ninf[
 -static const ]b4_int_type_for([b4_table])[ yytable[] =
 -{
 -  ]b4_table[
 +  ]b4_immediate[
  };
  
  /* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
@@@ -413,6 -450,19 +408,6 @@@ dnl We probably ought to introduce a ty
  {
    ]b4_conflicting_rules[
  };
 -
 -static const ]b4_int_type_for([b4_check])[ yycheck[] =
 -{
 -  ]b4_check[
 -};
 -
 -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
 -   symbol of state STATE-NUM.  */
 -static const ]b4_int_type_for([b4_stos])[ yystos[] =
 -{
 -  ]b4_stos[
 -};
 -
  \f
  /* Error token number */
  #define YYTERROR 1
@@@ -491,12 -541,9 +486,12 @@@ static const int YYEMPTY = -2
  
  typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
  
 -#define YYCHK(YYE)                                                           \
 -   do { YYRESULTTAG yyflag = YYE; if (yyflag != yyok) return yyflag; }       \
 -   while (YYID (0))
 +#define YYCHK(YYE)                              \
 +  do {                                          \
 +    YYRESULTTAG yychk_flag = YYE;               \
 +    if (yychk_flag != yyok)                     \
 +      return yychk_flag;                        \
 +  } while (YYID (0))
  
  #if YYDEBUG
  
  # endif
  
  # define YYDPRINTF(Args)                        \
 -do {                                            \
 -  if (yydebug)                                  \
 -    YYFPRINTF Args;                             \
 -} while (YYID (0))
 +  do {                                          \
 +    if (yydebug)                                \
 +      YYFPRINTF Args;                           \
 +  } while (YYID (0))
  
  ]b4_yy_symbol_print_generate([b4_c_ansi_function_def])[
  
 -# define YY_SYMBOL_PRINT(Title, Type, Value, Location)          \
 -do {                                                            \
 -  if (yydebug)                                                  \
 -    {                                                           \
 -      YYFPRINTF (stderr, "%s ", Title);                         \
 -      yy_symbol_print (stderr, Type, Value]b4_locuser_args([Location])[);        \
 -      YYFPRINTF (stderr, "\n");                                 \
 -    }                                                           \
 -} while (YYID (0))
 +# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                  \
 +  do {                                                                  \
 +    if (yydebug)                                                        \
 +      {                                                                 \
 +        YYFPRINTF (stderr, "%s ", Title);                               \
 +        yy_symbol_print (stderr, Type, Value]b4_locuser_args([Location])[);        \
 +        YYFPRINTF (stderr, "\n");                                       \
 +      }                                                                 \
 +  } while (YYID (0))
  
  /* Nonzero means print parse trace.  It is left uninitialized so that
     multiple parsers can coexist.  */
@@@ -557,7 -604,13 +552,7 @@@ int yydebug
  #define YYHEADROOM 2
  
  #ifndef YYSTACKEXPANDABLE
 -# if (! defined __cplusplus \
 -      || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
 -          && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))
  #  define YYSTACKEXPANDABLE 1
 -# else
 -#  define YYSTACKEXPANDABLE 0
 -# endif
  #endif
  
  #if YYSTACKEXPANDABLE
@@@ -654,7 -707,7 +649,7 @@@ typedef int yyStateNum
  typedef int yyRuleNum;
  
  /** Grammar symbol */
 -typedef short int yySymbol;
 +typedef int yySymbol;
  
  /** Item references, as in LALR(1) machine */
  typedef short int yyItemNum;
@@@ -675,7 -728,7 +670,7 @@@ struct yyGLRState 
    yyStateNum yylrState;
    /** Preceding state in this stack */
    yyGLRState* yypred;
 -  /** Source position of the first token produced by my symbol */
 +  /** Source position of the last token produced by my symbol */
    size_t yyposn;
    union {
      /** First in a chain of alternative reductions producing the
@@@ -787,16 -840,9 +782,16 @@@ yyfillin (yyGLRStackItem *yyvsp, int yy
    yyGLRState *s = yyvsp[yylow0].yystate.yypred;
    for (i = yylow0-1; i >= yylow1; i -= 1)
      {
 -      YYASSERT (s->yyresolved);
 -      yyvsp[i].yystate.yyresolved = yytrue;
 -      yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval;]b4_locations_if([[
 +#if YYDEBUG
 +      yyvsp[i].yystate.yylrState = s->yylrState;
 +#endif
 +      yyvsp[i].yystate.yyresolved = s->yyresolved;
 +      if (s->yyresolved)
 +        yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval;
 +      else
 +        /* The effect of using yysval or yyloc (in an immediate rule) is
 +         * undefined.  */
 +        yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULL;]b4_locations_if([[
        yyvsp[i].yystate.yyloc = s->yyloc;]])[
        s = yyvsp[i].yystate.yypred = s->yypred;
      }
@@@ -831,7 -877,7 +826,7 @@@ yyuserAction (yyRuleNum yyn, int yyrhsl
    yybool yynormal __attribute__ ((__unused__)) =
      (yystackp->yysplitPoint == YY_NULL);
    int yylow;
 -]b4_parse_param_use[]dnl
 +]b4_parse_param_use([yyvalp], [yylocp])dnl
  [# undef yyerrok
  # define yyerrok (yystackp->yyerrState = 0)
  # undef YYACCEPT
@@@ -934,7 -980,7 +929,7 @@@ yydestroyGLRState (char const *yymsg, y
      }
  }
  
 -/** Left-hand-side symbol for rule #RULE.  */
 +/** Left-hand-side symbol for rule #YYRULE.  */
  static inline yySymbol
  yylhsNonterm (yyRuleNum yyrule)
  {
  #define yypact_value_is_default(yystate) \
    ]b4_table_value_equals([[pact]], [[yystate]], [b4_pact_ninf])[
  
 -/** True iff LR state STATE has only a default reduction (regardless
 +/** True iff LR state YYSTATE has only a default reduction (regardless
   *  of token).  */
  static inline yybool
  yyisDefaultedState (yyStateNum yystate)
    return yypact_value_is_default (yypact[yystate]);
  }
  
 -/** The default reduction for STATE, assuming it has one.  */
 +/** The default reduction for YYSTATE, assuming it has one.  */
  static inline yyRuleNum
  yydefaultAction (yyStateNum yystate)
  {
   *    R < 0:  Reduce on rule -R.
   *    R = 0:  Error.
   *    R > 0:  Shift to state R.
 - *  Set *CONFLICTS to a pointer into yyconfl to 0-terminated list of
 - *  conflicting reductions.
 + *  Set *YYCONFLICTS to a pointer into yyconfl to a 0-terminated list
 + *  of conflicting reductions.
   */
  static inline void
  yygetLRActions (yyStateNum yystate, int yytoken,
  static inline yyStateNum
  yyLRgotoState (yyStateNum yystate, yySymbol yylhs)
  {
 -  int yyr;
 -  yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
 +  int yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
    if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
      return yytable[yyr];
    else
@@@ -1017,10 -1064,9 +1012,10 @@@ yyisErrorAction (int yyaction
  
                                  /* GLRStates */
  
 -/** Return a fresh GLRStackItem.  Callers should call
 - * YY_RESERVE_GLRSTACK afterwards to make sure there is sufficient
 - * headroom.  */
 +/** Return a fresh GLRStackItem in YYSTACKP.  The item is an LR state
 + *  if YYISSTATE, and otherwise a semantic option.  Callers should call
 + *  YY_RESERVE_GLRSTACK afterwards to make sure there is sufficient
 + *  headroom.  */
  
  static inline yyGLRStackItem*
  yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState)
  }
  
  /** Add a new semantic action that will execute the action for rule
 - *  RULENUM on the semantic values in RHS to the list of
 - *  alternative actions for STATE.  Assumes that RHS comes from
 - *  stack #K of *STACKP. */
 + *  YYRULE on the semantic values in YYRHS to the list of
 + *  alternative actions for YYSTATE.  Assumes that YYRHS comes from
 + *  stack #YYK of *YYSTACKP. */
  static void
  yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate,
 -                     yyGLRState* rhs, yyRuleNum yyrule)
 +                     yyGLRState* yyrhs, yyRuleNum yyrule)
  {
    yySemanticOption* yynewOption =
      &yynewGLRStackItem (yystackp, yyfalse)->yyoption;
 -  yynewOption->yystate = rhs;
 +  yynewOption->yystate = yyrhs;
    yynewOption->yyrule = yyrule;
    if (yystackp->yytops.yylookaheadNeeds[yyk])
      {
  
                                  /* GLRStacks */
  
 -/** Initialize SET to a singleton set containing an empty stack.  */
 +/** Initialize YYSET to a singleton set containing an empty stack.  */
  static yybool
  yyinitStateSet (yyGLRStateSet* yyset)
  {
@@@ -1086,8 -1132,8 +1081,8 @@@ static void yyfreeStateSet (yyGLRStateS
    YYFREE (yyset->yylookaheadNeeds);
  }
  
 -/** Initialize STACK to a single empty stack, with total maximum
 - *  capacity for all stacks of SIZE.  */
 +/** Initialize *YYSTACKP to a single empty stack, with total maximum
 + *  capacity for all stacks of YYSIZE.  */
  static yybool
  yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
  {
  # define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \
    &((YYTOITEMS) - ((YYFROMITEMS) - (yyGLRStackItem*) (YYX)))->YYTYPE
  
 -/** If STACK is expandable, extend it.  WARNING: Pointers into the
 +/** If *YYSTACKP is expandable, extend it.  WARNING: Pointers into the
      stack from outside should be considered invalid after this call.
      We always expand when there are 1 or fewer items left AFTER an
      allocation, so that we can avoid having external pointers exist
@@@ -1179,9 -1225,9 +1174,9 @@@ yyfreeGLRStack (yyGLRStack* yystackp
    yyfreeStateSet (&yystackp->yytops);
  }
  
 -/** Assuming that S is a GLRState somewhere on STACK, update the
 - *  splitpoint of STACK, if needed, so that it is at least as deep as
 - *  S.  */
 +/** Assuming that YYS is a GLRState somewhere on *YYSTACKP, update the
 + *  splitpoint of *YYSTACKP, if needed, so that it is at least as deep as
 + *  YYS.  */
  static inline void
  yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
  {
      yystackp->yysplitPoint = yys;
  }
  
 -/** Invalidate stack #K in STACK.  */
 +/** Invalidate stack #YYK in *YYSTACKP.  */
  static inline void
  yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
  {
    yystackp->yytops.yystates[yyk] = YY_NULL;
  }
  
 -/** Undelete the last stack that was marked as deleted.  Can only be
 -    done once after a deletion, and only when all other stacks have
 +/** Undelete the last stack in *YYSTACKP that was marked as deleted.  Can
 +    only be done once after a deletion, and only when all other stacks have
      been deleted.  */
  static void
  yyundeleteLastStack (yyGLRStack* yystackp)
@@@ -1248,9 -1294,8 +1243,9 @@@ yyremoveDeletes (yyGLRStack* yystackp
      }
  }
  
 -/** Shift to a new state on stack #K of STACK, corresponding to LR state
 - * LRSTATE, at input position POSN, with (resolved) semantic value SVAL.  */
 +/** Shift to a new state on stack #YYK of *YYSTACKP, corresponding to LR
 + * state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
 + * value *YYVALP and source location *YYLOCP.  */
  static inline void
  yyglrShift (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
              size_t yyposn,
    YY_RESERVE_GLRSTACK (yystackp);
  }
  
 -/** Shift stack #K of YYSTACK, to a new state corresponding to LR
 +/** Shift stack #YYK of *YYSTACKP, to a new state corresponding to LR
   *  state YYLRSTATE, at input position YYPOSN, with the (unresolved)
   *  semantic value of YYRHS under the action for YYRULE.  */
  static inline void
  yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
 -                 size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule)
 +                 size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
  {
    yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
  
    yystackp->yytops.yystates[yyk] = yynewState;
  
    /* Invokes YY_RESERVE_GLRSTACK.  */
 -  yyaddDeferredAction (yystackp, yyk, yynewState, rhs, yyrule);
 +  yyaddDeferredAction (yystackp, yyk, yynewState, yyrhs, yyrule);
  }
  
 -/** Pop the symbols consumed by reduction #RULE from the top of stack
 - *  #K of STACK, and perform the appropriate semantic action on their
 +#if !YYDEBUG
 +# define YY_REDUCE_PRINT(Args)
 +#else
 +# define YY_REDUCE_PRINT(Args)          \
 +do {                                    \
 +  if (yydebug)                          \
 +    yy_reduce_print Args;               \
 +} while (YYID (0))
 +
 +/*----------------------------------------------------------------------.
 +| Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
 +`----------------------------------------------------------------------*/
 +
 +/*ARGSUSED*/ static inline void
 +yy_reduce_print (int yynormal, yyGLRStackItem* yyvsp, size_t yyk,
 +                 yyRuleNum yyrule]b4_user_formals[)
 +{
 +  int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
 +  int yylow = 1;])[
 +  int yyi;
 +  YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n",
 +             (unsigned long int) yyk, yyrule - 1,
 +             (unsigned long int) yyrline[yyrule]);
 +  if (! yynormal)
 +    yyfillin (yyvsp, 1, -yynrhs);
 +  /* The symbols being reduced.  */
 +  for (yyi = 0; yyi < yynrhs; yyi++)
 +    {
 +      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
 +      yy_symbol_print (stderr,
 +                       yystos[yyvsp[yyi - yynrhs + 1].yystate.yylrState],
 +                       &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yysval
 +                       ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
 +                       b4_user_args[);
 +      if (!yyvsp[yyi - yynrhs + 1].yystate.yyresolved)
 +        YYFPRINTF (stderr, " (unresolved)");
 +      YYFPRINTF (stderr, "\n");
 +    }
 +}
 +#endif
 +
 +/** Pop the symbols consumed by reduction #YYRULE from the top of stack
 + *  #YYK of *YYSTACKP, and perform the appropriate semantic action on their
   *  semantic values.  Assumes that all ambiguities in semantic values
 - *  have been previously resolved.  Set *VALP to the resulting value,
 - *  and *LOCP to the computed location (if any).  Return value is as
 + *  have been previously resolved.  Set *YYVALP to the resulting value,
 + *  and *YYLOCP to the computed location (if any).  Return value is as
   *  for userAction.  */
  static inline YYRESULTTAG
  yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
    if (yystackp->yysplitPoint == YY_NULL)
      {
        /* Standard special case: single stack.  */
 -      yyGLRStackItem* rhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
 +      yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
        YYASSERT (yyk == 0);
        yystackp->yynextFree -= yynrhs;
        yystackp->yyspaceLeft += yynrhs;
        yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
 -      return yyuserAction (yyrule, yynrhs, rhs, yystackp,
 +      YY_REDUCE_PRINT ((1, yyrhs, yyk, yyrule]b4_user_args[));
 +      return yyuserAction (yyrule, yynrhs, yyrhs, yystackp,
                             yyvalp]b4_locuser_args[);
      }
    else
      {
 -      /* At present, doAction is never called in nondeterministic
 -       * mode, so this branch is never taken.  It is here in
 -       * anticipation of a future feature that will allow immediate
 -       * evaluation of selected actions in nondeterministic mode.  */
        int yyi;
        yyGLRState* yys;
        yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
          }
        yyupdateSplit (yystackp, yys);
        yystackp->yytops.yystates[yyk] = yys;
 +      YY_REDUCE_PRINT ((0, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, yyk, yyrule]b4_user_args[));
        return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
                             yystackp, yyvalp]b4_locuser_args[);
      }
  }
  
 -#if !YYDEBUG
 -# define YY_REDUCE_PRINT(Args)
 -#else
 -# define YY_REDUCE_PRINT(Args)          \
 -do {                                    \
 -  if (yydebug)                          \
 -    yy_reduce_print Args;               \
 -} while (YYID (0))
 -
 -/*----------------------------------------------------------.
 -| Report that the RULE is going to be reduced on stack #K.  |
 -`----------------------------------------------------------*/
 -
 -/*ARGSUSED*/ static inline void
 -yy_reduce_print (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
 -                 YYSTYPE* yyvalp]b4_locuser_formals[)
 -{
 -  int yynrhs = yyrhsLength (yyrule);
 -  yybool yynormal __attribute__ ((__unused__)) =
 -    (yystackp->yysplitPoint == YY_NULL);
 -  yyGLRStackItem* yyvsp = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
 -  int yylow = 1;
 -  int yyi;
 -  YYUSE (yyvalp);]b4_locations_if([
 -  YYUSE (yylocp);])[
 -]b4_parse_param_use[]dnl
 -[  YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n",
 -             (unsigned long int) yyk, yyrule - 1,
 -             (unsigned long int) yyrline[yyrule]);
 -  /* The symbols being reduced.  */
 -  for (yyi = 0; yyi < yynrhs; yyi++)
 -    {
 -      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
 -      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 -                       &]b4_rhs_value(yynrhs, yyi + 1)[
 -                       ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
 -                       b4_user_args[);
 -      YYFPRINTF (stderr, "\n");
 -    }
 -}
 -#endif
 -
 -/** Pop items off stack #K of STACK according to grammar rule RULE,
 +/** Pop items off stack #YYK of *YYSTACKP according to grammar rule YYRULE,
   *  and push back on the resulting nonterminal symbol.  Perform the
 - *  semantic action associated with RULE and store its value with the
 - *  newly pushed state, if FORCEEVAL or if STACK is currently
 + *  semantic action associated with YYRULE and store its value with the
 + *  newly pushed state, if YYFORCEEVAL or if *YYSTACKP is currently
   *  unambiguous.  Otherwise, store the deferred semantic action with
   *  the new state.  If the new state would have an identical input
   *  position, LR state, and predecessor to an existing state on the stack,
 - *  it is identified with that existing state, eliminating stack #K from
 - *  the STACK.  In this case, the (necessarily deferred) semantic value is
 + *  it is identified with that existing state, eliminating stack #YYK from
 + *  *YYSTACKP.  In this case, the semantic value is
   *  added to the options for the existing state's semantic value.
   */
  static inline YYRESULTTAG
@@@ -1396,18 -1444,11 +1391,18 @@@ yyglrReduce (yyGLRStack* yystackp, size
  
    if (yyforceEval || yystackp->yysplitPoint == YY_NULL)
      {
 +      YYRESULTTAG yyflag;
        YYSTYPE yysval;]b4_locations_if([
        YYLTYPE yyloc;])[
  
 -      YY_REDUCE_PRINT ((yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[));
 -      YYCHK (yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[));
 +      yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
 +      if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULL)
 +        {
 +          YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
 +                     (unsigned long int) yyk, yyrule - 1));
 +        }
 +      if (yyflag != yyok)
 +        return yyflag;
        YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyrule], &yysval, &yyloc);
        yyglrShift (yystackp, yyk,
                    yyLRgotoState (yystackp->yytops.yystates[yyk]->yylrState,
        yyupdateSplit (yystackp, yys);
        yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule));
        YYDPRINTF ((stderr,
 -                  "Reduced stack %lu by rule #%d; action deferred.  Now in state %d.\n",
 +                  "Reduced stack %lu by rule #%d; action deferred.  "
 +                  "Now in state %d.\n",
                    (unsigned long int) yyk, yyrule - 1, yynewLRState));
        for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
          if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULL)
@@@ -1502,7 -1542,7 +1497,7 @@@ yysplitStack (yyGLRStack* yystackp, siz
    return yystackp->yytops.yysize-1;
  }
  
 -/** True iff Y0 and Y1 represent identical options at the top level.
 +/** True iff YYY0 and YYY1 represent identical options at the top level.
   *  That is, they represent the same rule applied to RHS symbols
   *  that produce the same terminal symbols.  */
  static yybool
@@@ -1524,8 -1564,8 +1519,8 @@@ yyidenticalOptions (yySemanticOption* y
      return yyfalse;
  }
  
 -/** Assuming identicalOptions (Y0,Y1), destructively merge the
 - *  alternative semantic values for the RHS-symbols of Y1 and Y0.  */
 +/** Assuming identicalOptions (YYY0,YYY1), destructively merge the
 + *  alternative semantic values for the RHS-symbols of YYY1 and YYY0.  */
  static void
  yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
  {
@@@ -1604,11 -1644,11 +1599,11 @@@ static YYRESULTTAG yyresolveValue (yyGL
                                     yyGLRStack* yystackp]b4_user_formals[);
  
  
 -/** Resolve the previous N states starting at and including state S.  If result
 - *  != yyok, some states may have been left unresolved possibly with empty
 - *  semantic option chains.  Regardless of whether result = yyok, each state
 - *  has been left with consistent data so that yydestroyGLRState can be invoked
 - *  if necessary.  */
 +/** Resolve the previous YYN states starting at and including state YYS
 + *  on *YYSTACKP. If result != yyok, some states may have been left
 + *  unresolved possibly with empty semantic option chains.  Regardless
 + *  of whether result = yyok, each state has been left with consistent
 + *  data so that yydestroyGLRState can be invoked if necessary.  */
  static YYRESULTTAG
  yyresolveStates (yyGLRState* yys, int yyn,
                   yyGLRStack* yystackp]b4_user_formals[)
    return yyok;
  }
  
 -/** Resolve the states for the RHS of OPT, perform its user action, and return
 - *  the semantic value and location.  Regardless of whether result = yyok, all
 - *  RHS states have been destroyed (assuming the user action destroys all RHS
 +/** Resolve the states for the RHS of YYOPT on *YYSTACKP, perform its
 + *  user action, and return the semantic value and location in *YYVALP
 + *  and *YYLOCP.  Regardless of whether result = yyok, all RHS states
 + *  have been destroyed (assuming the user action destroys all RHS
   *  semantic values if invoked).  */
  static YYRESULTTAG
  yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp,
@@@ -1700,11 -1739,11 +1695,11 @@@ yyreportTree (yySemanticOption* yyx, in
          {
            if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
              YYFPRINTF (stderr, "%*s%s <empty>\n", yyindent+2, "",
 -                       yytokenName (yyrhs[yyprhs[yyx->yyrule]+yyi-1]));
 +                       yytokenName (yystos[yystates[yyi]->yylrState]));
            else
              YYFPRINTF (stderr, "%*s%s <tokens %lu .. %lu>\n", yyindent+2, "",
 -                       yytokenName (yyrhs[yyprhs[yyx->yyrule]+yyi-1]),
 -                       (unsigned long int) (yystates[yyi - 1]->yyposn + 1),
 +                       yytokenName (yystos[yystates[yyi]->yylrState]),
 +                       (unsigned long int) (yystates[yyi-1]->yyposn + 1),
                         (unsigned long int) yystates[yyi]->yyposn);
          }
        else
@@@ -1733,9 -1772,9 +1728,9 @@@ yyreportAmbiguity (yySemanticOption* yy
    return yyabort;
  }]b4_locations_if([[
  
 -/** Starting at and including state S1, resolve the location for each of the
 - *  previous N1 states that is unresolved.  The first semantic option of a state
 - *  is always chosen.  */
 +/** Resolve the locations for each of the YYN1 states in *YYSTACKP,
 + *  ending at YYS1.  Has no effect on previously resolved states.
 + *  The first semantic option of a state is always chosen.  */
  static void
  yyresolveLocations (yyGLRState* yys1, int yyn1,
                      yyGLRStack *yystackp]b4_user_formals[)
      }
  }]])[
  
 -/** Resolve the ambiguity represented in state S, perform the indicated
 - *  actions, and set the semantic value of S.  If result != yyok, the chain of
 - *  semantic options in S has been cleared instead or it has been left
 - *  unmodified except that redundant options may have been removed.  Regardless
 - *  of whether result = yyok, S has been left with consistent data so that
 +/** Resolve the ambiguity represented in state YYS in *YYSTACKP,
 + *  perform the indicated actions, and set the semantic value of YYS.
 + *  If result != yyok, the chain of semantic options in YYS has been
 + *  cleared instead or it has been left unmodified except that
 + *  redundant options may have been removed.  Regardless of whether
 + *  result = yyok, YYS has been left with consistent data so that
   *  yydestroyGLRState can be invoked if necessary.  */
  static YYRESULTTAG
  yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
@@@ -1932,6 -1970,10 +1927,6 @@@ static YYRESULTTA
  yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
                     size_t yyposn]b4_pure_formals[)
  {
 -  int yyaction;
 -  const short int* yyconflicts;
 -  yyRuleNum yyrule;
 -
    while (yystackp->yytops.yystates[yyk] != YY_NULL)
      {
        yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
  
        if (yyisDefaultedState (yystate))
          {
 -          yyrule = yydefaultAction (yystate);
 +          YYRESULTTAG yyflag;
 +          yyRuleNum yyrule = yydefaultAction (yystate);
            if (yyrule == 0)
              {
                YYDPRINTF ((stderr, "Stack %lu dies.\n",
                yymarkStackDeleted (yystackp, yyk);
                return yyok;
              }
 -          YYCHK (yyglrReduce (yystackp, yyk, yyrule, yyfalse]b4_user_args[));
 +          yyflag = yyglrReduce (yystackp, yyk, yyrule, yyimmediate[yyrule]]b4_user_args[);
 +          if (yyflag == yyerr)
 +            {
 +              YYDPRINTF ((stderr,
 +                          "Stack %lu dies "
 +                          "(predicate failure or explicit user error).\n",
 +                          (unsigned long int) yyk));
 +              yymarkStackDeleted (yystackp, yyk);
 +              return yyok;
 +            }
 +          if (yyflag != yyok)
 +            return yyflag;
          }
        else
          {
            yySymbol yytoken;
 +          int yyaction;
 +          const short int* yyconflicts;
 +
            yystackp->yytops.yylookaheadNeeds[yyk] = yytrue;
            if (yychar == YYEMPTY)
              {
  
            while (*yyconflicts != 0)
              {
 +              YYRESULTTAG yyflag;
                size_t yynewStack = yysplitStack (yystackp, yyk);
                YYDPRINTF ((stderr, "Splitting off stack %lu from %lu.\n",
                            (unsigned long int) yynewStack,
                            (unsigned long int) yyk));
 -              YYCHK (yyglrReduce (yystackp, yynewStack,
 -                                  *yyconflicts, yyfalse]b4_user_args[));
 -              YYCHK (yyprocessOneStack (yystackp, yynewStack,
 -                                        yyposn]b4_pure_args[));
 +              yyflag = yyglrReduce (yystackp, yynewStack,
 +                                    *yyconflicts,
 +                                    yyimmediate[*yyconflicts]]b4_user_args[);
 +              if (yyflag == yyok)
 +                YYCHK (yyprocessOneStack (yystackp, yynewStack,
 +                                          yyposn]b4_pure_args[));
 +              else if (yyflag == yyerr)
 +                {
 +                  YYDPRINTF ((stderr, "Stack %lu dies.\n",
 +                              (unsigned long int) yynewStack));
 +                  yymarkStackDeleted (yystackp, yynewStack);
 +                }
 +              else
 +                return yyflag;
                yyconflicts += 1;
              }
  
                break;
              }
            else
 -            YYCHK (yyglrReduce (yystackp, yyk, -yyaction,
 -                                yyfalse]b4_user_args[));
 +            {
 +              YYRESULTTAG yyflag = yyglrReduce (yystackp, yyk, -yyaction,
 +                                                yyimmediate[-yyaction]]b4_user_args[);
 +              if (yyflag == yyerr)
 +                {
 +                  YYDPRINTF ((stderr,
 +                              "Stack %lu dies "
 +                              "(predicate failure or explicit user error).\n",
 +                              (unsigned long int) yyk));
 +                  yymarkStackDeleted (yystackp, yyk);
 +                  break;
 +                }
 +              else if (yyflag != yyok)
 +                return yyflag;
 +            }
          }
      }
    return yyok;
@@@ -2291,6 -2294,7 +2286,6 @@@ yyrecoverSyntaxError (yyGLRStack* yysta
      }                                                                        \
    } while (YYID (0))
  
 -
  /*----------.
  | yyparse.  |
  `----------*/
@@@ -2612,7 -2616,9 +2607,7 @@@ yypdumpstack (yyGLRStack* yystackp
    YYFPRINTF (stderr, "\n");
  }
  #endif
 -]
 -
 -b4_epilogue
 +]b4_epilogue[]dnl
  dnl
  dnl glr.cc produces its own header.
  dnl
diff --combined data/glr.cc
index 9a9d7764b06ba71f130daeddc9351c6ead09f52a,8e46be3d40d6deaba2bb76950f398ee57473acaf..c21de402bbdcb15a20c6b02359e943385344b5e3
@@@ -1,3 -1,5 +1,3 @@@
 -                                                                    -*- C -*-
 -
  # C++ GLR skeleton for Bison
  
  # Copyright (C) 2002-2012 Free Software Foundation, Inc.
@@@ -27,7 -29,7 +27,7 @@@
  #
  #   The additional arguments are stored as members of the parser
  #   object, yyparser.  The C routines need to carry yyparser
 -#   throughout the C parser; that easy: just let yyparser become an
 +#   throughout the C parser; that's easy: make yyparser an
  #   additional parse-param.  But because the C++ skeleton needs to
  #   know the "real" original parse-param, we save them
  #   (b4_parse_param_orig).  Note that b4_parse_param is overquoted
  # The locations
  #
  #   We use location.cc just like lalr1.cc, but because glr.c stores
 -#   the locations in a (C++) union, the position and location classes
 +#   the locations in a union, the position and location classes
  #   must not have a constructor.  Therefore, contrary to lalr1.cc, we
  #   must not define "b4_location_constructors".  As a consequence the
  #   user must initialize the first positions (in particular the
  #   filename member).
  
  # We require a pure interface using locations.
 -m4_define([b4_locations_flag], [1])
 +m4_define([b4_percent_define(locations)], [])
  m4_define([b4_pure_flag],      [1])
  
  # The header is mandatory.
@@@ -126,7 -128,8 +126,7 @@@ m4_pushdef([b4_parse_param], m4_defn([b
    ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
      :])[
  #if YYDEBUG
 -    ]m4_ifset([b4_parse_param], [  ], [ :])[yydebug_ (false),
 -      yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
 +    ]m4_ifset([b4_parse_param], [  ], [ :])[yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
  #endif]b4_parse_param_cons[
    {
    }
      YYUSE (yyo);
      switch (yytype)
        {
 -  ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
 +]b4_symbol_foreach([b4_symbol_printer])dnl
  [        default:
            break;
        }
    ]b4_parser_class_name[::debug_level_type
    ]b4_parser_class_name[::debug_level () const
    {
 -    return yydebug_;
 +    return yydebug;
    }
  
    void
    ]b4_parser_class_name[::set_debug_level (debug_level_type l)
    {
 -    yydebug_ = l;
 +    yydebug = l;
    }
  
  #endif
  ]m4_popdef([b4_parse_param])dnl
  b4_namespace_close[
 -
  ]])
  
  
@@@ -222,7 -226,7 +222,7 @@@ m4_popdef([b4_parse_param]
  m4_divert_push(0)
  @output(b4_spec_defines_file@)@
  b4_copyright([Skeleton interface for Bison GLR parsers in C++],
 -             [2002-2006, 2009-2012])[
 +             [2002-2012])[
  
  /* C++ GLR parser skeleton written by Akim Demaille.  */
  
  
  ]b4_percent_code_get([[requires]])[
  
 +#include <stdexcept>
  #include <string>
  #include <iostream>
  ]b4_percent_define_ifdef([[location_type]], [],
                           [[#include "location.hh"]])[
  
- /* Using locations.  */
- #define YYLSP_NEEDED ]b4_locations_if([1], [0])[
  /* Enabling traces.  */
  #ifndef YYDEBUG
 -# define YYDEBUG ]b4_debug_flag[
 +# define YYDEBUG ]b4_parse_trace_if([1], [0])[
  #endif
  
  /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
    class ]b4_parser_class_name[
    {
    public:
 -    /// Symbol semantic values.
 -#ifndef YYSTYPE
 -]m4_ifdef([b4_stype],
 -[    union semantic_type
 -    {
 -b4_user_stype
 -    };],
 -[m4_if(b4_tag_seen_flag, 0,
 -[[    typedef int semantic_type;]],
 -[[    typedef YYSTYPE semantic_type;]])])[
 -#else
 -    typedef YYSTYPE semantic_type;
 -#endif
 -    /// Symbol locations.
 -    typedef ]b4_percent_define_get([[location_type]],
 -                                   [[location]])[ location_type;
 -    /// Tokens.
 -    struct token
 -    {
 -      ]b4_token_enums(b4_tokens)[
 -    };
 -    /// Token type.
 -    typedef token::yytokentype token_type;
 +]b4_public_types_declare[
  
      /// Build a parser object.
      ]b4_parser_class_name[ (]b4_parse_param_decl[);
      /// Set the current debugging level.
      void set_debug_level (debug_level_type l);
  
 -  private:
 -
    public:
      /// Report a syntax error.
      /// \param loc    where the syntax error is found.
      /// \param msg    a description of the syntax error.
      virtual void error (const location_type& loc, const std::string& msg);
 -  private:
  
  #if YYDEBUG
    public:
                                     const location_type* yylocationp);
    private:
      /* Debugging.  */
 -    int yydebug_;
      std::ostream* yycdebug_;
  #endif
  
diff --combined data/lalr1.cc
index b8334e835f3e56f117c78534f5f25e41d2645d51,e82e654f94723a81724d81c19638a2232600c2f9..7ad30e5c3a7369f16a6229b5a7a7487deb44627d
  
  m4_include(b4_pkgdatadir/[c++.m4])
  
 +
 +# b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
 +# --------------------------------------------------------------
 +# Declare "parser::yy<TABLE-NAME>_" which contents is CONTENT.
 +m4_define([b4_integral_parser_table_declare],
 +[m4_ifval([$3], [b4_c_comment([$3], [  ])
 +])dnl
 +  static const b4_int_type_for([$2]) yy$1_[[]];dnl
 +])
 +
 +# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
 +# -------------------------------------------------------------
 +# Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
 +m4_define([b4_integral_parser_table_define],
 +[  const b4_int_type_for([$2])
 +  b4_parser_class_name::yy$1_[[]] =
 +  {
 +  $2
 +  };dnl
 +])
 +
 +
 +# b4_symbol_value_template(VAL, [TYPE])
 +# -------------------------------------
 +# Same as b4_symbol_value, but used in a template method.  It makes
 +# a difference when using variants.
 +m4_copy([b4_symbol_value], [b4_symbol_value_template])
 +
 +
 +# b4_lhs_value([TYPE])
 +# --------------------
 +# Expansion of $<TYPE>$.
 +m4_define([b4_lhs_value],
 +          [b4_symbol_value([yylhs.value], [$1])])
 +
 +
 +# b4_lhs_location()
 +# -----------------
 +# Expansion of @$.
 +m4_define([b4_lhs_location],
 +          [yylhs.location])
 +
 +
 +# b4_rhs_data(RULE-LENGTH, NUM)
 +# -----------------------------
 +# Return the data corresponding to the symbol #NUM, where the current
 +# rule has RULE-LENGTH symbols on RHS.
 +m4_define([b4_rhs_data],
 +          [yystack_@{b4_subtract($@)@}])
 +
 +
 +# b4_rhs_state(RULE-LENGTH, NUM)
 +# ------------------------------
 +# The state corresponding to the symbol #NUM, where the current
 +# rule has RULE-LENGTH symbols on RHS.
 +m4_define([b4_rhs_state],
 +          [b4_rhs_data([$1], [$2]).state])
 +
 +
 +# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
 +# --------------------------------------
 +# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
 +# symbols on RHS.
 +m4_define([b4_rhs_value],
 +          [b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3])])
 +
 +
 +# b4_rhs_location(RULE-LENGTH, NUM)
 +# ---------------------------------
 +# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
 +# on RHS.
 +m4_define([b4_rhs_location],
 +          [b4_rhs_data([$1], [$2]).location])
 +
 +
 +# b4_symbol_action(SYMBOL-NUM, KIND)
 +# ----------------------------------
 +# Run the action KIND (destructor or printer) for SYMBOL-NUM.
 +# Same as in C, but using references instead of pointers.
 +m4_define([b4_symbol_action],
 +[b4_symbol_if([$1], [has_$2],
 +[m4_pushdef([b4_dollar_dollar],
 +    [b4_symbol_value_template([yysym.value],
 +                              b4_symbol_if([$1], [has_type],
 +                                           [b4_symbol([$1], [type])]))])dnl
 +m4_pushdef([b4_at_dollar], [yysym.location])dnl
 +      b4_symbol_case_([$1])
 +b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
 +        b4_symbol([$1], [$2])
 +b4_syncline([@oline@], [@ofile@])
 +        break;
 +
 +m4_popdef([b4_at_dollar])dnl
 +m4_popdef([b4_dollar_dollar])dnl
 +])])
 +
 +
 +m4_pushdef([b4_copyright_years],
 +           [2002-2012])
 +
  m4_define([b4_parser_class_name],
            [b4_percent_define_get([[parser_class_name]])])
  
  b4_defines_if([],
                [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
  
 -b4_percent_define_ifdef([[location_type]], [],
 +b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
    [# Backward compatibility.
 -  m4_define([b4_location_constructors])
 -  m4_include(b4_pkgdatadir/[location.cc])])
 +   m4_define([b4_location_constructors])
 +   m4_include(b4_pkgdatadir/[location.cc])])])
  m4_include(b4_pkgdatadir/[stack.hh])
 +b4_variant_if([m4_include(b4_pkgdatadir/[variant.hh])])
  
  # We do want M4 expansion after # for CPP macros.
  m4_changecom()
  m4_divert_push(0)dnl
 -b4_defines_if(
 -[@output(b4_spec_defines_file@)@
 -b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++],
 -             [2002-2012])
 +@output(b4_spec_defines_file@)@
 +b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
  [
  /**
   ** \file ]b4_spec_defines_file[
  
  ]b4_percent_code_get([[requires]])[
  
 +]b4_parse_assert_if([#include <cassert>])[
 +#include <stdexcept>
  #include <string>
  #include <iostream>
  #include "stack.hh"
 -]b4_percent_define_ifdef([[location_type]], [],
 -                         [[#include "location.hh"]])[
 +]b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
 +                                          [[#include "location.hh"]])])[
 +
 +]b4_variant_if([b4_namespace_open
 +b4_variant_define
 +b4_namespace_close])[
  
  ]b4_null_define[
  
  /* Enabling traces.  */
  #ifndef YYDEBUG
 -# define YYDEBUG ]b4_debug_flag[
 +# define YYDEBUG ]b4_parse_trace_if([1], [0])[
  #endif
  
- /* Enabling verbose error messages.  */
- #ifdef YYERROR_VERBOSE
- # undef YYERROR_VERBOSE
- # define YYERROR_VERBOSE 1
- #else
- # define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
- #endif
- /* Enabling the token table.  */
- #ifndef YYTOKEN_TABLE
- # define YYTOKEN_TABLE ]b4_token_table[
- #endif
  ]b4_namespace_open[
  
    /// A Bison parser.
    class ]b4_parser_class_name[
    {
    public:
 -    /// Symbol semantic values.
 -#ifndef YYSTYPE
 -]m4_ifdef([b4_stype],
 -[    union semantic_type
 -    {
 -b4_user_stype
 -    };],
 -[m4_if(b4_tag_seen_flag, 0,
 -[[    typedef int semantic_type;]],
 -[[    typedef YYSTYPE semantic_type;]])])[
 -#else
 -    typedef YYSTYPE semantic_type;
 -#endif
 -    /// Symbol locations.
 -    typedef ]b4_percent_define_get([[location_type]],
 -                                   [[location]])[ location_type;
 -    /// Tokens.
 -    struct token
 -    {
 -      ]b4_token_enums(b4_tokens)[
 -    };
 -    /// Token type.
 -    typedef token::yytokentype token_type;
 -
 +]b4_public_types_declare[
      /// Build a parser object.
      ]b4_parser_class_name[ (]b4_parse_param_decl[);
      virtual ~]b4_parser_class_name[ ();
      void set_debug_level (debug_level_type l);
  #endif
  
 -  private:
 -    /// Report a syntax error.
 -    /// \param loc    where the syntax error is found.
 +    /// Report a syntax error.]b4_locations_if([
 +    /// \param loc    where the syntax error is found.])[
      /// \param msg    a description of the syntax error.
 -    virtual void error (const location_type& loc, const std::string& msg);
 -
 -    /// Generate an error message.
 -    /// \param state   the state where the error occurred.
 -    /// \param tok     the lookahead token.
 -    virtual std::string yysyntax_error_ (int yystate, int tok);
 -
 -#if YYDEBUG
 -    /// \brief Report a symbol value on the debug stream.
 -    /// \param yytype       The token type.
 -    /// \param yyvaluep     Its semantic value.
 -    /// \param yylocationp  Its location.
 -    virtual void yy_symbol_value_print_ (int yytype,
 -                                       const semantic_type* yyvaluep,
 -                                       const location_type* yylocationp);
 -    /// \brief Report a symbol on the debug stream.
 -    /// \param yytype       The token type.
 -    /// \param yyvaluep     Its semantic value.
 -    /// \param yylocationp  Its location.
 -    virtual void yy_symbol_print_ (int yytype,
 -                                 const semantic_type* yyvaluep,
 -                                 const location_type* yylocationp);
 -#endif
 +    virtual void error (]b4_locations_if([const location_type& loc, ])[const std::string& msg);
  
 +    /// Report a syntax error.
 +    void error (const syntax_error& err);
  
 +  private:
      /// State numbers.
      typedef int state_type;
 -    /// State stack type.
 -    typedef stack<state_type>    state_stack_type;
 -    /// Semantic value stack type.
 -    typedef stack<semantic_type> semantic_stack_type;
 -    /// location stack type.
 -    typedef stack<location_type> location_stack_type;
 -
 -    /// The state stack.
 -    state_stack_type yystate_stack_;
 -    /// The semantic value stack.
 -    semantic_stack_type yysemantic_stack_;
 -    /// The location stack.
 -    location_stack_type yylocation_stack_;
 +
 +    /// Generate an error message.
 +    /// \param yystate   the state where the error occurred.
 +    /// \param yytoken   the lookahead token.
 +    virtual std::string yysyntax_error_ (state_type yystate, int yytoken);
 +
 +    /// Compute post-reduction state.
 +    /// \param yystate   the current state
 +    /// \param yylhs     the nonterminal to push on the stack
 +    state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
  
      /// Whether the given \c yypact_ value indicates a defaulted state.
      /// \param yyvalue   the value to check
  
      /// Internal symbol numbers.
      typedef ]b4_int_type_for([b4_translate])[ token_number_type;
 -    /* Tables.  */
 -    /// For a state, the index in \a yytable_ of its portion.
 -    static const ]b4_int_type_for([b4_pact])[ yypact_[];
      static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
 -
 -    /// For a state, default reduction number.
 -    /// Unless\a  yytable_ specifies something else to do.
 -    /// Zero means the default is an error.
 -    static const ]b4_int_type_for([b4_defact])[ yydefact_[];
 -
 -    static const ]b4_int_type_for([b4_pgoto])[ yypgoto_[];
 -    static const ]b4_int_type_for([b4_defgoto])[ yydefgoto_[];
 -
 -    /// What to do in a state.
 -    /// \a yytable_[yypact_[s]]: what to do in state \a s.
 -    /// - if positive, shift that token.
 -    /// - if negative, reduce the rule which number is the opposite.
 -    /// - if zero, do what YYDEFACT says.
 -    static const ]b4_int_type_for([b4_table])[ yytable_[];
      static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_;
  
-     /* Tables.  */
- ]b4_parser_tables_declare[
 -    static const ]b4_int_type_for([b4_check])[ yycheck_[];
--
- #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-     /// For a symbol, its name in clear.
-     static const char* const yytname_[];
- #endif]b4_error_verbose_if([
 -    /// For a state, its accessing symbol.
 -    static const ]b4_int_type_for([b4_stos])[ yystos_[];
 -
 -    /// For a rule, its LHS.
 -    static const ]b4_int_type_for([b4_r1])[ yyr1_[];
 -    /// For a rule, its RHS length.
 -    static const ]b4_int_type_for([b4_r2])[ yyr2_[]; ]b4_error_verbose_if([
++    // Tables.
++]b4_parser_tables_declare[]b4_error_verbose_if([
  
      /// Convert the symbol name \a n to a form suitable for a diagnostic.
      static std::string yytnamerr_ (const char *n);])[
  
- #if YYDEBUG
+ ]b4_token_table_if([], [[#if YYDEBUG]])[
+     /// For a symbol, its name in clear.
+     static const char* const yytname_[];
+ ]b4_token_table_if([[#if YYDEBUG]])[
 -    /// A type to store symbol numbers and -1.
 -    typedef ]b4_int_type_for([b4_rhs])[ rhs_number_type;
 -    /// A `-1'-separated list of the rules' RHS.
 -    static const rhs_number_type yyrhs_[];
 -    /// For each rule, the index of the first RHS symbol in \a yyrhs_.
 -    static const ]b4_int_type_for([b4_prhs])[ yyprhs_[];
 -    /// For each rule, its source line number.
 -    static const ]b4_int_type_for([b4_rline])[ yyrline_[];
 -    /// For each scanner token number, its symbol number.
 -    static const ]b4_int_type_for([b4_toknum])[ yytoken_number_[];
 +]b4_integral_parser_table_declare([rline], [b4_rline],
 +     [YYRLINE[YYN] -- Source line where rule number YYN was defined.])[
      /// Report on the debug stream that the rule \a r is going to be reduced.
      virtual void yy_reduce_print_ (int r);
      /// Print the state stack on the debug stream.
      virtual void yystack_print_ ();
  
--    /* Debugging.  */
++    // Debugging.
      int yydebug_;
      std::ostream* yycdebug_;
--#endif
++#endif // YYDEBUG
  
      /// Convert a scanner token number \a t to a symbol number.
 -    token_number_type yytranslate_ (int t);
 +    static inline token_number_type yytranslate_ (]b4_lex_symbol_if([token_type], [int])[ t);
 +
 +#if YYDEBUG
 +    /// \brief Display a symbol type, value and location.
 +    /// \param yyo    The output stream.
 +    /// \param yysym  The symbol.
 +    template <typename Exact>
 +    void yy_print_ (std::ostream& yyo,
 +                    const symbol_base_type<Exact>& yysym) const;
 +#endif
  
      /// \brief Reclaim the memory associated to a symbol.
 -    /// \param yymsg        Why this token is reclaimed.
 -    /// \param yytype       The symbol type.
 -    /// \param yyvaluep     Its semantic value.
 -    /// \param yylocationp  Its location.
 -    inline void yydestruct_ (const char* yymsg,
 -                           int yytype,
 -                           semantic_type* yyvaluep,
 -                           location_type* yylocationp);
 +    /// \param yymsg     Why this token is reclaimed.
 +    ///                  If null, print nothing.
 +    /// \param s         The symbol.
 +    template <typename Exact>
 +    inline void yy_destroy_ (const char* yymsg,
 +                             symbol_base_type<Exact>& yysym) const;
 +
 +  private:
 +    /// Element of the stack: a state and its attributes.
 +    struct stack_symbol_type : symbol_base_type<stack_symbol_type>
 +    {
 +      /// The parent class.
 +      typedef symbol_base_type<stack_symbol_type> super_type;
 +
 +      /// Default constructor.
 +      inline stack_symbol_type ();
 +
 +      /// Constructor.
 +      inline stack_symbol_type (]b4_args([state_type s],
 +                                         [const semantic_type& v],
 +                                         b4_locations_if([const location_type& l]))[);
 +
 +      /// The state.
 +      state_type state;
 +
 +      /// The type (corresponding to \a state).
 +      inline int type_get_ () const;
 +    };
 +
 +    /// Stack type.
 +    typedef stack<stack_symbol_type> stack_type;
 +
 +    /// The stack.
 +    stack_type yystack_;
 +
 +    /// Push a new state on the stack.
 +    /// \param m    a debug message to display
 +    ///             if null, no trace is output.
 +    /// \param s    the symbol
 +    /// \warning the contents of \a s.value is stolen.
 +    inline void yypush_ (const char* m, stack_symbol_type& s);
 +
 +    /// Push a new look ahead token on the state on the stack.
 +    /// \param m    a debug message to display
 +    ///             if null, no trace is output.
 +    /// \param s    the state
 +    /// \param sym  the symbol (for its value and location).
 +    /// \warning the contents of \a s.value is stolen.
 +    inline void yypush_ (const char* m, state_type s, symbol_type& sym);
  
      /// Pop \a n symbols the three stacks.
      inline void yypop_ (unsigned int n = 1);
  
      /* Constants.  */
 -    static const int yyeof_;
 -    /* LAST_ -- Last index in TABLE_.  */
 -    static const int yylast_;
 -    static const int yynnts_;
 -    static const int yyempty_;
 -    static const int yyfinal_;
 -    static const int yyterror_;
 -    static const int yyerrcode_;
 -    static const int yyntokens_;
 -    static const unsigned int yyuser_token_number_max_;
 -    static const token_number_type yyundef_token_;
 +    enum
 +    {
 +      yyeof_ = 0,
 +      yylast_ = ]b4_last[,           //< Last index in yytable_.
 +      yynnts_ = ]b4_nterms_number[,  //< Number of nonterminal symbols.
 +      yyempty_ = -2,
 +      yyfinal_ = ]b4_final_state_number[, //< Termination state number.
 +      yyterror_ = 1,
 +      yyerrcode_ = 256,
 +      yyntokens_ = ]b4_tokens_number[    //< Number of tokens.
 +    };
 +
  ]b4_parse_param_vars[
    };
 +
 +]b4_lex_symbol_if([b4_yytranslate_define
 +b4_public_types_define])[
  ]b4_namespace_close[
  
  ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
  ])[
  ]b4_percent_code_get([[provides]])[
  ]b4_cpp_guard_close([b4_spec_defines_file])
 -])dnl
  @output(b4_parser_file_name@)@
 -b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++],
 -             [2002-2012])
 +b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])
  b4_percent_code_get([[top]])[]dnl
  m4_if(b4_prefix, [yy], [],
  [
  #define yylex   b4_prefix[]lex])[
  
  /* First part of user declarations.  */
 -]b4_user_pre_prologue
 +]b4_user_pre_prologue[
  
 -b4_defines_if([[
 -#include "@basename(]b4_spec_defines_file[@)"]])[
 +#include "@basename(]b4_spec_defines_file[@)"
  
  /* User implementation prologue.  */
  ]b4_user_post_prologue
@@@ -393,12 -301,11 +378,12 @@@ b4_percent_code_get[]dn
  # endif
  #endif
  
 -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
 +]b4_locations_if([dnl
 +[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
     If N is 0, then set CURRENT to the empty location which ends
     the previous symbol: RHS[0] (always defined).  */
  
 -#define YYRHSLOC(Rhs, K) ((Rhs)[K])
 +#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
  #ifndef YYLLOC_DEFAULT
  # define YYLLOC_DEFAULT(Current, Rhs, N)                               \
   do                                                                    \
         (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end;        \
       }                                                                 \
   while (false)
 -#endif
 +#endif]])[
  
  /* Suppress unused-variable warnings by "using" E.  */
  #define YYUSE(e) ((void) (e))
  /* A pseudo ostream that takes yydebug_ into account.  */
  # define YYCDEBUG if (yydebug_) (*yycdebug_)
  
 -# define YY_SYMBOL_PRINT(Title, Type, Value, Location)        \
 -do {                                                  \
 -  if (yydebug_)                                               \
 -    {                                                 \
 -      *yycdebug_ << Title << ' ';                     \
 -      yy_symbol_print_ ((Type), (Value), (Location)); \
 -      *yycdebug_ << std::endl;                                \
 -    }                                                 \
 -} while (false)
 -
 -# define YY_REDUCE_PRINT(Rule)                \
 -do {                                  \
 -  if (yydebug_)                               \
 -    yy_reduce_print_ (Rule);          \
 -} while (false)
 -
 -# define YY_STACK_PRINT()             \
 -do {                                  \
 -  if (yydebug_)                               \
 -    yystack_print_ ();                        \
 -} while (false)
 +# define YY_SYMBOL_PRINT(Title, Symbol)         \
 +  do {                                          \
 +    if (yydebug_)                               \
 +    {                                           \
 +      *yycdebug_ << Title << ' ';               \
 +      yy_print_ (*yycdebug_, Symbol);           \
 +      *yycdebug_ << std::endl;                  \
 +    }                                           \
 +  } while (false)
 +
 +# define YY_REDUCE_PRINT(Rule)          \
 +  do {                                  \
 +    if (yydebug_)                       \
 +      yy_reduce_print_ (Rule);          \
 +  } while (false)
 +
 +# define YY_STACK_PRINT()               \
 +  do {                                  \
 +    if (yydebug_)                       \
 +      yystack_print_ ();                \
 +  } while (false)
  
  #else /* !YYDEBUG */
  
  # define YYCDEBUG if (false) std::cerr
 -# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
 -# define YY_REDUCE_PRINT(Rule)
 -# define YY_STACK_PRINT()
 +# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE(Symbol)
 +# define YY_REDUCE_PRINT(Rule)           static_cast<void>(0)
 +# define YY_STACK_PRINT()                static_cast<void>(0)
  
  #endif /* !YYDEBUG */
  
 -#define yyerrok               (yyerrstatus_ = 0)
 -#define yyclearin     (yychar = yyempty_)
 +#define yyerrok         (yyerrstatus_ = 0)
 +#define yyclearin       (yyempty = true)
  
 -#define YYACCEPT      goto yyacceptlab
 -#define YYABORT               goto yyabortlab
 -#define YYERROR               goto yyerrorlab
 +#define YYACCEPT        goto yyacceptlab
 +#define YYABORT         goto yyabortlab
 +#define YYERROR         goto yyerrorlab
  #define YYRECOVERING()  (!!yyerrstatus_)
  
  ]b4_namespace_open[]b4_error_verbose_if([[
    {
    }
  
 -#if YYDEBUG
 -  /*--------------------------------.
 -  | Print this symbol on YYOUTPUT.  |
 -  `--------------------------------*/
  
 -  inline void
 -  ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype,
 -                         const semantic_type* yyvaluep, const location_type* yylocationp)
 +  /*---------------.
 +  | Symbol types.  |
 +  `---------------*/
 +
 +]b4_lex_symbol_if([], [b4_public_types_define])[
 +
 +  // stack_symbol_type.
 +  ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type ()
 +    : super_type ()
 +    , state ()
 +  {
 +  }
 +
 +  ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (]b4_args(
 +                 [state_type s],
 +                 [const semantic_type& v],
 +                 b4_locations_if([const location_type& l]))[)
 +    : super_type (v]b4_locations_if([, l])[)
 +    , state (s)
 +  {
 +  }
 +
 +  int
 +  ]b4_parser_class_name[::stack_symbol_type::type_get_ () const
 +  {
 +    return yystos_[state];
 +  }
 +
 +
 +  template <typename Exact>
 +  void
 +  ]b4_parser_class_name[::yy_destroy_ (const char* yymsg,
 +                                       symbol_base_type<Exact>& yysym) const
 +  {
 +    if (yymsg)
 +      YY_SYMBOL_PRINT (yymsg, yysym);
 +
 +    // User destructor.
 +    int yytype = yysym.type_get ();
 +    switch (yytype)
 +      {
 +]b4_symbol_foreach([b4_symbol_destructor])dnl
 +[       default:
 +          break;
 +      }]b4_variant_if([
 +
 +    // Type destructor.
 +  b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[
 +  }
 +
 +#if YYDEBUG
 +  template <typename Exact>
 +  void
 +  ]b4_parser_class_name[::yy_print_ (std::ostream& yyo,
 +                                     const symbol_base_type<Exact>& yysym) const
    {
 -    YYUSE (yylocationp);
 -    YYUSE (yyvaluep);
 -    std::ostream& yyo = debug_stream ();
      std::ostream& yyoutput = yyo;
      YYUSE (yyoutput);
 +    int yytype = yysym.type_get ();
 +    yyo << (yytype < yyntokens_ ? "token" : "nterm")
 +        << ' ' << yytname_[yytype] << " ("]b4_locations_if([
 +        << yysym.location << ": "])[;
      switch (yytype)
        {
 -  ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
 +]b4_symbol_foreach([b4_symbol_printer])dnl
  [       default:
 -        break;
 +          break;
        }
 +    yyo << ')';
    }
 -
 +#endif
  
    void
 -  ]b4_parser_class_name[::yy_symbol_print_ (int yytype,
 -                         const semantic_type* yyvaluep, const location_type* yylocationp)
 +  ]b4_parser_class_name[::yypush_ (const char* m, state_type s,
 +                                   symbol_type& sym)
    {
 -    *yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm")
 -             << ' ' << yytname_[yytype] << " ("
 -             << *yylocationp << ": ";
 -    yy_symbol_value_print_ (yytype, yyvaluep, yylocationp);
 -    *yycdebug_ << ')';
 +    if (m)
 +      YY_SYMBOL_PRINT (m, sym);
 +]b4_variant_if(
 +[[    yystack_.push (stack_symbol_type (]b4_args(
 +                    [s],
 +                    [semantic_type()],
 +                    b4_locations_if([sym.location]))[));
 +    ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]],
 +                       [build], [sym.value])],
 +[[    yystack_.push (stack_symbol_type (]b4_args(
 +                      [s],
 +                      [sym.value],
 +                      b4_locations_if([sym.location]))[));]])[
    }
 -#endif
  
    void
 -  ]b4_parser_class_name[::yydestruct_ (const char* yymsg,
 -                         int yytype, semantic_type* yyvaluep, location_type* yylocationp)
 +  ]b4_parser_class_name[::yypush_ (const char* m, stack_symbol_type& s)
    {
 -    YYUSE (yylocationp);
 -    YYUSE (yymsg);
 -    YYUSE (yyvaluep);
 -
 -    YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 -
 -    switch (yytype)
 -      {
 -  ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[
 -      default:
 -        break;
 -      }
 +    if (m)
 +      YY_SYMBOL_PRINT (m, s);
 +]b4_variant_if(
 +[[    yystack_.push (stack_symbol_type (]b4_args(
 +                       [s.state],
 +                       [semantic_type()],
 +                       b4_locations_if([s.location]))[));
 +    ]b4_symbol_variant([[yystos_[s.state]]], [[yystack_[0].value]],
 +                       [build], [s.value])],
 +[    yystack_.push (s);])[
    }
  
    void
    ]b4_parser_class_name[::yypop_ (unsigned int n)
    {
 -    yystate_stack_.pop (n);
 -    yysemantic_stack_.pop (n);
 -    yylocation_stack_.pop (n);
 +    yystack_.pop (n);
    }
  
  #if YYDEBUG
    {
      yydebug_ = l;
    }
--#endif
++#endif // YYDEBUG
 +
 +  inline ]b4_parser_class_name[::state_type
 +  ]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
 +  {
 +    int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
 +    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
 +      return yytable_[yyr];
 +    else
 +      return yydefgoto_[yylhs - yyntokens_];
 +  }
  
    inline bool
    ]b4_parser_class_name[::yy_pact_value_is_default_ (int yyvalue)
    int
    ]b4_parser_class_name[::parse ()
    {
 -    /// Lookahead and lookahead in internal form.
 -    int yychar = yyempty_;
 -    int yytoken = 0;
 +    /// Whether yyla contains a lookahead.
 +    bool yyempty = true;
  
      /* State.  */
      int yyn;
      int yylen = 0;
 -    int yystate = 0;
  
      /* Error handling.  */
      int yynerrs_ = 0;
      int yyerrstatus_ = 0;
  
 -    /// Semantic value of the lookahead.
 -    semantic_type yylval;
 -    /// Location of the lookahead.
 -    location_type yylloc;
 +    /// The lookahead symbol.
 +    symbol_type yyla;]b4_locations_if([[
 +
      /// The locations where the error started and ended.
 -    location_type yyerror_range[3];
 +    stack_symbol_type yyerror_range[3];]])[
  
 -    /// $$.
 -    semantic_type yyval;
 -    /// @@$.
 -    location_type yyloc;
 +    /// $$ and @@$.
 +    stack_symbol_type yylhs;
  
 +    /// The return value of parse().
      int yyresult;
  
      YYCDEBUG << "Starting parse" << std::endl;
  
  ]m4_ifdef([b4_initial_action], [
 -m4_pushdef([b4_at_dollar],     [yylloc])dnl
 -m4_pushdef([b4_dollar_dollar], [yylval])dnl
 +m4_pushdef([b4_at_dollar],     [yyla.location])dnl
 +m4_pushdef([b4_dollar_dollar], [yyla.value])dnl
      /* User initialization code.  */
      b4_user_initial_action
  m4_popdef([b4_dollar_dollar])dnl
  m4_popdef([b4_at_dollar])])dnl
  
 -  [  /* Initialize the stacks.  The initial state will be pushed in
 +  [  /* Initialize the stack.  The initial state will be set in
         yynewstate, since the latter expects the semantical and the
         location values to have been already stored, initialize these
         stacks with a primary value.  */
 -    yystate_stack_ = state_stack_type (0);
 -    yysemantic_stack_ = semantic_stack_type (0);
 -    yylocation_stack_ = location_stack_type (0);
 -    yysemantic_stack_.push (yylval);
 -    yylocation_stack_.push (yylloc);
 +    yystack_ = stack_type (0);
 +    yypush_ (YY_NULL, 0, yyla);
  
 -    /* New state.  */
 +    // A new symbol was pushed on the stack.
    yynewstate:
 -    yystate_stack_.push (yystate);
 -    YYCDEBUG << "Entering state " << yystate << std::endl;
 +    YYCDEBUG << "Entering state " << yystack_[0].state << std::endl;
  
      /* Accept?  */
 -    if (yystate == yyfinal_)
 +    if (yystack_[0].state == yyfinal_)
        goto yyacceptlab;
  
      goto yybackup;
    yybackup:
  
      /* Try to take a decision without lookahead.  */
 -    yyn = yypact_[yystate];
 +    yyn = yypact_[yystack_[0].state];
      if (yy_pact_value_is_default_ (yyn))
        goto yydefault;
  
      /* Read a lookahead token.  */
 -    if (yychar == yyempty_)
 -      {
 -      YYCDEBUG << "Reading a token: ";
 -      yychar = ]b4_c_function_call([yylex], [int],
 -                                   [[YYSTYPE*], [&yylval]][]dnl
 -b4_locations_if([, [[location*], [&yylloc]]])dnl
 -m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
 -      }
 -
 -
 -    /* Convert token to internal form.  */
 -    if (yychar <= yyeof_)
 -      {
 -      yychar = yytoken = yyeof_;
 -      YYCDEBUG << "Now at end of input." << std::endl;
 -      }
 -    else
 +    if (yyempty)
        {
 -      yytoken = yytranslate_ (yychar);
 -      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
 +        YYCDEBUG << "Reading a token: ";
 +        try
 +        {
 +]b4_lex_symbol_if(
 +[          yyla = b4_c_function_call([yylex], [symbol_type],
 +                                     m4_ifdef([b4_lex_param], b4_lex_param));],
 +[          yyla.type = yytranslate_ (b4_c_function_call([yylex], [int],
 +                                     [[YYSTYPE*], [&yyla.value]][]dnl
 +b4_locations_if([, [[location*], [&yyla.location]]])dnl
 +m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
 +        }
 +        catch (const syntax_error& yyexc)
 +        {
 +          error (yyexc);
 +          goto yyerrlab1;
 +        }
 +        yyempty = false;
        }
 +    YY_SYMBOL_PRINT ("Next token is", yyla);
  
 -    /* If the proper action on seeing token YYTOKEN is to reduce or to
 -       detect an error, take that action.  */
 -    yyn += yytoken;
 -    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
 +    /* If the proper action on seeing token YYLA.TYPE is to reduce or
 +       to detect an error, take that action.  */
 +    yyn += yyla.type;
 +    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type)
        goto yydefault;
  
      /* Reduce or error.  */
      yyn = yytable_[yyn];
      if (yyn <= 0)
        {
 -      if (yy_table_value_is_error_ (yyn))
 -        goto yyerrlab;
 -      yyn = -yyn;
 -      goto yyreduce;
 +        if (yy_table_value_is_error_ (yyn))
 +          goto yyerrlab;
 +        yyn = -yyn;
 +        goto yyreduce;
        }
  
 -    /* Shift the lookahead token.  */
 -    YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 -
      /* Discard the token being shifted.  */
 -    yychar = yyempty_;
 -
 -    yysemantic_stack_.push (yylval);
 -    yylocation_stack_.push (yylloc);
 +    yyempty = true;
  
      /* Count tokens shifted since error; after three, turn off error
         status.  */
      if (yyerrstatus_)
        --yyerrstatus_;
  
 -    yystate = yyn;
 +    /* Shift the lookahead token.  */
 +    yypush_ ("Shifting", yyn, yyla);
      goto yynewstate;
  
    /*-----------------------------------------------------------.
    | yydefault -- do the default action for the current state.  |
    `-----------------------------------------------------------*/
    yydefault:
 -    yyn = yydefact_[yystate];
 +    yyn = yydefact_[yystack_[0].state];
      if (yyn == 0)
        goto yyerrlab;
      goto yyreduce;
    `-----------------------------*/
    yyreduce:
      yylen = yyr2_[yyn];
 +    yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
 +    /* Variants are always initialized to an empty instance of the
 +       correct type. The default $$=$1 action is NOT applied when using
 +       variants.  */
 +    b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[
      /* If YYLEN is nonzero, implement the default value of the action:
         `$$ = $1'.  Otherwise, use the top of the stack.
  
 -       Otherwise, the following line sets YYVAL to garbage.
 +       Otherwise, the following line sets YYLHS.VALUE to garbage.
         This behavior is undocumented and Bison
         users should not rely upon it.  */
      if (yylen)
 -      yyval = yysemantic_stack_[yylen - 1];
 +      yylhs.value = yystack_@{yylen - 1@}.value;
      else
 -      yyval = yysemantic_stack_[0];
 -
 +      yylhs.value = yystack_@{0@}.value;])[
 +]b4_locations_if([dnl
 +[
 +    // Compute the default @@$.
      {
 -      slice<location_type, location_stack_type> slice (yylocation_stack_, yylen);
 -      YYLLOC_DEFAULT (yyloc, slice, yylen);
 -    }
 +      slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
 +      YYLLOC_DEFAULT (yylhs.location, slice, yylen);
 +    }]])[
 +
 +    // Perform the reduction.
      YY_REDUCE_PRINT (yyn);
 -    switch (yyn)
 +    try
 +    {
 +      switch (yyn)
        {
 -      ]b4_user_actions[
 -      default:
 +]b4_user_actions[
 +        default:
            break;
        }
 -    /* User semantic actions sometimes alter yychar, and that requires
 -       that yytoken be updated with the new translation.  We take the
 -       approach of translating immediately before every use of yytoken.
 -       One alternative is translating here after every semantic action,
 -       but that translation would be missed if the semantic action
 -       invokes YYABORT, YYACCEPT, or YYERROR immediately after altering
 -       yychar.  In the case of YYABORT or YYACCEPT, an incorrect
 -       destructor might then be invoked immediately.  In the case of
 -       YYERROR, subsequent parser actions might lead to an incorrect
 -       destructor call or verbose syntax error message before the
 -       lookahead is translated.  */
 -    YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc);
 +    }
 +    catch (const syntax_error& yyexc)
 +    {
 +      error (yyexc);
 +      YYERROR;
 +    }
 +    YY_SYMBOL_PRINT ("-> $$ =", yylhs);
 +]b4_variant_if([[
 +    // Destroy the rhs symbols.
 +    for (int i = 0; i < yylen; ++i)
 +      // Destroy a variant which value may have been swapped with
 +      // yylhs.value (for instance if the action was "std::swap($$,
 +      // $1)").  The value of yylhs.value (hence possibly one of these
 +      // rhs symbols) depends on the default construction for this
 +      // type.  In the case of pointers for instance, no
 +      // initialization is done, so the value is junk.  Therefore do
 +      // not try to report the value of symbols about to be destroyed
 +      // in the debug trace, it's possibly junk.  Hence yymsg = 0.
 +      // Besides, that keeps exactly the same traces as with the other
 +      // Bison skeletons.
 +      yy_destroy_ (YY_NULL, yystack_[i]);]])[
  
      yypop_ (yylen);
      yylen = 0;
      YY_STACK_PRINT ();
  
 -    yysemantic_stack_.push (yyval);
 -    yylocation_stack_.push (yyloc);
 -
      /* Shift the result of the reduction.  */
 -    yyn = yyr1_[yyn];
 -    yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0];
 -    if (0 <= yystate && yystate <= yylast_
 -      && yycheck_[yystate] == yystate_stack_[0])
 -      yystate = yytable_[yystate];
 -    else
 -      yystate = yydefgoto_[yyn - yyntokens_];
 +    yypush_ (YY_NULL, yylhs);
      goto yynewstate;
  
 -  /*------------------------------------.
 -  | yyerrlab -- here on detecting error |
 -  `------------------------------------*/
 +  /*--------------------------------------.
 +  | yyerrlab -- here on detecting error |
 +  `--------------------------------------*/
    yyerrlab:
 -    /* Make sure we have latest lookahead translation.  See comments at
 -       user semantic actions for why this is necessary.  */
 -    yytoken = yytranslate_ (yychar);
 -
      /* If not already recovering from an error, report this error.  */
      if (!yyerrstatus_)
        {
 -      ++yynerrs_;
 -      if (yychar == yyempty_)
 -        yytoken = yyempty_;
 -      error (yylloc, yysyntax_error_ (yystate, yytoken));
 +        ++yynerrs_;
 +        error (]b4_args(b4_locations_if([yyla.location]),
 +                        [[yysyntax_error_ (yystack_[0].state,
 +                                           yyempty ? yyempty_ : yyla.type)]])[);
        }
  
 -    yyerror_range[1] = yylloc;
 +]b4_locations_if([[
 +    yyerror_range[1].location = yyla.location;]])[
      if (yyerrstatus_ == 3)
        {
 -      /* If just tried and failed to reuse lookahead token after an
 -       error, discard it.  */
 -
 -      if (yychar <= yyeof_)
 -        {
 -        /* Return failure if at end of input.  */
 -        if (yychar == yyeof_)
 -          YYABORT;
 -        }
 -      else
 -        {
 -          yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc);
 -          yychar = yyempty_;
 -        }
 +        /* If just tried and failed to reuse lookahead token after an
 +           error, discard it.  */
 +
 +        /* Return failure if at end of input.  */
 +        if (yyla.type == yyeof_)
 +          YYABORT;
 +        else if (!yyempty)
 +          {
 +            yy_destroy_ ("Error: discarding", yyla);
 +            yyempty = true;
 +          }
        }
  
      /* Else will try to reuse lookahead token after shifting the error
         YYERROR and the label yyerrorlab therefore never appears in user
         code.  */
      if (false)
 -      goto yyerrorlab;
 -
 -    yyerror_range[1] = yylocation_stack_[yylen - 1];
 +      goto yyerrorlab;]b4_locations_if([[
 +    yyerror_range[1].location = yystack_[yylen - 1].location;]])b4_variant_if([[
 +    /* $$ was initialized before running the user action.  */
 +    yy_destroy_ ("Error: discarding", yylhs);]])[
      /* Do not reclaim the symbols of the rule which action triggered
         this YYERROR.  */
      yypop_ (yylen);
      yylen = 0;
 -    yystate = yystate_stack_[0];
      goto yyerrlab1;
  
    /*-------------------------------------------------------------.
    | yyerrlab1 -- common code for both syntax error and YYERROR.  |
    `-------------------------------------------------------------*/
    yyerrlab1:
 -    yyerrstatus_ = 3; /* Each real token shifted decrements this.  */
 -
 -    for (;;)
 -      {
 -      yyn = yypact_[yystate];
 -      if (!yy_pact_value_is_default_ (yyn))
 -      {
 -        yyn += yyterror_;
 -        if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
 -          {
 -            yyn = yytable_[yyn];
 -            if (0 < yyn)
 -              break;
 -          }
 -      }
 -
 -      /* Pop the current state because it cannot handle the error token.  */
 -      if (yystate_stack_.height () == 1)
 -      YYABORT;
 -
 -      yyerror_range[1] = yylocation_stack_[0];
 -      yydestruct_ ("Error: popping",
 -                   yystos_[yystate],
 -                   &yysemantic_stack_[0], &yylocation_stack_[0]);
 -      yypop_ ();
 -      yystate = yystate_stack_[0];
 -      YY_STACK_PRINT ();
 -      }
 -
 -    yyerror_range[2] = yylloc;
 -    // Using YYLLOC is tempting, but would change the location of
 -    // the lookahead.  YYLOC is available though.
 -    YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
 -    yysemantic_stack_.push (yylval);
 -    yylocation_stack_.push (yyloc);
 +    yyerrstatus_ = 3;   /* Each real token shifted decrements this.  */
 +    {
 +      stack_symbol_type error_token;
 +      for (;;)
 +        {
 +          yyn = yypact_[yystack_[0].state];
 +          if (!yy_pact_value_is_default_ (yyn))
 +            {
 +              yyn += yyterror_;
 +              if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
 +                {
 +                  yyn = yytable_[yyn];
 +                  if (0 < yyn)
 +                    break;
 +                }
 +            }
  
 -    /* Shift the error token.  */
 -    YY_SYMBOL_PRINT ("Shifting", yystos_[yyn],
 -                   &yysemantic_stack_[0], &yylocation_stack_[0]);
 +          // Pop the current state because it cannot handle the error token.
 +          if (yystack_.size () == 1)
 +            YYABORT;
 +]b4_locations_if([[
 +          yyerror_range[1].location = yystack_[0].location;]])[
 +          yy_destroy_ ("Error: popping", yystack_[0]);
 +          yypop_ ();
 +          YY_STACK_PRINT ();
 +        }
 +]b4_locations_if([[
 +      yyerror_range[2].location = yyla.location;
 +      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);]])[
  
 -    yystate = yyn;
 +      /* Shift the error token.  */
 +      error_token.state = yyn;
 +      yypush_ ("Shifting", error_token);
 +    }
      goto yynewstate;
  
      /* Accept.  */
      goto yyreturn;
  
    yyreturn:
 -    if (yychar != yyempty_)
 -      {
 -        /* Make sure we have latest lookahead translation.  See comments
 -           at user semantic actions for why this is necessary.  */
 -        yytoken = yytranslate_ (yychar);
 -        yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval,
 -                     &yylloc);
 -      }
 +    if (!yyempty)
 +      yy_destroy_ ("Cleanup: discarding lookahead", yyla);
  
      /* Do not reclaim the symbols of the rule which action triggered
         this YYABORT or YYACCEPT.  */
      yypop_ (yylen);
 -    while (yystate_stack_.height () != 1)
 +    while (yystack_.size () != 1)
        {
 -      yydestruct_ ("Cleanup: popping",
 -                 yystos_[yystate_stack_[0]],
 -                 &yysemantic_stack_[0],
 -                 &yylocation_stack_[0]);
 -      yypop_ ();
 +        yy_destroy_ ("Cleanup: popping", yystack_[0]);
 +        yypop_ ();
        }
  
      return yyresult;
    }
  
 +  void
 +  ]b4_parser_class_name[::error (const syntax_error& yyexc)
 +  {
 +    error (]b4_args(b4_locations_if([yyexc.location]),
 +                    [[yyexc.what()]])[);
 +  }
 +
    // Generate an error message.
    std::string
    ]b4_parser_class_name[::yysyntax_error_ (]dnl
 -b4_error_verbose_if([int yystate, int yytoken],
 +b4_error_verbose_if([state_type yystate, int yytoken],
                      [int, int])[)
    {]b4_error_verbose_if([[
      std::string yyres;
           a consistent state with a default action.  There might have
           been a previous inconsistent state, consistent state with a
           non-default action, or user semantic action that manipulated
 -         yychar.
 +         yyla.  (However, yyla is currently not documented for users.)
         - Of course, the expected token list depends on states to have
           correct lookahead information, and it depends on the parser not
           to perform extra reductions after fetching a lookahead from the
    }
  
  
 -  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
 -     STATE-NUM.  */
    const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class_name::yypact_ninf_ = b4_pact_ninf[;
 -  const ]b4_int_type_for([b4_pact])[
 -  ]b4_parser_class_name[::yypact_[] =
 -  {
 -    ]b4_pact[
 -  };
 -
 -  /* YYDEFACT[S] -- default reduction number in state S.  Performed when
 -     YYTABLE doesn't specify something else to do.  Zero means the
 -     default is an error.  */
 -  const ]b4_int_type_for([b4_defact])[
 -  ]b4_parser_class_name[::yydefact_[] =
 -  {
 -    ]b4_defact[
 -  };
 -
 -  /* YYPGOTO[NTERM-NUM].  */
 -  const ]b4_int_type_for([b4_pgoto])[
 -  ]b4_parser_class_name[::yypgoto_[] =
 -  {
 -    ]b4_pgoto[
 -  };
 -
 -  /* YYDEFGOTO[NTERM-NUM].  */
 -  const ]b4_int_type_for([b4_defgoto])[
 -  ]b4_parser_class_name[::yydefgoto_[] =
 -  {
 -    ]b4_defgoto[
 -  };
  
 -  /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
 -     positive, shift that token.  If negative, reduce the rule which
 -     number is the opposite.  If YYTABLE_NINF_, syntax error.  */
    const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[;
 -  const ]b4_int_type_for([b4_table])[
 -  ]b4_parser_class_name[::yytable_[] =
 -  {
 -    ]b4_table[
 -  };
 -
 -  /* YYCHECK.  */
 -  const ]b4_int_type_for([b4_check])[
 -  ]b4_parser_class_name[::yycheck_[] =
 -  {
 -    ]b4_check[
 -  };
  
 -  /* STOS_[STATE-NUM] -- The (internal number of the) accessing
 -     symbol of state STATE-NUM.  */
 -  const ]b4_int_type_for([b4_stos])[
 -  ]b4_parser_class_name[::yystos_[] =
 -  {
 -    ]b4_stos[
 -  };
 -
 -#if YYDEBUG
 -  /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
 -     to YYLEX-NUM.  */
 -  const ]b4_int_type_for([b4_toknum])[
 -  ]b4_parser_class_name[::yytoken_number_[] =
 -  {
 -    ]b4_toknum[
 -  };
 -#endif
 -
 -  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 -  const ]b4_int_type_for([b4_r1])[
 -  ]b4_parser_class_name[::yyr1_[] =
 -  {
 -    ]b4_r1[
 -  };
 -
 -  /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 -  const ]b4_int_type_for([b4_r2])[
 -  ]b4_parser_class_name[::yyr2_[] =
 -  {
 -    ]b4_r2[
 -  };
 +]b4_parser_tables_define[
  
- #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+ ]b4_token_table_if([], [[#if YYDEBUG]])[
    /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
       First, the terminals, then, starting at \a yyntokens_, nonterminals.  */
    const char*
    const ]b4_parser_class_name[::yytname_[] =
    {
 -    ]b4_tname[
 +  ]b4_tname[
    };
- #endif
  
- #if YYDEBUG
+ ]b4_token_table_if([[#if YYDEBUG]])[
 -  /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 -  const ]b4_parser_class_name[::rhs_number_type
 -  ]b4_parser_class_name[::yyrhs_[] =
 -  {
 -    ]b4_rhs[
 -  };
 -
 -  /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
 -     YYRHS.  */
 -  const ]b4_int_type_for([b4_prhs])[
 -  ]b4_parser_class_name[::yyprhs_[] =
 -  {
 -    ]b4_prhs[
 -  };
 -
 -  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 -  const ]b4_int_type_for([b4_rline])[
 -  ]b4_parser_class_name[::yyrline_[] =
 -  {
 -    ]b4_rline[
 -  };
 +]b4_integral_parser_table_define([rline], [b4_rline])[
  
    // Print the state stack on the debug stream.
    void
    ]b4_parser_class_name[::yystack_print_ ()
    {
      *yycdebug_ << "Stack now";
 -    for (state_stack_type::const_iterator i = yystate_stack_.begin ();
 -       i != yystate_stack_.end (); ++i)
 -      *yycdebug_ << ' ' << *i;
 +    for (stack_type::const_iterator
 +           i = yystack_.begin (),
 +           i_end = yystack_.end ();
 +         i != i_end; ++i)
 +      *yycdebug_ << ' ' << i->state;
      *yycdebug_ << std::endl;
    }
  
      int yynrhs = yyr2_[yyrule];
      /* Print the symbols being reduced, and their result.  */
      *yycdebug_ << "Reducing stack by rule " << yyrule - 1
 -             << " (line " << yylno << "):" << std::endl;
 +               << " (line " << yylno << "):" << std::endl;
      /* The symbols being reduced.  */
      for (int yyi = 0; yyi < yynrhs; yyi++)
        YY_SYMBOL_PRINT ("   $" << yyi + 1 << " =",
 -                     yyrhs_[yyprhs_[yyrule] + yyi],
 -                     &]b4_rhs_value(yynrhs, yyi + 1)[,
 -                     &]b4_rhs_location(yynrhs, yyi + 1)[);
 +                       ]b4_rhs_data(yynrhs, yyi + 1)[);
    }
  #endif // YYDEBUG
  
 -  /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 -  ]b4_parser_class_name[::token_number_type
 -  ]b4_parser_class_name[::yytranslate_ (int t)
 -  {
 -    static
 -    const token_number_type
 -    translate_table[] =
 -    {
 -      ]b4_translate[
 -    };
 -    if ((unsigned int) t <= yyuser_token_number_max_)
 -      return translate_table[t];
 -    else
 -      return yyundef_token_;
 -  }
 -
 -  const int ]b4_parser_class_name[::yyeof_ = 0;
 -  const int ]b4_parser_class_name[::yylast_ = ]b4_last[;
 -  const int ]b4_parser_class_name[::yynnts_ = ]b4_nterms_number[;
 -  const int ]b4_parser_class_name[::yyempty_ = -2;
 -  const int ]b4_parser_class_name[::yyfinal_ = ]b4_final_state_number[;
 -  const int ]b4_parser_class_name[::yyterror_ = 1;
 -  const int ]b4_parser_class_name[::yyerrcode_ = 256;
 -  const int ]b4_parser_class_name[::yyntokens_ = ]b4_tokens_number[;
 -
 -  const unsigned int ]b4_parser_class_name[::yyuser_token_number_max_ = ]b4_user_token_number_max[;
 -  const ]b4_parser_class_name[::token_number_type ]b4_parser_class_name[::yyundef_token_ = ]b4_undef_token_number[;
 -
 +]b4_lex_symbol_if([], [b4_yytranslate_define])[
  ]b4_namespace_close[
 -]b4_epilogue
 +]b4_epilogue[]dnl
  m4_divert_pop(0)
 +m4_popdef([b4_copyright_years])dnl
diff --combined data/yacc.c
index b57794f063a0e4988c7716846ee794811485df99,7cf088b25b0d27880b7e95d616127945124d5c47..fe1040804d0242ac6c7ef11efa483fef84ab1f91
@@@ -1,12 -1,10 +1,12 @@@
                                                               -*- C -*-
 -
  # Yacc compatible skeleton for Bison
  
  # Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation,
  # Inc.
  
 +m4_pushdef([b4_copyright_years],
 +           [1984, 1989-1990, 2000-2012])
 +
  # This program is free software: you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation, either version 3 of the License, or
@@@ -76,8 -74,8 +76,8 @@@ m4_define([b4_pure_flag]
  # Expand IF-TRUE, if %pure-parser and %parse-param, IF-FALSE otherwise.
  m4_define([b4_yacc_pure_if],
  [b4_pure_if([m4_ifset([b4_parse_param],
 -                    [$1], [$2])],
 -          [$2])])
 +                      [$1], [$2])],
 +            [$2])])
  
  
  # b4_yyerror_args
@@@ -117,7 -115,7 +117,7 @@@ m4_define([b4_int_type]
  
         m4_eval([0 <= $1]),                [1], [unsigned int],
  
 -                                             [int])])
 +                                               [int])])
  
  
  ## ----------------- ##
  # --------------------
  # Expansion of $<TYPE>$.
  m4_define([b4_lhs_value],
 -[(yyval[]m4_ifval([$1], [.$1]))])
 +[b4_symbol_value(yyval, [$1])])
  
  
  # b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
  # Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
  # symbols on RHS.
  m4_define([b4_rhs_value],
 -[(yyvsp@{($2) - ($1)@}m4_ifval([$3], [.$3]))])
 +          [b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
  
  
  
@@@ -157,7 -155,7 +157,7 @@@ m4_define([b4_lhs_location]
  # Expansion of @NUM, where the current rule has RULE-LENGTH symbols
  # on RHS.
  m4_define([b4_rhs_location],
 -[(yylsp@{($2) - ($1)@})])
 +          [(yylsp@{b4_subtract([$2], [$1])@})])
  
  
  ## -------------- ##
@@@ -294,7 -292,8 +294,7 @@@ m4_define([b4_shared_declarations]
  m4_changecom()
  m4_divert_push(0)dnl
  @output(b4_parser_file_name@)@
 -b4_copyright([Bison implementation for Yacc-like parsers in C],
 -             [1984, 1989-1990, 2000-2012])[
 +b4_copyright([Bison implementation for Yacc-like parsers in C])[
  
  /* C LALR(1) parser skeleton written by Richard Stallman, by
     simplifying the original so-called "semantic" parser.  */
@@@ -334,14 -333,9 +334,9 @@@ m4_if(b4_prefix, [yy], []
  # undef YYERROR_VERBOSE
  # define YYERROR_VERBOSE 1
  #else
 -# define YYERROR_VERBOSE ]b4_error_verbose_flag[
 +# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
  #endif
  
- /* Enabling the token table.  */
- #ifndef YYTOKEN_TABLE
- # define YYTOKEN_TABLE ]b4_token_table[
- #endif
  /* In a future release of Bison, this section will be replaced
     by #include "@basename(]b4_spec_defines_file[@)".  */
  ]b4_shared_declarations[
@@@ -471,7 -465,7 +466,7 @@@ b4_push_if([], [b4_lac_if([], [
  #  endif
  #  if (defined __cplusplus && ! defined EXIT_SUCCESS \
         && ! ((defined YYMALLOC || defined malloc) \
 -           && (defined YYFREE || defined free)))
 +             && (defined YYFREE || defined free)))
  #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
  #   ifndef EXIT_SUCCESS
  #    define EXIT_SUCCESS 0
@@@ -496,8 -490,8 +491,8 @@@ void free (void *); /* INFRINGES ON USE
  
  #if (! defined yyoverflow \
       && (! defined __cplusplus \
 -       || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
 -           && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
 +         || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
 +             && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
  
  /* A type that is properly aligned for any stack member.  */
  union yyalloc
     elements in the stack, and YYPTR gives the new location of the
     stack.  Advance YYPTR to a properly aligned location for the next
     stack.  */
 -# define YYSTACK_RELOCATE(Stack_alloc, Stack)                         \
 -    do                                                                        \
 -      {                                                                       \
 -      YYSIZE_T yynewbytes;                                            \
 -      YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
 -      Stack = &yyptr->Stack_alloc;                                    \
 -      yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 -      yyptr += yynewbytes / sizeof (*yyptr);                          \
 -      }                                                                       \
 +# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
 +    do                                                                  \
 +      {                                                                 \
 +        YYSIZE_T yynewbytes;                                            \
 +        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
 +        Stack = &yyptr->Stack_alloc;                                    \
 +        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 +        yyptr += yynewbytes / sizeof (*yyptr);                          \
 +      }                                                                 \
      while (YYID (0))
  
  #endif
  #define YYNNTS  ]b4_nterms_number[
  /* YYNRULES -- Number of rules.  */
  #define YYNRULES  ]b4_rules_number[
 -/* YYNRULES -- Number of states.  */
 +/* YYNSTATES -- Number of states.  */
  #define YYNSTATES  ]b4_states_number[
  
 -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
 +   by yylex, with out-of-bounds checking.  */
  #define YYUNDEFTOK  ]b4_undef_token_number[
  #define YYMAXUTOK   ]b4_user_token_number_max[
  
 -#define YYTRANSLATE(YYX)                                              \
 +#define YYTRANSLATE(YYX)                                                \
    ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
  
 -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
 +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
 +   as returned by yylex, without out-of-bounds checking.  */
  static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
  {
    ]b4_translate[
  };
  
  #if YYDEBUG
 -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
 -   YYRHS.  */
 -static const ]b4_int_type_for([b4_prhs])[ yyprhs[] =
 -{
 -  ]b4_prhs[
 -};
 -
 -/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 -static const ]b4_int_type_for([b4_rhs])[ yyrhs[] =
 -{
 -  ]b4_rhs[
 -};
 -
 -/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 -static const ]b4_int_type_for([b4_rline])[ yyrline[] =
 -{
 -  ]b4_rline[
 -};
 +]b4_integral_parser_table_define([rline], [b4_rline],
 +     [YYRLINE[YYN] -- Source line where rule number YYN was defined.])[
  #endif
  
- #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+ #if YYDEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
  /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
     First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
  static const char *const yytname[] =
  #endif
  
  # ifdef YYPRINT
 -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
 -   token YYLEX-NUM.  */
 +/* YYTOKNUM[NUM] -- (External) token number corresponding to the
 +   (internal) symbol number NUM (which must be that of a token).  */
  static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
  {
    ]b4_toknum[
  };
  # endif
  
 -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 -static const ]b4_int_type_for([b4_r1])[ yyr1[] =
 -{
 -  ]b4_r1[
 -};
 -
 -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 -static const ]b4_int_type_for([b4_r2])[ yyr2[] =
 -{
 -  ]b4_r2[
 -};
 -
 -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
 -   Performed when YYTABLE doesn't specify something else to do.  Zero
 -   means the default is an error.  */
 -static const ]b4_int_type_for([b4_defact])[ yydefact[] =
 -{
 -  ]b4_defact[
 -};
 -
 -/* YYDEFGOTO[NTERM-NUM].  */
 -static const ]b4_int_type_for([b4_defgoto])[ yydefgoto[] =
 -{
 -  ]b4_defgoto[
 -};
 -
 -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
 -   STATE-NUM.  */
  #define YYPACT_NINF ]b4_pact_ninf[
 -static const ]b4_int_type_for([b4_pact])[ yypact[] =
 -{
 -  ]b4_pact[
 -};
 -
 -/* YYPGOTO[NTERM-NUM].  */
 -static const ]b4_int_type_for([b4_pgoto])[ yypgoto[] =
 -{
 -  ]b4_pgoto[
 -};
 -
 -/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
 -   positive, shift that token.  If negative, reduce the rule which
 -   number is the opposite.  If YYTABLE_NINF, syntax error.  */
 -#define YYTABLE_NINF ]b4_table_ninf[
 -static const ]b4_int_type_for([b4_table])[ yytable[] =
 -{
 -  ]b4_table[
 -};
  
  #define yypact_value_is_default(yystate) \
    ]b4_table_value_equals([[pact]], [[yystate]], [b4_pact_ninf])[
  
 +#define YYTABLE_NINF ]b4_table_ninf[
 +
  #define yytable_value_is_error(yytable_value) \
    ]b4_table_value_equals([[table]], [[yytable_value]], [b4_table_ninf])[
  
 -static const ]b4_int_type_for([b4_check])[ yycheck[] =
 -{
 -  ]b4_check[
 -};
 -
 -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
 -   symbol of state STATE-NUM.  */
 -static const ]b4_int_type_for([b4_stos])[ yystos[] =
 -{
 -  ]b4_stos[
 -};
 +]b4_parser_tables_define[
  
 -#define yyerrok               (yyerrstatus = 0)
 -#define yyclearin     (yychar = YYEMPTY)
 -#define YYEMPTY               (-2)
 -#define YYEOF         0
 +#define yyerrok         (yyerrstatus = 0)
 +#define yyclearin       (yychar = YYEMPTY)
 +#define YYEMPTY         (-2)
 +#define YYEOF           0
  
 -#define YYACCEPT      goto yyacceptlab
 -#define YYABORT               goto yyabortlab
 -#define YYERROR               goto yyerrorlab
 +#define YYACCEPT        goto yyacceptlab
 +#define YYABORT         goto yyabortlab
 +#define YYERROR         goto yyerrorlab
  
  
  /* Like YYERROR except do call yyerror.  This remains here temporarily
     in Bison 2.4.2's NEWS entry, where a plan to phase it out is
     discussed.  */
  
 -#define YYFAIL                goto yyerrlab
 +#define YYFAIL          goto yyerrlab
  #if defined YYFAIL
    /* This is here to suppress warnings from the GCC cpp's
       -Wunused-macros.  Normally we don't worry about that warning, but
    else                                                          \
      {                                                           \
        yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \
 -      YYERROR;                                                        \
 -    }                                                         \
 +      YYERROR;                                                  \
 +    }                                                           \
  while (YYID (0))
  
  
 -#define YYTERROR      1
 -#define YYERRCODE     256
 +#define YYTERROR        1
 +#define YYERRCODE       256
  
  
  /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
  
  #define YYRHSLOC(Rhs, K) ((Rhs)[K])
  #ifndef YYLLOC_DEFAULT
 -# define YYLLOC_DEFAULT(Current, Rhs, N)                              \
 -    do                                                                        \
 +# define YYLLOC_DEFAULT(Current, Rhs, N)                                \
 +    do                                                                  \
        if (YYID (N))                                                    \
 -      {                                                               \
 -        (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
 -        (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
 -        (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
 -        (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
 -      }                                                               \
 -      else                                                            \
 -      {                                                               \
 -        (Current).first_line   = (Current).last_line   =              \
 -          YYRHSLOC (Rhs, 0).last_line;                                \
 -        (Current).first_column = (Current).last_column =              \
 -          YYRHSLOC (Rhs, 0).last_column;                              \
 -      }                                                               \
 +        {                                                               \
 +          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
 +          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
 +          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
 +          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
 +        }                                                               \
 +      else                                                              \
 +        {                                                               \
 +          (Current).first_line   = (Current).last_line   =              \
 +            YYRHSLOC (Rhs, 0).last_line;                                \
 +          (Current).first_column = (Current).last_column =              \
 +            YYRHSLOC (Rhs, 0).last_column;                              \
 +        }                                                               \
      while (YYID (0))
  #endif]b4_locations_if([[
  
  
  #ifndef YY_LOCATION_PRINT
  # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
 -#  define YY_LOCATION_PRINT(File, Loc)                        \
 -     fprintf (File, "%d.%d-%d.%d",                    \
 -            (Loc).first_line, (Loc).first_column,     \
 -            (Loc).last_line,  (Loc).last_column)
 +#  define YY_LOCATION_PRINT(File, Loc)                  \
 +     fprintf (File, "%d.%d-%d.%d",                      \
 +              (Loc).first_line, (Loc).first_column,     \
 +              (Loc).last_line,  (Loc).last_column)
  # else
  #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
  # endif
  #  define YYFPRINTF fprintf
  # endif
  
 -# define YYDPRINTF(Args)                      \
 -do {                                          \
 -  if (yydebug)                                        \
 -    YYFPRINTF Args;                           \
 +# define YYDPRINTF(Args)                        \
 +do {                                            \
 +  if (yydebug)                                  \
 +    YYFPRINTF Args;                             \
  } while (YYID (0))
  
 -# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                          \
 -do {                                                                    \
 -  if (yydebug)                                                                  \
 -    {                                                                   \
 -      YYFPRINTF (stderr, "%s ", Title);                                         \
 -      yy_symbol_print (stderr,                                                  \
 -                Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
 -      YYFPRINTF (stderr, "\n");                                                 \
 -    }                                                                   \
 +# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
 +do {                                                                      \
 +  if (yydebug)                                                            \
 +    {                                                                     \
 +      YYFPRINTF (stderr, "%s ", Title);                                   \
 +      yy_symbol_print (stderr,                                            \
 +                  Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
 +      YYFPRINTF (stderr, "\n");                                           \
 +    }                                                                     \
  } while (YYID (0))
  
  ]b4_yy_symbol_print_generate([b4_c_function_def])[
  `------------------------------------------------------------------*/
  
  ]b4_c_function_def([yy_stack_print], [static void],
 -                 [[yytype_int16 *yybottom], [yybottom]],
 -                 [[yytype_int16 *yytop],    [yytop]])[
 +                   [[yytype_int16 *yybottom], [yybottom]],
 +                   [[yytype_int16 *yytop],    [yytop]])[
  {
    YYFPRINTF (stderr, "Stack now");
    for (; yybottom <= yytop; yybottom++)
    YYFPRINTF (stderr, "\n");
  }
  
 -# define YY_STACK_PRINT(Bottom, Top)                          \
 -do {                                                          \
 -  if (yydebug)                                                        \
 -    yy_stack_print ((Bottom), (Top));                         \
 +# define YY_STACK_PRINT(Bottom, Top)                            \
 +do {                                                            \
 +  if (yydebug)                                                  \
 +    yy_stack_print ((Bottom), (Top));                           \
  } while (YYID (0))
  
  
  `------------------------------------------------*/
  
  ]b4_c_function_def([yy_reduce_print], [static void],
 -                 [[YYSTYPE *yyvsp], [yyvsp]],
 +                   [[yytype_int16 *yyssp], [yyssp]],
 +                   [[YYSTYPE *yyvsp], [yyvsp]],
      b4_locations_if([[[YYLTYPE *yylsp], [yylsp]],
 -                 ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
 -                 b4_parse_param]))[
 +                   ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
 +                   b4_parse_param]))[
  {
 +  unsigned long int yylno = yyrline[yyrule];
    int yynrhs = yyr2[yyrule];
    int yyi;
 -  unsigned long int yylno = yyrline[yyrule];
    YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
 -           yyrule - 1, yylno);
 +             yyrule - 1, yylno);
    /* The symbols being reduced.  */
    for (yyi = 0; yyi < yynrhs; yyi++)
      {
        YYFPRINTF (stderr, "   $%d = ", yyi + 1);
 -      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 -                     &]b4_rhs_value(yynrhs, yyi + 1)[
 -                     ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
 -                     b4_user_args[);
 +      yy_symbol_print (stderr,
 +                       yystos[yyssp[yyi + 1 - yynrhs]],
 +                       &]b4_rhs_value(yynrhs, yyi + 1)[
 +                       ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
 +                       b4_user_args[);
        YYFPRINTF (stderr, "\n");
      }
  }
  
 -# define YY_REDUCE_PRINT(Rule)                \
 -do {                                  \
 -  if (yydebug)                                \
 -    yy_reduce_print (yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \
 +# define YY_REDUCE_PRINT(Rule)          \
 +do {                                    \
 +  if (yydebug)                          \
 +    yy_reduce_print (yyssp, yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \
  } while (YYID (0))
  
  /* Nonzero means print parse trace.  It is left uninitialized so that
@@@ -830,7 -891,7 +825,7 @@@ int yydebug
  
  
  /* YYINITDEPTH -- initial size of the parser's stacks.  */
 -#ifndef       YYINITDEPTH
 +#ifndef YYINITDEPTH
  # define YYINITDEPTH ]b4_stack_depth_init[
  #endif
  
@@@ -1137,27 -1198,27 +1132,27 @@@ yytnamerr (char *yyres, const char *yys
        char const *yyp = yystr;
  
        for (;;)
 -      switch (*++yyp)
 -        {
 -        case '\'':
 -        case ',':
 -          goto do_not_strip_quotes;
 -
 -        case '\\':
 -          if (*++yyp != '\\')
 -            goto do_not_strip_quotes;
 -          /* Fall through.  */
 -        default:
 -          if (yyres)
 -            yyres[yyn] = *yyp;
 -          yyn++;
 -          break;
 -
 -        case '"':
 -          if (yyres)
 -            yyres[yyn] = '\0';
 -          return yyn;
 -        }
 +        switch (*++yyp)
 +          {
 +          case '\'':
 +          case ',':
 +            goto do_not_strip_quotes;
 +
 +          case '\\':
 +            if (*++yyp != '\\')
 +              goto do_not_strip_quotes;
 +            /* Fall through.  */
 +          default:
 +            if (yyres)
 +              yyres[yyn] = *yyp;
 +            yyn++;
 +            break;
 +
 +          case '"':
 +            if (yyres)
 +              yyres[yyn] = '\0';
 +            return yyn;
 +          }
      do_not_strip_quotes: ;
      }
  
@@@ -1552,26 -1613,26 +1547,26 @@@ m4_ifdef([b4_at_dollar_used], [[  yylsp
  
  #ifdef yyoverflow
        {
 -      /* Give user a chance to reallocate the stack.  Use copies of
 -         these so that the &'s don't force the real ones into
 -         memory.  */
 -      YYSTYPE *yyvs1 = yyvs;
 -      yytype_int16 *yyss1 = yyss;]b4_locations_if([
 -      YYLTYPE *yyls1 = yyls;])[
 -
 -      /* Each stack pointer address is followed by the size of the
 -         data in use in that stack, in bytes.  This used to be a
 -         conditional around just the two extra args, but that might
 -         be undefined if yyoverflow is a macro.  */
 -      yyoverflow (YY_("memory exhausted"),
 -                  &yyss1, yysize * sizeof (*yyssp),
 -                  &yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([
 -                  &yyls1, yysize * sizeof (*yylsp),])[
 -                  &yystacksize);
 +        /* Give user a chance to reallocate the stack.  Use copies of
 +           these so that the &'s don't force the real ones into
 +           memory.  */
 +        YYSTYPE *yyvs1 = yyvs;
 +        yytype_int16 *yyss1 = yyss;]b4_locations_if([
 +        YYLTYPE *yyls1 = yyls;])[
 +
 +        /* Each stack pointer address is followed by the size of the
 +           data in use in that stack, in bytes.  This used to be a
 +           conditional around just the two extra args, but that might
 +           be undefined if yyoverflow is a macro.  */
 +        yyoverflow (YY_("memory exhausted"),
 +                    &yyss1, yysize * sizeof (*yyssp),
 +                    &yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([
 +                    &yyls1, yysize * sizeof (*yylsp),])[
 +                    &yystacksize);
  ]b4_locations_if([
 -      yyls = yyls1;])[
 -      yyss = yyss1;
 -      yyvs = yyvs1;
 +        yyls = yyls1;])[
 +        yyss = yyss1;
 +        yyvs = yyvs1;
        }
  #else /* no yyoverflow */
  # ifndef YYSTACK_RELOCATE
  # else
        /* Extend the stack our own way.  */
        if (YYMAXDEPTH <= yystacksize)
 -      goto yyexhaustedlab;
 +        goto yyexhaustedlab;
        yystacksize *= 2;
        if (YYMAXDEPTH < yystacksize)
 -      yystacksize = YYMAXDEPTH;
 +        yystacksize = YYMAXDEPTH;
  
        {
 -      yytype_int16 *yyss1 = yyss;
 -      union yyalloc *yyptr =
 -        (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 -      if (! yyptr)
 -        goto yyexhaustedlab;
 -      YYSTACK_RELOCATE (yyss_alloc, yyss);
 -      YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
 -      YYSTACK_RELOCATE (yyls_alloc, yyls);])[
 +        yytype_int16 *yyss1 = yyss;
 +        union yyalloc *yyptr =
 +          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 +        if (! yyptr)
 +          goto yyexhaustedlab;
 +        YYSTACK_RELOCATE (yyss_alloc, yyss);
 +        YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
 +        YYSTACK_RELOCATE (yyls_alloc, yyls);])[
  #  undef YYSTACK_RELOCATE
 -      if (yyss1 != yyssa)
 -        YYSTACK_FREE (yyss1);
 +        if (yyss1 != yyssa)
 +          YYSTACK_FREE (yyss1);
        }
  # endif
  #endif /* no yyoverflow */
        yylsp = yyls + yysize - 1;])[
  
        YYDPRINTF ((stderr, "Stack size increased to %lu\n",
 -                (unsigned long int) yystacksize));
 +                  (unsigned long int) yystacksize));
  
        if (yyss + yystacksize - 1 <= yyssp)
 -      YYABORT;
 +        YYABORT;
      }
  
    YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@@ -1844,20 -1905,20 +1839,20 @@@ yyerrlab
    if (yyerrstatus == 3)
      {
        /* If just tried and failed to reuse lookahead token after an
 -       error, discard it.  */
 +         error, discard it.  */
  
        if (yychar <= YYEOF)
 -      {
 -        /* Return failure if at end of input.  */
 -        if (yychar == YYEOF)
 -          YYABORT;
 -      }
 +        {
 +          /* Return failure if at end of input.  */
 +          if (yychar == YYEOF)
 +            YYABORT;
 +        }
        else
 -      {
 -        yydestruct ("Error: discarding",
 -                    yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
 -        yychar = YYEMPTY;
 -      }
 +        {
 +          yydestruct ("Error: discarding",
 +                      yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
 +          yychar = YYEMPTY;
 +        }
      }
  
    /* Else will try to reuse lookahead token after shifting the error
@@@ -1890,29 -1951,29 +1885,29 @@@ yyerrorlab
  | yyerrlab1 -- common code for both syntax error and YYERROR.  |
  `-------------------------------------------------------------*/
  yyerrlab1:
 -  yyerrstatus = 3;    /* Each real token shifted decrements this.  */
 +  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
  
    for (;;)
      {
        yyn = yypact[yystate];
        if (!yypact_value_is_default (yyn))
 -      {
 -        yyn += YYTERROR;
 -        if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
 -          {
 -            yyn = yytable[yyn];
 -            if (0 < yyn)
 -              break;
 -          }
 -      }
 +        {
 +          yyn += YYTERROR;
 +          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
 +            {
 +              yyn = yytable[yyn];
 +              if (0 < yyn)
 +                break;
 +            }
 +        }
  
        /* Pop the current state because it cannot handle the error token.  */
        if (yyssp == yyss)
 -      YYABORT;
 +        YYABORT;
  
  ]b4_locations_if([[      yyerror_range[1] = *yylsp;]])[
        yydestruct ("Error: popping",
 -                yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
 +                  yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
        YYPOPSTACK (1);
        yystate = *yyssp;
        YY_STACK_PRINT (yyss, yyssp);
@@@ -1977,7 -2038,7 +1972,7 @@@ yyreturn
    while (yyssp != yyss)
      {
        yydestruct ("Cleanup: popping",
 -                yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
 +                  yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
        YYPOPSTACK (1);
      }
  #ifndef yyoverflow
@@@ -1997,12 -2058,13 +1992,12 @@@ yypushreturn:]])
    return YYID (yyresult);
  }
  
 -
 -]b4_epilogue
 +]b4_epilogue[]dnl
  b4_defines_if(
  [@output(b4_spec_defines_file@)@
 -b4_copyright([Bison interface for Yacc-like parsers in C],
 -             [1984, 1989-1990, 2000-2012])[
 +b4_copyright([Bison interface for Yacc-like parsers in C])[
  
  ]b4_shared_declarations[
  ]])dnl b4_defines_if
  m4_divert_pop(0)
 +m4_popdef([b4_copyright_years])
diff --combined src/output.c
index 4fe11ccb79cc7bcbf3365aeda8758f69323ae5d2,29e9ba841c16c1933ae4d5903ddb31512aa93fc8..723870de6216fa4e46876877091c8ba207143da7
@@@ -21,9 -21,8 +21,9 @@@
  #include <config.h>
  #include "system.h"
  
 +#include <concat-filename.h>
  #include <configmake.h>
 -#include <error.h>
 +#include <filename.h>
  #include <get-errno.h>
  #include <quotearg.h>
  #include <spawn-pipe.h>
@@@ -55,51 -54,51 +55,51 @@@ static struct obstack format_obstack
  `-------------------------------------------------------------------*/
  
  
 -#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type)                      \
 -                                                                      \
 -static void                                                           \
 -Name (char const *name,                                                       \
 -      Type *table_data,                                                       \
 -      Type first,                                                     \
 -      int begin,                                                      \
 -      int end)                                                                \
 -{                                                                     \
 -  Type min = first;                                                   \
 -  Type max = first;                                                   \
 -  long int lmin;                                                      \
 -  long int lmax;                                                      \
 -  int i;                                                              \
 -  int j = 1;                                                          \
 -                                                                      \
 -  obstack_fgrow1 (&format_obstack, "%6d", first);                     \
 -  for (i = begin; i < end; ++i)                                               \
 -    {                                                                 \
 -      obstack_1grow (&format_obstack, ',');                           \
 -      if (j >= 10)                                                    \
 -      {                                                               \
 -        obstack_sgrow (&format_obstack, "\n  ");                      \
 -        j = 1;                                                        \
 -      }                                                               \
 -      else                                                            \
 -      ++j;                                                            \
 -      obstack_fgrow1 (&format_obstack, "%6d", table_data[i]);         \
 -      if (table_data[i] < min)                                                \
 -      min = table_data[i];                                            \
 -      if (max < table_data[i])                                                \
 -      max = table_data[i];                                            \
 -    }                                                                 \
 -  obstack_1grow (&format_obstack, 0);                                 \
 -  muscle_insert (name, obstack_finish (&format_obstack));             \
 -                                                                      \
 -  lmin = min;                                                         \
 -  lmax = max;                                                         \
 -  /* Build `NAME_min' and `NAME_max' in the obstack. */                       \
 -  obstack_fgrow1 (&format_obstack, "%s_min", name);                   \
 -  obstack_1grow (&format_obstack, 0);                                 \
 -  MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin);    \
 -  obstack_fgrow1 (&format_obstack, "%s_max", name);                   \
 -  obstack_1grow (&format_obstack, 0);                                 \
 -  MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax);    \
 +#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type)                        \
 +                                                                        \
 +static void                                                             \
 +Name (char const *name,                                                 \
 +      Type *table_data,                                                 \
 +      Type first,                                                       \
 +      int begin,                                                        \
 +      int end)                                                          \
 +{                                                                       \
 +  Type min = first;                                                     \
 +  Type max = first;                                                     \
 +  long int lmin;                                                        \
 +  long int lmax;                                                        \
 +  int i;                                                                \
 +  int j = 1;                                                            \
 +                                                                        \
 +  obstack_fgrow1 (&format_obstack, "%6d", first);                       \
 +  for (i = begin; i < end; ++i)                                         \
 +    {                                                                   \
 +      obstack_1grow (&format_obstack, ',');                             \
 +      if (j >= 10)                                                      \
 +        {                                                               \
 +          obstack_sgrow (&format_obstack, "\n  ");                      \
 +          j = 1;                                                        \
 +        }                                                               \
 +      else                                                              \
 +        ++j;                                                            \
 +      obstack_fgrow1 (&format_obstack, "%6d", table_data[i]);           \
 +      if (table_data[i] < min)                                          \
 +        min = table_data[i];                                            \
 +      if (max < table_data[i])                                          \
 +        max = table_data[i];                                            \
 +    }                                                                   \
 +  obstack_1grow (&format_obstack, 0);                                   \
 +  muscle_insert (name, obstack_finish (&format_obstack));               \
 +                                                                        \
 +  lmin = min;                                                           \
 +  lmax = max;                                                           \
 +  /* Build `NAME_min' and `NAME_max' in the obstack. */                 \
 +  obstack_fgrow1 (&format_obstack, "%s_min", name);                     \
 +  obstack_1grow (&format_obstack, 0);                                   \
 +  MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin);      \
 +  obstack_fgrow1 (&format_obstack, "%s_max", name);                     \
 +  obstack_1grow (&format_obstack, 0);                                   \
 +  MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax);      \
  }
  
  GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
@@@ -107,6 -106,7 +107,6 @@@ GENERATE_MUSCLE_INSERT_TABLE(muscle_ins
  GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
  GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
  GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
 -GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number)
  GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
  
  
@@@ -142,17 -142,15 +142,16 @@@ escaped_output (FILE *out, char const *
  static void
  prepare_symbols (void)
  {
-   MUSCLE_INSERT_BOOL ("token_table", token_table_flag);
    MUSCLE_INSERT_INT ("tokens_number", ntokens);
    MUSCLE_INSERT_INT ("nterms_number", nvars);
 +  MUSCLE_INSERT_INT ("symbols_number", nsyms);
    MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
    MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
  
    muscle_insert_symbol_number_table ("translate",
 -                                   token_translations,
 -                                   token_translations[0],
 -                                   1, max_user_token_number + 1);
 +                                     token_translations,
 +                                     token_translations[0],
 +                                     1, max_user_token_number + 1);
  
    /* tname -- token names.  */
    {
      set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS);
      for (i = 0; i < nsyms; i++)
        {
 -      char *cp = quotearg_alloc (symbols[i]->tag, -1, qo);
 -      /* Width of the next token, including the two quotes, the
 -         comma and the space.  */
 -      int width = strlen (cp) + 2;
 -
 -      if (j + width > 75)
 -        {
 -          obstack_sgrow (&format_obstack, "\n ");
 -          j = 1;
 -        }
 -
 -      if (i)
 -        obstack_1grow (&format_obstack, ' ');
 -      MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
 +        char *cp = quotearg_alloc (symbols[i]->tag, -1, qo);
 +        /* Width of the next token, including the two quotes, the
 +           comma and the space.  */
 +        int width = strlen (cp) + 2;
 +
 +        if (j + width > 75)
 +          {
 +            obstack_sgrow (&format_obstack, "\n ");
 +            j = 1;
 +          }
 +
 +        if (i)
 +          obstack_1grow (&format_obstack, ' ');
 +        MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
          free (cp);
 -      obstack_1grow (&format_obstack, ',');
 -      j += width;
 +        obstack_1grow (&format_obstack, ',');
 +        j += width;
        }
      free (qo);
      obstack_sgrow (&format_obstack, " ]b4_null[");
      for (i = 0; i < ntokens; ++i)
        values[i] = symbols[i]->user_token_number;
      muscle_insert_int_table ("toknum", values,
 -                           values[0], 1, ntokens);
 +                             values[0], 1, ntokens);
      free (values);
    }
  }
  
  
 -/*-------------------------------------------------------------.
 -| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
 -| rline, dprec, merger.                                        |
 -`-------------------------------------------------------------*/
 +/*----------------------------------------------------------------.
 +| Prepare the muscles related to the rules: r1, r2, rline, dprec, |
 +| merger, immediate.                                              |
 +`----------------------------------------------------------------*/
  
  static void
  prepare_rules (void)
  {
 -  rule_number r;
 -  unsigned int i = 0;
 -  item_number *rhs = xnmalloc (nritems, sizeof *rhs);
 -  unsigned int *prhs = xnmalloc (nrules, sizeof *prhs);
    unsigned int *rline = xnmalloc (nrules, sizeof *rline);
    symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
    unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
    int *dprec = xnmalloc (nrules, sizeof *dprec);
    int *merger = xnmalloc (nrules, sizeof *merger);
 +  int *immediate = xnmalloc (nrules, sizeof *immediate);
  
 +  rule_number r;
    for (r = 0; r < nrules; ++r)
      {
 -      item_number *rhsp = NULL;
 -      /* Index of rule R in RHS. */
 -      prhs[r] = i;
 -      /* RHS of the rule R. */
 -      for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
 -      rhs[i++] = *rhsp;
        /* LHS of the rule R. */
        r1[r] = rules[r].lhs->number;
        /* Length of rule R's RHS. */
 -      r2[r] = i - prhs[r];
 -      /* Separator in RHS. */
 -      rhs[i++] = -1;
 +      r2[r] = rule_rhs_length(&rules[r]);
        /* Line where rule was defined. */
        rline[r] = rules[r].location.start.line;
        /* Dynamic precedence (GLR).  */
        dprec[r] = rules[r].dprec;
        /* Merger-function index (GLR).  */
        merger[r] = rules[r].merger;
 +      /* Immediate reduction flags (GLR).  */
 +      immediate[r] = rules[r].is_predicate;
      }
 -  aver (i == nritems);
  
 -  muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
 -  muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
    muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
    muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
    muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
    muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
    muscle_insert_int_table ("merger", merger, 0, 0, nrules);
 +  muscle_insert_int_table ("immediate", immediate, 0, 0, nrules);
  
    MUSCLE_INSERT_INT ("rules_number", nrules);
    MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
  
 -  free (rhs);
 -  free (prhs);
    free (rline);
    free (r1);
    free (r2);
    free (dprec);
    free (merger);
 +  free (immediate);
  }
  
  /*--------------------------------------------.
@@@ -265,7 -274,7 +264,7 @@@ prepare_states (void
    for (i = 0; i < nstates; ++i)
      values[i] = states[i]->accessing_symbol;
    muscle_insert_symbol_number_table ("stos", values,
 -                                   0, 1, nstates);
 +                                     0, 1, nstates);
    free (values);
  
    MUSCLE_INSERT_INT ("last", high);
  }
  
  
 +/*-------------------------------------------------------.
 +| Compare two symbols by type-name, and then by number.  |
 +`-------------------------------------------------------*/
 +
 +static int
 +symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
 +{
 +  int res = UNIQSTR_CMP((*lhs)->type_name, (*rhs)->type_name);
 +  if (res)
 +    return res;
 +  return (*lhs)->number - (*rhs)->number;
 +}
 +
 +
 +/*----------------------------------------------------------------.
 +| Return a (malloc'ed) table of the symbols sorted by type-name.  |
 +`----------------------------------------------------------------*/
 +
 +static symbol **
 +symbols_by_type_name (void)
 +{
 +  typedef int (*qcmp_type) (const void *, const void *);
 +  symbol **res = xmemdup (symbols, nsyms * sizeof *res);
 +  qsort (res, nsyms, sizeof *res, (qcmp_type) &symbol_type_name_cmp);
 +  return res;
 +}
 +
 +
 +/*------------------------------------------------------------------.
 +| Define b4_type_names, which is a list of (lists of the numbers of |
 +| symbols with same type-name).                                     |
 +`------------------------------------------------------------------*/
 +
 +static void
 +type_names_output (FILE *out)
 +{
 +  int i;
 +  symbol **syms = symbols_by_type_name ();
 +  fputs ("m4_define([b4_type_names],\n[", out);
 +  for (i = 0; i < nsyms; /* nothing */)
 +    {
 +      // The index of the first symbol of the current type-name.
 +      int i0 = i;
 +      fputs (i ? ",\n[" : "[", out);
 +      for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
 +        fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
 +      fputs ("]", out);
 +    }
 +  fputs ("])\n\n", out);
 +  free (syms);
 +}
 +
 +
 +/*-------------------------------------.
 +| The list of all the symbol numbers.  |
 +`-------------------------------------*/
 +
 +static void
 +symbol_numbers_output (FILE *out)
 +{
 +  int i;
 +  fputs ("m4_define([b4_symbol_numbers],\n[", out);
 +  for (i = 0; i < nsyms; ++i)
 +    fprintf (out, "%s[%d]", i ? ", " : "", i);
 +  fputs ("])\n\n", out);
 +}
 +
  
  /*---------------------------------.
  | Output the user actions to OUT.  |
@@@ -355,18 -297,17 +354,18 @@@ user_actions_output (FILE *out
    for (r = 0; r < nrules; ++r)
      if (rules[r].action)
        {
 -      fprintf (out, "b4_case(%d, [b4_syncline(%d, ", r + 1,
 -               rules[r].action_location.start.line);
 -      escaped_output (out, rules[r].action_location.start.file);
 -      fprintf (out, ")\n[    %s]])\n\n", rules[r].action);
 +        fprintf (out, "b4_%scase(%d, [b4_syncline(%d, ",
 +                 rules[r].is_predicate ? "predicate_" : "",
 +                 r + 1, rules[r].action_location.start.line);
 +        escaped_output (out, rules[r].action_location.start.file);
 +        fprintf (out, ")\n[    %s]])\n\n", rules[r].action);
        }
    fputs ("])\n\n", out);
  }
  
 -/*--------------------------------------.
 -| Output the merge functions to OUT.   |
 -`--------------------------------------*/
 +/*------------------------------------.
 +| Output the merge functions to OUT.  |
 +`------------------------------------*/
  
  static void
  merger_output (FILE *out)
    for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
      {
        if (p->type[0] == '\0')
 -      fprintf (out, "  case %d: *yy0 = %s (*yy0, *yy1); break;\n",
 -               n, p->name);
 +        fprintf (out, "  case %d: *yy0 = %s (*yy0, *yy1); break;\n",
 +                 n, p->name);
        else
 -      fprintf (out, "  case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
 -               n, p->type, p->name);
 +        fprintf (out, "  case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
 +                 n, p->type, p->name);
      }
    fputs ("]])\n\n", out);
  }
  
 +
 +/*---------------------------------------------.
 +| Prepare the muscles for symbol definitions.  |
 +`---------------------------------------------*/
 +
 +static void
 +prepare_symbol_definitions (void)
 +{
 +  int i;
 +  for (i = 0; i < nsyms; ++i)
 +    {
 +      symbol *sym = symbols[i];
 +      const char *key;
 +      const char *value;
 +
 +#define SET_KEY(Entry)                                          \
 +      obstack_fgrow2 (&format_obstack, "symbol(%d, %s)",        \
 +                      i, Entry);                                \
 +      obstack_1grow (&format_obstack, 0);                       \
 +      key = obstack_finish (&format_obstack);
 +
 +#define SET_KEY2(Entry, Suffix)                                 \
 +      obstack_fgrow3 (&format_obstack, "symbol(%d, %s_%s)",     \
 +                      i, Entry, Suffix);                        \
 +      obstack_1grow (&format_obstack, 0);                       \
 +      key = obstack_finish (&format_obstack);
 +
 +      // Whether the symbol has an identifier.
 +      value = symbol_id_get (sym);
 +      SET_KEY("has_id");
 +      MUSCLE_INSERT_INT (key, !!value);
 +
 +      // Its identifier.
 +      SET_KEY("id");
 +      MUSCLE_INSERT_STRING (key, value ? value : "");
 +
 +      // Its tag.  Typically for documentation purpose.
 +      SET_KEY("tag");
 +      MUSCLE_INSERT_STRING (key, sym->tag);
 +
 +      SET_KEY("user_number");
 +      MUSCLE_INSERT_INT (key, sym->user_token_number);
 +
 +      SET_KEY("is_token");
 +      MUSCLE_INSERT_INT (key,
 +                         i < ntokens && sym != errtoken && sym != undeftoken);
 +
 +      SET_KEY("number");
 +      MUSCLE_INSERT_INT (key, sym->number);
 +
 +      SET_KEY("has_type");
 +      MUSCLE_INSERT_INT (key, !!sym->type_name);
 +
 +      SET_KEY("type");
 +      MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
 +
 +      {
 +        int j;
 +        for (j = 0; j < CODE_PROPS_SIZE; ++j)
 +          {
 +            /* "printer", not "%printer".  */
 +            char const *pname = code_props_type_string (j) + 1;
 +            code_props const *p = symbol_code_props_get (sym, j);
 +            SET_KEY2("has", pname);
 +            MUSCLE_INSERT_INT (key, !!p->code);
 +
 +            if (p->code)
 +              {
 +                SET_KEY2(pname, "file");
 +                MUSCLE_INSERT_STRING (key, p->location.start.file);
 +
 +                SET_KEY2(pname, "line");
 +                MUSCLE_INSERT_INT (key, p->location.start.line);
 +
 +                SET_KEY(pname);
 +                MUSCLE_INSERT_STRING_RAW (key, p->code);
 +              }
 +          }
 +      }
 +#undef SET_KEY2
 +#undef SET_KEY
 +    }
 +}
 +
 +
  /*--------------------------------------.
  | Output the tokens definition to OUT.  |
  `--------------------------------------*/
@@@ -487,19 -343,75 +486,19 @@@ token_definitions_output (FILE *out
      {
        symbol *sym = symbols[i];
        int number = sym->user_token_number;
 +      uniqstr id = symbol_id_get (sym);
  
        /* At this stage, if there are literal string aliases, they are
           part of SYMBOLS, so we should not find their aliased symbols
           here.  */
        aver (number != USER_NUMBER_HAS_STRING_ALIAS);
  
 -      /* Skip error token.  */
 -      if (sym == errtoken)
 -      continue;
 -
 -      /* If this string has an alias, then it is necessarily the alias
 -       which is to be output.  */
 -      if (sym->alias)
 -      sym = sym->alias;
 -
 -      /* Don't output literal chars or strings (when defined only as a
 -       string).  Note that must be done after the alias resolution:
 -       think about `%token 'f' "f"'.  */
 -      if (sym->tag[0] == '\'' || sym->tag[0] == '\"')
 -      continue;
 -
 -      /* Don't #define nonliteral tokens whose names contain periods,
 -         dashes or '$' (as does the default value of the EOF token).  */
 -      if (mbschr (sym->tag, '.')
 -          || mbschr (sym->tag, '-')
 -          || mbschr (sym->tag, '$'))
 -      continue;
 -
 -      fprintf (out, "%s[[[%s]], %d]",
 -             sep, sym->tag, number);
 -      sep = ",\n";
 -    }
 -  fputs ("])\n\n", out);
 -}
 -
 -
 -/*---------------------------------------------------.
 -| Output the symbol destructors or printers to OUT.  |
 -`---------------------------------------------------*/
 -
 -static void
 -symbol_code_props_output (FILE *out, char const *what,
 -                          code_props const *(*get)(symbol const *))
 -{
 -  int i;
 -  char const *sep = "";
 -
 -  fputs ("m4_define([b4_symbol_", out);
 -  fputs (what, out);
 -  fputs ("], \n[", out);
 -  for (i = 0; i < nsyms; ++i)
 -    {
 -      symbol *sym = symbols[i];
 -      char const *code = (*get) (sym)->code;
 -      if (code)
 +      /* Skip error token and tokens without identifier.  */
 +      if (sym != errtoken && id)
          {
 -          location loc = (*get) (sym)->location;
 -          /* Filename, lineno,
 -             Symbol-name, Symbol-number,
 -             code, optional typename.  */
 -          fprintf (out, "%s[", sep);
 +          fprintf (out, "%s[[[%s]], %d]",
 +                   sep, id, number);
            sep = ",\n";
 -          escaped_output (out, loc.start.file);
 -          fprintf (out, ", %d, ", loc.start.line);
 -          escaped_output (out, sym->tag);
 -          fprintf (out, ", %d, [[%s]]", sym->number, code);
 -          if (sym->type_name)
 -            fprintf (out, ", [[%s]]", sym->type_name);
 -          fputc (']', out);
          }
      }
    fputs ("])\n\n", out);
@@@ -513,30 -425,30 +512,30 @@@ prepare_actions (void
       lookahead token type.  */
  
    muscle_insert_rule_number_table ("defact", yydefact,
 -                                 yydefact[0], 1, nstates);
 +                                   yydefact[0], 1, nstates);
  
    /* Figure out what to do after reducing with each rule, depending on
       the saved state from before the beginning of parsing the data
       that matched this rule.  */
    muscle_insert_state_number_table ("defgoto", yydefgoto,
 -                                  yydefgoto[0], 1, nsyms - ntokens);
 +                                    yydefgoto[0], 1, nsyms - ntokens);
  
  
    /* Output PACT. */
    muscle_insert_base_table ("pact", base,
 -                           base[0], 1, nstates);
 +                             base[0], 1, nstates);
    MUSCLE_INSERT_INT ("pact_ninf", base_ninf);
  
    /* Output PGOTO. */
    muscle_insert_base_table ("pgoto", base,
 -                           base[nstates], nstates + 1, nvectors);
 +                             base[nstates], nstates + 1, nvectors);
  
    muscle_insert_base_table ("table", table,
 -                          table[0], 1, high + 1);
 +                            table[0], 1, high + 1);
    MUSCLE_INSERT_INT ("table_ninf", table_ninf);
  
    muscle_insert_base_table ("check", check,
 -                          check[0], 1, high + 1);
 +                            check[0], 1, high + 1);
  
    /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus
       YYPACT) so that in states with unresolved conflicts, the default
       that case.  Nevertheless, it seems even better to be able to use
       the GLR skeletons even without the non-deterministic tables.  */
    muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
 -                                  conflict_table[0], 1, high + 1);
 +                                    conflict_table[0], 1, high + 1);
    muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
 -                                  0, 1, conflict_list_cnt);
 +                                    0, 1, conflict_list_cnt);
  }
  
 +
  /*--------------------------------------------.
  | Output the definitions of all the muscles.  |
  `--------------------------------------------*/
@@@ -562,12 -473,13 +561,12 @@@ static voi
  muscles_output (FILE *out)
  {
    fputs ("m4_init()\n", out);
 -
 -  user_actions_output (out);
    merger_output (out);
 +  symbol_numbers_output (out);
    token_definitions_output (out);
 -  symbol_code_props_output (out, "destructors", &symbol_destructor_get);
 -  symbol_code_props_output (out, "printers", &symbol_printer_get);
 -
 +  type_names_output (out);
 +  user_actions_output (out);
 +  // Must be last.
    muscles_m4_output (out);
  }
  \f
  static void
  output_skeleton (void)
  {
 -  FILE *in;
    int filter_fd[2];
 -  char const *argv[10];
    pid_t pid;
  
    /* Compute the names of the package data dir and skeleton files.  */
 -  char const m4sugar[] = "m4sugar/m4sugar.m4";
 -  char const m4bison[] = "bison.m4";
 -  char *full_m4sugar;
 -  char *full_m4bison;
 -  char *full_skeleton;
 -  char const *p;
 -  char const *m4 = (p = getenv ("M4")) ? p : M4;
 -  char const *pkgdatadir = compute_pkgdatadir ();
 -  size_t skeleton_size = strlen (skeleton) + 1;
 -  size_t pkgdatadirlen = strlen (pkgdatadir);
 -  while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
 -    pkgdatadirlen--;
 -  full_skeleton = xmalloc (pkgdatadirlen + 1
 -                         + (skeleton_size < sizeof m4sugar
 -                            ? sizeof m4sugar : skeleton_size));
 -  memcpy (full_skeleton, pkgdatadir, pkgdatadirlen);
 -  full_skeleton[pkgdatadirlen] = '/';
 -  strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
 -  full_m4sugar = xstrdup (full_skeleton);
 -  strcpy (full_skeleton + pkgdatadirlen + 1, m4bison);
 -  full_m4bison = xstrdup (full_skeleton);
 -  if (mbschr (skeleton, '/'))
 -    strcpy (full_skeleton, skeleton);
 -  else
 -    strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);
 +  char const *m4 = (m4 = getenv ("M4")) ? m4 : M4;
 +  char const *datadir = pkgdatadir ();
 +  char *m4sugar = xconcatenated_filename (datadir, "m4sugar/m4sugar.m4", NULL);
 +  char *m4bison = xconcatenated_filename (datadir, "bison.m4", NULL);
 +  char *skel = (IS_PATH_WITH_DIR (skeleton)
 +                ? xstrdup (skeleton)
 +                : xconcatenated_filename (datadir, skeleton, NULL));
  
    /* Test whether m4sugar.m4 is readable, to check for proper
       installation.  A faulty installation can cause deadlock, so a
       cheap sanity check is worthwhile.  */
 -  xfclose (xfopen (full_m4sugar, "r"));
 +  xfclose (xfopen (m4sugar, "r"));
  
    /* Create an m4 subprocess connected to us via two pipes.  */
  
    if (trace_flag & trace_tools)
      fprintf (stderr, "running: %s %s - %s %s\n",
 -             m4, full_m4sugar, full_m4bison, full_skeleton);
 +             m4, m4sugar, m4bison, skel);
  
    /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a
       position-dependent manner.  Keep it as the first argument so that all
       <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
       for details.  */
    {
 +    char const *argv[10];
      int i = 0;
      argv[i++] = m4;
  
        argv[i++] = M4_GNU_OPTION;
  
      argv[i++] = "-I";
 -    argv[i++] = pkgdatadir;
 +    argv[i++] = datadir;
      if (trace_flag & trace_m4)
        argv[i++] = "-dV";
 -    argv[i++] = full_m4sugar;
 +    argv[i++] = m4sugar;
      argv[i++] = "-";
 -    argv[i++] = full_m4bison;
 -    argv[i++] = full_skeleton;
 +    argv[i++] = m4bison;
 +    argv[i++] = skel;
      argv[i++] = NULL;
      aver (i <= ARRAY_CARDINALITY (argv));
 +
 +    /* The ugly cast is because gnulib gets the const-ness wrong.  */
 +    pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
 +                            true, filter_fd);
    }
  
 -  /* The ugly cast is because gnulib gets the const-ness wrong.  */
 -  pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
 -                          true, filter_fd);
 -  free (full_m4sugar);
 -  free (full_m4bison);
 -  free (full_skeleton);
 +  free (m4sugar);
 +  free (m4bison);
 +  free (skel);
  
    if (trace_flag & trace_muscles)
      muscles_output (stderr);
    {
 -    FILE *out = fdopen (filter_fd[1], "w");
 -    if (! out)
 -      error (EXIT_FAILURE, get_errno (),
 -             "fdopen");
 +    FILE *out = xfdopen (filter_fd[1], "w");
      muscles_output (out);
      xfclose (out);
    }
  
    /* Read and process m4's output.  */
    timevar_push (TV_M4);
 -  in = fdopen (filter_fd[0], "r");
 -  if (! in)
 -    error (EXIT_FAILURE, get_errno (),
 -         "fdopen");
 -  scan_skel (in);
 -  /* scan_skel should have read all of M4's output.  Otherwise, when we
 -     close the pipe, we risk letting M4 report a broken-pipe to the
 -     Bison user.  */
 -  aver (feof (in));
 -  xfclose (in);
 +  {
 +    FILE *in = xfdopen (filter_fd[0], "r");
 +    scan_skel (in);
 +    /* scan_skel should have read all of M4's output.  Otherwise, when we
 +       close the pipe, we risk letting M4 report a broken-pipe to the
 +       Bison user.  */
 +    aver (feof (in));
 +    xfclose (in);
 +  }
    wait_subprocess (pid, "m4", false, false, true, true, NULL);
    timevar_pop (TV_M4);
  }
  static void
  prepare (void)
  {
 -  /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented
 -     for the user.  */
 -  char const *use_push_for_pull_env = getenv ("BISON_USE_PUSH_FOR_PULL");
 -  bool use_push_for_pull_flag = false;
 -  if (use_push_for_pull_env != NULL
 -      && use_push_for_pull_env[0] != '\0'
 -      && 0 != strcmp (use_push_for_pull_env, "0"))
 -    use_push_for_pull_flag = true;
 +  /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be
 +     documented for the user.  */
 +  char const *cp = getenv ("BISON_USE_PUSH_FOR_PULL");
 +  bool use_push_for_pull_flag = cp && *cp && strtol (cp, 0, 10);
  
    /* Flags. */
 -  MUSCLE_INSERT_BOOL ("debug_flag", debug_flag);
    MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
 -  MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose);
    MUSCLE_INSERT_BOOL ("glr_flag", glr_parser);
 -  MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
    MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser);
    MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
    MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
+   MUSCLE_INSERT_BOOL ("token_table_flag", token_table_flag);
    MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag);
    MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
  
      /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs
         would never be expanded.  Hopefully no one has M4-special characters in
         his Bison installation path.  */
 -    MUSCLE_INSERT_STRING_RAW ("pkgdatadir", compute_pkgdatadir ());
 +    MUSCLE_INSERT_STRING_RAW ("pkgdatadir", pkgdatadir ());
    }
  }
  
@@@ -731,7 -673,6 +731,7 @@@ output (void
    prepare_rules ();
    prepare_states ();
    prepare_actions ();
 +  prepare_symbol_definitions ();
  
    prepare ();
  
  }
  
  char const *
 -compute_pkgdatadir (void)
 +pkgdatadir (void)
  {
 -  char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
 -  return pkgdatadir ? pkgdatadir : PKGDATADIR;
 +  char const *cp = getenv ("BISON_PKGDATADIR");
 +  return cp ? cp : PKGDATADIR;
  }
diff --combined tests/actions.at
index 1f05eb8e4f1bb6b59394f0fc9c07d5246c7f8c80,e8e8cd972093632d23b02b2db499f4817dc8b065..755d633463eae74a95815e5034ff0083867ff448
@@@ -30,7 -30,7 +30,7 @@@ AT_SETUP([Mid-rule actions]
  
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA_GRAMMAR([[input.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  %{
  ]AT_YYERROR_DECLARE[
@@@ -51,7 -51,7 +51,7 @@@ exp:     { putchar ('0'); 
     ;
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE(123456789)[
+ ]AT_YYLEX_DEFINE(["123456789"])[
  int
  main (void)
  {
@@@ -80,7 -80,7 +80,7 @@@ AT_SETUP([Exotic Dollars]
  
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA_GRAMMAR([[input.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  %{
  ]AT_YYERROR_DECLARE[
@@@ -116,7 -116,7 +116,7 @@@ sum_of_the_five_previous_values
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([])[
+ ]AT_YYLEX_DEFINE[
  int
  main (void)
  {
@@@ -136,7 -136,7 +136,7 @@@ AT_PARSER_CHECK([./input], 0
  AT_DATA_GRAMMAR([[input.y]],
  [[
  %{
 -#include <stdio.h>
 +# include <stdio.h>
  ]AT_YYERROR_DECLARE[
  ]AT_YYLEX_DECLARE[
    typedef struct { int val; } stype;
@@@ -151,7 -151,7 +151,7 @@@ sum: { printf ("%d\n", $0.val + $-1.va
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE()[
+ ]AT_YYLEX_DEFINE[
  int
  main (void)
  {
@@@ -264,7 -264,7 +264,7 @@@ input
        V(input, $$, @$, ": /* Nothing */\n");
      }
  | line input /* Right recursive to load the stack so that popping at
 -              END can be exercised.  */
 +                END can be exercised.  */
      {
        $$ = 2;
        V(input, $$, @$, ": ");
@@@ -561,7 -561,7 +561,7 @@@ m4_define([AT_CHECK_PRINTER_AND_DESTRUC
  
  $3
  _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
 -[%error-verbose
 +[%define parse.error verbose
  %debug
  %verbose
  %locations
@@@ -592,7 -592,7 +592,7 @@@ AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-p
  AT_SETUP([Default tagless %printer and %destructor])
  AT_BISON_OPTION_PUSHDEFS([%locations])
  AT_DATA_GRAMMAR([[input.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  %locations
  %initial-action {
@@@ -636,7 -636,7 +636,7 @@@ start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; 
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([abcd], [[yylval = res]])[
+ ]AT_YYLEX_DEFINE(["abcd"], [[yylval = res]])[
  
  int
  main (void)
@@@ -694,7 -694,7 +694,7 @@@ AT_CLEANU
  AT_SETUP([Default tagged and per-type %printer and %destructor])
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA_GRAMMAR([[input.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  
  %{
@@@ -748,7 -748,7 +748,7 @@@ start
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([abcdef])[
+ ]AT_YYLEX_DEFINE(["abcdef"])[
  
  int
  main (void)
@@@ -826,7 -826,7 +826,7 @@@ m4_define([_AT_CHECK_DEFAULT_PRINTER_AN
  
  AT_BISON_OPTION_PUSHDEFS([%locations])
  AT_DATA_GRAMMAR([[input]]$1[[.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  %locations
  %initial-action {
@@@ -966,7 -966,7 +966,7 @@@ start
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([abd], [yylval = res])[
+ ]AT_YYLEX_DEFINE(["abd"], [yylval = res])[
  int
  main (void)
  {
@@@ -1066,7 -1066,7 +1066,7 @@@ start: { USE($$); } 
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([])[
+ ]AT_YYLEX_DEFINE[
  int
  main (void)
  {
@@@ -1121,7 -1121,7 +1121,7 @@@ start
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([])[
+ ]AT_YYLEX_DEFINE[
  int
  main (void)
  {
@@@ -1245,37 -1245,37 +1245,37 @@@ AT_DATA([input.y]
  start: test2 test1 test0 testc;
  
  test2
 -: 'a' { semi;                 /* TEST:N:2 */ }
 -| 'b' { if (0) {no_semi}      /* TEST:N:2 */ }
 -| 'c' { if (0) {semi;}                /* TEST:N:2 */ }
 -| 'd' { semi;   no_semi               /* TEST:Y:2 */ }
 -| 'e' { semi(); no_semi()     /* TEST:Y:2 */ }
 -| 'f' { semi[]; no_semi[]     /* TEST:Y:2 */ }
 -| 'g' { semi++; no_semi++     /* TEST:Y:2 */ }
 -| 'h' { {no_semi} no_semi     /* TEST:Y:2 */ }
 -| 'i' { {semi;}   no_semi     /* TEST:Y:2 */ }
 +: 'a' { semi;                   /* TEST:N:2 */ }
 +| 'b' { if (0) {no_semi}        /* TEST:N:2 */ }
 +| 'c' { if (0) {semi;}          /* TEST:N:2 */ }
 +| 'd' { semi;   no_semi         /* TEST:Y:2 */ }
 +| 'e' { semi(); no_semi()       /* TEST:Y:2 */ }
 +| 'f' { semi[]; no_semi[]       /* TEST:Y:2 */ }
 +| 'g' { semi++; no_semi++       /* TEST:Y:2 */ }
 +| 'h' { {no_semi} no_semi       /* TEST:Y:2 */ }
 +| 'i' { {semi;}   no_semi       /* TEST:Y:2 */ }
  ;
  test1
 -  : 'a' { semi;                       // TEST:N:1 ;
 -} | 'b' { if (0) {no_semi}    // TEST:N:1 ;
 -} | 'c' { if (0) {semi;}      // TEST:N:1 ;
 -} | 'd' { semi;   no_semi     // TEST:Y:1 ;
 -} | 'e' { semi(); no_semi()   // TEST:Y:1 ;
 -} | 'f' { semi[]; no_semi[]   // TEST:Y:1 ;
 -} | 'g' { semi++; no_semi++   // TEST:Y:1 ;
 -} | 'h' { {no_semi} no_semi   // TEST:Y:1 ;
 -} | 'i' { {semi;}   no_semi   // TEST:Y:1 ;
 +  : 'a' { semi;                 // TEST:N:1 ;
 +} | 'b' { if (0) {no_semi}      // TEST:N:1 ;
 +} | 'c' { if (0) {semi;}        // TEST:N:1 ;
 +} | 'd' { semi;   no_semi       // TEST:Y:1 ;
 +} | 'e' { semi(); no_semi()     // TEST:Y:1 ;
 +} | 'f' { semi[]; no_semi[]     // TEST:Y:1 ;
 +} | 'g' { semi++; no_semi++     // TEST:Y:1 ;
 +} | 'h' { {no_semi} no_semi     // TEST:Y:1 ;
 +} | 'i' { {semi;}   no_semi     // TEST:Y:1 ;
  } ;
  test0
 -  : 'a' { semi;                       // TEST:N:1 {}
 -} | 'b' { if (0) {no_semi}    // TEST:N:1 {}
 -} | 'c' { if (0) {semi;}      // TEST:N:1 {}
 -} | 'd' { semi;   no_semi     // TEST:Y:1 {}
 -} | 'e' { semi(); no_semi()   // TEST:Y:1 {}
 -} | 'f' { semi[]; no_semi[]   // TEST:Y:1 {}
 -} | 'g' { semi++; no_semi++   // TEST:Y:1 {}
 -} | 'h' { {no_semi} no_semi   // TEST:Y:1 {}
 -} | 'i' { {semi;}   no_semi   // TEST:Y:1 {}
 +  : 'a' { semi;                 // TEST:N:1 {}
 +} | 'b' { if (0) {no_semi}      // TEST:N:1 {}
 +} | 'c' { if (0) {semi;}        // TEST:N:1 {}
 +} | 'd' { semi;   no_semi       // TEST:Y:1 {}
 +} | 'e' { semi(); no_semi()     // TEST:Y:1 {}
 +} | 'f' { semi[]; no_semi[]     // TEST:Y:1 {}
 +} | 'g' { semi++; no_semi++     // TEST:Y:1 {}
 +} | 'h' { {no_semi} no_semi     // TEST:Y:1 {}
 +} | 'i' { {semi;}   no_semi     // TEST:Y:1 {}
  } ;
  
  testc
@@@ -1381,7 -1381,7 +1381,7 @@@ accept: /*empty*/ 
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([a])[
+ ]AT_YYLEX_DEFINE(["a"])[
  int
  main (void)
  {
@@@ -1417,7 -1417,7 +1417,7 @@@ AT_DATA_GRAMMAR([input.y]
  # include <assert.h>
  
    ]AT_YYERROR_DECLARE[
-   static int yylex (YYSTYPE *yylval);
+   ]AT_YYLEX_DECLARE[
  }
  %%
  input:
@@@ -1432,15 -1432,7 +1432,7 @@@ exp
  
  %%
  ]AT_YYERROR_DEFINE[
- static int
- yylex (YYSTYPE *yylval)
- {
-   static char const input[] = "bcd";
-   static size_t toknum;
-   assert (toknum < sizeof input);
-   *yylval = (toknum + 1) * 10;
-   return input[toknum++];
- }
+ ]AT_YYLEX_DEFINE(["bcd"], [*lvalp = (toknum + 1) * 10])[
  
  int
  main (void)
diff --combined tests/conflicts.at
index 3cced5d7652d255a54f8b94cfcb6093a036f3842,a46acc5ad74d1722de91e6c3ba225c4230bff272..ed6d607304655bda06560b3859807b57ef39d466
@@@ -1,6 -1,7 +1,6 @@@
  # Exercising Bison on conflicts.                         -*- Autotest -*-
  
 -# Copyright (C) 2002-2005, 2007, 2009-2012 Free Software Foundation,
 -# Inc.
 +# Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc.
  
  # This program is free software: you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
@@@ -141,11 -142,11 +141,11 @@@ AT_CLEANU
  
  
  
 -## -------------------------------------- ##
 -## %error-verbose and consistent errors.  ##
 -## -------------------------------------- ##
 +## ------------------------------------------- ##
 +## parse.error=verbose and consistent errors.  ##
 +## ------------------------------------------- ##
  
 -AT_SETUP([[%error-verbose and consistent errors]])
 +AT_SETUP([[parse.error=verbose and consistent errors]])
  
  m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
  
@@@ -163,6 -164,7 +163,6 @@@ AT_SKEL_JAVA_IF([AT_DATA], [AT_DATA_GRA
  }]], [[
  
  %code {]AT_SKEL_CC_IF([[
 -  #include <cassert>
    #include <string>]], [[
    #include <assert.h>
    #include <stdio.h>
  
  ]$1[
  
 -%error-verbose
 +%define parse.error verbose
  
  %%
  
@@@ -370,7 -372,7 +370,7 @@@ error-reduce
  ;
  
  consistent-reduction: /*empty*/ {
 -  assert (yychar == ]AT_SKEL_CC_IF([[yyempty_]], [[YYEMPTY]])[);
 +  assert (yychar == YYEMPTY);
    yylval = 0;
    yychar = 'b';
  } ;
@@@ -394,7 -396,11 +394,7 @@@ AT_CONSISTENT_ERRORS_CHECK([[%glr-parse
                             [AT_USER_ACTION_GRAMMAR],
                             [AT_USER_ACTION_INPUT],
                             [['b']], [[none]])
 -AT_CONSISTENT_ERRORS_CHECK([[%language "c++"]],
 -                           [AT_USER_ACTION_GRAMMAR],
 -                           [AT_USER_ACTION_INPUT],
 -                           [['b']], [[none]])
 -# No Java test because yychar cannot be manipulated by users.
 +# No C++ or Java test because yychar cannot be manipulated by users.
  
  AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reductions consistent]],
                             [AT_USER_ACTION_GRAMMAR],
@@@ -485,7 -491,7 +485,7 @@@ reduce-nonassoc: %prec 'a'
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([aaa])[
+ ]AT_YYLEX_DEFINE(["aaa"])[
  
  int
  main (void)
@@@ -735,62 -741,6 +735,62 @@@ state 
  AT_CLEANUP
  
  
 +## ---------------------- ##
 +## %precedence suffices.  ##
 +## ---------------------- ##
 +
 +AT_SETUP([%precedence suffices])
 +
 +AT_DATA([input.y],
 +[[%precedence "then"
 +%precedence "else"
 +%%
 +stmt:
 +  "if" cond "then" stmt
 +| "if" cond "then" stmt "else" stmt
 +| "stmt"
 +;
 +
 +cond:
 +  "exp"
 +;
 +]])
 +
 +AT_BISON_CHECK([-o input.c input.y])
 +
 +AT_CLEANUP
 +
 +
 +## ------------------------------ ##
 +## %precedence does not suffice.  ##
 +## ------------------------------ ##
 +
 +AT_SETUP([%precedence does not suffice])
 +
 +AT_DATA([input.y],
 +[[%precedence "then"
 +%precedence "else"
 +%%
 +stmt:
 +  "if" cond "then" stmt
 +| "if" cond "then" stmt "else" stmt
 +| "stmt"
 +;
 +
 +cond:
 +  "exp"
 +| cond "then" cond
 +;
 +]])
 +
 +AT_BISON_CHECK([-o input.c input.y], 0, [],
 +[[input.y: conflicts: 1 shift/reduce
 +input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond
 +]])
 +
 +AT_CLEANUP
 +
 +
  ## -------------------------------- ##
  ## Defaulted Conflicted Reduction.  ##
  ## -------------------------------- ##
diff --combined tests/local.at
index d5c73657833510e31fe421ef9243252cc588db2f,1baf6616f75321b53db704b4cd8824ee2b804a35..ba5a43ff930365d6f186b2fa75ab6e1f1f3146fd
@@@ -98,7 -98,7 +98,7 @@@ m4_define([AT_BISON_OPTION_PUSHDEFS]
  # --------------------------------------------------
  # This macro works around the impossibility to define macros
  # inside macros, because issuing `[$1]' is not possible in M4 :(.
 -# This sucks hard, GNU M4 should really provide M5 like $$1.
 +# This sucks hard, GNU M4 should really provide M5-like $$1.
  m4_define([_AT_BISON_OPTION_PUSHDEFS],
  [m4_if([$1$2], $[1]$[2], [],
         [m4_fatal([$0: Invalid arguments: $@])])dnl
@@@ -141,9 -141,6 +141,9 @@@ m4_pushdef([AT_NAME_PREFIX]
  [m4_bmatch([$3], [\(%define api\.prefix\|%name-prefix\) ".*"],
             [m4_bregexp([$3], [\(%define api\.prefix\|%name-prefix\) "\([^""]*\)"], [\2])],
             [yy])])
 +m4_pushdef([AT_TOKEN_PREFIX],
 +[m4_bmatch([$3], [%define api.tokens.prefix ".*"],
 +           [m4_bregexp([$3], [%define api.tokens.prefix "\(.*\)"], [\1])])])
  m4_pushdef([AT_API_prefix],
  [m4_bmatch([$3], [%define api\.prefix ".*"],
             [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
  # yyerror receives the location if %location & %pure & (%glr or %parse-param).
  m4_pushdef([AT_YYERROR_ARG_LOC_IF],
  [AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
 -                  [$2])])
 +                    [$2])])
  # yyerror always sees the locations (when activated), except if
  # (yacc & pure & !param).  FIXME: This is wrong.  See the manual.
  m4_pushdef([AT_YYERROR_SEES_LOC_IF],
  [AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
 -                                      [$1])],
 -                          [$1])],
 -              [$2])])
 +                                        [$1])],
 +                            [$1])],
 +                [$2])])
  
  # The interface is pure: either because %define api.pure, or because we
  # are using the C++ parsers.
  m4_pushdef([AT_PURE_LEX_IF],
  [AT_PURE_IF([$1],
 -          [AT_SKEL_CC_IF([$1], [$2])])])
 +            [AT_SKEL_CC_IF([$1], [$2])])])
  
  m4_pushdef([AT_YYSTYPE],
  [AT_SKEL_CC_IF([AT_NAME_PREFIX[::parser::semantic_type]],
@@@ -178,15 -175,15 +178,15 @@@ AT_PURE_LEX_IF
  [m4_pushdef([AT_LOC], [(*llocp)])
   m4_pushdef([AT_VAL], [(*lvalp)])
   m4_pushdef([AT_YYLEX_FORMALS],
 -          [AT_YYSTYPE *lvalp[]AT_LOCATION_IF([, AT_YYLTYPE *llocp])])
 +            [AT_YYSTYPE *lvalp[]AT_LOCATION_IF([, AT_YYLTYPE *llocp])])
   m4_pushdef([AT_YYLEX_ARGS],
 -          [lvalp[]AT_LOCATION_IF([, llocp])])
 +            [lvalp[]AT_LOCATION_IF([, llocp])])
   m4_pushdef([AT_USE_LEX_ARGS],
 -          [(void) lvalp;AT_LOCATION_IF([(void) llocp])])
 +            [(void) lvalp;AT_LOCATION_IF([(void) llocp])])
   m4_pushdef([AT_YYLEX_PRE_FORMALS],
 -          [AT_YYLEX_FORMALS, ])
 +            [AT_YYLEX_FORMALS, ])
   m4_pushdef([AT_YYLEX_PRE_ARGS],
 -          [AT_YYLEX_ARGS, ])
 +            [AT_YYLEX_ARGS, ])
  ],
  [m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]])
   m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]])
@@@ -205,8 -202,6 +205,8 @@@ AT_SKEL_CC_IF
      [AT_LOC_PUSHDEF([begin.line], [begin.column], [end.line], [end.column])])],
    [AT_LOC_PUSHDEF([first_line], [first_column], [last_line], [last_column])])
  
 +
 +AT_GLR_IF([AT_KEYWORDS([glr])])
  ])# _AT_BISON_OPTION_PUSHDEFS
  
  
@@@ -296,8 -291,11 +296,11 @@@ $2]
  # AT_YYLEX_PROTOTYPE
  # AT_YYLEX_DECLARE_EXTERN
  # AT_YYLEX_DECLARE
- # AT_YYLEX_DEFINE(INPUT-STRING, [ACTION])
- # ---------------------------------------
+ # AT_YYLEX_DEFINE([INPUT], [ACTION])
+ # ----------------------------------
+ # INPUT can be empty, or in double quotes, or a list (in braces).
+ # ACTION may compute yylval for instance, using "res" as token type,
+ # and "toknum" as the number of calls to yylex (starting at 0).
  m4_define([AT_YYLEX_PROTOTYPE],
  [int AT_NAME_PREFIX[]lex (]AT_YYLEX_FORMALS[)[]dnl
  ])
@@@ -315,7 -313,9 +318,9 @@@ m4_define([AT_YYLEX_DEFINE]
  static
  ]AT_YYLEX_PROTOTYPE[
  {
-   static char const input[] = "$1";
+   ]m4_bmatch([$1], [^\(".*"\)?$],
+              [[static char const input[] = ]m4_default([$1], [""])],
+              [[static int const input[] = ]$1])[;
    static size_t toknum = 0;
    int res;
    ]AT_USE_LEX_ARGS[;
@@@ -375,11 -375,13 +380,11 @@@ stati
  }]],
  [c++], [[/* A C++ error reporting function.  */
  void
 -]AT_NAME_PREFIX[::parser::error (const location_type& l, const std::string& m)
 -{
 -  (void) l;
 -  std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
 +]AT_NAME_PREFIX[::parser::error (]AT_LOCATION_IF([[const location_type& l, ]])[const std::string& m)
 +{  std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
  }]],
  [java], [AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s)
 -  {
 +{
      if (l == null)
        System.err.println (s);
      else
    public void yyerror (String s)
    {
      System.err.println (s);
 -  }]])])dnl
 +}]])])dnl
  ])
  
  
@@@ -564,7 -566,7 +569,7 @@@ m4_define([AT_COMPILE]
                    [-o $1],
                    [m4_default([$2], [m4_bpatsubst([$1], [\.o$]).c])],
                    [m4_bmatch([$1], [[.]], [], [$LIBS])]),
 -         0, [ignore], [ignore])])
 +           0, [ignore], [ignore])])
  
  # AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc])
  # ---------------------------------------------
@@@ -583,7 -585,7 +588,7 @@@ AT_CHECK(m4_join([ ]
                   [-o $1],
                   [m4_default([$2], [m4_bpatsubst([$1], [\.o$]).cc])],
                   [m4_bmatch([$1], [[.]], [], [$LIBS])]),
 -       0, [ignore], [ignore])])
 +         0, [ignore], [ignore])])
  
  # AT_JAVA_COMPILE(SOURCES)
  # ------------------------
@@@ -622,23 -624,23 +627,23 @@@ m4_define([AT_FULL_COMPILE]
  [java],
    [AT_BISON_CHECK([-o $1.java $1.y])
     AT_LANG_COMPILE([$1],
 -                   m4_join([ ],
 -                           [$1.java],
 -                           m4_ifval($2, [[$1-$2.java]]),
 +                    m4_join([ ],
 +                            [$1.java],
 +                            m4_ifval($2, [[$1-$2.java]]),
                             m4_ifval($3, [[$1-$3.java]])))],
  [c++],
    [AT_BISON_CHECK([-o $1.cc $1.y])
     AT_LANG_COMPILE([$1],
 -                   m4_join([ ],
 -                           [$1.cc],
 -                           m4_ifval($2, [[$1-$2.cc]]),
 +                     m4_join([ ],
 +                             [$1.cc],
 +                             m4_ifval($2, [[$1-$2.cc]]),
                             m4_ifval($3, [[$1-$3.cc]])))],
  [c],
    [AT_BISON_CHECK([-o $1.c $1.y])
     AT_LANG_COMPILE([$1],
 -                   m4_join([ ],
 -                           [$1.c],
 -                           m4_ifval($2, [[$1-$2.c]]),
 +                  m4_join([ ],
 +                          [$1.c],
 +                          m4_ifval($2, [[$1-$2.c]]),
                             m4_ifval($3, [[$1-$3.c]])))])
  ])
  
diff --combined tests/regression.at
index b23cbcfdffbdaafa24f7eacdc56bf9d9022b2120,c2795f6651a6fe079cd4726d271bc29b0b9634c8..91378febd43cf13e3646f668f61b4c9c8e0f1407
@@@ -463,15 -463,7 +463,7 @@@ AT_DATA_GRAMMAR([input.y]
  exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!";
  %%
  ]AT_YYERROR_DEFINE[
- int
- yylex (void)
- {
-   static int called;
-   if (called++)
-     abort ();
-   return SPECIAL;
- }
+ ]AT_YYLEX_DEFINE([{ SPECIAL }])[
  
  int
  main (void)
@@@ -546,7 -538,7 +538,7 @@@ AT_SETUP([Web2c Report]
  AT_KEYWORDS([report])
  
  AT_DATA([input.y],
 -[[%token      undef_id_tok const_id_tok
 +[[%token        undef_id_tok const_id_tok
  
  %start CONST_DEC_PART
  \f
@@@ -556,12 -548,12 +548,12 @@@ CONST_DEC_PART
          ;
  
  CONST_DEC_LIST:
 -        CONST_DEC
 +          CONST_DEC
          | CONST_DEC_LIST CONST_DEC
          ;
  
  CONST_DEC:
 -        { } undef_id_tok '=' const_id_tok ';'
 +          { } undef_id_tok '=' const_id_tok ';'
          ;
  %%
  ]])
@@@ -767,6 -759,15 +759,6 @@@ AT_CHECK([[cat tables.c]], 0
         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
@@@ -780,24 -781,32 +772,24 @@@ 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[] =
 +static const yytype_int8 yypact[] =
  {
 -       0,     2,     1,     0,     2,     4,     2
 +      -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 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_int8 yydefgoto[] =
 +{
 +      -1,     2,     3,     4,     8
 +};
  static const yytype_uint8 yytable[] =
  {
        10,     1,    11,     5,     6,     0,     7,     9
@@@ -811,14 -820,6 +803,14 @@@ 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
  # 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 <cstdlib>],
- [#include <stdlib.h>
- #include <stdio.h>
- ]AT_YYERROR_DECLARE[])
- %}
+ [[%code provides
+ {
+   ]AT_YYERROR_DECLARE[
+   ]AT_YYLEX_DECLARE[
+ }
  $1
  %token ARROW INVALID NUMBER STRING DATA
  %defines
@@@ -888,7 -887,8 +878,8 @@@ member: STRIN
     | INVALID
     ;
  %%
- AT_YYERROR_DEFINE[
+ ]AT_YYERROR_DEFINE[
+ ]AT_YYLEX_DEFINE([":"])[
  ]AT_LALR1_CC_IF(
  [int
  yyparse ()
  #endif
    return parser.parse ();
  }
- ])
- #include <assert.h>
- static int
- yylex (AT_LALR1_CC_IF([int *lval], [void]))
- [{
-   static int const tokens[] =
-     {
-       ':', -1
-     };
-   static size_t toknum;
-   ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC.  */])[
-   assert (toknum < sizeof tokens / sizeof *tokens);
-   return tokens[toknum++];
- }]
+ ])[
  
  int
  main (void)
  {
    return yyparse ();
  }
- ])
+ ]])
  ])# _AT_DATA_DANCER_Y
  
  
@@@ -954,11 -940,11 +931,11 @@@ AT_CHECK_DANCER([%skeleton "lalr1.cc"]
  # --------------------------------
  m4_define([_AT_DATA_EXPECT2_Y],
  [AT_DATA_GRAMMAR([expect2.y],
 -[[%{
 -static int yylex (]AT_LALR1_CC_IF([int *], [void]));
 -AT_LALR1_CC_IF([],
 -[[#include <stdio.h>
 -#include <stdlib.h>
 +[%{
 +static int yylex (AT_LALR1_CC_IF([int *], [void]));
 +AT_LALR1_CC_IF([[#include <cstdlib>]],
 +[[#include <stdlib.h>
 +#include <stdio.h>
  ]AT_YYERROR_DECLARE])[
  %}
  $1
@@@ -1054,7 -1040,7 +1031,7 @@@ AT_DATA_GRAMMAR([input.y]
  start:
    {
      printf ("Bison would once convert this action to a midrule because of the"
 -          " subsequent braced code.\n");
 +            " subsequent braced code.\n");
    }
    ;
  
  %printer { fprintf (yyoutput, "PRINTER"); } 'a';
  
  %%
  ]AT_YYERROR_DEFINE[
- static int
- yylex (void)
- {
-   return 'a';
- }
+ ]AT_YYLEX_DEFINE(["a"])[
  
  int
  main (void)
@@@ -1201,13 -1182,7 +1173,7 @@@ sr_conflict
  %%
  
  ]AT_YYERROR_DEFINE[
- int
- yylex (void)
- {
-   static int const input[] = { 1, 2, 3, 0 };
-   static int const *inputp = input;
-   return *inputp++;
- }
+ ]AT_YYLEX_DEFINE([{ 1, 2, 3, 0 }])[
  
  int
  main (void)
@@@ -1237,9 -1212,8 +1203,9 @@@ AT_CLEANU
  
  AT_SETUP([[parse-gram.y: LALR = IELR]])
  
 -# Avoid differences in synclines by telling bison that the output files
 -# have the same name.
 +# Avoid tests/bison's dark magic by processing a local copy of the
 +# grammar.  Avoid differences in synclines by telling bison that the
 +# output files have the same name.
  [cp $abs_top_srcdir/src/parse-gram.y input.y]
  AT_BISON_CHECK([[-o input.c -Dlr.type=lalr input.y]])
  [mv input.c lalr.c]
@@@ -1253,11 -1227,11 +1219,11 @@@ AT_CLEANU
  
  
  
 -## --------------------------------------- ##
 -## %error-verbose and YYSTACK_USE_ALLOCA.  ##
 -## --------------------------------------- ##
 +## -------------------------------------------- ##
 +## parse.error=verbose and YYSTACK_USE_ALLOCA.  ##
 +## -------------------------------------------- ##
  
 -AT_SETUP([[%error-verbose and YYSTACK_USE_ALLOCA]])
 +AT_SETUP([[parse.error=verbose and YYSTACK_USE_ALLOCA]])
  
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA_GRAMMAR([input.y],
    #define YYSTACK_USE_ALLOCA 1
  }
  
 -%error-verbose
 +%define parse.error verbose
  
  %%
  
@@@ -1301,10 -1275,10 +1267,10 @@@ syntax_error
  %%
  
  ]AT_YYERROR_DEFINE[
 -/* Induce two syntax error messages (which requires full error
 -   recovery by shifting 3 tokens) in order to detect any loss of the
 -   reallocated buffer.  */
 +  /* Induce two syntax error messages (which requires full error
 +     recovery by shifting 3 tokens) in order to detect any loss of the
 +     reallocated buffer.  */
- ]AT_YYLEX_DEFINE([abc])[
+ ]AT_YYLEX_DEFINE(["abc"])[
  int
  main (void)
  {
@@@ -1324,9 -1298,9 +1290,9 @@@ AT_CLEANU
  
  
  
 -## ------------------------- ##
 -## %error-verbose overflow.  ##
 -## ------------------------- ##
 +## ------------------------------ ##
 +## parse.error=verbose overflow.  ##
 +## ------------------------------ ##
  
  # Imagine the case where YYSTACK_ALLOC_MAXIMUM = YYSIZE_MAXIMUM and an
  # invocation of yysyntax_error has caused yymsg_alloc to grow to exactly
  # size calculation would return YYSIZE_MAXIMUM to yyparse.  Then,
  # yyparse would invoke yyerror using the old contents of yymsg.
  
 -AT_SETUP([[%error-verbose overflow]])
 +AT_SETUP([[parse.error=verbose overflow]])
 +
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA_GRAMMAR([input.y],
  [[%code {
    #define YYMAXDEPTH 100
  }
  
 -%error-verbose
 +%define parse.error verbose
  
  %%
  
@@@ -1410,9 -1383,9 +1376,9 @@@ syntax_error2
  %%
  
  ]AT_YYERROR_DEFINE[
 -/* Induce two syntax error messages (which requires full error
 -   recovery by shifting 3 tokens).  */
 +  /* Induce two syntax error messages (which requires full error
 +     recovery by shifting 3 tokens).  */
- ]AT_YYLEX_DEFINE([abc])[
+ ]AT_YYLEX_DEFINE(["abc"])[
  int
  main (void)
  {
@@@ -1461,7 -1434,7 +1427,7 @@@ AT_DATA_GRAMMAR([input.y]
  }
  
  ]$1[
 -%error-verbose
 +%define parse.error verbose
  %token 'c'
  
  %%
@@@ -1562,7 -1535,7 +1528,7 @@@ A: /*empty*/ | 'a' 
  
  %%
  ]AT_YYERROR_DEFINE[
- ]AT_YYLEX_DEFINE([$1])[
+ ]AT_YYLEX_DEFINE(["$1"])[
  int
  main (void)
  {