]> git.saurik.com Git - bison.git/commitdiff
Merge remote-tracking branch 'origin/maint'
authorAkim Demaille <akim@lrde.epita.fr>
Tue, 6 Nov 2012 17:23:47 +0000 (18:23 +0100)
committerAkim Demaille <akim@lrde.epita.fr>
Tue, 6 Nov 2012 17:30:16 +0000 (18:30 +0100)
* origin/maint: (24 commits)
  tests: calc: modernize the use of locations
  tests: remove useless location initializations
  lalr1.cc: always initialize yylval.
  tests: check that C and C++ objects can be linked together.
  yacc.c: also disable -Wuninitialized.
  glr.cc, yacc.c: initialize yylloc properly
  yacc.c, glr.c: a better YY_LOCATION_PRINT
  yacc.c: simplify initialization
  doc: formatting changes
  c++: fix position operator signatures
  tests: remove useless location initialization.
  tests: fix locations in C
  tests: handle %parse-param in the generated yyerror
  tests: simplifications
  grammars: fix display of nul character in error message
  tests: sort
  tests: cosmetic changes
  comment changes
  autoconf: update
  gnulib: update
  ...

Conflicts:
data/lalr1.cc
gnulib
src/scan-gram.l
submodules/autoconf
tests/calc.at

17 files changed:
1  2 
NEWS
THANKS
data/c.m4
data/glr.c
data/glr.cc
data/lalr1.cc
data/location.cc
data/yacc.c
src/scan-gram.l
tests/actions.at
tests/calc.at
tests/glr-regression.at
tests/headers.at
tests/input.at
tests/local.at
tests/named-refs.at
tests/regression.at

diff --combined NEWS
index a2ea735e8faac7bd3d533ec1044e2649f5f9a920,b7a1a727d9d9b888ff410a3a7c62426d28fdfec6..c067ac09150a7f85e1610ae0a557817cabfc5fc8
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -2,246 -2,6 +2,246 @@@ GNU Bison NEW
  
  * Noteworthy changes in release ?.? (????-??-??) [?]
  
 +** Incompatible changes
 +
 +*** Obsolete features
 +
 +  Support for YYFAIL is removed (deprecated in Bison 2.4.2).
 +  Support for yystype and yyltype (instead of YYSTYPE and YYLTYPE)
 +  is removed (deprecated in Bison 1.875).
 +  Support for YYPARSE_PARAM is removed (deprecated in Bison 1.875).
 +
 +** Warnings
 +
 +*** Enhancements of the -Werror option
 +
 +  The -Werror=CATEGORY option is now recognized, and will treat specified
 +  warnings as errors. The warnings need not have been explicitly activated
 +  using the -W option, this is similar to what GCC 4.7 does.
 +
 +  For example, given the following command line, Bison will treat both
 +  warnings related to POSIX Yacc incompatibilities and S/R conflicts as
 +  errors (and only those):
 +
 +    $ bison -Werror=yacc,error=conflicts-sr input.y
 +
 +  If no categories are specified, -Werror will make all active warnings into
 +  errors. For example, the following line does the same the previous example:
 +
 +    $ bison -Werror -Wnone -Wyacc -Wconflicts-sr input.y
 +
 +  (By default -Wconflicts-sr,conflicts-rr,deprecated,other is enabled.)
 +
 +  Note that the categories in this -Werror option may not be prefixed with
 +  "no-". However, -Wno-error[=CATEGORY] is valid.
 +
 +  Note that -y enables -Werror=yacc. Therefore it is now possible to require
 +  Yacc-like behavior (e.g., always generate y.tab.c), but to report
 +  incompatibilities as warnings: "-y -Wno-error=yacc".
 +
 +*** The display of warnings is now richer
 +
 +  The option that controls a given warning is now displayed:
 +
 +    foo.y:4.6: warning: type clash on default action: <foo> != <bar> [-Wother]
 +
 +  In the case of warnings treated as errors, the prefix is changed from
 +  "warning: " to "error: ", and the suffix is displayed, in a manner similar
 +  to GCC, as [-Werror=CATEGORY].
 +
 +  For instance, where the previous version of Bison would report (and exit
 +  with failure):
 +
 +    bison: warnings being treated as errors
 +    input.y:1.1: warning: stray ',' treated as white space
 +
 +  it now reports:
 +
 +    input.y:1.1: error: stray ',' treated as white space [-Werror=other]
 +
 +*** Deprecated constructs
 +
 +  The new 'deprecated' warning category flags obsolete constructs whose
 +  support will be discontinued.  It is enabled by default.  These warnings
 +  used to be reported as 'other' warnings.
 +
 +*** 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
 +
 +*** Undefined but unused symbols
 +
 +  Bison used to raise an error for undefined symbols that are not used in
 +  the grammar.  This is now only a warning.
 +
 +    %printer    {} symbol1
 +    %destructor {} symbol2
 +    %type <type>   symbol3
 +    %%
 +    exp: "a";
 +
 +*** 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>
 +
 +*** Conflicts
 +
 +  The warnings and error messages about shift/reduce and reduce/reduce
 +  conflicts have been normalized.  For instance on the following foo.y file:
 +
 +    %glr-parser
 +    %%
 +    exp: exp '+' exp | '0' | '0';
 +
 +  compare the previous version of bison:
 +
 +    $ bison foo.y
 +    foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce
 +    $ bison -Werror foo.y
 +    bison: warnings being treated as errors
 +    foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce
 +
 +  with the new behavior:
 +
 +    $ bison foo.y
 +    foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +    foo.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
 +    $ bison -Werror foo.y
 +    foo.y: error: 1 shift/reduce conflict [-Werror=conflicts-sr]
 +    foo.y: error: 2 reduce/reduce conflicts [-Werror=conflicts-rr]
 +
 +  When %expect or %expect-rr is used, such as with bar.y:
 +
 +    %expect 0
 +    %glr-parser
 +    %%
 +    exp: exp '+' exp | '0' | '0';
 +
 +  Former behavior:
 +
 +    $ bison bar.y
 +    bar.y: conflicts: 1 shift/reduce, 2 reduce/reduce
 +    bar.y: expected 0 shift/reduce conflicts
 +    bar.y: expected 0 reduce/reduce conflicts
 +
 +  New one:
 +
 +    $ bison bar.y
 +    bar.y: error: shift/reduce conflicts: 1 found, 0 expected
 +    bar.y: error: reduce/reduce conflicts: 2 found, 0 expected
 +
 +** 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++ skeletons improvements
 +
 +*** The parser header is no longer mandatory (lalr1.cc, glr.cc)
 +
 +  Using %defines is now optional.  Without it, the needed support classes
 +  are defined in the generated parser, instead of additional files (such as
 +  location.hh, position.hh and stack.hh).
 +
 +*** Locations are no longer mandatory (lalr1.cc, glr.cc)
 +
 +  Both lalr1.cc and glr.cc no longer require %location.
 +
 +*** syntax_error exception (lalr1.cc)
 +
 +  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.token.prefix
 +
 +  The variable api.token.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.token.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).
 +
 +** Renamed %define variables
 +
 +  The following variables have been renamed for consistency.  Backward
 +  compatibility is ensured, but upgrading is recommended.
 +
 +    lr.default-reductions      -> lr.default-reduction
 +    lr.keep-unreachable-states -> lr.keep-unreachable-state
 +    namespace                  -> api.namespace
 +
 +** Variable parse.error
 +
 +  This variable 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 run-time
 +  expressions.
 +
 +** The directive %expect-rr is now an error in non GLR mode
 +
 +  It used to be an error only if used in non GLR mode, _and_ if there are
 +  reduce/reduce conflicts.
 +
 +* Noteworthy changes in release ?.? (????-??-??) [?]
 +
  ** Changes in the format of error messages
  
    This used to be the format of many error reports:
    The reductions are now explicitly represented as transitions to other
    diamond shaped nodes.
  
+ * Noteworthy changes in release ?.? (????-??-??) [?]
+   We consider compiler warnings about Bison generated parsers to be bugs.
+   Rather than working around them in your own project, please consider
+   reporting them to us.
+ ** Bug fixes
+   Warnings about uninitialized yylval and/or yylloc for push parsers with a
+   pure interface have been fixed for GCC 4.0 up to 4.8, and Clang 2.9 to
+   3.2.
+   Other issues in the test suite have been addressed.
+   Nul characters are correctly displayed in error messages.
+   When possible, yylloc is correctly initialized before calling yylex.  It
+   is no longer necessary to initialize it in the %initial-action.
  * Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
  
    Bison 2.6.3's --version was incorrect.  This release fixes this issue.
  
  * Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
  
 -  Bison no longer executes user-specified M4 code when processing a grammar.
 + Bison no longer executes user-specified M4 code when processing a grammar.
  
  ** Future Changes
  
  
  * Noteworthy changes in release 2.6 (2012-07-19) [stable]
  
 -** Future Changes
 +** Future changes
  
    The next major release of Bison will drop support for the following
    deprecated features.  Please report disagreements to bug-bison@gnu.org.
@@@ -2196,8 -1975,8 +2215,8 @@@ along with this program.  If not, see <
   LocalWords:  namespaces strerror const autoconfiguration Dconst Autoconf's FDL
   LocalWords:  Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
   LocalWords:  extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
 - LocalWords:  lang yyoutput dvi html ps POSIX lvalp llocp calc yyo fval Wmaybe
 - LocalWords:  yyvsp pragmas noreturn java's
 + LocalWords:  lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
 + LocalWords:  TOK calc yyo fval Wconflicts
  
  Local Variables:
  mode: outline
diff --combined THANKS
index 4fbbbb0b81db32278318587766dfabeeef94dd6e,21e7a1dd855ffc4e98cd6096629dab010d77cbe3..eab6349b9abd8af897a2b213f1f585c59df48bad
--- 1/THANKS
--- 2/THANKS
+++ b/THANKS
@@@ -64,6 -64,7 +64,7 @@@ Laurent Mascherpa         laurent.masch
  Lie Yan                   lie.yan@kaust.edu.sa
  Magnus Fromreide          magfr@lysator.liu.se
  Marc Autret               autret_m@epita.fr
+ Marc Mendiola             mmendiol@usc.edu
  Martin Jacobs             martin.jacobs@arcor.de
  Martin Mokrejs            mmokrejs@natur.cuni.cz
  Martin Nylin              martin.nylin@linuxmail.org
@@@ -71,7 -72,6 +72,7 @@@ Matt Kraai                kraai@alumni.
  Matt Rosing               rosing@peakfive.com
  Michael Hayes             m.hayes@elec.canterbury.ac.nz
  Michael Raskin            7c6f434c@mail.ru
 +Michiel De Wilde          mdewilde.agilent@gmail.com
  Mickael Labau             labau_m@epita.fr
  Mike Castle               dalgoda@ix.netcom.com
  Neil Booth                NeilB@earthling.net
@@@ -89,8 -89,8 +90,9 @@@ Paul Hilfinger            Hilfinger@CS.
  Per Allansson             per@appgate.com
  Peter Fales               psfales@lucent.com
  Peter Hamorsky            hamo@upjs.sk
+ Peter Simons              simons@cryp.to
  Piotr Gackiewicz          gacek@intertel.com.pl
 +Quentin Hocquet           hocquet@gostai.com
  Quoc Peyrot               chojin@lrde.epita.fr
  R Blake                   blakers@mac.com
  Raja R Harinath           harinath@cs.umn.edu
diff --combined data/c.m4
index 51ffbe3bf6463318605e6e53ad9853e7d2f33ca1,8bd96b8573f728b0bbf35c593ef33ddea5a082f8..91126a82b84ef325cb83ed406f5d4b0fdf33c2a1
+++ b/data/c.m4
@@@ -51,28 -51,11 +51,28 @@@ 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_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_comment],
 +[b4_comment_([$1], [$2/* ], [$2   ], [$2  */])])
 +
  
  # b4_identification
  # -----------------
@@@ -130,7 -113,7 +130,7 @@@ m4_define_default([b4_union_name], [b4_
  # b4_user_args
  # ------------
  m4_define([b4_user_args],
 -[m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])])
 +[m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])])
  
  
  # b4_parse_param
@@@ -154,13 -137,11 +154,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
  ])
  
@@@ -182,7 -163,7 +182,7 @@@ m4_define([b4_int_type]
  
         m4_eval([0 <= $1]),                [1], [unsigned int],
  
 -                                             [int])])
 +                                               [int])])
  
  
  # b4_int_type_for(NAME)
@@@ -197,11 -178,12 +197,11 @@@ m4_define([b4_int_type_for]
  # --------------------------------------------
  # Without inducing a comparison warning from the compiler, check if the
  # literal value LITERAL equals VALUE from table TABLE, which must have
 -# TABLE_min and TABLE_max defined.  YYID must be defined as an identity
 -# function that suppresses warnings about constant conditions.
 +# TABLE_min and TABLE_max defined.
  m4_define([b4_table_value_equals],
  [m4_if(m4_eval($3 < m4_indir([b4_]$1[_min])
                 || m4_indir([b4_]$1[_max]) < $3), [1],
 -       [[YYID (0)]],
 +       [[0]],
         [(!!(($2) == ($3)))])])
  
  
@@@ -230,125 -212,166 +230,125 @@@ 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_comment([$3], [  ])])dnl
 +static const b4_int_type_for([$2]) yy$1[[]] =
 +{
 +  $2
 +};dnl
 +])
  
  
  ## ------------------------- ##
  ## Assigning token numbers.  ##
  ## ------------------------- ##
  
 -# b4_token_define(TOKEN-NAME, TOKEN-NUMBER)
 -# -----------------------------------------
 +# b4_token_define(TOKEN-NUM)
 +# --------------------------
  # Output the definition of this token as #define.
  m4_define([b4_token_define],
 -[#define $1 $2
 -])
 +[b4_token_format([#define %s %s], [$1])])
  
 -
 -# b4_token_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
 -# -------------------------------------------------------
 -# Output the definition of the tokens (if there are) as #defines.
 +# b4_token_defines
 +# ----------------
 +# Output the definition of the tokens.
  m4_define([b4_token_defines],
 -[m4_if([$#$1], [1], [],
 -[/* Tokens.  */
 -m4_map([b4_token_define], [$@])])
 -])
 +[b4_any_token_visible_if([/* Tokens.  */
 +m4_join([
 +], b4_symbol_map([b4_token_define]))
 +])])
  
  
 -# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
 -# ---------------------------------------
 +# b4_token_enum(TOKEN-NUM)
 +# ------------------------
  # Output the definition of this token as an enum.
  m4_define([b4_token_enum],
 -[$1 = $2])
 +[b4_token_format([%s = %s], [$1])])
  
  
 -# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
 -# -----------------------------------------------------
 +# b4_token_enums
 +# --------------
  # Output the definition of the tokens (if there are) as enums.
  m4_define([b4_token_enums],
 -[m4_if([$#$1], [1], [],
 -[[/* Tokens.  */
 +[b4_any_token_visible_if([[/* Tokens.  */
  #ifndef ]b4_api_PREFIX[TOKENTYPE
  # define ]b4_api_PREFIX[TOKENTYPE
 -   /* Put the tokens into the symbol table, so that GDB and other debuggers
 -      know about them.  */
 -   enum ]b4_api_prefix[tokentype {
 -]m4_map_sep([     b4_token_enum], [,
 -],
 -         [$@])[
 -   };
 +  /* Put the tokens into the symbol table, so that GDB and other debuggers
 +     know about them.  */
 +  enum ]b4_api_prefix[tokentype
 +  {
 +    ]m4_join([,
 +    ],
 +             b4_symbol_map([b4_token_enum]))[
 +  };
  #endif
  ]])])
  
  
 -# b4_token_enums_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
 -# -------------------------------------------------------------
 -# Output the definition of the tokens (if there are any) as enums and, if POSIX
 -# Yacc is enabled, as #defines.
 +# b4_token_enums_defines
 +# ----------------------
 +# Output the definition of the tokens (if there are any) as enums and,
 +# if POSIX Yacc is enabled, as #defines.
  m4_define([b4_token_enums_defines],
 -[b4_token_enums($@)b4_yacc_if([b4_token_defines($@)], [])
 -])
 +[b4_token_enums[]b4_yacc_if([b4_token_defines])])
  
  
 +## ----------------- ##
 +## Semantic Values.  ##
 +## ----------------- ##
  
 -## --------------------------------------------- ##
 -## Defining C functions in both K&R and ANSI-C.  ##
 -## --------------------------------------------- ##
  
 +# 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]))])
  
 -# b4_modern_c
 -# -----------
 -# A predicate useful in #if to determine whether C is ancient or modern.
 -#
 -# If __STDC__ is defined, the compiler is modern.  IBM xlc 7.0 when run
 -# as 'cc' doesn't define __STDC__ (or __STDC_VERSION__) for pedantic
 -# reasons, but it defines __C99__FUNC__ so check that as well.
 -# Microsoft C normally doesn't define these macros, but it defines _MSC_VER.
 -# Consider a C++ compiler to be modern if it defines __cplusplus.
 -#
 -m4_define([b4_c_modern],
 -  [[(defined __STDC__ || defined __C99__FUNC__ \
 -     || defined __cplusplus || defined _MSC_VER)]])
  
 -# b4_c_function_def(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 -# ----------------------------------------------------------
 -# Declare the function NAME.
 -m4_define([b4_c_function_def],
 -[#if b4_c_modern
 -b4_c_ansi_function_def($@)
 -#else
 -$2
 -$1 (b4_c_knr_formal_names(m4_shift2($@)))
 -b4_c_knr_formal_decls(m4_shift2($@))
 -#endif[]dnl
 -])
 +
 +## ---------------------- ##
 +## Defining C functions.  ##
 +## ---------------------- ##
  
  
 -# b4_c_ansi_function_def(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 -# ---------------------------------------------------------------
 -# Declare the function NAME in ANSI.
 -m4_define([b4_c_ansi_function_def],
 +# b4_function_define(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 +# -----------------------------------------------------------
 +# Declare the function NAME in C.
 +m4_define([b4_function_define],
  [$2
 -$1 (b4_c_ansi_formals(m4_shift2($@)))[]dnl
 +$1 (b4_formals(m4_shift2($@)))[]dnl
  ])
  
  
 -# b4_c_ansi_formals([DECL1, NAME1], ...)
 -# --------------------------------------
 -# Output the arguments ANSI-C definition.
 -m4_define([b4_c_ansi_formals],
 +# b4_formals([DECL1, NAME1], ...)
 +# -------------------------------
 +# The formal arguments of a C function definition.
 +m4_define([b4_formals],
  [m4_if([$#], [0], [void],
         [$#$1], [1], [void],
 -             [m4_map_sep([b4_c_ansi_formal], [, ], [$@])])])
 +               [m4_map_sep([b4_formal], [, ], [$@])])])
  
 -m4_define([b4_c_ansi_formal],
 +m4_define([b4_formal],
  [$1])
  
  
 -# b4_c_knr_formal_names([DECL1, NAME1], ...)
 -# ------------------------------------------
 -# Output the argument names.
 -m4_define([b4_c_knr_formal_names],
 -[m4_map_sep([b4_c_knr_formal_name], [, ], [$@])])
 -
 -m4_define([b4_c_knr_formal_name],
 -[$2])
 -
 -
 -# b4_c_knr_formal_decls([DECL1, NAME1], ...)
 -# ------------------------------------------
 -# 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;])
 -
 -
  
 -## ------------------------------------------------------------ ##
 -## Declaring (prototyping) C functions in both K&R and ANSI-C.  ##
 -## ------------------------------------------------------------ ##
 +## ----------------------- ##
 +## Declaring C functions.  ##
 +## ----------------------- ##
  
  
 -# b4_c_function_decl(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 -# -----------------------------------------------------------
 +# b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 +# ------------------------------------------------------------
  # Declare the function NAME.
 -m4_define([b4_c_function_decl],
 -[#if defined __STDC__ || defined __cplusplus
 -b4_c_ansi_function_decl($@)
 -#else
 -$2 $1 ();
 -#endif[]dnl
 -])
 -
 -
 -# b4_c_ansi_function_decl(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 -# ----------------------------------------------------------------
 -# Declare the function NAME.
 -m4_define([b4_c_ansi_function_decl],
 -[$2 $1 (b4_c_ansi_formals(m4_shift2($@)));[]dnl
 +m4_define([b4_function_declare],
 +[$2 $1 (b4_formals(m4_shift2($@)));[]dnl
  ])
  
  
  ## --------------------- ##
  
  
 -# b4_c_function_call(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
 +# b4_function_call(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
  # -----------------------------------------------------------
  # Call the function NAME with arguments NAME1, NAME2 etc.
 -m4_define([b4_c_function_call],
 -[$1 (b4_c_args(m4_shift2($@)))[]dnl
 +m4_define([b4_function_call],
 +[$1 (b4_args(m4_shift2($@)))[]dnl
  ])
  
  
 -# b4_c_args([DECL1, NAME1], ...)
 -# ------------------------------
 +# b4_args([DECL1, NAME1], ...)
 +# ----------------------------
  # Output the arguments NAME1, NAME2...
 -m4_define([b4_c_args],
 -[m4_map_sep([b4_c_arg], [, ], [$@])])
 +m4_define([b4_args],
 +[m4_map_sep([b4_arg], [, ], [$@])])
  
 -m4_define([b4_c_arg],
 +m4_define([b4_arg],
  [$2])
  
  
  ## ----------- ##
  
  # b4_sync_start(LINE, FILE)
 -# -----------------------
 +# -------------------------
  m4_define([b4_sync_start], [[#]line $1 $2])
  
  
  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)
 -# -------------------------------------------------
 -# Issue the code for a symbol action (e.g., %printer).
 -#
 -# Define b4_dollar_dollar([TYPE-NAME]), and b4_at_dollar, which are
 -# invoked where $<TYPE-NAME>$ and @$ were specified by the user.
 -m4_define([b4_symbol_actions],
 -[b4_dollar_pushdef([(*yyvaluep)], [$6], [(*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;
 -b4_dollar_popdef[]dnl
 -])
 +    break;])
  
  
 -# b4_yydestruct_generate(FUNCTION-DECLARATOR)
 -# -------------------------------------------
 -# Generate the "yydestruct" function, which declaration is issued using
 -# FUNCTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
 -# or "b4_c_function_def" for K&R.
 -m4_define_default([b4_yydestruct_generate],
 +# b4_yydestruct_define
 +# --------------------
 +# Define the "yydestruct" function.
 +m4_define_default([b4_yydestruct_define],
  [[/*-----------------------------------------------.
  | Release the memory associated to this symbol.  |
  `-----------------------------------------------*/
  
 -/*ARGSUSED*/
 -]$1([yydestruct],
 +]b4_function_define([yydestruct],
      [static void],
      [[const char *yymsg],    [yymsg]],
      [[int yytype],           [yytype]],
  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
  ])
  
  
 -# b4_yy_symbol_print_generate(FUNCTION-DECLARATOR)
 -# ------------------------------------------------
 -# Generate the "yy_symbol_print" function, which declaration is issued using
 -# FUNCTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
 -# or "b4_c_function_def" for K&R.
 -m4_define_default([b4_yy_symbol_print_generate],
 +# b4_yy_symbol_print_define
 +# -------------------------
 +# Define the "yy_symbol_print" function.
 +m4_define_default([b4_yy_symbol_print_define],
  [[
  /*--------------------------------.
  | Print this symbol on YYOUTPUT.  |
  `--------------------------------*/
  
 -/*ARGSUSED*/
 -]$1([yy_symbol_value_print],
 +]b4_function_define([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;
      }
  }
  
  | Print this symbol on YYOUTPUT.  |
  `--------------------------------*/
  
 -]$1([yy_symbol_print],
 +]b4_function_define([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]))[
  {
@@@ -521,6 -564,7 +521,6 @@@ m4_define([b4_declare_yylstype]
  [m4_if(b4_tag_seen_flag, 0,
  [[typedef int ]b4_api_PREFIX[STYPE;
  # define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[
 -# define ]b4_api_prefix[stype ]b4_api_PREFIX[STYPE /* obsolescent; will be withdrawn */
  # define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
  #endif]b4_locations_if([[
  
@@@ -532,6 -576,7 +532,6 @@@ typedef struct ]b4_api_PREFIX[LTYP
    int last_line;
    int last_column;
  } ]b4_api_PREFIX[LTYPE;
 -# define ]b4_api_prefix[ltype ]b4_api_PREFIX[LTYPE /* obsolescent; will be withdrawn */
  # define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
  # define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
  #endif]])
@@@ -546,17 -591,17 +546,17 @@@ m4_define([b4_YYDEBUG_define]
  [[/* Enabling traces.  */
  ]m4_if(b4_api_prefix, [yy],
  [[#ifndef YYDEBUG
 -# define YYDEBUG ]b4_debug_flag[
 +# define YYDEBUG ]b4_parse_trace_if([1], [0])[
  #endif]],
  [[#ifndef ]b4_api_PREFIX[DEBUG
  # if defined YYDEBUG
 -#  if YYDEBUG
 +#if YYDEBUG
  #   define ]b4_api_PREFIX[DEBUG 1
  #  else
  #   define ]b4_api_PREFIX[DEBUG 0
  #  endif
  # else /* ! defined YYDEBUG */
 -#  define ]b4_api_PREFIX[DEBUG ]b4_debug_flag[
 +#  define ]b4_api_PREFIX[DEBUG ]b4_parse_trace_if([1], [0])[
  # endif /* ! defined YYDEBUG */
  #endif  /* ! defined ]b4_api_PREFIX[DEBUG */]])[]dnl
  ])
@@@ -581,7 -626,7 +581,7 @@@ m4_define([b4_yylloc_default_define]
  #ifndef YYLLOC_DEFAULT
  # define YYLLOC_DEFAULT(Current, Rhs, N)                                \
      do                                                                  \
 -      if (YYID (N))                                                     \
 +      if (N)                                                            \
          {                                                               \
            (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
            (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
            (Current).first_column = (Current).last_column =              \
              YYRHSLOC (Rhs, 0).last_column;                              \
          }                                                               \
 -    while (YYID (0))
 +    while (0)
  #endif
  ]])
+ # b4_yy_location_print_define
+ # ---------------------------
+ # Define YY_LOCATION_PRINT.
+ m4_define([b4_yy_location_print_define],
+ [b4_locations_if([[
+ /* YY_LOCATION_PRINT -- Print the location on the stream.
+    This macro was not mandated originally: define only if we know
+    we won't break user code: when these are the locations we know.  */
+ #ifndef YY_LOCATION_PRINT
+ # if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
+ #  define YY_LOCATION_PRINT(File, Loc)                                   \
+   do {                                                                   \
+     fprintf (File, "%d.%d", (Loc).first_line, (Loc).first_column);       \
+     if ((Loc).first_line < (Loc).last_line)                              \
+       fprintf (File, "-%d.%d", (Loc).last_line,  (Loc).last_column - 1); \
+     else if ((Loc).first_column < (Loc).last_column - 1)                 \
+       fprintf (File, "-%d", (Loc).last_column - 1);                      \
+   } while (0)
+ # else
+ #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+ # endif
+ #endif]],
+ [[/* This macro is provided for backward compatibility. */
+ #ifndef YY_LOCATION_PRINT
+ # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+ #endif]])
+ ])
+ # b4_yyloc_default
+ # ----------------
+ # Expand to a possible default value for yylloc.
+ m4_define([b4_yyloc_default],
+ [[
+ # if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
+   = { ]m4_join([, ],
+                m4_defn([b4_location_initial_line]),
+                m4_defn([b4_location_initial_column]),
+                m4_defn([b4_location_initial_line]),
+                m4_defn([b4_location_initial_column]))[ }
+ # endif
+ ]])
diff --combined data/glr.c
index e2363a2083bf184202dfc53ad1737eced8d11e23,9bd95228da6e0615a627d416f338f7b6b54a1e4e..9038c7475d0d42e66829154d9f608862d4786cb1
@@@ -52,7 -52,7 +52,7 @@@ m4_ifndef([b4_pure_flag]
  # This is not shared with yacc.c in c.m4 because  GLR relies on ISO C
  # formal argument declarations.
  m4_define([b4_user_formals],
 -[m4_ifset([b4_parse_param], [, b4_c_ansi_formals(b4_parse_param)])])
 +[m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])])
  
  
  # b4_lex_param
@@@ -71,7 -71,7 +71,7 @@@ m4_ifdef([b4_lex_param], [, ]b4_lex_par
  # a trailing comma.
  m4_define([b4_yyerror_args],
  [b4_pure_if([b4_locations_if([yylocp, ])])dnl
 -m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
 +m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
  
  
  # b4_lyyerror_args
@@@ -79,7 -79,7 +79,7 @@@
  # Same as above, but on the lookahead, hence &yylloc instead of yylocp.
  m4_define([b4_lyyerror_args],
  [b4_pure_if([b4_locations_if([&yylloc, ])])dnl
 -m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
 +m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
  
  
  # b4_pure_args
@@@ -126,15 -126,7 +126,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])])
  
  
  
@@@ -162,7 -154,7 +162,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)])
  
  
  ## -------------- ##
  # b4_shared_declarations
  # ----------------------
  # Declaration that might either go into the header (if --defines)
 -# or open coded in the parser body.
 -m4_define([b4_shared_declarations],
 +# or open coded in the parser body.  glr.cc has its own definition.
 +m4_if(b4_skeleton, ["glr.c"],
 +[m4_define([b4_shared_declarations],
  [b4_declare_yydebug[
  ]b4_percent_code_get([[requires]])[
 -]b4_token_enums(b4_tokens)[
 +]b4_token_enums[
  ]b4_declare_yylstype[
 -]b4_c_ansi_function_decl(b4_prefix[parse], [int], b4_parse_param)[
 +]b4_function_declare(b4_prefix[parse], [int], b4_parse_param)[
  ]b4_percent_code_get([[provides]])[]dnl
  ])
 -
 +])
  
  ## -------------- ##
  ## Output files.  ##
@@@ -215,7 -206,7 +215,7 @@@ b4_percent_code_get([[top]])
  #define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
  #define yylloc  ]b4_prefix[lloc]])])[
  
 -/* Copy the first part of user declarations.  */
 +/* First part of user declarations.  */
  ]b4_user_pre_prologue[
  
  ]b4_null_define[
  # 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
  
  /* 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.
-    Since the default value is undefined, this behavior is
-    technically correct.  */
- static YYSTYPE yyval_default;
+    right-hand sides.  Unlike the standard yacc.c template, here we set
+    the default value of $$ to a zeroed-out value.  Since the default
+    value is undefined, this behavior is technically correct.  */
+ static YYSTYPE yyval_default;]b4_locations_if([[
+ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
  
  /* Copy the second part of user declarations.  */
  ]b4_user_post_prologue
@@@ -259,12 -250,22 +259,12 @@@ b4_percent_code_get[]dn
  #endif
  
  /* Suppress unused-variable warnings by "using" E.  */
 -#if ! defined lint || defined __GNUC__
 +#ifdef __GNUC__
  # define YYUSE(E) ((void) (E))
  #else
  # define YYUSE(E) /* empty */
  #endif
  
 -/* Identity function, used to suppress warnings about constant conditions.  */
 -#ifndef lint
 -# define YYID(N) (N)
 -#else
 -]b4_c_function_def([YYID], [static int], [[int i], [i]])[
 -{
 -  return i;
 -}
 -#endif
 -
  #ifndef YYFREE
  # define YYFREE free
  #endif
@@@ -349,6 -350,19 +349,6 @@@ static const ]b4_int_type_for([b4_trans
  };
  
  #if ]b4_api_PREFIX[DEBUG
 -/* 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[] =
  {
@@@ -365,10 -379,17 +365,10 @@@ 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[] =
@@@ -382,11 -403,41 +382,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[] =
 -{
 -  ]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[] =
 +/* YYIMMEDIATE[RULE-NUM] -- True iff rule #RULE-NUM is not to be deferred, as
 +   in the case of predicates.  */
 +static const yybool yyimmediate[] =
  {
 -  ]b4_table[
 +  ]b4_immediate[
  };
  
  /* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
@@@ -408,35 -459,29 +408,17 @@@ 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[
 -};
 -
  /* Error token number */
  #define YYTERROR 1
  
  ]b4_locations_if([[
- #ifndef YYLLOC_DEFAULT
  ]b4_yylloc_default_define[
  # define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
- /* YY_LOCATION_PRINT -- Print the location on the stream.
-    This macro was not mandated originally: define only if we know
-    we won't break user code: when these are the locations we know.  */
- # define YY_LOCATION_PRINT(File, Loc)                   \
-     fprintf (File, "%d.%d-%d.%d",                       \
-              (Loc).first_line, (Loc).first_column,      \
-              (Loc).last_line,  (Loc).last_column)
- #endif
- ]],[
- #ifndef YYLLOC_DEFAULT
- # define YYLLOC_DEFAULT(Current, Rhs, N) ((void) 0)
- #endif
- ])[
- #ifndef YY_LOCATION_PRINT
- # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
- #endif
+ ]])[
+ ]b4_yy_location_print_define[
  
  /* YYLEX -- calling `yylex' with the right arguments.  */
 -#define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[
 +#define YYLEX ]b4_function_call([yylex], [int], b4_lex_param)[
  
  ]b4_pure_if(
  [
@@@ -464,12 -509,9 +446,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 (0)
  
  #if ]b4_api_PREFIX[DEBUG
  
  # endif
  
  # define YYDPRINTF(Args)                        \
 -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))
 +  do {                                          \
 +    if (yydebug)                                \
 +      YYFPRINTF Args;                           \
 +  } while (0)
 +
 +]b4_yy_symbol_print_define[
 +
 +# 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 (0)
  
  /* Nonzero means print parse trace.  It is left uninitialized so that
     multiple parsers can coexist.  */
@@@ -530,7 -572,13 +512,7 @@@ int yydebug
  #define YYHEADROOM 2
  
  #ifndef YYSTACKEXPANDABLE
 -# if (! defined __cplusplus \
 -      || (]b4_locations_if([[defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL \
 -          && ]])[defined ]b4_api_PREFIX[STYPE_IS_TRIVIAL && ]b4_api_PREFIX[STYPE_IS_TRIVIAL))
  #  define YYSTACKEXPANDABLE 1
 -# else
 -#  define YYSTACKEXPANDABLE 0
 -# endif
  #endif
  
  #if YYSTACKEXPANDABLE
    do {                                                  \
      if (Yystack->yyspaceLeft < YYHEADROOM)              \
        yyexpandGLRStack (Yystack);                       \
 -  } while (YYID (0))
 +  } while (0)
  #else
  # define YY_RESERVE_GLRSTACK(Yystack)                   \
    do {                                                  \
      if (Yystack->yyspaceLeft < YYHEADROOM)              \
        yyMemoryExhausted (Yystack);                      \
 -  } while (YYID (0))
 +  } while (0)
  #endif
  
  
@@@ -627,7 -675,7 +609,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;
@@@ -648,7 -696,7 +630,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
@@@ -760,16 -808,9 +742,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 ]b4_api_PREFIX[DEBUG
 +      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;
      }
@@@ -796,7 -837,7 +778,7 @@@ yyfill (yyGLRStackItem *yyvsp, int *yyl
   *  value ($$), and yylocp points to place for location information
   *  (@@$).  Returns yyok for normal return, yyaccept for YYACCEPT,
   *  yyerr for YYERROR, yyabort for YYABORT.  */
 -/*ARGSUSED*/ static YYRESULTTAG
 +static YYRESULTTAG
  yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
                yyGLRStack* yystackp,
                YYSTYPE* yyvalp]b4_locuser_formals[)
    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
  # undef yyclearin
  # undef YYRECOVERING
  }
 -\f
  
 -/*ARGSUSED*/ static void
 +
 +static void
  yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
  {
    YYUSE (yy0);
  
    switch (yyn)
      {
 -      ]b4_mergers[
 +]b4_mergers[
        default: break;
      }
  }
  
                                /* Bison grammar-table manipulation.  */
  
 -]b4_yydestruct_generate([b4_c_ansi_function_def])[
 +]b4_yydestruct_define[
  
  /** Number of symbols composing the right hand side of rule #RULE.  */
  static inline int
@@@ -907,7 -948,7 +889,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
@@@ -990,10 -1032,9 +972,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)
  {
@@@ -1059,8 -1100,8 +1041,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
@@@ -1152,9 -1193,9 +1134,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)
@@@ -1221,9 -1262,8 +1203,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 !]b4_api_PREFIX[DEBUG
 +# define YY_REDUCE_PRINT(Args)
 +#else
 +# define YY_REDUCE_PRINT(Args)          \
 +do {                                    \
 +  if (yydebug)                          \
 +    yy_reduce_print Args;               \
 +} while (0)
 +
 +/*----------------------------------------------------------------------.
 +| Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
 +`----------------------------------------------------------------------*/
 +
 +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 !]b4_api_PREFIX[DEBUG
 -# 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
@@@ -1369,18 -1412,11 +1351,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)
@@@ -1475,7 -1510,7 +1457,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
@@@ -1497,8 -1532,8 +1479,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)
  {
          {
            yySemanticOption** yyz0p = &yys0->yysemantics.yyfirstVal;
            yySemanticOption* yyz1 = yys1->yysemantics.yyfirstVal;
 -          while (YYID (yytrue))
 +          while (yytrue)
              {
                if (yyz1 == *yyz0p || yyz1 == YY_NULL)
                  break;
@@@ -1577,11 -1612,11 +1559,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,
@@@ -1673,11 -1707,11 +1655,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
  }
  #endif
  
 -/*ARGSUSED*/ static YYRESULTTAG
 +static YYRESULTTAG
  yyreportAmbiguity (yySemanticOption* yyx0,
                     yySemanticOption* yyx1]b4_pure_formals[)
  {
    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[)
@@@ -1905,6 -1938,10 +1887,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;
  }
  
 -/*ARGSUSED*/ static void
 +static void
  yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
  {
    if (yystackp->yyerrState != 0)
  /* Recover from a syntax error on *YYSTACKP, assuming that *YYSTACKP->YYTOKENP,
     yylval, and yylloc are the syntactic category, semantic value, and location
     of the lookahead.  */
 -/*ARGSUSED*/ static void
 +static void
  yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
  {
    size_t yyk;
    if (yystackp->yyerrState == 3)
      /* We just shifted the error token and (perhaps) took some
         reductions.  Skip tokens until we can proceed.  */
 -    while (YYID (yytrue))
 +    while (yytrue)
        {
          yySymbol yytoken;
          if (yychar == YYEOF)
      default:                                                                 \
        goto yybuglab;                                                         \
      }                                                                        \
 -  } while (YYID (0))
 -
 +  } while (0)
  
  /*----------.
  | yyparse.  |
  `----------*/
  
 -]b4_c_ansi_function_def([yyparse], [int], b4_parse_param)[
 +]b4_function_define([yyparse], [int], b4_parse_param)[
  {
    int yyresult;
    yyGLRStack yystack;
    YYDPRINTF ((stderr, "Starting parse\n"));
  
    yychar = YYEMPTY;
-   yylval = yyval_default;
- ]b4_locations_if([
- #if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
-   yylloc.first_line   = yylloc.last_line   = ]b4_location_initial_line[;
-   yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
- #endif
- ])
- m4_ifdef([b4_initial_action], [
+   yylval = yyval_default;]b4_locations_if([
+   yylloc = yyloc_default;])[
+ ]m4_ifdef([b4_initial_action], [
  b4_dollar_pushdef([yylval], [], [yylloc])dnl
 -/* User initialization code.  */
 -b4_user_initial_action
 +  /* User initialization code.  */
 +  b4_user_initial_action
  b4_dollar_popdef])[]dnl
  [
    if (! yyinitGLRStack (yystackp, YYINITDEPTH))
    yyglrShift (&yystack, 0, 0, 0, &yylval]b4_locations_if([, &yylloc])[);
    yyposn = 0;
  
 -  while (YYID (yytrue))
 +  while (yytrue)
      {
        /* For efficiency, we have two loops, the first of which is
           specialized to deterministic operation (single stack, no
           potential ambiguity).  */
        /* Standard mode */
 -      while (YYID (yytrue))
 +      while (yytrue)
          {
            yyRuleNum yyrule;
            int yyaction;
              }
          }
  
 -      while (YYID (yytrue))
 +      while (yytrue)
          {
            yySymbol yytoken_to_shift;
            size_t yys;
        yyfreeGLRStack (&yystack);
      }
  
 -  /* Make sure YYID is used.  */
 -  return YYID (yyresult);
 +  return yyresult;
  }
  
  /* DEBUGGING ONLY */
diff --combined data/glr.cc
index 88dad042618a31878c6574662cd7e5c3121c61dd,0e53d61915833343458c5c49022fb35a397c0e3a..8841f10be51d31b646c7859cfb1b26289b6afae9
@@@ -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])
 +# We require a pure interface.
  m4_define([b4_pure_flag],      [1])
  
 -# The header is mandatory.
 -b4_defines_if([],
 -              [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
 -
  m4_include(b4_pkgdatadir/[c++.m4])
 -b4_percent_define_ifdef([[api.location.type]], [],
 -                        [m4_include(b4_pkgdatadir/[location.cc])])
 +b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                [m4_include(b4_pkgdatadir/[location.cc])])])
  
  m4_define([b4_parser_class_name],
            [b4_percent_define_get([[parser_class_name]])])
  m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
  
  
 -# b4_yy_symbol_print_generate
 -# ---------------------------
 +# b4_yy_symbol_print_define
 +# -------------------------
  # Bypass the default implementation to generate the "yy_symbol_print"
  # and "yy_symbol_value_print" functions.
 -m4_define([b4_yy_symbol_print_generate],
 +m4_define([b4_yy_symbol_print_define],
  [[
  /*--------------------.
  | Print this symbol.  |
  `--------------------*/
  
 -]b4_c_ansi_function_def([yy_symbol_print],
 +]b4_function_define([yy_symbol_print],
      [static void],
 -    [[FILE *],               []],
 -    [[int yytype],           [yytype]],
 +    [[FILE *],      []],
 +    [[int yytype],  [yytype]],
      [[const ]b4_namespace_ref::b4_parser_class_name[::semantic_type *yyvaluep],
 -                             [yyvaluep]],
 +                    [yyvaluep]][]dnl
 +b4_locations_if([,
      [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
 -                             [yylocationp]],
 +                    [yylocationp]]]),
      b4_parse_param)[
  {
  ]b4_parse_param_use[]dnl
  [  yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
  }
- ]])
+ ]])[
  
+ # Hijack the initial action to initialize the locations.
+ ]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
+ [m4_define([b4_initial_action],
+ [yylloc.initialize ();]m4_ifdef([b4_initial_action], [
+ m4_defn([b4_initial_action])]))])])[
  
  # Hijack the post prologue to insert early definition of YYLLOC_DEFAULT
  # and declaration of yyerror.
- m4_append([b4_post_prologue],
]m4_append([b4_post_prologue],
  [b4_syncline([@oline@], [@ofile@])[
  ]b4_yylloc_default_define[
  #define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
 -]b4_c_ansi_function_decl([yyerror],
 -    [static void],
 +]b4_function_declare([yyerror],
 +    [static void],b4_locations_if([
      [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
 -                        [yylocationp]],
 +                        [yylocationp]],])
      b4_parse_param,
      [[const char* msg], [msg]])])
  
@@@ -106,26 -117,27 +111,26 @@@ m4_append([b4_epilogue]
  | Report an error.  |
  `------------------*/
  
 -]b4_c_ansi_function_def([yyerror],
 -    [static void],
 +]b4_function_define([yyerror],
 +    [static void],b4_locations_if([
      [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
 -                        [yylocationp]],
 +                        [yylocationp]],])
      b4_parse_param,
      [[const char* msg], [msg]])[
  {
  ]b4_parse_param_use[]dnl
 -[  yyparser.error (*yylocationp, msg);
 +[  yyparser.error (]b4_locations_if([[*yylocationp, ]])[msg);
  }
  
  
  ]b4_namespace_open[
 -]dnl In this section, the parse param are the original parse_params.
 +]dnl In this section, the parse params are the original parse_params.
  m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
  [  /// Build a parser object.
    ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
      :])[
  #if ]b4_api_PREFIX[DEBUG
 -    ]m4_ifset([b4_parse_param], [  ], [ :])[
 -      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[
    {
    }
  
    inline void
    ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype,
 -                           const semantic_type* yyvaluep,
 -                           const location_type* yylocationp)
 -  {
 -    YYUSE (yylocationp);
 +                           const semantic_type* yyvaluep]b4_locations_if([[,
 +                           const location_type* yylocationp]])[)
 +  {]b4_locations_if([[
 +    YYUSE (yylocationp);]])[
      YYUSE (yyvaluep);
      std::ostream& yyoutput = debug_stream ();
      std::ostream& yyo = yyoutput;
      YYUSE (yyo);
      switch (yytype)
        {
 -  ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
 +]b4_symbol_foreach([b4_symbol_printer])dnl
  [        default:
            break;
        }
  
    void
    ]b4_parser_class_name[::yy_symbol_print_ (int yytype,
 -                           const semantic_type* yyvaluep,
 -                           const location_type* yylocationp)
 +                           const semantic_type* yyvaluep]b4_locations_if([[,
 +                           const location_type* yylocationp]])[)
    {
      *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
 -               << ' ' << yytname[yytype] << " ("
 -               << *yylocationp << ": ";
 -    yy_symbol_value_print_ (yytype, yyvaluep, yylocationp);
 +               << ' ' << yytname[yytype] << " ("]b4_locations_if([[
 +               << *yylocationp << ": "]])[;
 +    yy_symbol_value_print_ (yytype, yyvaluep]b4_locations_if([[, yylocationp]])[);
      *yycdebug_ << ')';
    }
  
  
  #endif
  ]m4_popdef([b4_parse_param])dnl
 -b4_namespace_close])
 -
 -
 -# Let glr.c believe that the user arguments include the parser itself.
 -m4_ifset([b4_parse_param],
 -[m4_pushdef([b4_parse_param],
 -            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],]
 -m4_defn([b4_parse_param]))],
 -[m4_pushdef([b4_parse_param],
 -            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]])
 +b4_namespace_close
  ])
 -m4_include(b4_pkgdatadir/[glr.c])
 -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])[
  
 -/* C++ GLR parser skeleton written by Akim Demaille.  */
 -
 -]b4_cpp_guard_open([b4_spec_defines_file])[
 -
 -]b4_percent_code_get([[requires]])[
 +# b4_shared_declarations
 +# ----------------------
 +# Declaration that might either go into the header (if --defines)
 +# or open coded in the parser body.
 +m4_define([b4_shared_declarations],
 +[dnl In this section, the parse params are the original parse_params.
 +m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
 +b4_percent_code_get([[requires]])[
  
 -# include <string>
 -# include <iostream>
 -]b4_percent_define_ifdef([[api.location.type]], [],
 -                         [[# include "location.hh"]])[
 +#include <stdexcept>
 +#include <string>
 +#include <iostream>]b4_defines_if([
 +b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                         [[#include "location.hh"]])])])[
  
  ]b4_YYDEBUG_define[
  
  ]b4_namespace_open[
 +]b4_defines_if([],
 +[b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                          [b4_position_define
 +b4_location_define])])])[
 +
    /// A Bison parser.
    class ]b4_parser_class_name[
    {
    public:
 -    /// Symbol semantic values.
 -# ifndef ]b4_api_PREFIX[STYPE
 -]m4_ifdef([b4_stype],
 -[    union semantic_type
 -    {
 -b4_user_stype
 -    };],
 -[m4_if(b4_tag_seen_flag, 0,
 -[[    typedef int semantic_type;]],
 -[[    typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[
 -# else
 -    typedef ]b4_api_PREFIX[STYPE semantic_type;
 -# endif
 -    /// Symbol locations.
 -    typedef ]b4_percent_define_get([[api.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.
 +    /// 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);
 -  private:
 +    virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg);
  
  # if ]b4_api_PREFIX[DEBUG
    public:
      /// \brief Report a symbol value on the debug stream.
      /// \param yytype       The token type.
 -    /// \param yyvaluep     Its semantic value.
 -    /// \param yylocationp  Its location.
 +    /// \param yyvaluep     Its semantic value.]b4_locations_if([[
 +    /// \param yylocationp  Its location.]])[
      virtual void yy_symbol_value_print_ (int yytype,
 -                                         const semantic_type* yyvaluep,
 -                                         const location_type* yylocationp);
 +                                         const semantic_type* yyvaluep]b4_locations_if([[,
 +                                         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.
 +    /// \param yyvaluep     Its semantic value.]b4_locations_if([[
 +    /// \param yylocationp  Its location.]])[
      virtual void yy_symbol_print_ (int yytype,
 -                                   const semantic_type* yyvaluep,
 -                                   const location_type* yylocationp);
 +                                   const semantic_type* yyvaluep]b4_locations_if([[,
 +                                   const location_type* yylocationp]])[);
    private:
      /* Debugging.  */
      std::ostream* yycdebug_;
 -# endif
 +#endif
  
  ]b4_parse_param_vars[
    };
  
  ]dnl Redirections for glr.c.
  b4_percent_define_flag_if([[global_tokens_and_yystype]],
 -[b4_token_defines(b4_tokens)])
 +[b4_token_defines])
  [
  #ifndef ]b4_api_PREFIX[STYPE
  # define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type
  
  ]b4_namespace_close[
  ]b4_percent_code_get([[provides]])[
 +]m4_popdef([b4_parse_param])dnl
 +])
 +
 +b4_defines_if(
 +[m4_changecom()dnl
 +m4_divert_push(0)dnl
 +@output(b4_spec_defines_file@)@
 +b4_copyright([Skeleton interface for Bison GLR parsers in C++],
 +             [2002-2012])[
 +
 +/* C++ GLR parser skeleton written by Akim Demaille.  */
 +
 +]b4_cpp_guard_open([b4_spec_defines_file])[
 +]b4_shared_declarations[
  ]b4_cpp_guard_close([b4_spec_defines_file])[
  ]m4_divert_pop(0)
 +m4_changecom[#])])
 +
 +# Let glr.c (and b4_shared_declarations) believe that the user
 +# arguments include the parser itself.
 +m4_ifset([b4_parse_param],
 +[m4_pushdef([b4_parse_param],
 +            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],]
 +m4_defn([b4_parse_param]))],
 +[m4_pushdef([b4_parse_param],
 +            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]])
 +])
 +m4_include(b4_pkgdatadir/[glr.c])
 +m4_popdef([b4_parse_param])
diff --combined data/lalr1.cc
index 7e5baeb026b37c06005fee239d4860cd577a1c33,e45b2e1f860cf48ff9c66be677b5f20001008240..34eef13801a661d2db596f4d0da6612f7521d1fd
  
  m4_include(b4_pkgdatadir/[c++.m4])
  
 -m4_define([b4_parser_class_name],
 -          [b4_percent_define_get([[parser_class_name]])])
  
 -# The header is mandatory.
 -b4_defines_if([],
 -              [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
 +# 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_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_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
 +b4_dollar_pushdef([yysym.value],
 +                   b4_symbol_if([$1], [has_type],
 +                                [m4_dquote(b4_symbol([$1], [type]))]),
 +                   [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;
  
 -b4_percent_define_ifdef([[api.location.type]], [],
 -  [# Backward compatibility.
 -  m4_define([b4_location_constructors])
 -  m4_include(b4_pkgdatadir/[location.cc])])
 -m4_include(b4_pkgdatadir/[stack.hh])
 +m4_popdef([b4_symbol_value])[]dnl
 +b4_dollar_popdef[]dnl
 +])])
  
 -# 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])
 -[
 -/**
 - ** \file ]b4_spec_defines_file[
 - ** Define the ]b4_namespace_ref[::parser class.
 - */
 -
 -/* C++ LALR(1) parser skeleton written by Akim Demaille.  */
  
 -]b4_cpp_guard_open([b4_spec_defines_file])[
 +m4_pushdef([b4_copyright_years],
 +           [2002-2012])
  
 -]b4_percent_code_get([[requires]])[
 +m4_define([b4_parser_class_name],
 +          [b4_percent_define_get([[parser_class_name]])])
  
 -#include <string>
 -#include <iostream>
 -#include "stack.hh"
 -]b4_percent_define_ifdef([[api.location.type]], [],
 -                         [[#include "location.hh"]])[
 +b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +  [# Backward compatibility.
 +   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])])
 +
 +# b4_shared_declarations
 +# ----------------------
 +# Declaration that might either go into the header (if --defines)
 +# or open coded in the parser body.
 +m4_define([b4_shared_declarations],
 +[b4_percent_code_get([[requires]])[
 +]b4_parse_assert_if([# include <cassert>])[
 +# include <deque>
 +# include <iostream>
 +# include <stdexcept>
 +# include <string>]b4_defines_if([[
 +# include "stack.hh"
 +]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                          [[# include "location.hh"]])])])[
  
  ]b4_YYDEBUG_define[
  
  ]b4_namespace_open[
  
 +]b4_defines_if([],
 +[b4_stack_define
 +b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
 +                                         [b4_position_define
 +b4_location_define])])])[
 +
 +]b4_variant_if([b4_variant_define])[
 +
    /// A Bison parser.
    class ]b4_parser_class_name[
    {
    public:
 -    /// Symbol semantic values.
 -#ifndef ]b4_api_PREFIX[STYPE
 -]m4_ifdef([b4_stype],
 -[    union semantic_type
 -    {
 -b4_user_stype
 -    };],
 -[m4_if(b4_tag_seen_flag, 0,
 -[[    typedef int semantic_type;]],
 -[[    typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[
 -#else
 -    typedef ]b4_api_PREFIX[STYPE semantic_type;
 -#endif
 -    /// Symbol locations.
 -    typedef ]b4_percent_define_get([[api.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 ]b4_api_PREFIX[DEBUG
 -    /// \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_;
  
 -    static const ]b4_int_type_for([b4_check])[ yycheck_[];
 -
 -    /// 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);])[
      /// For a symbol, its name in clear.
      static const char* const yytname_[];
  ]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
 -    /// 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 // ]b4_api_PREFIX[DEBUG
  
      /// Convert a scanner token number \a t to a symbol number.
 -    token_number_type yytranslate_ (int t);
 +    static inline token_number_type yytranslate_ (]b4_token_ctor_if([token_type], [int])[ t);
 +
 +#if ]b4_api_PREFIX[DEBUG
 +    /// \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.
 -    ///                     If null, do not display the symbol, just free it.
 -    /// \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_join([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_token_ctor_if([b4_yytranslate_define
 +b4_public_types_define])[
  ]b4_namespace_close[
  
  ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
 -[b4_token_defines(b4_tokens)
 +[b4_token_defines
  
  #ifndef ]b4_api_PREFIX[STYPE
   /* Redirection for backward compatibility.  */
  #endif
  ])[
  ]b4_percent_code_get([[provides]])[
 +]])
 +
 +# We do want M4 expansion after # for CPP macros.
 +m4_changecom()
 +b4_defines_if(
 +[m4_divert_push(0)dnl
 +@output(b4_spec_defines_file@)@
 +b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
 +[
 +/**
 + ** \file ]b4_spec_defines_file[
 + ** Define the ]b4_namespace_ref[::parser class.
 + */
 +
 +/* C++ LALR(1) parser skeleton written by Akim Demaille.  */
 +
 +]b4_cpp_guard_open([b4_spec_defines_file])[
 +]b4_shared_declarations[
  ]b4_cpp_guard_close([b4_spec_defines_file])
 -])dnl
 +m4_divert_pop(0)dnl
 +])
 +
 +
 +m4_divert_push(0)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], [],
  [
  // Take the name prefix into account.
  #define yylex   b4_prefix[]lex])[
  
 -/* First part of user declarations.  */
 +// First part of user declarations.
  ]b4_user_pre_prologue[
  
 -]b4_defines_if([[
 -#include "@basename(]b4_spec_defines_file[@)"]])[
 +]b4_null_define[
 +
 +]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]],
 +               [b4_shared_declarations])[
  
  /* User implementation prologue.  */
  ]b4_user_post_prologue[
  ]b4_percent_code_get[
  
 -]b4_null_define[
 -
  #ifndef YY_
  # if defined YYENABLE_NLS && YYENABLE_NLS
  #  if ENABLE_NLS
  # endif
  #endif
  
 -#define YYRHSLOC(Rhs, K) ((Rhs)[K])
 -]b4_yylloc_default_define[
 +]b4_locations_if([dnl
 +[#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
 +]b4_yylloc_default_define])[
  
  /* 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 /* !]b4_api_PREFIX[DEBUG */
  
  # define YYCDEBUG if (false) std::cerr
 -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) YYUSE(Type)
 -# define YY_REDUCE_PRINT(Rule)        static_cast<void>(0)
 -# define YY_STACK_PRINT()             static_cast<void>(0)
 +# 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 /* !]b4_api_PREFIX[DEBUG */
  
 -#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 ]b4_api_PREFIX[DEBUG
 -  /*--------------------------------.
 -  | 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_token_ctor_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_join(
 +                 [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 ]b4_api_PREFIX[DEBUG
 +  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_join(
 +                    [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_join(
 +                      [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);
 -
 -    if (yymsg)
 -      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_join(
 +                       [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 ]b4_api_PREFIX[DEBUG
    {
      yydebug_ = l;
    }
 -#endif
 +#endif // ]b4_api_PREFIX[DEBUG
 +
 +  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.  */
+     // State.
      int yyn;
      int yylen = 0;
 -    int yystate = 0;
  
-     /* Error handling.  */
+     // Error handling.
      int yynerrs_ = 0;
      int yyerrstatus_ = 0;
  
 -    /// Semantic value of the lookahead.
 -    static semantic_type yyval_default;
 -    semantic_type yylval = yyval_default;
 -    /// 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;
  
      // FIXME: This shoud be completely indented.  It is not yet to
      YYCDEBUG << "Starting parse" << std::endl;
  
  ]m4_ifdef([b4_initial_action], [
 -b4_dollar_pushdef([yylval], [], [yylloc])dnl
 -/* User initialization code.  */
 -b4_user_initial_action
 +b4_dollar_pushdef([yyla.value], [], [yyla.location])dnl
 +    /* User initialization code.  */
 +    b4_user_initial_action
  b4_dollar_popdef])[]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_)
 +    if (yyempty)
        {
          YYCDEBUG << "Reading a token: ";
 -        yychar = ]b4_c_function_call([yylex], [int],
 -                                     [b4_api_PREFIX[STYPE*], [&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
 -      {
 -      yytoken = yytranslate_ (yychar);
 -      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
 +        try
 +          {
 +]b4_token_ctor_if(
 +[            yyla = b4_function_call([yylex], [symbol_type],
 +                                     m4_ifdef([b4_lex_param], b4_lex_param));],
 +[            yyla.type = yytranslate_ (b4_function_call([yylex], [int],
 +                                     [b4_api_PREFIX[STYPE*], [&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
        {
 -        ]b4_user_actions[
 -      default:
 -        break;
 +        switch (yyn)
 +          {
 +]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_join(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
 +
 +        /* Return failure if at end of input.  */
 +        if (yyla.type == yyeof_)
 +          YYABORT;
 +        else if (!yyempty)
            {
 -            yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc);
 -            yychar = yyempty_;
 +            yy_destroy_ ("Error: discarding", yyla);
 +            yyempty = true;
            }
        }
  
         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 (1 < yystate_stack_.height ())
 +    while (1 < yystack_.size ())
        {
 -        yydestruct_ ("Cleanup: popping",
 -                     yystos_[yystate_stack_[0]],
 -                     &yysemantic_stack_[0],
 -                     &yylocation_stack_[0]);
 +        yy_destroy_ ("Cleanup: popping", yystack_[0]);
          yypop_ ();
        }
  
      return yyresult;
 -    }
 +  }
      catch (...)
        {
          YYCDEBUG << "Exception caught: cleaning lookahead and stack"
                   << std::endl;
          // Do not try to display the values of the reclaimed symbols,
          // as their printer might throw an exception.
 -        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_ (YY_NULL, yytoken, &yylval, &yylloc);
 -          }
 +        if (!yyempty)
 +          yy_destroy_ (YY_NULL, yyla);
  
 -        while (1 < yystate_stack_.height ())
 +        while (1 < yystack_.size ())
            {
 -            yydestruct_ (YY_NULL,
 -                         yystos_[yystate_stack_[0]],
 -                         &yysemantic_stack_[0],
 -                         &yylocation_stack_[0]);
 +            yy_destroy_ (YY_NULL, yystack_[0]);
              yypop_ ();
            }
          throw;
        }
    }
  
 +  void
 +  ]b4_parser_class_name[::error (const syntax_error& yyexc)
 +  {
 +    error (]b4_join(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 ]b4_api_PREFIX[DEBUG
 -  /* 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[
  
  ]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
    /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    const char*
    const ]b4_parser_class_name[::yytname_[] =
    {
 -    ]b4_tname[
 +  ]b4_tname[
    };
  
  ]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
 -  /* 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 // ]b4_api_PREFIX[DEBUG
  
 -  /* 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_token_ctor_if([], [b4_yytranslate_define])[
  ]b4_namespace_close[
  ]b4_epilogue[]dnl
  m4_divert_pop(0)
 +m4_popdef([b4_copyright_years])dnl
diff --combined data/location.cc
index 14688ca4e32f57034507ae8a7fe82084b23c97a7,49f5f349534d67d3d64c178e4e94728b7a50d5df..5879ea374e581bf331b67d30a67baa3c589cb5b1
@@@ -1,6 -1,6 +1,6 @@@
  # C++ skeleton for Bison
  
 -# Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc.
 +# Copyright (C) 2002-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
  # You should have received a copy of the GNU General Public License
  # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
 -# We do want M4 expansion after # for CPP macros.
 -m4_changecom()
 -m4_divert_push(0)dnl
 -@output(b4_dir_prefix[]position.hh@)@
 -b4_copyright([Positions for Bison parsers in C++],
 -             [2002-2007, 2009-2012])[
 -
 -/**
 - ** \file ]b4_dir_prefix[position.hh
 - ** Define the ]b4_namespace_ref[::position class.
 - */
 -
 -]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
 -
 -# include <algorithm> // std::max
 -# include <iostream>
 -# include <string>
 -
 -]b4_null_define[
 +m4_pushdef([b4_copyright_years],
 +           [2002-2012])
  
 -]b4_namespace_open[
 -  /// Abstract a position.
 +# b4_position_define
 +# ------------------
 +# Define class position.
 +m4_define([b4_position_define],
 +[[  /// Abstract a position.
    class position
    {
    public:
@@@ -73,7 -87,7 +73,7 @@@
    };
  
    /// Add and assign a position.
-   inline const position&
+   inline position&
    operator+= (position& res, const int width)
    {
      res.columns (width);
    }
  
    /// Add and assign a position.
-   inline const position&
+   inline position&
    operator-= (position& res, const int width)
    {
      return res += -width;
        ostr << *pos.filename << ':';
      return ostr << pos.line << '.' << pos.column;
    }
 +]])
  
 -]b4_namespace_close[
 -]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
 -@output(b4_dir_prefix[]location.hh@)@
 -b4_copyright([Locations for Bison parsers in C++],
 -             [2002-2007, 2009-2012])[
 -
 -/**
 - ** \file ]b4_dir_prefix[location.hh
 - ** Define the ]b4_namespace_ref[::location class.
 - */
 -
 -]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
 -
 -# include "position.hh"
 -
 -]b4_namespace_open[
  
 -  /// Abstract a location.
 +# b4_location_define
 +# ------------------
 +m4_define([b4_location_define],
 +[[  /// Abstract a location.
    class location
    {
    public:
      position last = loc.end - 1;
      ostr << loc.begin;
      if (last.filename
 -      && (!loc.begin.filename
 -          || *loc.begin.filename != *last.filename))
 +        && (!loc.begin.filename
 +            || *loc.begin.filename != *last.filename))
        ostr << '-' << last;
      else if (loc.begin.line != last.line)
        ostr << '-' << last.line  << '.' << last.column;
        ostr << '-' << last.column;
      return ostr;
    }
 +]])
 +
  
 +# We do want M4 expansion after # for CPP macros.
 +m4_changecom()
 +b4_defines_if([
 +m4_divert_push(0)dnl
 +@output(b4_dir_prefix[]position.hh@)@
 +b4_copyright([Positions for Bison parsers in C++])[
 +
 +/**
 + ** \file ]b4_dir_prefix[position.hh
 + ** Define the ]b4_namespace_ref[::position class.
 + */
 +
 +]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
 +
 +# include <algorithm> // std::max
 +# include <iostream>
 +# include <string>
 +
 +]b4_null_define[
 +
 +]b4_namespace_open[
 +]b4_position_define[
  ]b4_namespace_close[
 +]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
 +@output(b4_dir_prefix[]location.hh@)@
 +b4_copyright([Locations for Bison parsers in C++])[
 +
 +/**
 + ** \file ]b4_dir_prefix[location.hh
 + ** Define the ]b4_namespace_ref[::location class.
 + */
 +
 +]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
  
 +# include "position.hh"
 +
 +]b4_namespace_open[
 +]b4_location_define[
 +]b4_namespace_close[
  ]b4_cpp_guard_close([b4_dir_prefix[]location.hh])
  m4_divert_pop(0)
 +])# b4_defines_if
 +m4_popdef([b4_copyright_years])dnl
  m4_changecom([#])
diff --combined data/yacc.c
index 9ff20322700230a903b0ec73d9ca74614f66f055,2e0ecc258f37f41c1013e34c1cdd31b2f3d03e2b..ebc41276bc2b30fea6bcb61131440de82840905f
@@@ -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
@@@ -85,7 -83,7 +85,7 @@@
  # Arguments passed to yyerror: user args plus yylloc.
  m4_define([b4_yyerror_args],
  [b4_yacc_pure_if([b4_locations_if([&yylloc, ])])dnl
 -m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
 +m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
  
  
  # b4_lex_param
@@@ -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])@})])
  
  
  ## -------------- ##
@@@ -173,10 -171,11 +173,11 @@@ m4_define([b4_declare_scanner_communica
  int yychar;
  
  ]b4_pure_if([[
- #if defined __GNUC__ && (4 < __GNUC__ + (6 <= __GNUC_MINOR__))
+ #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
  /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
  # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
      _Pragma ("GCC diagnostic push") \
+     _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
      _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
  # define YY_IGNORE_MAYBE_UNINITIALIZED_END \
      _Pragma ("GCC diagnostic pop")
  /* Default value used for initialization, for pacifying older GCCs
     or non-GCC compilers.  */
  static YYSTYPE yyval_default;
- # define YYLVAL_INITIALIZE() (yylval = yyval_default)
+ # define YY_INITIAL_VALUE(Value) = Value
  #endif]])[
- #ifndef YYLVAL_INITIALIZE
- # define YYLVAL_INITIALIZE()
- #endif
  #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
  # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
  # define YY_IGNORE_MAYBE_UNINITIALIZED_END
  #endif
+ #ifndef YY_INITIAL_VALUE
+ # define YY_INITIAL_VALUE(Value) /* Nothing. */
+ #endif
  
  /* The semantic value of the lookahead symbol.  */
- YYSTYPE yylval;]b4_locations_if([[
+ YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
  
  /* Location data for the lookahead symbol.  */
- YYLTYPE yylloc;]])b4_pure_if([], [[
+ YYLTYPE yylloc][]b4_yyloc_default[;
+ ]])b4_pure_if([], [[
  
  /* Number of syntax errors so far.  */
  int yynerrs;]])])
@@@ -261,19 -261,19 +263,19 @@@ enum { YYPUSH_MORE = 4 }
  
  typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
  
 -]b4_pull_if([b4_c_function_decl([b4_prefix[parse]], [[int]], b4_parse_param)
 -])b4_c_function_decl([b4_prefix[push_parse]], [[int]],
 +]b4_pull_if([b4_function_declare([b4_prefix[parse]], [[int]], b4_parse_param)
 +])b4_function_declare([b4_prefix[push_parse]], [[int]],
    [[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([,
    [[[int pushed_char]], [[pushed_char]]],
    [[b4_api_PREFIX[STYPE const *pushed_val]], [[pushed_val]]]b4_locations_if([,
-   [[b4_api_PREFIX[LTYPE const *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [,
+   [[b4_api_PREFIX[LTYPE *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [,
    b4_parse_param]))
 -b4_pull_if([b4_c_function_decl([b4_prefix[pull_parse]], [[int]],
 +b4_pull_if([b4_function_declare([b4_prefix[pull_parse]], [[int]],
    [[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [,
    b4_parse_param]))])
 -b4_c_function_decl([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
 +b4_function_declare([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
                      [[[void]], []])
 -b4_c_function_decl([b4_prefix[pstate_delete]], [[void]],
 +b4_function_declare([b4_prefix[pstate_delete]], [[void]],
                     [[b4_prefix[pstate *ps]], [[ps]]])dnl
  ])
  
  # -------------------
  # When not the push parser.
  m4_define([b4_declare_yyparse_],
 -[[#ifdef YYPARSE_PARAM
 -]b4_c_function_decl(b4_prefix[parse], [int],
 -                    [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
 -#else /* ! YYPARSE_PARAM */
 -]b4_c_function_decl(b4_prefix[parse], [int], b4_parse_param)[
 -#endif /* ! YYPARSE_PARAM */]dnl
 -])
 +[b4_function_declare(b4_prefix[parse], [int], b4_parse_param)])
  
  
  # b4_declare_yyparse
@@@ -300,7 -306,7 +302,7 @@@ m4_define([b4_shared_declarations]
  [b4_cpp_guard_open([b4_spec_defines_file])[
  ]b4_declare_yydebug[
  ]b4_percent_code_get([[requires]])[
 -]b4_token_enums_defines(b4_tokens)[
 +]b4_token_enums_defines[
  ]b4_declare_yylstype[
  ]b4_declare_yyparse[
  ]b4_percent_code_get([[provides]])[
  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.  */
@@@ -359,7 -366,7 +361,7 @@@ m4_if(b4_api_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
  
  ]m4_ifval(m4_quote(b4_spec_defines_file),
@@@ -384,8 -391,10 +386,8 @@@ typedef unsigned char yytype_uint8
  
  #ifdef YYTYPE_INT8
  typedef YYTYPE_INT8 yytype_int8;
 -#elif ]b4_c_modern[
 -typedef signed char yytype_int8;
  #else
 -typedef short int yytype_int8;
 +typedef signed char yytype_int8;
  #endif
  
  #ifdef YYTYPE_UINT16
@@@ -405,7 -414,7 +407,7 @@@ typedef short int yytype_int16
  #  define YYSIZE_T __SIZE_TYPE__
  # elif defined size_t
  #  define YYSIZE_T size_t
 -# elif ! defined YYSIZE_T && ]b4_c_modern[
 +# elif ! defined YYSIZE_T
  #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
  #  define YYSIZE_T size_t
  # else
  #endif
  
  /* Suppress unused-variable warnings by "using" E.  */
 -#if ! defined lint || defined __GNUC__
 +#ifdef __GNUC__
  # define YYUSE(E) ((void) (E))
  #else
  # define YYUSE(E) /* empty */
  #endif
  
 -/* Identity function, used to suppress warnings about constant conditions.  */
 -#ifndef lint
 -# define YYID(N) (N)
 -#else
 -]b4_c_function_def([YYID], [static int], [[int yyi], [yyi]])[
 -{
 -  return yyi;
 -}
 -#endif
 -
  #if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[
  
  /* The parser invokes alloca or malloc; define the necessary symbols.  */]dnl
@@@ -452,7 -471,7 +454,7 @@@ b4_push_if([], [b4_lac_if([], [
  #    define alloca _alloca
  #   else
  #    define YYSTACK_ALLOC alloca
 -#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && ]b4_c_modern[
 +#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
  #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
        /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
  #     ifndef EXIT_SUCCESS
  
  # ifdef YYSTACK_ALLOC
     /* Pacify GCC's `empty if-body' warning.  */
 -#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
 +#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
  #  ifndef YYSTACK_ALLOC_MAXIMUM
      /* The OS might guarantee only one guard page at the bottom of the stack,
         and a page size can be as small as 4096 bytes.  So we cannot safely
  #  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
  #  endif
  #  ifndef YYMALLOC
  #   define YYMALLOC malloc
 -#   if ! defined malloc && ! defined EXIT_SUCCESS && ]b4_c_modern[
 +#   if ! defined malloc && ! defined EXIT_SUCCESS
  void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
  #   endif
  #  endif
  #  ifndef YYFREE
  #   define YYFREE free
 -#   if ! defined free && ! defined EXIT_SUCCESS && ]b4_c_modern[
 +#   if ! defined free && ! defined EXIT_SUCCESS
  void free (void *); /* INFRINGES ON USER NAME SPACE */
  #   endif
  #  endif
  
  #if (! defined yyoverflow \
       && (! defined __cplusplus \
 -       || (]b4_locations_if([[defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL \
 -           && ]])[defined ]b4_api_PREFIX[STYPE_IS_TRIVIAL && ]b4_api_PREFIX[STYPE_IS_TRIVIAL)))
 +         || (]b4_locations_if([[defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL \
 +             && ]])[defined ]b4_api_PREFIX[STYPE_IS_TRIVIAL && ]b4_api_PREFIX[STYPE_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);                          \
 -      }                                                                       \
 -    while (YYID (0))
 +# 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 (0)
  
  #endif
  
            for (yyi = 0; yyi < (Count); yyi++)   \
              (Dst)[yyi] = (Src)[yyi];            \
          }                                       \
 -      while (YYID (0))
 +      while (0)
  #  endif
  # endif
  #endif /* !YYCOPY_NEEDED */
  #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 ]b4_api_PREFIX[DEBUG
 -/* 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 ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
@@@ -614,35 -647,105 +616,35 @@@ 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[
 -};
 +]b4_parser_tables_define[
  
 -/* 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[
 -};
 +#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 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
 -
 -
 -/* Like YYERROR except do call yyerror.  This remains here temporarily
 -   to ease the transition to the new meaning of YYERROR, for GCC.
 -   Once GCC version 2 has supplanted version 1, this can go.  However,
 -   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
 -   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
 -   discussed.  */
 -
 -#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
 -     some users do, and we want to make it easy for users to remove
 -     YYFAIL uses, which will produce warnings from Bison 2.5.  */
 -#endif
  
  #define YYRECOVERING()  (!!yyerrstatus)
  
    else                                                          \
      {                                                           \
        yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \
 -      YYERROR;                                                        \
 -    }                                                         \
 -while (YYID (0))
 +      YYERROR;                                                  \
 +    }                                                           \
 +while (0)
  
+ /* Error token number */
 -#define YYTERROR      1
 -#define YYERRCODE     256
 +#define YYTERROR        1
 +#define YYERRCODE       256
  
  ]b4_locations_if([[
  ]b4_yylloc_default_define[
  #define YYRHSLOC(Rhs, K) ((Rhs)[K])
- /* YY_LOCATION_PRINT -- Print the location on the stream.
-    This macro was not mandated originally: define only if we know
-    we won't break user code: when these are the locations we know.  */
- #ifndef YY_LOCATION_PRINT
- # if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_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)
- # else
- #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
- # endif
- #endif]],
- [[/* This macro is provided for backward compatibility. */
- #ifndef YY_LOCATION_PRINT
- # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
- #endif]])[
+ ]])[
+ ]b4_yy_location_print_define[
  
  /* YYLEX -- calling `yylex' with the right arguments.  */
  #ifdef YYLEX_PARAM
  # define YYLEX yylex (]b4_pure_if([&yylval[]b4_locations_if([, &yylloc]), ])[YYLEX_PARAM)
  #else
 -# define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[
 +# define YYLEX ]b4_function_call([yylex], [int], b4_lex_param)[
  #endif
  
  /* Enable debugging if requested.  */
  #  define YYFPRINTF fprintf
  # endif
  
 -# 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");                                                 \
 -    }                                                                   \
 -} while (YYID (0))
 -
 -]b4_yy_symbol_print_generate([b4_c_function_def])[
 +# define YYDPRINTF(Args)                        \
 +do {                                            \
 +  if (yydebug)                                  \
 +    YYFPRINTF Args;                             \
 +} while (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");                                           \
 +    }                                                                     \
 +} while (0)
 +
 +]b4_yy_symbol_print_define[
  
  /*------------------------------------------------------------------.
  | yy_stack_print -- Print the state stack from its BOTTOM up to its |
  | TOP (included).                                                   |
  `------------------------------------------------------------------*/
  
 -]b4_c_function_def([yy_stack_print], [static void],
 -                 [[yytype_int16 *yybottom], [yybottom]],
 -                 [[yytype_int16 *yytop],    [yytop]])[
 +]b4_function_define([yy_stack_print], [static void],
 +                   [[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));                         \
 -} while (YYID (0))
 +# define YY_STACK_PRINT(Bottom, Top)                            \
 +do {                                                            \
 +  if (yydebug)                                                  \
 +    yy_stack_print ((Bottom), (Top));                           \
 +} while (0)
  
  
  /*------------------------------------------------.
  | Report that the YYRULE is going to be reduced.  |
  `------------------------------------------------*/
  
 -]b4_c_function_def([yy_reduce_print], [static void],
 -                 [[YYSTYPE *yyvsp], [yyvsp]],
 +]b4_function_define([yy_reduce_print], [static void],
 +                   [[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[); \
 -} while (YYID (0))
 +# define YY_REDUCE_PRINT(Rule)          \
 +do {                                    \
 +  if (yydebug)                          \
 +    yy_reduce_print (yyssp, yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \
 +} while (0)
  
  /* Nonzero means print parse trace.  It is left uninitialized so that
     multiple parsers can coexist.  */
@@@ -798,7 -881,7 +782,7 @@@ int yydebug
  
  
  /* YYINITDEPTH -- initial size of the parser's stacks.  */
 -#ifndef       YYINITDEPTH
 +#ifndef YYINITDEPTH
  # define YYINITDEPTH ]b4_stack_depth_init[
  #endif
  
@@@ -918,7 -1001,7 +902,7 @@@ do 
            goto yyerrlab;                                         \
        }                                                          \
      }                                                            \
 -} while (YYID (0))
 +} while (0)
  
  /* Discard any previous initial lookahead context because of Event,
     which may be a lookahead change or an invalidation of the currently
@@@ -941,7 -1024,7 +925,7 @@@ do 
                     Event "\n");                                          \
        yy_lac_established = 0;                                            \
      }                                                                    \
 -} while (YYID (0))
 +} while (0)
  #else
  # define YY_LAC_DISCARD(Event) yy_lac_established = 0
  #endif
@@@ -1057,7 -1140,7 +1041,7 @@@ yy_lac (yytype_int16 *yyesa, yytype_int
  #   define yystrlen strlen
  #  else
  /* Return the length of YYSTR.  */
 -]b4_c_function_def([yystrlen], [static YYSIZE_T],
 +]b4_function_define([yystrlen], [static YYSIZE_T],
     [[const char *yystr], [yystr]])[
  {
    YYSIZE_T yylen;
  #  else
  /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
     YYDEST.  */
 -]b4_c_function_def([yystpcpy], [static char *],
 +]b4_function_define([yystpcpy], [static char *],
     [[char *yydest], [yydest]], [[const char *yysrc], [yysrc]])[
  {
    char *yyd = yydest;
@@@ -1105,27 -1188,27 +1089,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: ;
      }
  
@@@ -1164,6 -1247,10 +1148,6 @@@ yysyntax_error (YYSIZE_T *yymsg_alloc, 
    int yycount = 0;
  
    /* There are many possibilities here to consider:
 -     - Assume YYFAIL is not used.  It's too flawed to consider.  See
 -       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
 -       for details.  YYERROR is fine as it does not invoke this
 -       function.
       - If this state is a consistent state with a default action, then
         the only way this function was invoked is if the default action
         is an error action.  In that case, don't check for expected
  }
  #endif /* YYERROR_VERBOSE */
  
 -]b4_yydestruct_generate([b4_c_function_def])[
 +]b4_yydestruct_define[
  
  ]b4_pure_if([], [
  
@@@ -1309,13 -1396,13 +1293,13 @@@ struct yypstat
  
  static char yypstate_allocated = 0;]])b4_pull_if([
  
 -b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
 +b4_function_define([[yyparse]], [[int]], b4_parse_param)[
  {
    return yypull_parse (YY_NULL]m4_ifset([b4_parse_param],
 -                                  [[, ]b4_c_args(b4_parse_param)])[);
 +                                  [[, ]b4_args(b4_parse_param)])[);
  }
  
 -]b4_c_function_def([[yypull_parse]], [[int]],
 +]b4_function_define([[yypull_parse]], [[int]],
    [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
    b4_parse_param]))[
  {
    yypstate *yyps_local;]b4_pure_if([[
    int yychar;
    YYSTYPE yylval;]b4_locations_if([[
-   YYLTYPE yylloc;]])])[
+   YYLTYPE yylloc][]b4_yyloc_default[;]])])[
    if (yyps)
      yyps_local = yyps;
    else
    do {
      yychar = YYLEX;
      yystatus =
 -      yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])[);
 +      yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
    } while (yystatus == YYPUSH_MORE);
    if (!yyps)
      yypstate_delete (yyps_local);
  }]])[
  
  /* Initialize the parser data structure.  */
 -]b4_c_function_def([[yypstate_new]], [[yypstate *]])[
 +]b4_function_define([[yypstate_new]], [[yypstate *]])[
  {
    yypstate *yyps;]b4_pure_if([], [[
    if (yypstate_allocated)
    return yyps;
  }
  
 -]b4_c_function_def([[yypstate_delete]], [[void]],
 +]b4_function_define([[yypstate_delete]], [[void]],
                     [[[yypstate *yyps]], [[yyps]]])[
  {
  #ifndef yyoverflow
  | yypush_parse.  |
  `---------------*/
  
 -]b4_c_function_def([[yypush_parse]], [[int]],
 +]b4_function_define([[yypush_parse]], [[int]],
    [[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
    [[[int yypushed_char]], [[yypushed_char]]],
    [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
-   [[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
+   [[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
    b4_parse_param]))], [[
  
  
  | yyparse.  |
  `----------*/
  
 -#ifdef YYPARSE_PARAM
 -]b4_c_function_def([yyparse], [int],
 -                   [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
 -#else /* ! YYPARSE_PARAM */
 -]b4_c_function_def([yyparse], [int], b4_parse_param)[
 -#endif]])[
 +]b4_function_define([yyparse], [int], b4_parse_param)])[
  {]b4_pure_if([b4_declare_scanner_communication_variables
  ])b4_push_if([b4_pure_if([], [[
    int yypushed_char = yychar;
        goto yyread_pushed_token;
      }]])[
  
-   yyss = yyssa;
-   yyvs = yyvsa;]b4_locations_if([[
-   yyls = yylsa;]])[
+   yyssp = yyss = yyssa;
+   yyvsp = yyvs = yyvsa;]b4_locations_if([[
+   yylsp = yyls = yylsa;]])[
    yystacksize = YYINITDEPTH;]b4_lac_if([[
  
    yyes = yyesa;
    yyerrstatus = 0;
    yynerrs = 0;
    yychar = YYEMPTY; /* Cause a token to be read.  */
-   /* Initialize stack pointers.
-      Waste one element of value and location stack
-      so that they stay on the same level as the state stack.
-      The wasted elements are never initialized.  */
-   yyssp = yyss;
-   yyvsp = yyvs;]b4_locations_if([[
-   yylsp = yyls;]])[
-   YYLVAL_INITIALIZE ();]b4_locations_if([[
- #if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
-   /* Initialize the default location before parsing starts.  */
-   yylloc.first_line   = yylloc.last_line   = ]b4_location_initial_line[;
-   yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[;
- #endif]])
- m4_ifdef([b4_initial_action],[
+ ]m4_ifdef([b4_initial_action], [
  b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [],
-                   [m4_define([b4_at_dollar_used])yylloc])dnl
+                [m4_define([b4_at_dollar_used])dnl
+ b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
  /* User initialization code.  */
  b4_user_initial_action
  b4_dollar_popdef[]dnl
  m4_ifdef([b4_dollar_dollar_used],[[  yyvsp[0] = yylval;
- ]])dnl
- m4_ifdef([b4_at_dollar_used], [[  yylsp[0] = yylloc;
  ]])])dnl
+ b4_locations_if([[  yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])[;
+ ]])dnl
  [  goto yysetstate;
  
  /*------------------------------------------------------------.
  
  #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));
@@@ -1748,9 -1826,9 +1718,9 @@@ yyreduce
    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.  */
    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
@@@ -1850,29 -1928,29 +1820,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);
@@@ -1939,7 -2017,7 +1909,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
@@@ -1955,14 -2033,17 +1925,14 @@@ yypushreturn:]])
    if (yymsg != yymsgbuf)
      YYSTACK_FREE (yymsg);
  #endif
 -  /* Make sure YYID is used.  */
 -  return YYID (yyresult);
 +  return yyresult;
  }
 -
 -
  ]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/scan-gram.l
index 95edacc58daf07c52bf6f57bd645019d9b5d9f28,ad061cc6f86159ba93da4023e60fa326111f8b86..98124556872b6251aa7ce8a6d44feb6639744520
@@@ -17,7 -17,7 +17,7 @@@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  
 -%option debug nodefault noinput nounput noyywrap never-interactive
 +%option debug nodefault noinput noyywrap never-interactive
  %option prefix="gram_" outfile="lex.yy.c"
  
  %{
  #define gram_wrap() 1
  
  #define FLEX_PREFIX(Id) gram_ ## Id
 -#include "flex-scanner.h"
 +#include <src/flex-scanner.h>
  
 -#include "complain.h"
 -#include "files.h"
 -#include "gram.h"
 -#include "quotearg.h"
 -#include "reader.h"
 -#include "uniqstr.h"
 +#include <src/complain.h>
 +#include <src/files.h>
 +#include <src/getargs.h>
 +#include <src/gram.h>
 +#include <quotearg.h>
 +#include <src/reader.h>
 +#include <src/uniqstr.h>
  
  #include <c-ctype.h>
  #include <mbswidth.h>
  #include <quote.h>
  
 -#include "scan-gram.h"
 +#include <src/scan-gram.h>
  
  #define YY_DECL GRAM_LEX_DECL
  
 -#define YY_USER_INIT                                  \
 -   code_start = scanner_cursor = loc->start;          \
 +#define YY_USER_INIT                                    \
 +   code_start = scanner_cursor = loc->start;            \
  
  /* Location of scanner cursor.  */
  static boundary scanner_cursor;
  static size_t no_cr_read (FILE *, char *, size_t);
  #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
  
 +#define RETURN_PERCENT_PARAM(Value)                     \
 +  RETURN_VALUE(PERCENT_PARAM, param, param_ ## Value)
 +
 +#define RETURN_PERCENT_FLAG(Value)                              \
 +  RETURN_VALUE(PERCENT_FLAG, uniqstr, uniqstr_new (Value))
 +
 +#define RETURN_VALUE(Token, Field, Value)       \
 +  do {                                          \
 +    val->Field = Value;                         \
 +    return Token;                               \
 +  } while (0)
 +
  #define ROLLBACK_CURRENT_TOKEN                                  \
    do {                                                          \
 -    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);   \
 +    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);     \
      yyless (0);                                                 \
    } while (0)
  
 +#define DEPRECATED(Msg)                                         \
 +  do {                                                          \
 +    size_t i;                                                   \
 +    complain (loc, Wdeprecated,                                 \
 +              _("deprecated directive: %s, use %s"),            \
 +              quote (yytext), quote_n (1, Msg));                \
 +    scanner_cursor.column -= mbsnwidth (Msg, strlen (Msg), 0);  \
 +    for (i = strlen (Msg); i != 0; --i)                         \
 +      unput (Msg[i - 1]);                                       \
 +  } while (0)
 +
  /* A string representing the most recently saved token.  */
  static char *last_string;
  
@@@ -114,15 -90,12 +114,15 @@@ static void unexpected_newline (boundar
   /* A identifier was just read in directives/rules.  Special state
      to capture the sequence 'identifier :'. */
  %x SC_AFTER_IDENTIFIER
 + /* A complex tag, with nested angles brackets. */
 +%x SC_TAG
  
 - /* Three types of user code:
 + /* Four types of user code:
      - prologue (code between '%{' '%}' in the first section, before %%);
      - actions, printers, union, etc, (between braced in the middle section);
 -    - epilogue (everything after the second %%). */
 -%x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE
 +    - epilogue (everything after the second %%).
 +    - predicate (code between '%?{' and '{' in middle section); */
 +%x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE SC_PREDICATE
   /* C and C++ comments in code. */
  %x SC_COMMENT SC_LINE_COMMENT
   /* Strings and characters in code. */
   /* Bracketed identifiers support. */
  %x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID
  
 -letter          [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
 -id      {letter}({letter}|[-0-9])*
 +letter    [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
 +id        {letter}({letter}|[-0-9])*
  directive %{id}
 -int     [0-9]+
 +int       [0-9]+
  
  /* POSIX says that a tag must be both an id and a C union member, but
     historically almost any character is allowed in a tag.  We disallow
 -   NUL and newline, as this simplifies our implementation.  */
 -tag    [^\0\n>]+
 +   NUL, as this simplifies our implementation.  We disallow angle
 +   bracket to match them in nested pairs: several languages use them
 +   for generics/template types.  */
 +tag      [^\0<>]+
  
  /* Zero or more instances of backslash-newline.  Following GCC, allow
     white space between the backslash and the newline.  */
 -splice         (\\[ \f\t\v]*\n)*
 +splice   (\\[ \f\t\v]*\n)*
 +
 +/* An equal sign, with optional leading whitespaces. This is used in some
 +   deprecated constructs. */
 +eqopt    ([[:space:]]*=)?
  
  %%
  %{
 -  /* Nesting level of the current code in braces.  */
 -  int braces_level PACIFY_CC (= 0);
 +  /* Nesting level.  Either for nested braces, or nested angle brackets
 +     (but not mixed).  */
 +  int nesting PACIFY_CC (= 0);
  
    /* Parent context state, when applicable.  */
    int context_state PACIFY_CC (= 0);
  <INITIAL,SC_AFTER_IDENTIFIER,SC_BRACKETED_ID,SC_RETURN_BRACKETED_ID>
  {
    /* Comments and white space.  */
 -  ","          warn_at (*loc, _("stray ',' treated as white space"));
 +  "," {
 +     complain (loc, Wother, _("stray ',' treated as white space"));
 +  }
    [ \f\n\t\v]  |
    "//".*       ;
    "/*" {
    `----------------------------*/
  
    /* For directives that are also command line options, the regex must be
 -      "%..."
 +        "%..."
       after "[-_]"s are removed, and the directive must match the --long
       option name, with a single string argument.  Otherwise, add exceptions
       to ../build-aux/cross-options.pl.  */
  {
    "%binary"                         return PERCENT_NONASSOC;
    "%code"                           return PERCENT_CODE;
 -  "%debug"                          return PERCENT_DEBUG;
 -  "%default"[-_]"prec"              return PERCENT_DEFAULT_PREC;
 +  "%debug"                          RETURN_PERCENT_FLAG("parse.trace");
 +  "%default-prec"                   return PERCENT_DEFAULT_PREC;
    "%define"                         return PERCENT_DEFINE;
    "%defines"                        return PERCENT_DEFINES;
    "%destructor"                     return PERCENT_DESTRUCTOR;
    "%dprec"                          return PERCENT_DPREC;
 -  "%error"[-_]"verbose"             return PERCENT_ERROR_VERBOSE;
 +  "%error-verbose"                  return PERCENT_ERROR_VERBOSE;
    "%expect"                         return PERCENT_EXPECT;
 -  "%expect"[-_]"rr"                 return PERCENT_EXPECT_RR;
 +  "%expect-rr"                      return PERCENT_EXPECT_RR;
    "%file-prefix"                    return PERCENT_FILE_PREFIX;
 -  "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
 +  "%fixed-output-files"             return PERCENT_YACC;
    "%initial-action"                 return PERCENT_INITIAL_ACTION;
    "%glr-parser"                     return PERCENT_GLR_PARSER;
    "%language"                       return PERCENT_LANGUAGE;
    "%left"                           return PERCENT_LEFT;
 -  "%lex-param"                      return PERCENT_LEX_PARAM;
 -  "%locations"                      return PERCENT_LOCATIONS;
 +  "%lex-param"                      RETURN_PERCENT_PARAM(lex);
 +  "%locations"                      RETURN_PERCENT_FLAG("locations");
    "%merge"                          return PERCENT_MERGE;
 -  "%name"[-_]"prefix"               return PERCENT_NAME_PREFIX;
 -  "%no"[-_]"default"[-_]"prec"      return PERCENT_NO_DEFAULT_PREC;
 -  "%no"[-_]"lines"                  return PERCENT_NO_LINES;
 +  "%name-prefix"                    return PERCENT_NAME_PREFIX;
 +  "%no-default-prec"                return PERCENT_NO_DEFAULT_PREC;
 +  "%no-lines"                       return PERCENT_NO_LINES;
    "%nonassoc"                       return PERCENT_NONASSOC;
    "%nondeterministic-parser"        return PERCENT_NONDETERMINISTIC_PARSER;
    "%nterm"                          return PERCENT_NTERM;
    "%output"                         return PERCENT_OUTPUT;
 -  "%parse-param"                    return PERCENT_PARSE_PARAM;
 +  "%param"                          RETURN_PERCENT_PARAM(both);
 +  "%parse-param"                    RETURN_PERCENT_PARAM(parse);
    "%prec"                           return PERCENT_PREC;
 +  "%precedence"                     return PERCENT_PRECEDENCE;
    "%printer"                        return PERCENT_PRINTER;
 -  "%pure"[-_]"parser"               return PERCENT_PURE_PARSER;
 +  "%pure-parser"                    RETURN_PERCENT_FLAG("api.pure");
    "%require"                        return PERCENT_REQUIRE;
    "%right"                          return PERCENT_RIGHT;
    "%skeleton"                       return PERCENT_SKELETON;
    "%start"                          return PERCENT_START;
    "%term"                           return PERCENT_TOKEN;
    "%token"                          return PERCENT_TOKEN;
 -  "%token"[-_]"table"               return PERCENT_TOKEN_TABLE;
 +  "%token-table"                    return PERCENT_TOKEN_TABLE;
    "%type"                           return PERCENT_TYPE;
    "%union"                          return PERCENT_UNION;
    "%verbose"                        return PERCENT_VERBOSE;
    "%yacc"                           return PERCENT_YACC;
  
 +  /* deprecated */
 +  "%default"[-_]"prec"              DEPRECATED("%default-prec");
 +  "%error"[-_]"verbose"             DEPRECATED("%define parse.error verbose");
 +  "%expect"[-_]"rr"                 DEPRECATED("%expect-rr");
 +  "%file-prefix"{eqopt}             DEPRECATED("%file-prefix");
 +  "%fixed"[-_]"output"[-_]"files"   DEPRECATED("%fixed-output-files");
 +  "%name"[-_]"prefix"{eqopt}        DEPRECATED("%name-prefix");
 +  "%no"[-_]"default"[-_]"prec"      DEPRECATED("%no-default-prec");
 +  "%no"[-_]"lines"                  DEPRECATED("%no-lines");
 +  "%output"{eqopt}                  DEPRECATED("%output");
 +  "%pure"[-_]"parser"               DEPRECATED("%pure-parser");
 +  "%token"[-_]"table"               DEPRECATED("%token-table");
 +
    {directive} {
 -    complain_at (*loc, _("invalid directive: %s"), quote (yytext));
 +    complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
    }
  
    "="                     return EQUAL;
    "|"                     return PIPE;
    ";"                     return SEMICOLON;
 -  "<*>"                   return TYPE_TAG_ANY;
 -  "<>"                    return TYPE_TAG_NONE;
  
    {id} {
      val->uniqstr = uniqstr_new (yytext);
    /* Identifiers may not start with a digit.  Yet, don't silently
       accept "1FOO" as "1 FOO".  */
    {int}{id} {
 -    complain_at (*loc, _("invalid identifier: %s"), quote (yytext));
 +    complain (loc, complaint, _("invalid identifier: %s"), quote (yytext));
    }
  
    /* Characters.  */
 -  "'"       token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
 +  "'"         token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
  
    /* Strings. */
 -  "\""              token_start = loc->start; BEGIN SC_ESCAPED_STRING;
 +  "\""        token_start = loc->start; BEGIN SC_ESCAPED_STRING;
  
    /* Prologue. */
    "%{"        code_start = loc->start; BEGIN SC_PROLOGUE;
    /* Code in between braces.  */
    "{" {
      STRING_GROW;
 -    braces_level = 0;
 +    nesting = 0;
      code_start = loc->start;
      BEGIN SC_BRACED_CODE;
    }
  
 +  /* Semantic predicate. */
 +  "%?"[ \f\n\t\v]*"{" {
 +    nesting = 0;
 +    code_start = loc->start;
 +    BEGIN SC_PREDICATE;
 +  }
 +
    /* A type. */
 +  "<*>"       return TAG_ANY;
 +  "<>"        return TAG_NONE;
    "<"{tag}">" {
      obstack_grow (&obstack_for_string, yytext + 1, yyleng - 2);
      STRING_FINISH;
      val->uniqstr = uniqstr_new (last_string);
      STRING_FREE;
 -    return TYPE;
 +    return TAG;
 +  }
 +  "<"         {
 +    nesting = 0;
 +    token_start = loc->start;
 +    BEGIN SC_TAG;
    }
  
    "%%" {
    }
  
    . {
-     complain (loc, complaint, _("invalid character: %s"), quote (yytext));
 -    complain_at (*loc, _("invalid character: %s"), quote_mem (yytext, yyleng));
++    complain (loc, complaint, _("invalid character: %s"),
++              quote_mem (yytext, yyleng));
    }
  
    <<EOF>> {
  }
  
  
 +  /*--------------------------------------------------------------.
 +  | Supporting \0 complexifies our implementation for no expected |
 +  | added value.                                                  |
 +  `--------------------------------------------------------------*/
 +
 +<SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING,SC_TAG>
 +{
 +  \0        complain (loc, complaint, _("invalid null character"));
 +}
 +
 +
    /*-----------------------------------------------------------------.
    | Scanning after an identifier, checking whether a colon is next.  |
    `-----------------------------------------------------------------*/
    "[" {
      if (bracketed_id_str)
        {
 -      ROLLBACK_CURRENT_TOKEN;
 -      BEGIN SC_RETURN_BRACKETED_ID;
 -      *loc = id_loc;
 -      return ID;
 +        ROLLBACK_CURRENT_TOKEN;
 +        BEGIN SC_RETURN_BRACKETED_ID;
 +        *loc = id_loc;
 +        return ID;
        }
      else
        {
 -      bracketed_id_start = loc->start;
 -      bracketed_id_context_state = YY_START;
 -      BEGIN SC_BRACKETED_ID;
 +        bracketed_id_start = loc->start;
 +        bracketed_id_context_state = YY_START;
 +        BEGIN SC_BRACKETED_ID;
        }
    }
    ":" {
    {id} {
      if (bracketed_id_str)
        {
 -      complain_at (*loc, _("unexpected identifier in bracketed name: %s"),
 -                   quote (yytext));
 +        complain (loc, complaint,
 +                  _("unexpected identifier in bracketed name: %s"),
 +                  quote (yytext));
        }
      else
        {
 -      bracketed_id_str = uniqstr_new (yytext);
 -      bracketed_id_loc = *loc;
 +        bracketed_id_str = uniqstr_new (yytext);
 +        bracketed_id_loc = *loc;
        }
    }
    "]" {
      BEGIN bracketed_id_context_state;
      if (bracketed_id_str)
        {
 -      if (INITIAL == bracketed_id_context_state)
 -        {
 -          val->uniqstr = bracketed_id_str;
 -          bracketed_id_str = 0;
 -          *loc = bracketed_id_loc;
 -          return BRACKETED_ID;
 -        }
 +        if (INITIAL == bracketed_id_context_state)
 +          {
 +            val->uniqstr = bracketed_id_str;
 +            bracketed_id_str = 0;
 +            *loc = bracketed_id_loc;
 +            return BRACKETED_ID;
 +          }
        }
      else
 -      complain_at (*loc, _("an identifier expected"));
 +      complain (loc, complaint, _("an identifier expected"));
    }
    . {
 -    complain_at (*loc, _("invalid character in bracketed name: %s"),
 -               quote_mem (yytext, yyleng));
 +    complain (loc, complaint, _("invalid character in bracketed name: %s"),
-                  quote (yytext));
++              quote_mem (yytext, yyleng));
    }
    <<EOF>> {
      BEGIN bracketed_id_context_state;
  <SC_YACC_COMMENT>
  {
    "*/"     BEGIN context_state;
 -  .|\n           ;
 +  .|\n     ;
    <<EOF>>  unexpected_eof (token_start, "*/"); BEGIN context_state;
  }
  
  <SC_COMMENT>
  {
    "*"{splice}"/"  STRING_GROW; BEGIN context_state;
 -  <<EOF>>       unexpected_eof (token_start, "*/"); BEGIN context_state;
 +  <<EOF>>         unexpected_eof (token_start, "*/"); BEGIN context_state;
  }
  
  
  
  <SC_LINE_COMMENT>
  {
 -  "\n"                 STRING_GROW; BEGIN context_state;
 -  {splice}     STRING_GROW;
 -  <<EOF>>      BEGIN context_state;
 +  "\n"           STRING_GROW; BEGIN context_state;
 +  {splice}       STRING_GROW;
 +  <<EOF>>        BEGIN context_state;
  }
  
  
  
    /*----------------------------------------------------------.
    | Scanning a Bison character literal, decoding its escapes. |
 -  | The initial quote is already eaten.                             |
 +  | The initial quote is already eaten.                       |
    `----------------------------------------------------------*/
  
  <SC_ESCAPED_CHARACTER>
        /* FIXME: Eventually, make these errors.  */
        if (last_string[0] == '\0')
          {
 -          warn_at (*loc, _("empty character literal"));
 +          complain (loc, Wother, _("empty character literal"));
            /* '\0' seems dangerous even if we are about to complain.  */
            val->character = '\'';
          }
        else if (last_string[1] != '\0')
 -        warn_at (*loc, _("extra characters in character literal"));
 +        complain (loc, Wother,
 +                  _("extra characters in character literal"));
      }
      if (yytext[0] == '\n')
        unexpected_newline (token_start, "'");
        /* FIXME: Eventually, make these errors.  */
        if (last_string[0] == '\0')
          {
 -          warn_at (*loc, _("empty character literal"));
 +          complain (loc, Wother, _("empty character literal"));
            /* '\0' seems dangerous even if we are about to complain.  */
            val->character = '\'';
          }
        else if (last_string[1] != '\0')
 -        warn_at (*loc, _("extra characters in character literal"));
 +        complain (loc, Wother,
 +                  _("extra characters in character literal"));
      }
      unexpected_eof (token_start, "'");
      STRING_FREE;
    }
  }
  
 -<SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING>
 +  /*-----------------------------------------------------------.
 +  | Scanning a Bison nested tag.  The initial angle bracket is |
 +  | already eaten.                                             |
 +  `-----------------------------------------------------------*/
 +
 +<SC_TAG>
  {
 -  \0      complain_at (*loc, _("invalid null character"));
 -}
 +  ">" {
 +    --nesting;
 +    if (nesting < 0)
 +      {
 +        STRING_FINISH;
 +        loc->start = token_start;
 +        val->uniqstr = uniqstr_new (last_string);
 +        STRING_FREE;
 +        BEGIN INITIAL;
 +        return TAG;
 +      }
 +    STRING_GROW;
 +  }
  
 +  [^<>]+ STRING_GROW;
 +  "<"+   STRING_GROW; nesting += yyleng;
 +
 +  <<EOF>> {
 +    unexpected_eof (token_start, ">");
 +    STRING_FINISH;
 +    loc->start = token_start;
 +    val->uniqstr = uniqstr_new (last_string);
 +    STRING_FREE;
 +    BEGIN INITIAL;
 +    return TAG;
 +  }
 +}
  
    /*----------------------------.
    | Decode escaped characters.  |
    \\[0-7]{1,3} {
      unsigned long int c = strtoul (yytext + 1, NULL, 8);
      if (!c || UCHAR_MAX < c)
 -      complain_at (*loc, _("invalid number after \\-escape: %s"),
 +      complain (loc, complaint, _("invalid number after \\-escape: %s"),
                     yytext+1);
      else
        obstack_1grow (&obstack_for_string, c);
      verify (UCHAR_MAX < ULONG_MAX);
      unsigned long int c = strtoul (yytext + 2, NULL, 16);
      if (!c || UCHAR_MAX < c)
 -      complain_at (*loc, _("invalid number after \\-escape: %s"),
 +      complain (loc, complaint, _("invalid number after \\-escape: %s"),
                     yytext+1);
      else
        obstack_1grow (&obstack_for_string, c);
    }
  
 -  \\a obstack_1grow (&obstack_for_string, '\a');
 -  \\b obstack_1grow (&obstack_for_string, '\b');
 -  \\f obstack_1grow (&obstack_for_string, '\f');
 -  \\n obstack_1grow (&obstack_for_string, '\n');
 -  \\r obstack_1grow (&obstack_for_string, '\r');
 -  \\t obstack_1grow (&obstack_for_string, '\t');
 -  \\v obstack_1grow (&obstack_for_string, '\v');
 +  \\a   obstack_1grow (&obstack_for_string, '\a');
 +  \\b   obstack_1grow (&obstack_for_string, '\b');
 +  \\f   obstack_1grow (&obstack_for_string, '\f');
 +  \\n   obstack_1grow (&obstack_for_string, '\n');
 +  \\r   obstack_1grow (&obstack_for_string, '\r');
 +  \\t   obstack_1grow (&obstack_for_string, '\t');
 +  \\v   obstack_1grow (&obstack_for_string, '\v');
  
    /* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
    \\("\""|"'"|"?"|"\\")  obstack_1grow (&obstack_for_string, yytext[1]);
    \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
      int c = convert_ucn_to_byte (yytext);
      if (c <= 0)
 -      complain_at (*loc, _("invalid number after \\-escape: %s"),
 +      complain (loc, complaint, _("invalid number after \\-escape: %s"),
                     yytext+1);
      else
        obstack_1grow (&obstack_for_string, c);
    }
 -  \\(.|\n)    {
 +  \\(.|\n)      {
      char const *p = yytext + 1;
      /* Quote only if escaping won't make the character visible.  */
      if (c_isspace ((unsigned char) *p) && c_isprint ((unsigned char) *p))
        p = quote (p);
      else
        p = quotearg_style_mem (escape_quoting_style, p, 1);
 -    complain_at (*loc, _("invalid character after \\-escape: %s"), p);
 +    complain (loc, complaint, _("invalid character after \\-escape: %s"),
 +                 p);
    }
  }
  
  
  <SC_CHARACTER,SC_STRING>
  {
 -  {splice}|\\{splice}[^\n\[\]]        STRING_GROW;
 +  {splice}|\\{splice}[^\n\[\]]  STRING_GROW;
  }
  
  <SC_CHARACTER>
  {
 -  "'"         STRING_GROW; BEGIN context_state;
 -  \n          unexpected_newline (token_start, "'"); BEGIN context_state;
 -  <<EOF>>     unexpected_eof (token_start, "'"); BEGIN context_state;
 +  "'"           STRING_GROW; BEGIN context_state;
 +  \n            unexpected_newline (token_start, "'"); BEGIN context_state;
 +  <<EOF>>       unexpected_eof (token_start, "'"); BEGIN context_state;
  }
  
  <SC_STRING>
  {
 -  "\""                STRING_GROW; BEGIN context_state;
 -  \n          unexpected_newline (token_start, "\""); BEGIN context_state;
 -  <<EOF>>     unexpected_eof (token_start, "\""); BEGIN context_state;
 +  "\""          STRING_GROW; BEGIN context_state;
 +  \n            unexpected_newline (token_start, "\""); BEGIN context_state;
 +  <<EOF>>       unexpected_eof (token_start, "\""); BEGIN context_state;
  }
  
  
    | Strings, comments etc. can be found in user code.  |
    `---------------------------------------------------*/
  
 -<SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
 +<SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE,SC_PREDICATE>
  {
    "'" {
      STRING_GROW;
  
  
    /*-----------------------------------------------------------.
 -  | Scanning some code in braces (actions). The initial "{" is |
 -  | already eaten.                                             |
 +  | Scanning some code in braces (actions, predicates). The    |
 +  | initial "{" is already eaten.                              |
    `-----------------------------------------------------------*/
  
 -<SC_BRACED_CODE>
 +<SC_BRACED_CODE,SC_PREDICATE>
  {
 -  "{"|"<"{splice}"%"  STRING_GROW; braces_level++;
 -  "%"{splice}">"      STRING_GROW; braces_level--;
 -  "}" {
 -    obstack_1grow (&obstack_for_string, '}');
 -
 -    --braces_level;
 -    if (braces_level < 0)
 -      {
 -      STRING_FINISH;
 -      loc->start = code_start;
 -      val->code = last_string;
 -      BEGIN INITIAL;
 -      return BRACED_CODE;
 -      }
 -  }
 +  "{"|"<"{splice}"%"  STRING_GROW; nesting++;
 +  "%"{splice}">"      STRING_GROW; nesting--;
  
    /* Tokenize '<<%' correctly (as '<<' '%') rather than incorrrectly
       (as '<' '<%').  */
    "<"{splice}"<"  STRING_GROW;
  
    <<EOF>> {
 +    int token = (YY_START == SC_BRACED_CODE) ? BRACED_CODE : BRACED_PREDICATE;
      unexpected_eof (code_start, "}");
      STRING_FINISH;
      loc->start = code_start;
      val->code = last_string;
      BEGIN INITIAL;
 -    return BRACED_CODE;
 +    return token;
    }
  }
  
 +<SC_BRACED_CODE>
 +{
 +  "}" {
 +    obstack_1grow (&obstack_for_string, '}');
 +
 +    --nesting;
 +    if (nesting < 0)
 +      {
 +        STRING_FINISH;
 +        loc->start = code_start;
 +        val->code = last_string;
 +        BEGIN INITIAL;
 +        return BRACED_CODE;
 +      }
 +  }
 +}
 +
 +<SC_PREDICATE>
 +{
 +  "}" {
 +    --nesting;
 +    if (nesting < 0)
 +      {
 +        STRING_FINISH;
 +        loc->start = code_start;
 +        val->code = last_string;
 +        BEGIN INITIAL;
 +        return BRACED_PREDICATE;
 +      }
 +    else
 +      obstack_1grow (&obstack_for_string, '}');
 +  }
 +}
  
    /*--------------------------------------------------------------.
    | Scanning some prologue: from "%{" (already scanned) to "%}".  |
    | By default, grow the string obstack with the input.  |
    `-----------------------------------------------------*/
  
 -<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE,SC_STRING,SC_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>.    |
 -<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>\n STRING_GROW;
 +<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE,SC_STRING,SC_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>. |
 +  <SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE>\n    STRING_GROW;
  
  %%
  
@@@ -854,35 -726,35 +855,35 @@@ no_cr_read (FILE *fp, char *buf, size_
      {
        char *w = memchr (buf, '\r', bytes_read);
        if (w)
 -      {
 -        char const *r = ++w;
 -        char const *lim = buf + bytes_read;
 -
 -        for (;;)
 -          {
 -            /* Found an '\r'.  Treat it like '\n', but ignore any
 -               '\n' that immediately follows.  */
 -            w[-1] = '\n';
 -            if (r == lim)
 -              {
 -                int ch = getc (fp);
 -                if (ch != '\n' && ungetc (ch, fp) != ch)
 -                  break;
 -              }
 -            else if (*r == '\n')
 -              r++;
 -
 -            /* Copy until the next '\r'.  */
 -            do
 -              {
 -                if (r == lim)
 -                  return w - buf;
 -              }
 -            while ((*w++ = *r++) != '\r');
 -          }
 -
 -        return w - buf;
 -      }
 +        {
 +          char const *r = ++w;
 +          char const *lim = buf + bytes_read;
 +
 +          for (;;)
 +            {
 +              /* Found an '\r'.  Treat it like '\n', but ignore any
 +                 '\n' that immediately follows.  */
 +              w[-1] = '\n';
 +              if (r == lim)
 +                {
 +                  int ch = getc (fp);
 +                  if (ch != '\n' && ungetc (ch, fp) != ch)
 +                    break;
 +                }
 +              else if (*r == '\n')
 +                r++;
 +
 +              /* Copy until the next '\r'.  */
 +              do
 +                {
 +                  if (r == lim)
 +                    return w - buf;
 +                }
 +              while ((*w++ = *r++) != '\r');
 +            }
 +
 +          return w - buf;
 +        }
      }
  
    return bytes_read;
@@@ -902,8 -774,7 +903,8 @@@ scan_integer (char const *number, int b
  
    if (INT_MAX < num)
      {
 -      complain_at (loc, _("integer out of range: %s"), quote (number));
 +      complain (&loc, complaint, _("integer out of range: %s"),
 +                   quote (number));
        num = INT_MAX;
      }
  
  /*------------------------------------------------------------------.
  | Convert universal character name UCN to a single-byte character,  |
  | and return that character.  Return -1 if UCN does not correspond  |
 -| to a single-byte character.                                     |
 +| to a single-byte character.                                       |
  `------------------------------------------------------------------*/
  
  static int
@@@ -942,22 -813,22 +943,22 @@@ convert_ucn_to_byte (char const *ucn
         about.  */
      static signed char const table[] =
        {
 -      '\0',   -1,   -1,   -1,   -1,   -1,   -1, '\a',
 -      '\b', '\t', '\n', '\v', '\f', '\r',   -1,   -1,
 -        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
 -        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
 -       ' ',  '!',  '"',  '#',  '$',  '%',  '&', '\'',
 -       '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',
 -       '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
 -       '8',  '9',  ':',  ';',  '<',  '=',  '>',  '?',
 -       '@',  'A',  'B',  'C',  'D',  'E',  'F',  'G',
 -       'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
 -       'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
 -       'X',  'Y',  'Z',  '[', '\\',  ']',  '^',  '_',
 -       '`',  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 -       'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 -       'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 -       'x',  'y',  'z',  '{',  '|',  '}',  '~'
 +        '\0',   -1,   -1,   -1,   -1,   -1,   -1, '\a',
 +        '\b', '\t', '\n', '\v', '\f', '\r',   -1,   -1,
 +          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
 +          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
 +         ' ',  '!',  '"',  '#',  '$',  '%',  '&', '\'',
 +         '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',
 +         '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
 +         '8',  '9',  ':',  ';',  '<',  '=',  '>',  '?',
 +         '@',  'A',  'B',  'C',  'D',  'E',  'F',  'G',
 +         'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
 +         'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
 +         'X',  'Y',  'Z',  '[', '\\',  ']',  '^',  '_',
 +         '`',  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 +         'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 +         'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 +         'x',  'y',  'z',  '{',  '|',  '}',  '~'
        };
  
      code = code < sizeof table ? table[code] : -1;
@@@ -977,11 -848,11 +978,11 @@@ handle_syncline (char *args, location l
  {
    char *after_num;
    unsigned long int lineno = strtoul (args, &after_num, 10);
 -  char *file = mbschr (after_num, '"') + 1;
 -  *mbschr (file, '"') = '\0';
 +  char *file = strchr (after_num, '"') + 1;
 +  *strchr (file, '"') = '\0';
    if (INT_MAX <= lineno)
      {
 -      warn_at (loc, _("line number overflow"));
 +      complain (&loc, Wother, _("line number overflow"));
        lineno = INT_MAX;
      }
    current_file = uniqstr_new (file);
  
  /*----------------------------------------------------------------.
  | For a token or comment starting at START, report message MSGID, |
 -| which should say that an end marker was found before                  |
 -| the expected TOKEN_END.                                       |
 +| which should say that an end marker was found before            |
 +| the expected TOKEN_END.                                         |
  `----------------------------------------------------------------*/
  
  static void
@@@ -1003,9 -874,9 +1004,9 @@@ unexpected_end (boundary start, char co
    loc.end = scanner_cursor;
    token_end = quote (token_end);
    // Instead of '\'', display "'".
 -  if (!strcmp (token_end, "'\\''"))
 +  if (STREQ (token_end, "'\\''"))
      token_end = "\"'\"";
 -  complain_at (loc, _(msgid), token_end);
 +  complain (&loc, complaint, _(msgid), token_end);
  }
  
  
diff --combined tests/actions.at
index 4b0019b84f112ad4ea4b763df29bf429d973cc41,01e3e57d2c109d79af7046b1f8a9a941ae83b8de..7b220a280ce4918e9efdca56fbabe678dd534354
@@@ -1,4 -1,4 +1,4 @@@
 -# Executing Actions.                               -*- Autotest -*-
 +e# Executing Actions.                               -*- Autotest -*-
  
  # Copyright (C) 2001-2012 Free Software Foundation, Inc.
  
@@@ -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[
@@@ -69,6 -69,76 +69,76 @@@ AT_PARSER_CHECK([./input], 0
  AT_CLEANUP
  
  
+ ## ------------------ ##
+ ## Initial location.  ##
+ ## ------------------ ##
+ # AT_TEST(SKELETON-NAME, DIRECTIVES)
+ # ----------------------------------
+ # Check the the initial location is correct.
+ m4_pushdef([AT_TEST],
+ [AT_SETUP([Initial location: $1 $2])
+ AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2 %parse-param { int x }])
+ AT_DATA_GRAMMAR([[input.y]],
+ [[%defines /* FIXME: Required by lalr1.cc in Bison 2.6. */
+ %locations
+ %debug
+ %skeleton "$1"
+ $2
+ %parse-param { int x } // Useless, but used to force yyerror purity.
+ %code
+ {
+ # include <stdio.h>
+ # include <stdlib.h> // getenv
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
+ }
+ %%
+ exp: { ]AT_SKEL_CC_IF([[std::cerr << @$ << std::endl]],
+                       [[YY_LOCATION_PRINT(stderr, @$); fputc ('\n', stderr)]])[; }
+ %%
+ ]AT_YYERROR_DEFINE[
+ ]AT_YYLEX_PROTOTYPE[
+ {]AT_PURE_IF([
+   YYUSE(lvalp);
+   YYUSE(llocp);], [AT_SKEL_CC_IF([
+   YYUSE(lvalp);
+   YYUSE(llocp);])])[
+   return 'x';
+ }
+ int
+ main (void)
+ {]AT_SKEL_CC_IF([[
+   yy::parser p (0);
+   p.set_debug_level (!!getenv("YYDEBUG"));
+   return p.parse ();]], [[
+   yydebug = !!getenv("YYDEBUG");
+   return !!yyparse (0);]])[
+ }
+ ]])
+ AT_FULL_COMPILE([input])
+ AT_PARSER_CHECK([./input], 1, [],
+ [[1.1
+ 1.1: syntax error
+ ]])
+ AT_BISON_OPTION_POPDEFS
+ AT_CLEANUP
+ ])
+ ## FIXME: test Java, and iterate over skeletons.
+ AT_TEST([yacc.c])
+ AT_TEST([yacc.c], [%define api.pure])
+ AT_TEST([yacc.c], [%define api.push-pull both])
+ AT_TEST([yacc.c], [%define api.push-pull both %define api.pure])
+ AT_TEST([glr.c])
+ AT_TEST([lalr1.cc])
+ AT_TEST([glr.cc])
+ m4_popdef([AT_TEST])
  
  
  
@@@ -80,7 -150,7 +150,7 @@@ AT_SETUP([Exotic Dollars]
  
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA_GRAMMAR([[input.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  %{
  ]AT_YYERROR_DECLARE[
@@@ -136,7 -206,7 +206,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;
@@@ -159,8 -229,7 +229,7 @@@ main (void
  }
  ]])
  
- AT_BISON_CHECK([[-o input.c input.y]])
- AT_COMPILE([[input]])
+ AT_FULL_COMPILE([input])
  AT_PARSER_CHECK([[./input]], [[0]],
  [[6
  ]])
@@@ -264,7 -333,7 +333,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, $$, @$, ": ");
@@@ -305,7 -374,7 +374,7 @@@ line
        $$ = -1;
        V(line,  $$, @$, ": ");
        V('(',   $1, @1, " ");
 -      fprintf (stderr, "error (@%d-%d) ", RANGE (@2));
 +      fprintf (stderr, "error (@%d-%d) ", RANGE(@2));
        V(')',   $3, @3, "\n");
      }
  ;
@@@ -557,11 -626,11 +626,11 @@@ AT_BISON_OPTION_POPDEF
  # AT_CHECK_PRINTER_AND_DESTRUCTOR([BISON-OPTIONS], [UNION-FLAG], [SKIP_FLAG])
  # ---------------------------------------------------------------------------
  m4_define([AT_CHECK_PRINTER_AND_DESTRUCTOR],
- [AT_SETUP([Printers and Destructors $2: $1])
+ [AT_SETUP([Printers and Destructors$2]m4_ifval([$1], [[: $1]]))
  
  $3
  _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
 -[%error-verbose
 +[%define parse.error verbose
  %debug
  %verbose
  %locations
@@@ -572,13 -641,13 +641,13 @@@ AT_CLEANU
  
  
  AT_CHECK_PRINTER_AND_DESTRUCTOR([])
 -AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
 +AT_CHECK_PRINTER_AND_DESTRUCTOR([], [with union])
  
  AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
 -AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
 +AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [with union])
  
  AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
 -AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
 +AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union])
  
  
  
  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 {
-   @$.first_line = @$.last_line = 1;
-   @$.first_column = @$.last_column = 1;
- }
  
  %{
  # include <stdio.h>
@@@ -646,10 -711,7 +711,10 @@@ main (void
  }
  ]])
  
 -AT_BISON_CHECK([-o input.c input.y])
 +AT_BISON_CHECK([-o input.c input.y], [], [],
- [[input.y:27.3-5: warning: useless %destructor for type <*> [-Wother]
- input.y:27.3-5: warning: useless %printer for type <*> [-Wother]
++[[input.y:23.3-5: warning: useless %destructor for type <*> [-Wother]
++input.y:23.3-5: warning: useless %printer for type <*> [-Wother]
 +]])
  AT_COMPILE([input])
  AT_PARSER_CHECK([./input], 1,
  [[<> destructor for 'd' @ 4.
  ]],
  [[Starting parse
  Entering state 0
- Reading a token: Next token is token 'a' (1.1-1.1: <> printer for 'a' @ 1)
- Shifting token 'a' (1.1-1.1: <> printer for 'a' @ 1)
+ Reading a token: Next token is token 'a' (1.1: <> printer for 'a' @ 1)
+ Shifting token 'a' (1.1: <> printer for 'a' @ 1)
  Entering state 1
- Reading a token: Next token is token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2)
- Shifting token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2)
+ Reading a token: Next token is token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
+ Shifting token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
  Entering state 3
- Reading a token: Next token is token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
- Shifting token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
+ Reading a token: Next token is token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
+ Shifting token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
  Entering state 5
- Reading a token: Next token is token 'd' (1.4-1.4: <> printer for 'd' @ 4)
- Shifting token 'd' (1.4-1.4: <> printer for 'd' @ 4)
+ Reading a token: Next token is token 'd' (1.4: <> printer for 'd' @ 4)
+ Shifting token 'd' (1.4: <> printer for 'd' @ 4)
  Entering state 6
  Reading a token: Now at end of input.
- 1.5-4: syntax error, unexpected $end, expecting 'e'
- Error: popping token 'd' (1.4-1.4: <> printer for 'd' @ 4)
+ 1.5: syntax error, unexpected $end, expecting 'e'
+ Error: popping token 'd' (1.4: <> printer for 'd' @ 4)
  Stack now 0 1 3 5
- Error: popping token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
+ Error: popping token 'c' (1.3: 'b'/'c' printer for 'c' @ 3)
  Stack now 0 1 3
- Error: popping token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2)
+ Error: popping token 'b' (1.2: 'b'/'c' printer for 'b' @ 2)
  Stack now 0 1
- Error: popping token 'a' (1.1-1.1: <> printer for 'a' @ 1)
+ Error: popping token 'a' (1.1: <> printer for 'a' @ 1)
  Stack now 0
- Cleanup: discarding lookahead token $end (1.5-1.5: )
+ Cleanup: discarding lookahead token $end (1.5: )
  Stack now 0
  ]])
  
@@@ -697,7 -759,7 +762,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
  
  %{
@@@ -761,10 -823,7 +826,10 @@@ main (void
  }
  ]])
  
 -AT_BISON_CHECK([-o input.c input.y])
 +AT_BISON_CHECK([-o input.c input.y], [], [],
 +[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
 +input.y:22.3-4: warning: useless %printer for type <> [-Wother]
 +]])
  AT_COMPILE([input])
  AT_PARSER_CHECK([./input], 1,
  [[<*>/<field2>/e destructor.
@@@ -823,22 -882,18 +888,18 @@@ AT_CLEANU
  
  AT_SETUP([Default %printer and %destructor for user-defined end token])
  
 -# _AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(TYPED)
 -# -------------------------------------------------------------
 -m4_define([_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN],
 +# AT_TEST(TYPED)
 +# --------------
 +m4_pushdef([AT_TEST],
  [m4_if($1, 0,
    [m4_pushdef([kind], []) m4_pushdef([not_kind], [*])],
    [m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])])
  
  AT_BISON_OPTION_PUSHDEFS([%locations])
  AT_DATA_GRAMMAR([[input]]$1[[.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  %locations
- %initial-action {
-   @$.first_line = @$.last_line = 1;
-   @$.first_column = @$.last_column = 1;
- }
  
  %{
  # include <stdio.h>
@@@ -897,43 -952,32 +958,43 @@@ main (void
  ]])
  AT_BISON_OPTION_POPDEFS
  
 -AT_BISON_CHECK([-o input$1.c input$1.y])
 +AT_BISON_CHECK([-o input$1.c input$1.y], [], [],
 +[m4_if([$1], [0],
- [[input0.y:27.3-5: warning: useless %destructor for type <*> [-Wother]
- input0.y:27.3-5: warning: useless %printer for type <*> [-Wother]
++[[input0.y:23.3-5: warning: useless %destructor for type <*> [-Wother]
++input0.y:23.3-5: warning: useless %printer for type <*> [-Wother]
 +]],
- [[input1.y:27.3-4: warning: useless %destructor for type <> [-Wother]
- input1.y:27.3-4: warning: useless %printer for type <> [-Wother]
++[[input1.y:23.3-4: warning: useless %destructor for type <> [-Wother]
++input1.y:23.3-4: warning: useless %printer for type <> [-Wother]
 +]])])
 +
  AT_COMPILE([input$1])
 +
  AT_PARSER_CHECK([./input$1], 0,
  [[<]]kind[[> for 'E' @ 1.
  <]]kind[[> for 'S' @ 1.
  ]],
  [[Starting parse
  Entering state 0
- Reducing stack by rule 1 (line 46):
- -> $$ = nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1)
+ Reducing stack by rule 1 (line 42):
+ -> $$ = nterm start (1.1: <]]kind[[> for 'S' @ 1)
  Stack now 0
  Entering state 1
  Reading a token: Now at end of input.
- Shifting token END (1.1-1.1: <]]kind[[> for 'E' @ 1)
+ Shifting token END (1.1: <]]kind[[> for 'E' @ 1)
  Entering state 2
  Stack now 0 1 2
- Cleanup: popping token END (1.1-1.1: <]]kind[[> for 'E' @ 1)
- Cleanup: popping nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1)
+ Cleanup: popping token END (1.1: <]]kind[[> for 'E' @ 1)
+ Cleanup: popping nterm start (1.1: <]]kind[[> for 'S' @ 1)
  ]])
  
  m4_popdef([kind])
  m4_popdef([not_kind])
  ])
  
 -_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(0)
 -_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(1)
 +AT_TEST(0)
 +AT_TEST(1)
 +
 +m4_popdef([AT_TEST])
  
  AT_CLEANUP
  
@@@ -993,10 -1037,7 +1054,10 @@@ main (void
  ]])
  AT_BISON_OPTION_POPDEFS
  
 -AT_BISON_CHECK([-o input.c input.y])
 +AT_BISON_CHECK([-o input.c input.y], [], [],
 +[[input.y:21.6-8: warning: useless %destructor for type <*> [-Wother]
 +input.y:21.6-8: warning: useless %printer for type <*> [-Wother]
 +]])
  AT_COMPILE([input])
  AT_PARSER_CHECK([./input], [1], [],
  [[Starting parse
@@@ -1095,10 -1136,7 +1156,10 @@@ main (void
  ]])
  AT_BISON_OPTION_POPDEFS
  
 -AT_BISON_CHECK([-o input.c input.y])
 +AT_BISON_CHECK([-o input.c input.y], [], [],
 +[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
 +input.y:22.3-4: warning: useless %printer for type <> [-Wother]
 +]])
  AT_COMPILE([input])
  
  AT_CLEANUP
@@@ -1155,10 -1193,8 +1216,10 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([-o input.c input.y], 0,,
 -[[input.y:33.3-23: warning: unset value: $$
 -input.y:30.3-35.37: warning: unused value: $3
 +[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
 +input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
 +input.y:33.3-23: warning: unset value: $$ [-Wother]
 +input.y:30.3-35.37: warning: unused value: $3 [-Wother]
  ]])
  
  AT_COMPILE([input])
@@@ -1259,9 -1295,8 +1320,9 @@@ AT_CHECK_ACTION_LOCATIONS([[%printer]]
  ## Qualified $$ in actions.  ##
  ## ------------------------- ##
  
 -# Check that we can used qualified $$ (v.g., $<type>$) not only in
 -# rule actions, but also where $$ is valid: %printer and %destructor.
 +# Check that we can use qualified $$ (v.g., $<type>$) not only in rule
 +# actions, but also where $$ is valid: %destructor/%printer and
 +# %initial-action.
  #
  # FIXME: Not actually checking %destructor, but it's the same code as
  # %printer...
  m4_pushdef([AT_TEST],
  [AT_SETUP([[Qualified $$ in actions: $1]])
  
 -AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1"])
 +AT_BISON_OPTION_PUSHDEFS([%skeleton "$1"])
  
  AT_DATA_GRAMMAR([[input.y]],
  [[%skeleton "$1"
 -%defines   // FIXME: Mandated by lalr1.cc in Bison 2.6.
 -%locations // FIXME: Mandated by lalr1.cc in Bison 2.6.
  %debug
  %code requires
  {
@@@ -1353,7 -1390,10 +1414,7 @@@ AT_FULL_COMPILE([[input]]
  AT_PARSER_CHECK([./input], 0, [], [stderr])
  # Don't be too picky on the traces, GLR is not exactly the same.  Keep
  # only the lines from the printer.
 -#
 -# Don't care about locations.  FIXME: remove their removal when Bison
 -# supports C++ without locations.
 -AT_CHECK([[sed -ne 's/([-0-9.]*: /(/;/ival:/p' stderr]], 0,
 +AT_CHECK([[sed -ne '/ival:/p' stderr]], 0,
  [[Reading a token: Next token is token UNTYPED (ival: 10, fval: 0.1)
  Shifting token UNTYPED (ival: 10, fval: 0.1)
  Reading a token: Next token is token INT (ival: 20, fval: 0.2)
@@@ -1391,37 -1431,37 +1452,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
@@@ -1438,42 -1478,42 +1499,42 @@@ string;"
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o input.c input.y]], [0], [],
 -[[input.y:8.48: warning: a ';' might be needed at the end of action code
 -input.y:8.48: warning: future versions of Bison will not add the ';'
 -input.y:9.48: warning: a ';' might be needed at the end of action code
 -input.y:9.48: warning: future versions of Bison will not add the ';'
 -input.y:10.48: warning: a ';' might be needed at the end of action code
 -input.y:10.48: warning: future versions of Bison will not add the ';'
 -input.y:11.48: warning: a ';' might be needed at the end of action code
 -input.y:11.48: warning: future versions of Bison will not add the ';'
 -input.y:12.48: warning: a ';' might be needed at the end of action code
 -input.y:12.48: warning: future versions of Bison will not add the ';'
 -input.y:13.48: warning: a ';' might be needed at the end of action code
 -input.y:13.48: warning: future versions of Bison will not add the ';'
 -input.y:20.1: warning: a ';' might be needed at the end of action code
 -input.y:20.1: warning: future versions of Bison will not add the ';'
 -input.y:21.1: warning: a ';' might be needed at the end of action code
 -input.y:21.1: warning: future versions of Bison will not add the ';'
 -input.y:22.1: warning: a ';' might be needed at the end of action code
 -input.y:22.1: warning: future versions of Bison will not add the ';'
 -input.y:23.1: warning: a ';' might be needed at the end of action code
 -input.y:23.1: warning: future versions of Bison will not add the ';'
 -input.y:24.1: warning: a ';' might be needed at the end of action code
 -input.y:24.1: warning: future versions of Bison will not add the ';'
 -input.y:25.1: warning: a ';' might be needed at the end of action code
 -input.y:25.1: warning: future versions of Bison will not add the ';'
 -input.y:31.1: warning: a ';' might be needed at the end of action code
 -input.y:31.1: warning: future versions of Bison will not add the ';'
 -input.y:32.1: warning: a ';' might be needed at the end of action code
 -input.y:32.1: warning: future versions of Bison will not add the ';'
 -input.y:33.1: warning: a ';' might be needed at the end of action code
 -input.y:33.1: warning: future versions of Bison will not add the ';'
 -input.y:34.1: warning: a ';' might be needed at the end of action code
 -input.y:34.1: warning: future versions of Bison will not add the ';'
 -input.y:35.1: warning: a ';' might be needed at the end of action code
 -input.y:35.1: warning: future versions of Bison will not add the ';'
 -input.y:36.1: warning: a ';' might be needed at the end of action code
 -input.y:36.1: warning: future versions of Bison will not add the ';'
 +[[input.y:8.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:8.48: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:9.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:9.48: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:10.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:10.48: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:11.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:11.48: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:12.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:12.48: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:13.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:13.48: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:20.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:20.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:21.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:21.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:22.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:22.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:23.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:23.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:24.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:24.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:25.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:25.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:31.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:31.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:32.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:32.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:33.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:33.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:34.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:34.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:35.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:35.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
 +input.y:36.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
 +input.y:36.1: warning: future versions of Bison will not add the ';' [-Wdeprecated]
  ]])
  
  AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]],       [[3]])
diff --combined tests/calc.at
index bdc80284a5adebcc9704f83afa1dc164b4244498,4ab725b38930879f0c39177fd451411015c82098..f336b69eba2aaff1a4de8ce9eb93386663e847e6
@@@ -178,18 -178,7 +178,7 @@@ read_signed_integer (]AT_YYLEX_FORMALS[
  
  ]AT_YYLEX_PROTOTYPE[
  {
-   static int init = 1;
    int c;
-   if (init)
-     {
-       init = 0;
- ]AT_LOCATION_IF([
-       AT_LOC_LAST_COLUMN = 1;
-       AT_LOC_LAST_LINE = 1;
- ])[
-     }
    /* Skip current token, then white spaces.  */
    do
      {
      {
        unget_char (]AT_YYLEX_PRE_ARGS[ c);
        ]AT_VAL[.ival = read_signed_integer (]AT_YYLEX_ARGS[);
 -      return NUM;
 +      return ]AT_TOKEN_PREFIX[NUM;
      }
  
    /* Return end-of-file.  */
    if (c == EOF)
 -    return CALC_EOF;
 +    return ]AT_TOKEN_PREFIX[CALC_EOF;
  
    /* Return single chars. */
    return c;
@@@ -261,6 -250,8 +250,8 @@@ AT_SKEL_CC_IF
  {
    semantic_value ival;
  };
+ %printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
+                           [[fprintf (yyoutput, "%d", $$)]])[; } <ival>;
  
  %code provides
  {
  FILE *input;
  static int power (int base, int exponent);
  
- ]AT_SKEL_CC_IF(,
- [static void yyerror (AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])
-                      AT_PARAM_IF([semantic_value *result, int *count, ])
-                      const char *s
-                      );])[
+ ]AT_YYERROR_DECLARE[
  ]AT_YYLEX_DECLARE_EXTERN[
  }
  
- ]AT_SKEL_CC_IF([AT_LOCATION_IF([AT_LOCATION_TYPE_IF([], [
- /* The lalr1.cc skeleton, for backward compatibility, defines
-    a constructor for position that initializes the filename.  The
-    glr.cc skeleton does not (and in fact cannot: location/position
-    are stored in a union, from which objects with constructors are
-    excluded in C++). */
- %initial-action {
-   @$.initialize ();
- }
- ])])])[
+ ]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([[
+ %initial-action
+ {
+   @$.first.l = @$.first.c = 1;
+   @$.last = @$.first;
+ }]])])[
  
  /* Bison Declarations */
  %token CALC_EOF 0 "end of input"
  %token <ival> NUM "number"
  %type  <ival> exp
  
 -%nonassoc '=' /* comparison            */
 +%nonassoc '='   /* comparison          */
  %left '-' '+'
  %left '*' '/'
 -%left NEG     /* negation--unary minus */
 -%right '^'    /* exponentiation        */
 +%precedence NEG /* negation--unary minus */
 +%right '^'      /* exponentiation        */
  
  /* Grammar follows */
  %%
@@@ -365,27 -348,8 +348,8 @@@ power (int base, int exponent
        o << '-' << s.last.c - 1;
      return o;
    }
- ]])
- AT_YYERROR_DEFINE],
- [/* A C error reporting function.  */
- static void
- yyerror (AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])
-          AT_PARAM_IF([semantic_value *result, int *count, ])
-          const char *s)
- {
- AT_PARAM_IF([(void) result; (void) count;])
- AT_YYERROR_SEES_LOC_IF([
-   fprintf (stderr, "%d.%d",
-            AT_LOC_FIRST_LINE, AT_LOC_FIRST_COLUMN);
-   if (AT_LOC_FIRST_LINE != AT_LOC_LAST_LINE)
-     fprintf (stderr, "-%d.%d",
-              AT_LOC_LAST_LINE,  AT_LOC_LAST_COLUMN - 1);
-   else if (AT_LOC_FIRST_COLUMN != AT_LOC_LAST_COLUMN - 1)
-     fprintf (stderr, "-%d",
-              AT_LOC_LAST_COLUMN - 1);
-   fprintf (stderr, ": ");])
-   fprintf (stderr, "%s\n", s);
- }])[
+ ]])])[
+ ]AT_YYERROR_DEFINE[
  ]AT_DEFINES_IF([],
  [AT_CALC_LEX
  AT_CALC_MAIN])])
@@@ -448,7 -412,7 +412,7 @@@ AT_PARSER_CHECK([./calc input], 0, [], 
  # If BISON-OPTIONS contains `%location', then make sure the ERROR-LOCATION
  # is correctly output on stderr.
  #
 -# If BISON-OPTIONS contains `%error-verbose', then make sure the
 +# If BISON-OPTIONS contains `%define parse.error verbose', then make sure the
  # IF-YYERROR-VERBOSE message is properly output after `syntax error, '
  # on STDERR.
  #
@@@ -490,7 -454,7 +454,7 @@@ AT_YYERROR_SEES_LOC_IF([]
  [[sed 's/^[-0-9.]*: //' expout >at-expout
  mv at-expout expout]])
  # 4. If error-verbose is not used, strip the`, unexpected....' part.
 -m4_bmatch([$1], [%error-verbose], [],
 +m4_bmatch([$1], [%define parse.error verbose], [],
  [[sed 's/syntax error, .*$/syntax error/' expout >at-expout
  mv at-expout expout]])
  # 5. Check
@@@ -508,10 -472,8 +472,10 @@@ m4_define([AT_CHECK_SPACES]
    print "$.: {$_}\n"
      if (# No starting/ending empty lines.
          (eof || $. == 1) && /^\s*$/
 -        # No trailing space.  FIXME: not ready for "maint".
 -        # || /\s$/
 +        # No trailing space.
 +        || /\s$/
 +        # No tabs.
 +        || /\t/
          )' $1
  ])dnl
  ])
@@@ -552,7 -514,7 +516,7 @@@ _AT_CHECK_CALC([$1]
                 [842])
  
  # Some syntax errors.
- _AT_CHECK_CALC_ERROR([$1], [1], [0 0], [15],
+ _AT_CHECK_CALC_ERROR([$1], [1], [1 2], [15],
                       [1.3: syntax error, unexpected number])
  _AT_CHECK_CALC_ERROR([$1], [1], [1//2], [20],
                       [1.3: syntax error, unexpected '/', expecting number or '-' or '(' or '!'])
@@@ -596,10 -558,10 +560,10 @@@ calc: error: 4444 != 1]
  
  # The same, but this time exercising explicitly triggered syntax errors.
  # POSIX says the lookahead causing the error should not be discarded.
- _AT_CHECK_CALC_ERROR([$1], [0], [(!) + (0 0) = 1], [102],
+ _AT_CHECK_CALC_ERROR([$1], [0], [(!) + (1 2) = 1], [102],
  [1.10: syntax error, unexpected number
  calc: error: 2222 != 1])
- _AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (0 0) = 1], [113],
+ _AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (1 2) = 1], [113],
  [1.4: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
  1.12: syntax error, unexpected number
  calc: error: 2222 != 1])
@@@ -637,26 -599,26 +601,26 @@@ AT_CHECK_CALC_LALR(
  AT_CHECK_CALC_LALR([%defines])
  AT_CHECK_CALC_LALR([%locations])
  
 -AT_CHECK_CALC_LALR([%name-prefix="calc"]) dnl test deprecated `='
 +AT_CHECK_CALC_LALR([%name-prefix "calc"])
  AT_CHECK_CALC_LALR([%verbose])
  AT_CHECK_CALC_LALR([%yacc])
 -AT_CHECK_CALC_LALR([%error-verbose])
 +AT_CHECK_CALC_LALR([%define parse.error verbose])
  
  AT_CHECK_CALC_LALR([%define api.pure %locations])
  AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %locations])
 -AT_CHECK_CALC_LALR([%error-verbose %locations])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %locations])
  
 -AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR([%error-verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
  
  AT_CHECK_CALC_LALR([%debug])
 -AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
  
 -AT_CHECK_CALC_LALR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
  
- AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
 -AT_CHECK_CALC_LALR([%define api.pure %error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
++AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
  
  
  # ----------------------- #
@@@ -681,21 -643,21 +645,21 @@@ AT_CHECK_CALC_GLR([%name-prefix "calc"]
  AT_CHECK_CALC_GLR([%define api.prefix "calc"])
  AT_CHECK_CALC_GLR([%verbose])
  AT_CHECK_CALC_GLR([%yacc])
 -AT_CHECK_CALC_GLR([%error-verbose])
 +AT_CHECK_CALC_GLR([%define parse.error verbose])
  
  AT_CHECK_CALC_GLR([%define api.pure %locations])
 -AT_CHECK_CALC_GLR([%error-verbose %locations])
 +AT_CHECK_CALC_GLR([%define parse.error verbose %locations])
  
 -AT_CHECK_CALC_GLR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR([%define parse.error verbose %locations %defines %name-prefix "calc" %verbose %yacc])
  
  AT_CHECK_CALC_GLR([%debug])
 -AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
  
 -AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
  
- AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
- AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
 -AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 -AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
++AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
++AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
  
  
  # ----------------------------- #
  AT_BANNER([[Simple LALR(1) C++ Calculator.]])
  
  # First let's try using %skeleton
 -AT_CHECK_CALC([%skeleton "lalr1.cc" %defines %locations])
 +AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
  
  # AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
  # ---------------------------------------
  # Start a testing chunk which compiles `calc' grammar with
  # the C++ skeleton, and performs several tests over the parser.
  m4_define([AT_CHECK_CALC_LALR1_CC],
 -[AT_CHECK_CALC([%language "C++" %defines %locations] $@)])
 +[AT_CHECK_CALC([%language "C++"] $@)])
  
  AT_CHECK_CALC_LALR1_CC([])
 -AT_CHECK_CALC_LALR1_CC([%define api.location.type Span])
 -AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR1_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations])
 +AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type Span])
 +AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
  
 -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
  
 -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
 +
- AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
++AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 +
- AT_CHECK_CALC_LALR1_CC([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
- AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
++AT_CHECK_CALC_LALR1_CC([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
++AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
  
  
  
  AT_BANNER([[Simple GLR C++ Calculator.]])
  
  # Again, we try also using %skeleton.
 -AT_CHECK_CALC([%skeleton "glr.cc" %defines %locations])
 +AT_CHECK_CALC([%skeleton "glr.cc"])
  
  # AT_CHECK_CALC_GLR_CC([BISON-OPTIONS])
  # -------------------------------------
  # Start a testing chunk which compiles `calc' grammar with
  # the GLR C++ skeleton, and performs several tests over the parser.
  m4_define([AT_CHECK_CALC_GLR_CC],
 -[AT_CHECK_CALC([%language "C++" %glr-parser %defines %locations] $@)])
 +[AT_CHECK_CALC([%language "C++" %glr-parser] $@)])
  
  AT_CHECK_CALC_GLR_CC([])
 -AT_CHECK_CALC_GLR_CC([%define api.location.type Span])
 -AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_GLR_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%locations])
 +AT_CHECK_CALC_GLR_CC([%locations %define api.location.type Span])
 +AT_CHECK_CALC_GLR_CC([%defines %define parse.error verbose %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix "calc" %verbose %yacc])
  
  AT_CHECK_CALC_GLR_CC([%debug])
 -AT_CHECK_CALC_GLR_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
  
 -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
  
- AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
- AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} {int *count}])
 -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
++AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
++AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
diff --combined tests/glr-regression.at
index b376c1c05ea771bdadfa0beef1c4f033b478a07b,ad93d40e1b5519379b9a8ad11ebd44c0f550f650..80248aa4e661a6232f5841ca9473d1688c1dca43
@@@ -93,8 -93,8 +93,8 @@@ yylex (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr1.c glr-regr1.y]], 0, [],
 -[glr-regr1.y: conflicts: 1 shift/reduce
 -])
 +[[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +]])
  AT_COMPILE([glr-regr1])
  AT_PARSER_CHECK([[echo BPBPB | ./glr-regr1]], 0,
  [[E -> 'B'
@@@ -208,8 -208,8 +208,8 @@@ main (int argc, char **argv
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [],
 -[glr-regr2a.y: conflicts: 2 shift/reduce
 -])
 +[[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
 +]])
  AT_COMPILE([glr-regr2a])
  
  AT_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0,
@@@ -325,9 -325,8 +325,9 @@@ main(int argc, char* argv[]
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [],
 -[glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce
 -])
 +[[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr3])
  
  AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]],
@@@ -418,8 -417,8 +418,8 @@@ merge (YYSTYPE s1, YYSTYPE s2
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [],
 -[glr-regr4.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr4])
  
  AT_PARSER_CHECK([[./glr-regr4]], 0,
@@@ -478,8 -477,8 +478,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [],
 -[glr-regr5.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr5])
  
  AT_PARSER_CHECK([[./glr-regr5]], 0, [],
@@@ -530,8 -529,8 +530,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [],
 -[glr-regr6.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr6])
  
  AT_PARSER_CHECK([[./glr-regr6]], 0,
@@@ -619,8 -618,8 +619,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [],
 -[glr-regr7.y: conflicts: 2 reduce/reduce
 -])
 +[[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr7])
  
  AT_PARSER_CHECK([[./glr-regr7]], 2, [],
@@@ -713,8 -712,8 +713,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [],
 -[glr-regr8.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr8])
  
  AT_PARSER_CHECK([[./glr-regr8]], 0,
@@@ -793,8 -792,8 +793,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [],
 -[glr-regr9.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr9])
  
  AT_PARSER_CHECK([[./glr-regr9]], 0, [],
@@@ -849,8 -848,8 +849,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [],
 -[glr-regr10.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr10])
  
  AT_PARSER_CHECK([[./glr-regr10]], 0, [], [])
@@@ -907,8 -906,8 +907,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [],
 -[glr-regr11.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr11])
  
  AT_PARSER_CHECK([[./glr-regr11]], 0, [], [])
@@@ -1028,9 -1027,8 +1028,9 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [],
 -[glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
 -])
 +[[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr12])
  
  AT_PARSER_CHECK([[./glr-regr12]], 0, [], [])
@@@ -1359,8 -1357,8 +1359,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [],
 -[glr-regr14.y: conflicts: 3 reduce/reduce
 -])
 +[[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr14])
  
  AT_PARSER_CHECK([[./glr-regr14]], 0,
@@@ -1452,8 -1450,8 +1452,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [],
 -[glr-regr15.y: conflicts: 2 reduce/reduce
 -])
 +[[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr15])
  
  AT_PARSER_CHECK([[./glr-regr15]], 0, [],
@@@ -1512,8 -1510,8 +1512,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [],
 -[glr-regr16.y: conflicts: 1 reduce/reduce
 -])
 +[[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr16])
  
  AT_PARSER_CHECK([[./glr-regr16]], 0, [],
@@@ -1545,13 -1543,6 +1545,6 @@@ AT_DATA_GRAMMAR([glr-regr17.y]
    ]AT_YYLEX_DECLARE[
  %}
  
- %initial-action {
-   @$.first_line = 1;
-   @$.first_column = 1;
-   @$.last_line = 1;
-   @$.last_column = 1;
- }
  %%
  
  /* Tests the case of an empty RHS that has inherited the location of the
@@@ -1597,8 -1588,8 +1590,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [],
 -[glr-regr17.y: conflicts: 3 reduce/reduce
 -])
 +[[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
 +]])
  AT_COMPILE([glr-regr17])
  
  AT_PARSER_CHECK([[./glr-regr17]], 0, [],
@@@ -1652,11 -1643,11 +1645,11 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
 -[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
 +[[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
  glr-regr18.y:25.18-24:     previous declaration
  glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
  glr-regr18.y:26.18-24:     previous declaration
 -])
 +]])
  
  AT_CLEANUP
  
@@@ -1700,8 -1691,8 +1693,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o input.c input.y]], 0, [],
 -[input.y: conflicts: 1 reduce/reduce
 -])
 +[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +]])
  AT_COMPILE([input])
  
  AT_PARSER_CHECK([[./input]], 1, [],
diff --combined tests/headers.at
index 4192c05b68b5b23fed0f6ea792efc68e4080ed67,8a05d34d8ddfe1cb314aa430ced0d19a30093290..509a413df82a1478d8517fcee4570875e9997bd2
@@@ -169,14 -169,13 +169,14 @@@ AT_SKEL_CC_IF([]
    [AT_CHECK([$EGREP yy $1.h], [1])])
  
  # Check there is not 'YY' left.
 -# Ignore comments, YYPARSE_PARAM (obsolete), YYPUSH_MORE(_DEFINED)?
 -# (constant definition), YY_\w+_INCLUDED (header guards).
 +# Ignore comments, YYPUSH_MORE(_DEFINED)?  (constant definition),
 +# YY_\w+_INCLUDED (header guards).
  #
  # YYDEBUG (not renamed) can be read, but not changed.
 -AT_CHECK([[sed -ne 's,/\*[^*]*\*/,,g;s,//.*,,' \
 -                -e '/YY/p' ]$1.AT_SKEL_CC_IF([hh], [h])[ |
 -     $EGREP -wv 'YY(PARSE_PARAM|PUSH_MORE(_DEFINED)?|_[0-9A-Z_]+_INCLUDED)|(defined|if) YYDEBUG']],
 +AT_CHECK([[$PERL -0777 -e 's{/\*.*?\*/}{}sg;s,//.*,,;' \
 +            ]$1.AT_SKEL_CC_IF([hh], [h])[ |
 +         grep 'YY' |
 +     $EGREP -wv 'YY(PUSH_MORE(_DEFINED)?|_[0-9A-Z_]+_INCLUDED)|(defined|if) YYDEBUG']],
           [1])
  
  AT_LANG_COMPILE([$1.o])
@@@ -241,9 -240,6 +241,6 @@@ AT_TEST([x7], [%define api.push-pull bo
  AT_TEST([x8], [%define api.pure %define api.push-pull both])
  #AT_TEST([x5], [%locations %language "c++" %glr-parser])
  
- AT_COMPILE_CXX([parser], [[x[1-8].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
- AT_CHECK([./parser], [0], [[expout]])
  # Check that the headers are self-contained, and protected against
  # multiple inclusions.  While at it, check they are sane for C++.
  for h in *.h *.hh
@@@ -257,6 -253,12 +254,12 @@@ EO
    AT_COMPILE_CXX([$h.o])
  done
  
+ # Do this late, so that other checks have been performed.
+ AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
+ AT_COMPILE_CXX([parser], [[x[1-8].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
+ AT_CHECK([./parser], [0], [[expout]])
  m4_popdef([AT_TEST])
  
  AT_CLEANUP
diff --combined tests/input.at
index 181a2dd6e04ec493192faf065aa207a4e365e610,35812c807be1c4b4114d8c8d208ae3dd9ee9724e..f7f5adfc9e978a820405421cf52c4a6e909ea451
@@@ -20,6 -20,67 +20,67 @@@ AT_BANNER([[Input Processing.]]
  # Mostly test that we are robust to mistakes.
  
  
+ ## ---------------- ##
+ ## Invalid inputs.  ##
+ ## ---------------- ##
+ AT_SETUP([Invalid inputs])
+ AT_DATA([input.y],
+ [[\000\001\002\377?
+ %%
+ ?
+ default: 'a' }
+ %&
+ %a-does-not-exist
+ %-
+ %{
+ ]])
+ AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y || exit 77]])
+ AT_BISON_CHECK([input.y], [1], [],
+ [[input.y:1.1: error: invalid character: '\0'
+ input.y:1.1: error: invalid character: '\001'
+ input.y:1.1: error: invalid character: '\002'
+ input.y:1.1: error: invalid character: '\377'
+ input.y:1.2: error: invalid character: '?'
+ input.y:3.1: error: invalid character: '?'
+ input.y:4.14: error: invalid character: '}'
+ input.y:5.1: error: invalid character: '%'
+ input.y:5.2: error: invalid character: '&'
+ input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
+ input.y:7.1: error: invalid character: '%'
+ input.y:7.2: error: invalid character: '-'
+ input.y:8.1-9.0: error: missing '%}' at end of file
+ input.y:8.1-9.0: error: syntax error, unexpected %{...%}
+ ]])
+ AT_CLEANUP
+ AT_SETUP([Invalid inputs with {}])
+ # We used to SEGV here.  See
+ # http://lists.gnu.org/archive/html/bug-bison/2005-07/msg00053.html
+ AT_DATA([input.y],
+ [[
+ %destructor
+ %initial-action
+ %lex-param
+ %parse-param
+ %printer
+ %union
+ ]])
+ AT_BISON_CHECK([input.y], [1], [],
+ [[input.y:3.1-15: error: syntax error, unexpected %initial-action, expecting {...}
+ ]])
+ AT_CLEANUP
  ## ------------ ##
  ## Invalid $n.  ##
  ## ------------ ##
@@@ -60,9 -121,9 +121,9 @@@ exp: foo { $$; } foo { $2; } fo
  AT_BISON_CHECK([input.y], [1], [],
  [[input.y:5.12-13: error: $$ for the midrule at $2 of 'exp' has no declared type
  input.y:5.24-25: error: $2 of 'exp' has no declared type
 -input.y:5.6-32: warning: type clash on default action: <bar> != <>
 -input.y:6.6-8: warning: type clash on default action: <bar> != <>
 -input.y:7.5: warning: empty rule for typed nonterminal, and no action
 +input.y:5.6-32: warning: type clash on default action: <bar> != <> [-Wother]
 +input.y:6.6-8: warning: type clash on default action: <bar> != <> [-Wother]
 +input.y:7.5: warning: empty rule for typed nonterminal, and no action [-Wother]
  ]])
  
  AT_CLEANUP
  # --------------------------------
  # Generate the token, type, and destructor
  # declarations for the unused values tests.
 -
  m4_define([_AT_UNUSED_VALUES_DECLARATIONS],
  [[[%token <integer> INT;
  %type <integer> a b c d e f g h i j k l;
  
  
  # AT_CHECK_UNUSED_VALUES(DECLARATIONS_AFTER, CHECK_MIDRULE_VALUES)
 -# ------------------------------------------------------------------
 -# Generate a grammar to test unused values,
 -# compile it, run it.  If DECLARATIONS_AFTER
 -# is set, then the token, type, and destructor
 -# declarations are generated after the rules
 -# rather than before.  If CHECK_MIDRULE_VALUES
 -# is set, then --warnings=midrule-values is
 -# set.
 -
 +# ----------------------------------------------------------------
 +# Generate a grammar to test unused values, compile it, run it.  If
 +# DECLARATIONS_AFTER is set, then the token, type, and destructor
 +# declarations are generated after the rules rather than before.  If
 +# CHECK_MIDRULE_VALUES is set, then --warnings=midrule-values is set.
  m4_define([AT_CHECK_UNUSED_VALUES],
  [AT_DATA([input.y],
  m4_ifval($1, [
@@@ -113,39 -179,39 +174,39 @@@ _AT_UNUSED_VALUES_DECLARATIONS]
  )
  
  AT_BISON_CHECK(m4_ifval($2, [ --warnings=midrule-values ])[ input.y], [0], [],
 -[[input.y:11.10-32: warning: unset value: $]$[
 -input.y:11.10-32: warning: unused value: $]1[
 -input.y:11.10-32: warning: unused value: $]3[
 -input.y:11.10-32: warning: unused value: $]5[
 -input.y:12.9: warning: empty rule for typed nonterminal, and no action
 -]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $$
 -input.y:13.26-41: warning: unset value: $$
 -]]])[[input.y:13.10-62: warning: unset value: $]$[
 -input.y:13.10-62: warning: unused value: $]3[
 -input.y:13.10-62: warning: unused value: $]5[
 -]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $$
 -]]])[[input.y:14.10-49: warning: unset value: $]$[
 -input.y:14.10-49: warning: unused value: $]3[
 -input.y:14.10-49: warning: unused value: $]5[
 -input.y:15.10-37: warning: unset value: $]$[
 -input.y:15.10-37: warning: unused value: $]3[
 -input.y:15.10-37: warning: unused value: $]5[
 -input.y:17.10-58: warning: unset value: $]$[
 -input.y:17.10-58: warning: unused value: $]1[
 -]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]2[
 -]]])[[input.y:17.10-58: warning: unused value: $]3[
 -]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]4[
 -]]])[[input.y:17.10-58: warning: unused value: $]5[
 -input.y:18.10-72: warning: unset value: $]$[
 -input.y:18.10-72: warning: unused value: $]1[
 -input.y:18.10-72: warning: unused value: $]3[
 -]]m4_ifval($2, [[[input.y:18.10-72: warning: unused value: $]4[
 -]]])[[input.y:18.10-72: warning: unused value: $]5[
 -]]m4_ifval($2, [[[input.y:20.10-55: warning: unused value: $]3[
 -]]])[[input.y:21.10-68: warning: unset value: $]$[
 -input.y:21.10-68: warning: unused value: $]1[
 -input.y:21.10-68: warning: unused value: $]2[
 -]]m4_ifval($2, [[[input.y:21.10-68: warning: unused value: $]4[
 +[[input.y:11.10-32: warning: unset value: $]$[ [-Wother]
 +input.y:11.10-32: warning: unused value: $]1[ [-Wother]
 +input.y:11.10-32: warning: unused value: $]3[ [-Wother]
 +input.y:11.10-32: warning: unused value: $]5[ [-Wother]
 +input.y:12.9: warning: empty rule for typed nonterminal, and no action [-Wother]
 +]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $$ [-Wmidrule-values]
 +input.y:13.26-41: warning: unset value: $$ [-Wmidrule-values]
 +]]])[[input.y:13.10-62: warning: unset value: $]$[ [-Wother]
 +input.y:13.10-62: warning: unused value: $]3[ [-Wother]
 +input.y:13.10-62: warning: unused value: $]5[ [-Wother]
 +]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $$ [-Wmidrule-values]
 +]]])[[input.y:14.10-49: warning: unset value: $]$[ [-Wother]
 +input.y:14.10-49: warning: unused value: $]3[ [-Wother]
 +input.y:14.10-49: warning: unused value: $]5[ [-Wother]
 +input.y:15.10-37: warning: unset value: $]$[ [-Wother]
 +input.y:15.10-37: warning: unused value: $]3[ [-Wother]
 +input.y:15.10-37: warning: unused value: $]5[ [-Wother]
 +input.y:17.10-58: warning: unset value: $]$[ [-Wother]
 +input.y:17.10-58: warning: unused value: $]1[ [-Wother]
 +]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]2[ [-Wmidrule-values]
 +]]])[[input.y:17.10-58: warning: unused value: $]3[ [-Wother]
 +]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]4[ [-Wmidrule-values]
 +]]])[[input.y:17.10-58: warning: unused value: $]5[ [-Wother]
 +input.y:18.10-72: warning: unset value: $]$[ [-Wother]
 +input.y:18.10-72: warning: unused value: $]1[ [-Wother]
 +input.y:18.10-72: warning: unused value: $]3[ [-Wother]
 +]]m4_ifval($2, [[[input.y:18.10-72: warning: unused value: $]4[ [-Wmidrule-values]
 +]]])[[input.y:18.10-72: warning: unused value: $]5[ [-Wother]
 +]]m4_ifval($2, [[[input.y:20.10-55: warning: unused value: $]3[ [-Wmidrule-values]
 +]]])[[input.y:21.10-68: warning: unset value: $]$[ [-Wother]
 +input.y:21.10-68: warning: unused value: $]1[ [-Wother]
 +input.y:21.10-68: warning: unused value: $]2[ [-Wother]
 +]]m4_ifval($2, [[[input.y:21.10-68: warning: unused value: $]4[ [-Wmidrule-values]
  ]]]))])
  
  
@@@ -200,29 -266,29 +261,29 @@@ start: 
  ]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:1.13-29: error: redeclaration for default tagged %destructor
 +[[input.y:1.13-29: error: %destructor redeclaration for <*>
  input.y:1.13-29:     previous declaration
 -input.y:2.10-24: error: redeclaration for default tagged %printer
 +input.y:2.10-24: error: %printer redeclaration for <*>
  input.y:2.10-24:     previous declaration
 -input.y:4.13-29: error: redeclaration for default tagged %destructor
 +input.y:4.13-29: error: %destructor redeclaration for <*>
  input.y:1.13-29:     previous declaration
 -input.y:5.10-24: error: redeclaration for default tagged %printer
 +input.y:5.10-24: error: %printer redeclaration for <*>
  input.y:2.10-24:     previous declaration
 -input.y:7.13-29: error: redeclaration for default tagless %destructor
 +input.y:7.13-29: error: %destructor redeclaration for <>
  input.y:7.13-29:     previous declaration
 -input.y:8.10-24: error: redeclaration for default tagless %printer
 +input.y:8.10-24: error: %printer redeclaration for <>
  input.y:8.10-24:     previous declaration
 -input.y:10.13-29: error: redeclaration for default tagless %destructor
 +input.y:10.13-29: error: %destructor redeclaration for <>
  input.y:7.13-29:      previous declaration
 -input.y:11.10-24: error: redeclaration for default tagless %printer
 +input.y:11.10-24: error: %printer redeclaration for <>
  input.y:8.10-24:      previous declaration
 -input.y:17.13-29: error: redeclaration for default tagged %destructor
 +input.y:17.13-29: error: %destructor redeclaration for <*>
  input.y:4.13-29:      previous declaration
 -input.y:18.10-24: error: redeclaration for default tagged %printer
 +input.y:18.10-24: error: %printer redeclaration for <*>
  input.y:5.10-24:      previous declaration
 -input.y:20.13-29: error: redeclaration for default tagless %destructor
 +input.y:20.13-29: error: %destructor redeclaration for <>
  input.y:10.13-29:     previous declaration
 -input.y:21.10-24: error: redeclaration for default tagless %printer
 +input.y:21.10-24: error: %printer redeclaration for <>
  input.y:11.10-24:     previous declaration
  ]])
  
@@@ -271,123 -337,6 +332,123 @@@ input.y:5.10-24:      previous declarat
  
  AT_CLEANUP
  
 +## ------------------- ##
 +## Undefined symbols.  ##
 +## ------------------- ##
 +
 +AT_SETUP([Undefined symbols])
 +
 +AT_DATA([[input.y]],
 +[[%printer {} foo baz
 +%destructor {} bar
 +%type <foo> qux
 +%%
 +exp: bar;
 +]])
 +
 +AT_BISON_CHECK([input.y], [1], [],
 +[[input.y:2.16-18: error: symbol bar is used, but is not defined as a token and has no rules
 +input.y:1.17-19: warning: symbol baz is used, but is not defined as a token and has no rules [-Wother]
 +input.y:1.13-15: warning: symbol foo is used, but is not defined as a token and has no rules [-Wother]
 +input.y:3.13-15: warning: symbol qux is used, but is not defined as a token and has no rules [-Wother]
 +]])
 +
 +AT_CLEANUP
 +
 +
 +## ----------------------------------------------------- ##
 +## Unassociated types used for a printer or destructor.  ##
 +## ----------------------------------------------------- ##
 +
 +AT_SETUP([Unassociated types used for a printer or destructor])
 +
 +AT_DATA([[input.y]],
 +[[%token <type1> tag1
 +%type <type2> tag2
 +
 +%printer { } <type1> <type3>
 +%destructor { } <type2> <type4>
 +
 +%%
 +
 +exp: tag1 { $1; }
 +   | tag2 { $1; }
 +
 +tag2: "a" { $$; }
 +]])
 +
 +AT_BISON_CHECK([input.y], [0], [],
 +[[input.y:4.22-28: warning: type <type3> is used, but is not associated to any symbol [-Wother]
 +input.y:5.25-31: warning: type <type4> is used, but is not associated to any symbol [-Wother]
 +]])
 +
 +AT_CLEANUP
 +
 +
 +## --------------------------------- ##
 +## Useless printers or destructors.  ##
 +## --------------------------------- ##
 +
 +AT_SETUP([Useless printers or destructors])
 +
 +# AT_TEST([INPUT], [STDERR])
 +# --------------------------
 +m4_pushdef([AT_TEST],
 +[AT_DATA([[input.y]],
 +[$1
 +])
 +AT_BISON_CHECK([input.y], [0], [], [$2
 +])])
 +
 +AT_TEST([[%token <type1> token1
 +%token <type2> token2
 +%token <type3> token3
 +%token <type4> token4
 +%token <type5> token51 token52
 +%token <type6> token61 token62
 +%token <type7> token7
 +
 +%printer {} token1
 +%destructor {} token2
 +%printer {} token51
 +%destructor {} token61
 +
 +%printer {} token7
 +
 +%printer {} <type1>
 +%destructor {} <type2>
 +%printer {} <type3>
 +%destructor {} <type4>
 +
 +%printer {} <type5>
 +%destructor {} <type6>
 +
 +%destructor {} <type7>
 +
 +%%
 +exp: "a";]],
 +[[input.y:16.13-19: warning: useless %printer for type <type1> [-Wother]
 +input.y:17.16-22: warning: useless %destructor for type <type2> [-Wother]]])
 +
 +# If everybody is typed, <> is useless.
 +AT_TEST([[%type <type> exp
 +%token <type> a
 +%printer {} <> <*>
 +%%
 +exp: a;]],
 +[[input.y:3.13-14: warning: useless %printer for type <> [-Wother]]])
 +
 +# If nobody is typed, <*> is useless.
 +AT_TEST([[%token a
 +%printer {} <> <*>
 +%%
 +exp: a;]],
 +[[input.y:2.16-18: warning: useless %printer for type <*> [-Wother]]])
 +
 +m4_popdef([AT_TEST])
 +
 +AT_CLEANUP
 +
  
  ## ---------------------------------------- ##
  ## Unused values with default %destructor.  ##
@@@ -407,9 -356,9 +468,9 @@@ tagged: { } 
  ]])
  
  AT_BISON_CHECK([input.y], [0], [],
 -[[input.y:6.8-45: warning: unset value: $$
 -input.y:6.8-45: warning: unused value: $2
 -input.y:7.6-8: warning: unset value: $$
 +[[input.y:6.8-45: warning: unset value: $$ [-Wother]
 +input.y:6.8-45: warning: unused value: $2 [-Wother]
 +input.y:7.6-8: warning: unset value: $$ [-Wother]
  ]])
  
  AT_DATA([[input.y]],
@@@ -424,8 -373,8 +485,8 @@@ tagged: { } 
  ]])
  
  AT_BISON_CHECK([input.y], [0], [],
 -[[input.y:6.8-45: warning: unused value: $4
 -input.y:8.9-11: warning: unset value: $$
 +[[input.y:6.8-45: warning: unused value: $4 [-Wother]
 +input.y:8.9-11: warning: unset value: $$ [-Wother]
  ]])
  
  AT_CLEANUP
@@@ -448,9 -397,9 +509,9 @@@ end: { }  
  ]])
  
  AT_BISON_CHECK([input.y], [0], [],
 -[[input.y:6.8-22: warning: unset value: $$
 -input.y:6.8-22: warning: unused value: $2
 -input.y:7.6-8: warning: unset value: $$
 +[[input.y:6.8-22: warning: unset value: $$ [-Wother]
 +input.y:6.8-22: warning: unused value: $2 [-Wother]
 +input.y:7.6-8: warning: unset value: $$ [-Wother]
  ]])
  
  AT_CLEANUP
@@@ -628,7 -577,7 +689,7 @@@ yylex (void
  }
  ]])
  
 -# Pacify Emacs' font-lock-mode: "
 +# Pacify Emacs'font-lock-mode: "
  
  AT_DATA([main.c],
  [[typedef int value;
@@@ -707,8 -656,8 +768,8 @@@ AT_CHECK_REQUIRE(100.0, 63
  
  AT_SETUP([String aliases for character tokens])
  
 -# Bison once thought a character token and its alias were different symbols
 -# with the same user token number.
 +# Bison once thought a character token and its alias were different
 +# symbols with the same user token number.
  
  AT_DATA_GRAMMAR([input.y],
  [[%token 'a' "a"
@@@ -751,15 -700,15 +812,15 @@@ without_period: "WITHOUT.PERIOD"
  AT_BISON_OPTION_POPDEFS
  
  # POSIX Yacc accept periods, but not dashes.
 -AT_BISON_CHECK([--yacc input.y], [1], [],
 -[[input.y:9.8-16: POSIX Yacc forbids dashes in symbol names: WITH-DASH
 -input.y:18.8-16: POSIX Yacc forbids dashes in symbol names: with-dash
 +AT_BISON_CHECK([--yacc -Wno-error input.y], [], [],
 +[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH [-Wyacc]
 +input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
  ]])
  
  # So warn about them.
  AT_BISON_CHECK([-Wyacc input.y], [], [],
 -[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH
 -input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash
 +[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH [-Wyacc]
 +input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
  ]])
  
  # Dashes are fine for GNU Bison.
@@@ -832,10 -781,10 +893,10 @@@ AT_CLEANU
  
  AT_SETUP([Unclosed constructs])
  
 -# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed constructs, so
 -# they were prepended to whatever it STRING_GROW'ed next.  It also threw them
 -# away rather than returning them to the parser.  The effect was confusing
 -# subsequent error messages.
 +# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed
 +# constructs, so they were prepended to whatever it STRING_GROW'ed
 +# next.  It also threw them away rather than returning them to the
 +# parser.  The effect was confusing subsequent error messages.
  
  AT_DATA([input.y],
  [[%token A "a
@@@ -877,8 -826,8 +938,8 @@@ AT_CLEANU
  
  AT_SETUP([%start after first rule])
  
 -# Bison once complained that a %start after the first rule was a redeclaration
 -# of the start symbol.
 +# Bison once complained that a %start after the first rule was a
 +# redeclaration of the start symbol.
  
  AT_DATA([input.y],
  [[%%
@@@ -927,7 -876,7 +988,7 @@@ start: %prec PREC 
  ]])
  
  AT_BISON_CHECK([[input.y]], [[0]], [],
 -[[input.y:2.8-17: warning: token for %prec is not defined: PREC
 +[[input.y:2.8-17: warning: token for %prec is not defined: PREC [-Wother]
  ]])
  
  AT_CLEANUP
@@@ -1139,15 -1088,15 +1200,15 @@@ AT_SETUP([[%define enum variables]]
  
  # Front-end.
  AT_DATA([[input.y]],
 -[[%define lr.default-reductions bogus
 +[[%define lr.default-reduction bogus
  %%
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [[1]], [[]],
 -[[input.y:1.9-29: error: invalid value for %define variable 'lr.default-reductions': 'bogus'
 -input.y:1.9-29:     accepted value: 'most'
 -input.y:1.9-29:     accepted value: 'consistent'
 -input.y:1.9-29:     accepted value: 'accepting'
 +[[input.y:1.9-28: error: invalid value for %define variable 'lr.default-reduction': 'bogus'
 +input.y:1.9-28:     accepted value: 'most'
 +input.y:1.9-28:     accepted value: 'consistent'
 +input.y:1.9-28:     accepted value: 'accepting'
  ]])
  
  # Back-end.
@@@ -1159,9 -1108,9 +1220,9 @@@ start: 
  ]])
  AT_BISON_CHECK([[input.y]], [1], [],
  [[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
 -input.y:1.9-21: error: accepted value: 'pull'
 -input.y:1.9-21: error: accepted value: 'push'
 -input.y:1.9-21: error: accepted value: 'both'
 +input.y:1.9-21:     accepted value: 'pull'
 +input.y:1.9-21:     accepted value: 'push'
 +input.y:1.9-21:     accepted value: 'both'
  ]])
  
  AT_CLEANUP
@@@ -1181,11 -1130,10 +1242,11 @@@ AT_DATA([[input.y]]
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [1], [],
 -[[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
 -input.y:1.9-21: error: accepted value: 'pull'
 -input.y:1.9-21: error: accepted value: 'push'
 -input.y:1.9-21: error: accepted value: 'both'
 +[[input.y:1.9-21: warning: deprecated %define variable name: 'api.push_pull', use 'api.push-pull' [-Wdeprecated]
 +input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
 +input.y:1.9-21:     accepted value: 'pull'
 +input.y:1.9-21:     accepted value: 'push'
 +input.y:1.9-21:     accepted value: 'both'
  ]])
  
  AT_DATA([[input.y]],
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [1], [],
 -[[input.y:1.9-34: error: invalid value for %define Boolean variable 'lr.keep-unreachable-states'
 +[[input.y:1.9-34: warning: deprecated %define variable name: 'lr.keep_unreachable_states', use 'lr.keep-unreachable-state' [-Wdeprecated]
 +input.y:1.9-34: error: invalid value for %define Boolean variable 'lr.keep-unreachable-state'
 +]])
 +
 +AT_DATA([[input.y]],
 +[[%define namespace "foo"
 +%define api.namespace "foo"
 +%%
 +start: ;
 +]])
 +AT_BISON_CHECK([[input.y]], [1], [],
 +[[input.y:1.9-17: warning: deprecated %define variable name: 'namespace', use 'api.namespace' [-Wdeprecated]
 +input.y:2.9-21: error: %define variable 'api.namespace' redefined
 +input.y:1.9-17:     previous definition
  ]])
  
  AT_DATA([[input.y]],
@@@ -1268,14 -1203,14 +1329,14 @@@ m4_define([AT_CHECK_NAMESPACE_ERROR]
  AT_DATA([[input.y]],
  [[%language "C++"
  %defines
 -%define namespace "]$1["
 +%define api.namespace "]$1["
  %%
  start: ;
  ]])
  
  AT_BISON_CHECK([[input.y]], [1], [],
  [m4_foreach([b4_arg], m4_dquote(m4_shift($@)),
 -[[input.y:3.9-17: error: ]b4_arg[
 +[[input.y:3.9-21: error: ]b4_arg[
  ]])])
  ])
  
@@@ -1324,10 -1259,10 +1385,10 @@@ start: 
  AT_CHECK([[$PERL -e "print 'start: \'';" >> empty.y || exit 77]])
  
  AT_BISON_CHECK([empty.y], [1], [],
 -[[empty.y:2.8-9: warning: empty character literal
 -empty.y:3.8-4.0: warning: empty character literal
 +[[empty.y:2.8-9: warning: empty character literal [-Wother]
 +empty.y:3.8-4.0: warning: empty character literal [-Wother]
  empty.y:3.8-4.0: error: missing "'" at end of line
 -empty.y:4.8: warning: empty character literal
 +empty.y:4.8: warning: empty character literal [-Wother]
  empty.y:4.8: error: missing "'" at end of file
  ]])
  
@@@ -1339,10 -1274,10 +1400,10 @@@ start: 'a
  AT_CHECK([[$PERL -e "print 'start: \'ab';" >> two.y || exit 77]])
  
  AT_BISON_CHECK([two.y], [1], [],
 -[[two.y:2.8-11: warning: extra characters in character literal
 -two.y:3.8-4.0: warning: extra characters in character literal
 +[[two.y:2.8-11: warning: extra characters in character literal [-Wother]
 +two.y:3.8-4.0: warning: extra characters in character literal [-Wother]
  two.y:3.8-4.0: error: missing "'" at end of line
 -two.y:4.8-10: warning: extra characters in character literal
 +two.y:4.8-10: warning: extra characters in character literal [-Wother]
  two.y:4.8-10: error: missing "'" at end of file
  ]])
  
@@@ -1354,10 -1289,10 +1415,10 @@@ start: 'ab
  AT_CHECK([[$PERL -e "print 'start: \'abc';" >> three.y || exit 77]])
  
  AT_BISON_CHECK([three.y], [1], [],
 -[[three.y:2.8-12: warning: extra characters in character literal
 -three.y:3.8-4.0: warning: extra characters in character literal
 +[[three.y:2.8-12: warning: extra characters in character literal [-Wother]
 +three.y:3.8-4.0: warning: extra characters in character literal [-Wother]
  three.y:3.8-4.0: error: missing "'" at end of line
 -three.y:4.8-11: warning: extra characters in character literal
 +three.y:4.8-11: warning: extra characters in character literal [-Wother]
  three.y:4.8-11: error: missing "'" at end of file
  ]])
  
@@@ -1385,25 -1320,25 +1446,25 @@@ AT_CHECK([[$PERL -e 'print "start: \"\\
  
  AT_BISON_CHECK([input.y], [1], [],
  [[input.y:2.9-12: error: invalid number after \-escape: 777
 -input.y:2.8-13: warning: empty character literal
 +input.y:2.8-13: warning: empty character literal [-Wother]
  input.y:2.16-17: error: invalid number after \-escape: 0
 -input.y:2.15-18: warning: empty character literal
 +input.y:2.15-18: warning: empty character literal [-Wother]
  input.y:2.21-25: error: invalid number after \-escape: xfff
 -input.y:2.20-26: warning: empty character literal
 +input.y:2.20-26: warning: empty character literal [-Wother]
  input.y:2.29-31: error: invalid number after \-escape: x0
 -input.y:2.28-32: warning: empty character literal
 +input.y:2.28-32: warning: empty character literal [-Wother]
  input.y:3.9-14: error: invalid number after \-escape: uffff
 -input.y:3.8-15: warning: empty character literal
 +input.y:3.8-15: warning: empty character literal [-Wother]
  input.y:3.18-23: error: invalid number after \-escape: u0000
 -input.y:3.17-24: warning: empty character literal
 +input.y:3.17-24: warning: empty character literal [-Wother]
  input.y:3.27-36: error: invalid number after \-escape: Uffffffff
 -input.y:3.26-37: warning: empty character literal
 +input.y:3.26-37: warning: empty character literal [-Wother]
  input.y:3.40-49: error: invalid number after \-escape: U00000000
 -input.y:3.39-50: warning: empty character literal
 +input.y:3.39-50: warning: empty character literal [-Wother]
  input.y:4.9-10: error: invalid character after \-escape: ' '
 -input.y:4.8-11: warning: empty character literal
 +input.y:4.8-11: warning: empty character literal [-Wother]
  input.y:4.14-15: error: invalid character after \-escape: A
 -input.y:4.13-16: warning: empty character literal
 +input.y:4.13-16: warning: empty character literal [-Wother]
  input.y:5.9-16: error: invalid character after \-escape: \t
  input.y:5.17: error: invalid character after \-escape: \f
  input.y:5.18: error: invalid character after \-escape: \0
@@@ -1448,19 -1383,20 +1509,19 @@@ foo-bar: 
  
  # -Werror is not enabled by -Wall or equivalent.
  AT_BISON_CHECK([[-Wall input.y]], [[0]], [[]],
 -[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar
 +[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
  ]])
  AT_BISON_CHECK([[-W input.y]], [[0]], [[]],
 -[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar
 +[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
  ]])
  AT_BISON_CHECK([[-Wno-none input.y]], [[0]], [[]],
 -[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar
 +[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
  ]])
  
  # -Werror is not disabled by -Wnone or equivalent.
  AT_BISON_CHECK([[-Werror,none,yacc input.y]], [[1]], [[]], [[stderr]])
  AT_CHECK([[sed 's/^.*bison:/bison:/' stderr]], [[0]],
 -[[bison: warnings being treated as errors
 -input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar
 +[[input.y:2.1-7: error: POSIX Yacc forbids dashes in symbol names: foo-bar [-Werror=yacc]
  ]])
  [mv stderr experr]
  AT_BISON_CHECK([[-Werror,no-all,yacc input.y]], [[1]], [[]], [[experr]])
@@@ -1507,8 -1443,7 +1568,8 @@@ AT_SETUP([[Stray $ or @]]
  # check that the warnings are reported once, not three times.
  
  AT_DATA_GRAMMAR([[input.y]],
 -[[%token TOK
 +[[%type <TYPE> exp
 +%token <TYPE> TOK TOK2
  %destructor     { $%; @%; } <*> exp TOK;
  %initial-action { $%; @%; };
  %printer        { $%; @%; } <*> exp TOK;
@@@ -1517,14 -1452,14 +1578,14 @@@ exp: TOK        { $%; @%; $$ = $1; }
  ]])
  
  AT_BISON_CHECK([[input.y]], 0, [],
 -[[input.y:10.19: warning: stray '$'
 -input.y:10.23: warning: stray '@'
 -input.y:11.19: warning: stray '$'
 -input.y:11.23: warning: stray '@'
 -input.y:12.19: warning: stray '$'
 -input.y:12.23: warning: stray '@'
 -input.y:14.19: warning: stray '$'
 -input.y:14.23: warning: stray '@'
 +[[input.y:11.19: warning: stray '$' [-Wother]
 +input.y:11.23: warning: stray '@' [-Wother]
 +input.y:12.19: warning: stray '$' [-Wother]
 +input.y:12.23: warning: stray '@' [-Wother]
 +input.y:13.19: warning: stray '$' [-Wother]
 +input.y:13.23: warning: stray '@' [-Wother]
 +input.y:15.19: warning: stray '$' [-Wother]
 +input.y:15.23: warning: stray '@' [-Wother]
  ]])
  
  AT_CLEANUP
@@@ -1547,7 -1482,6 +1608,7 @@@ m4_pushdef([AT_TEST]
  [AT_DATA([[input.y]],
  [[%type <$1(DEAD %type)> exp
  %token <$1(DEAD %token)> a
 +%token b
  %initial-action
  {
    $$;
  };
  %%
  exp:
 -  a a[last]
 +  a a[name] b
    {
      $$;
      $][1;
      $<$1(DEAD action 1)>$
      $<$1(DEAD action 2)>1
 -    $<$1(DEAD action 3)>last
 +    $<$1(DEAD action 3)>name
      $<$1(DEAD action 4)>0
      ;
    };
@@@ -1594,121 -1528,3 +1655,121 @@@ AT_TEST([@:>@m4_errprintn]
  m4_popdef([AT_TEST])
  
  AT_CLEANUP
 +
 +##----------------------- ##
 +## Deprecated directives. ##
 +## ---------------------- ##
 +
 +AT_SETUP([[Deprecated directives]])
 +
 +AT_KEYWORDS([[deprec]])
 +
 +AT_DATA_GRAMMAR([[input.y]],
 +[[
 +%default_prec
 +%error_verbose
 +%expect_rr 0
 +%file-prefix = "foo"
 +%file-prefix
 + =
 +"bar"
 +%fixed-output_files
 +%fixed_output-files
 +%fixed-output-files
 +%name-prefix= "foo"
 +%no-default_prec
 +%no_default-prec
 +%no_lines
 +%output = "foo"
 +%pure_parser
 +%token_table
 +%glr-parser
 +%% exp : '0'
 +]])
 +
 +AT_BISON_CHECK([[input.y]], [[0]], [[]],
 +[[input.y:10.1-13: warning: deprecated directive: '%default_prec', use '%default-prec' [-Wdeprecated]
 +input.y:11.1-14: warning: deprecated directive: '%error_verbose', use '%define parse.error verbose' [-Wdeprecated]
 +input.y:12.1-10: warning: deprecated directive: '%expect_rr', use '%expect-rr' [-Wdeprecated]
 +input.y:13.1-14: warning: deprecated directive: '%file-prefix =', use '%file-prefix' [-Wdeprecated]
 +input.y:14.1-15.2: warning: deprecated directive: '%file-prefix\n =', use '%file-prefix' [-Wdeprecated]
 +input.y:17.1-19: warning: deprecated directive: '%fixed-output_files', use '%fixed-output-files' [-Wdeprecated]
 +input.y:18.1-19: warning: deprecated directive: '%fixed_output-files', use '%fixed-output-files' [-Wdeprecated]
 +input.y:20.1-13: warning: deprecated directive: '%name-prefix=', use '%name-prefix' [-Wdeprecated]
 +input.y:21.1-16: warning: deprecated directive: '%no-default_prec', use '%no-default-prec' [-Wdeprecated]
 +input.y:22.1-16: warning: deprecated directive: '%no_default-prec', use '%no-default-prec' [-Wdeprecated]
 +input.y:23.1-9: warning: deprecated directive: '%no_lines', use '%no-lines' [-Wdeprecated]
 +input.y:24.1-9: warning: deprecated directive: '%output =', use '%output' [-Wdeprecated]
 +input.y:25.1-12: warning: deprecated directive: '%pure_parser', use '%pure-parser' [-Wdeprecated]
 +input.y:26.1-12: warning: deprecated directive: '%token_table', use '%token-table' [-Wdeprecated]
 +]])
 +
 +AT_CLEANUP
 +
 +## ---------------------------- ##
 +## Unput's effect on locations. ##
 +## ---------------------------- ##
 +dnl When the scanner detects a deprecated construct, it unputs the correct
 +dnl version, but it should *not* have any impact on the scanner cursor. If it
 +dnl does, the locations of directives on the same line become erroneous.
 +
 +AT_SETUP([[Unput's effect on locations]])
 +
 +AT_KEYWORDS([[deprec]])
 +
 +AT_DATA_GRAMMAR([[input.y]],
 +[[
 +%glr-parser
 +%expect_rr 42 %expect_rr 42
 +              %expect_rr 42
 +%error_verbose %error_verbose
 +               %error_verbose
 +%% exp: '0'
 +]])
 +
 +AT_BISON_CHECK([[input.y]], [[1]], [[]],
 +[[input.y:11.1-10: warning: deprecated directive: '%expect_rr', use '%expect-rr' [-Wdeprecated]
 +input.y:11.15-24: warning: deprecated directive: '%expect_rr', use '%expect-rr' [-Wdeprecated]
 +input.y:12.15-24: warning: deprecated directive: '%expect_rr', use '%expect-rr' [-Wdeprecated]
 +input.y:13.1-14: warning: deprecated directive: '%error_verbose', use '%define parse.error verbose' [-Wdeprecated]
 +input.y:13.16-29: warning: deprecated directive: '%error_verbose', use '%define parse.error verbose' [-Wdeprecated]
 +input.y:13.11-21: error: %define variable 'parse.error' redefined
 +input.y:13-6:         previous definition
 +input.y:14.16-29: warning: deprecated directive: '%error_verbose', use '%define parse.error verbose' [-Wdeprecated]
 +input.y:14.11-21: error: %define variable 'parse.error' redefined
 +input.y:13.11-21:     previous definition
 +]])
 +
 +AT_CLEANUP
 +
 +##--------------------------- ##
 +## Non-deprecated directives. ##
 +## -------------------------- ##
 +
 +AT_SETUP([[Non-deprecated directives]])
 +
 +AT_KEYWORDS([[deprec]])
 +
 +AT_DATA_GRAMMAR([[input.y]],
 +[[
 +%default-prec
 +%error-verbose
 +%expect-rr 42
 +%file-prefix "foo"
 +%file-prefix
 +"bar"
 +%fixed-output-files
 +%name-prefix "foo"
 +%no-default-prec
 +%no-lines
 +%output "foo"
 +%pure-parser
 +%token-table
 +%% exp : '0'
 +]])
 +
 +AT_BISON_CHECK([[input.y]], [[0]], [[]],
 +[[input.y: warning: %expect-rr applies only to GLR parsers [-Wother]
 +]])
 +
 +AT_CLEANUP
diff --combined tests/local.at
index 9fd641c4b01f9163a9dbb6b6aedd80ff075098b4,e2fd1beb5a31e1febf0b0b8834df700e54bc312d..d120712d3bc27a60be23b7a57f725439fc63e7f1
@@@ -109,7 -109,7 +109,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
@@@ -119,6 -119,7 +119,7 @@@ m4_pushdef([AT_SKEL_CC_IF]
  [m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
  m4_pushdef([AT_SKEL_JAVA_IF],
  [m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])])
+ # The target language: "c", "c++", or "java".
  m4_pushdef([AT_LANG],
  [AT_SKEL_JAVA_IF([java],
                   [AT_SKEL_CC_IF([c++],
@@@ -140,6 -141,12 +141,13 @@@ m4_pushdef([AT_LOCATION_TYPE_IF]
  [m4_bmatch([$3], [%define \(api\.location\.type\|location_type\)], [$1], [$2])])
  m4_pushdef([AT_PARAM_IF],
  [m4_bmatch([$3], [%parse-param], [$1], [$2])])
 -# E.g., %parse-param { int x } {int y} -> "int x, int y, ".
+ # Comma-terminated list of formals parse-parameters.
++# E.g., %parse-param { int x } %parse-param {int y} -> "int x, int y, ".
++# FIXME: Support grouped parse-param.
+ m4_pushdef([AT_PARSE_PARAMS])
+ m4_bpatsubst([$3], [%parse-param { *\([^{}]*[^{} ]\) *}],
+              [m4_append([AT_PARSE_PARAMS], [\1, ])])
  m4_pushdef([AT_PURE_IF],
  [m4_bmatch([$3], [%define  *api\.pure\|%pure-parser],
             [m4_bmatch([$3], [%define  *api\.pure *"?false"?], [$2], [$1])],
@@@ -152,11 -159,6 +160,11 @@@ 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_CTOR_IF],
 +[m4_bmatch([$3], [%define api.token.constructor], [$1], [$2])])
 +m4_pushdef([AT_TOKEN_PREFIX],
 +[m4_bmatch([$3], [%define api.token.prefix ".*"],
 +           [m4_bregexp([$3], [%define api.token.prefix "\(.*\)"], [\1])])])
  m4_pushdef([AT_API_prefix],
  [m4_bmatch([$3], [%define api\.prefix ".*"],
             [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
@@@ -166,20 -168,20 +174,20 @@@ m4_pushdef([AT_API_PREFIX]
  # 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]],
@@@ -193,15 -195,15 +201,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)]])
@@@ -220,8 -222,6 +228,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
  
  
@@@ -243,13 -243,12 +251,14 @@@ m4_popdef([AT_YYERROR_SEES_LOC_IF]
  m4_popdef([AT_YYERROR_ARG_LOC_IF])
  m4_popdef([AT_API_PREFIX])
  m4_popdef([AT_API_prefix])
 +m4_popdef([AT_TOKEN_PREFIX])
 +m4_popdef([AT_TOKEN_CTOR_IF])
  m4_popdef([AT_NAME_PREFIX])
  m4_popdef([AT_GLR_OR_PARAM_IF])
  m4_popdef([AT_PURE_AND_LOC_IF])
  m4_popdef([AT_LOCATION_TYPE_IF])
  m4_popdef([AT_LOCATION_IF])
+ m4_popdef([AT_PARSE_PARAMS])
  m4_popdef([AT_PARAM_IF])
  m4_popdef([AT_LEXPARAM_IF])
  m4_popdef([AT_YACC_IF])
@@@ -359,7 -358,7 +368,7 @@@ stati
  # Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
  m4_define([AT_YYERROR_FORMALS],
  [m4_case(AT_LANG,
- [c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])[const char *msg]])[]dnl
+ [c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])AT_PARSE_PARAMS [const char *msg]])[]dnl
  ])
  
  m4_define([AT_YYERROR_PROTOTYPE],
@@@ -383,26 -382,23 +392,21 @@@ m4_define([AT_YYERROR_DEFINE]
  /* A C error reporting function.  */
  static
  ]AT_YYERROR_PROTOTYPE[
- {
- ]AT_YYERROR_SEES_LOC_IF([[
-   fprintf (stderr, "%d.%d",
-            ]AT_LOC_FIRST_LINE[, ]AT_LOC_FIRST_COLUMN[);
-   if (]AT_LOC_FIRST_LINE[ != ]AT_LOC_LAST_LINE[)
-     fprintf (stderr, "-%d.%d",
-              ]AT_LOC_LAST_LINE[,  ]AT_LOC_LAST_COLUMN[ - 1);
-   else if (]AT_LOC_FIRST_COLUMN[ != ]AT_LOC_LAST_COLUMN[ - 1)
-     fprintf (stderr, "-%d",
-              ]AT_LOC_LAST_COLUMN[ - 1);
+ {]m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]),
+               [[^,]+[^A-Za-z_0-9]\([A-Za-z_][A-Za-z_0-9]*\), *], [
+   YYUSE(\1);])dnl
+ AT_YYERROR_SEES_LOC_IF([[
+   YY_LOCATION_PRINT (stderr, ]AT_LOC[);
    fprintf (stderr, ": ");]])[
    fprintf (stderr, "%s\n", msg);
  }]],
  [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
@@@ -449,6 -445,10 +453,6 @@@ m4_define([AT_BISON_CHECK]
  [m4_null_if([$2], [AT_BISON_CHECK_XML($@)])
  AT_BISON_CHECK_NO_XML($@)])
  
 -m4_define([AT_BISON_WERROR_MSG],
 -          [[bison: warnings being treated as errors]])
 -
 -
  # AT_BISON_CHECK_(BISON_ARGS, [OTHER_AT_CHECK_ARGS])
  # --------------------------------------------------
  # Low-level macro to run bison once.
@@@ -473,7 -473,7 +477,7 @@@ m4_define([AT_BISON_CHECK_WARNINGS_]
  # as /bin/sh, sets the shell variable POSIXLY_CORRECT to y, but not
  # the environment variable.
  if env | grep '^POSIXLY_CORRECT=' >/dev/null; then :; else
 -  ]AT_SAVE_SPECIAL_FILES[
 +          ]AT_SAVE_SPECIAL_FILES[
  
    # To avoid expanding it repeatedly, store specified stdout.
    ]AT_DATA([expout], [$3])[
  
    # Build expected stderr up to and including the "warnings being
    # treated as errors" message.
 -  ]AT_DATA([[at-bison-check-warnings]], [$4])[
 -  at_bison_check_first=`sed -n \
 -    '/: warning: /{=;q;}' at-bison-check-warnings`
 -  : ${at_bison_check_first:=1}
 -  at_bison_check_first_tmp=`sed -n \
 -    '/conflicts: [0-9].*reduce$/{=;q;}' at-bison-check-warnings`
 -  : ${at_bison_check_first_tmp:=1}
 -  if test $at_bison_check_first_tmp -lt $at_bison_check_first; then
 -    at_bison_check_first=$at_bison_check_first_tmp
 -  fi
 -  if test $at_bison_check_first -gt 1; then
 -    sed -n "1,`expr $at_bison_check_first - 1`"p \
 -      at-bison-check-warnings > experr
 -  fi
 -  echo ']AT_BISON_WERROR_MSG[' >> experr
 -
 -  # Finish building expected stderr and check.  Unlike warnings,
 -  # complaints cause bison to exit early.  Thus, with -Werror, bison
 -  # does not necessarily report all warnings that it does without
 -  # -Werror, but it at least reports one.
 -  at_bison_check_last=`sed -n '$=' stderr`
 -  : ${at_bison_check_last:=1}
 -  at_bison_check_last=`expr $at_bison_check_last - 1`
 -  sed -n "$at_bison_check_first,$at_bison_check_last"p \
 -    at-bison-check-warnings >> experr
 -  ]AT_CHECK([[sed 's,.*/\(]AT_BISON_WERROR_MSG[\)$,\1,' \
 -              stderr 1>&2]], [[0]], [[]], [experr])[
 +  ]AT_DATA([[experr]], [$4])[
 +  $PERL -pi -e 's{(.*): warning: (.*)\[-W(.*)\]$}
 +                 {$][1: error: $][2\@<:@-Werror=$][3@:>@}' experr
 +  ]AT_CHECK([[sed 's,.*/$,,' stderr 1>&2]], [[0]], [[]], [experr])[
  
    # Now check --warnings=error.
    cp stderr experr
@@@ -528,10 -551,10 +532,10 @@@ m4_define([AT_BISON_CHECK_XML]
    # Don't combine these Bison invocations since we want to be sure that
    # --report=all isn't required to get the full XML file.
    AT_BISON_CHECK_([[--report=all --report-file=xml-tests/test.output \
 -                  --graph=xml-tests/test.dot ]]AT_BISON_ARGS,
 -                  [[0]], [ignore], [ignore])
 +             --graph=xml-tests/test.dot ]]AT_BISON_ARGS,
 +           [[0]], [ignore], [ignore])
    AT_BISON_CHECK_([[--xml=xml-tests/test.xml ]]AT_BISON_ARGS,
 -                 [[0]], [ignore], [ignore])
 +           [[0]], [ignore], [ignore])
    m4_popdef([AT_BISON_ARGS])dnl
    [cp xml-tests/test.output expout]
    AT_CHECK([[$XSLTPROC \
@@@ -580,7 -603,7 +584,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])
  # ---------------------------------------------
@@@ -599,7 -622,7 +603,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)
  # ------------------------
@@@ -639,27 -662,65 +643,65 @@@ 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]])))])
  ])
  
  
+ # AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
+ # --------------------------------
+ # Check that we can link together C and C++ objects.
+ m4_define([AT_SKIP_IF_CANNOT_LINK_C_AND_CXX],
+ [AT_DATA([c-and-cxx.h],
+ [[#ifdef __cplusplus
+ extern "C"
+ {
+ #endif
+   int fortytwo (void);
+ #ifdef __cplusplus
+ }
+ #endif
+ ]])
+ AT_DATA([c-only.c],
+ [[#include "c-and-cxx.h"
+ int
+ main (void)
+ {
+   return fortytwo () == 42 ? 0 : 1;
+ }
+ ]])
+ AT_DATA([cxx-only.cc],
+ [[#include "c-and-cxx.h"
+ int fortytwo ()
+ {
+   return 42;
+ }
+ ]])
+ AT_COMPILE([c-only.o], [c-only.c])
+ AT_COMPILE_CXX([cxx-only.o], [cxx-only.cc])
+ AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS $LDFLAGS c-only.o cxx-only.o -o c-and-cxx ||
+           exit 77], [ignore], [ignore])
+ AT_CHECK([./c-and-cxx])
+ ])
  ## ---------------------------- ##
  ## Running a generated parser.  ##
  ## ---------------------------- ##
diff --combined tests/named-refs.at
index ff1d424817dab6f9fcd1bd83e9756d0d948bbf36,9582c01d16260bd34f76d0f781bf1756ffc10c38..8c0fbb90a240474bd2a69d47739ef3966582a35f
@@@ -46,10 -46,10 +46,10 @@@ static int power (int base, int exponen
  %token <ival> NUM "number"
  %type  <ival> exp
  
 -%nonassoc '='   /* comparison        */
 +%nonassoc '='   /* comparison          */
  %left '-' '+'
  %left '*' '/'
 -%left NEG /* negation--unary minus */
 +%precedence NEG /* negation--unary minus */
  %right '^'      /* exponentiation        */
  
  %%
@@@ -211,10 -211,10 +211,10 @@@ static int power (int base, int exponen
  %token <ival> NUM "number"
  %type  <ival> exp
  
 -%nonassoc '='   /* comparison        */
 +%nonassoc '='   /* comparison          */
  %left '-' '+'
  %left '*' '/'
 -%left NEG /* negation--unary minus */
 +%precedence NEG /* negation--unary minus */
  %right '^'      /* exponentiation        */
  
  %%
@@@ -253,7 -253,7 +253,7 @@@ exp
  AT_BISON_CHECK([-o test.c test.y], 1, [],
  [[test.y:50.51-60: error: invalid reference: '$<ival>lo9'
  test.y:50.3-68:      symbol not found in production: lo9
 -test.y:51.51-60: warning: misleading reference: '$<ival>exp'
 +test.y:51.51-60: warning: misleading reference: '$<ival>exp' [-Wother]
  test.y:42.1-3:       refers to: $exp at $$
  test.y:51.7:         possibly meant: $x, hiding $exp at $1
  test.y:51.41:        possibly meant: $r, hiding $exp at $4
@@@ -277,7 -277,7 +277,7 @@@ foo: '1
  foo.bar: '2'
  ]])
  AT_BISON_CHECK([-o test.c test.y], 0, [],
 -[[test.y:11.22-29: warning: misleading reference: '$foo.bar'
 +[[test.y:11.22-29: warning: misleading reference: '$foo.bar' [-Wother]
  test.y:11.8-10:      refers to: $foo at $1
  test.y:11.12-18:     possibly meant: $[foo.bar] at $2
  ]])
@@@ -443,14 -443,19 +443,19 @@@ AT_SETUP([Stray symbols in brackets]
  AT_DATA_GRAMMAR([test.y],
  [[
  %%
- start: foo[ /* aaa */ *&-.+ ] bar
+ start: foo[ /* aaa */ *&-.+\000\001\002\377 ] bar
    { s = $foo; }
  ]])
+ AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' test.y || exit 77]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
  [[test.y:11.23: error: invalid character in bracketed name: '*'
  test.y:11.24: error: invalid character in bracketed name: '&'
  test.y:11.25: error: invalid character in bracketed name: '-'
  test.y:11.27: error: invalid character in bracketed name: '+'
+ test.y:11.28: error: invalid character in bracketed name: '\0'
+ test.y:11.28: error: invalid character in bracketed name: '\001'
+ test.y:11.28: error: invalid character in bracketed name: '\002'
+ test.y:11.28: error: invalid character in bracketed name: '\377'
  ]])
  AT_CLEANUP
  
@@@ -573,7 -578,7 +578,7 @@@ start
  ;
  ]])
  AT_BISON_CHECK([[test.y]], [[0]], [],
 -[[test.y:4.9: warning: stray '$'
 -test.y:5.9: warning: stray '@'
 +[[test.y:4.9: warning: stray '$' [-Wother]
 +test.y:5.9: warning: stray '@' [-Wother]
  ]])
  AT_CLEANUP
diff --combined tests/regression.at
index 8a285af177776f9967b1e2fbc57df634e672fb62,b6bff17cb0743128f82bc74360e74f54b48baba4..f17359416a9e1ba448ee0e71eef4353eb5961b7c
@@@ -209,7 -209,7 +209,7 @@@ exp: '(' exp ')' | NUM 
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([-v -o input.c input.y], 0, [],
 -[[input.y:6.8-14: warning: symbol "<=" used more than once as a literal string
 +[[input.y:6.8-14: warning: symbol "<=" used more than once as a literal string [-Wother]
  ]])
  
  AT_CLEANUP
@@@ -478,8 -478,8 +478,8 @@@ AT_BISON_OPTION_POPDEF
  # C-string literal.  Also notice that unnecessary escaping, such as "\?", from
  # the user specification is eliminated.
  AT_BISON_CHECK([-o input.c input.y], [[0]], [[]],
 -[[input.y:22.8-14: warning: symbol SPECIAL redeclared
 -input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string
 +[[input.y:22.8-14: warning: symbol SPECIAL redeclared [-Wother]
 +input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string [-Wother]
  ]])
  AT_COMPILE([input])
  
@@@ -538,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
@@@ -548,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 ';'
          ;
  %%
  ]])
@@@ -759,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
@@@ -772,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
@@@ -803,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
@@@ -930,11 -939,11 +930,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
@@@ -1029,7 -1038,7 +1029,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");
    }
    ;
  
@@@ -1182,8 -1191,8 +1182,8 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o input.c input.y]], [[0]],,
 -[[input.y:23.5-19: warning: rule useless in parser due to conflicts: start: start
 -input.y:27.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias"
 +[[input.y:23.5-19: warning: rule useless in parser due to conflicts: start: start [-Wother]
 +input.y:27.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" [-Wother]
  ]])
  AT_COMPILE([[input]])
  AT_PARSER_CHECK([[./input]])
@@@ -1201,9 -1210,8 +1201,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]
@@@ -1217,11 -1225,11 +1217,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
  
  %%
  
@@@ -1265,9 -1273,9 +1265,9 @@@ 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"])[
  int
  main (void)
@@@ -1288,9 -1296,9 +1288,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
  
  %%
  
@@@ -1374,8 -1381,8 +1374,8 @@@ 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"])[
  int
  main (void)
@@@ -1425,7 -1432,7 +1425,7 @@@ AT_DATA_GRAMMAR([input.y]
  }
  
  ]$1[
 -%error-verbose
 +%define parse.error verbose
  %token 'c'
  
  %%
@@@ -1461,7 -1468,7 +1461,7 @@@ main (void
  AT_BISON_CHECK([[-Dparse.lac=full -Dparse.lac.es-capacity-initial=1 \
                   -Dparse.lac.memory-trace=full \
                   -t -o input.c input.y]], [[0]], [],
 -[[input.y: conflicts: 21 shift/reduce
 +[[input.y: warning: 21 shift/reduce conflicts [-Wconflicts-sr]
  ]])
  AT_COMPILE([[input]])
  AT_PARSER_CHECK([[./input > stdout.txt 2> stderr.txt]], [[1]])
@@@ -1537,7 -1544,7 +1537,7 @@@ main (void
  
  AT_BISON_CHECK([[-Dparse.lac=full -Dparse.lac.es-capacity-initial=1 \
                   -t -o input.c input.y]], [[0]], [],
 -[[input.y: conflicts: 8 shift/reduce
 +[[input.y: warning: 8 shift/reduce conflicts [-Wconflicts-sr]
  ]])
  AT_COMPILE([[input]])
  AT_BISON_OPTION_POPDEFS
@@@ -1590,14 -1597,14 +1590,14 @@@ AT_CLEANU
  m4_pushdef([AT_TEST],
  [AT_SETUP([[Lex and parse params: $1]])
  
- AT_BISON_OPTION_PUSHDEFS([%locations %skeleton $1])
+ AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" %parse-param { int x } %parse-param { int y }])
  
  ## FIXME: Improve parsing of parse-param and use the generated
  ## yyerror.
  AT_DATA_GRAMMAR([input.y],
  [[%defines
  %locations
- %skeleton $1
+ %skeleton "$1"
  %union { int ival; }
  %parse-param { int x }
  // Spaces, tabs, and new lines.
  #include <stdio.h>
  #include <stdlib.h>
  
- ]AT_SKEL_CC_IF([], [[
- static
- void
- yyerror (int x, int y, const char *msg)
- {
-   fprintf (stderr, "x: %d, y: %d, %s\n", x, y, msg);
- }]])[
+   ]AT_YYERROR_DECLARE[
    ]AT_YYLEX_DECLARE[
  %}
  
  %%
  exp: 'a' { fprintf (stdout, "x: %d, y: %d\n", x, y); };
  %%
+ ]AT_YYERROR_DEFINE[
  ]AT_YYLEX_DEFINE(["a"])[
  
  ]AT_SKEL_CC_IF(
- [AT_YYERROR_DEFINE
- int
+ [int
  yyparse (int x, int y)
  {
    yy::parser parser(x, y);
@@@ -1654,9 -1653,9 +1646,9 @@@ AT_CLEANU
  ])
  
  ## FIXME: test Java, and iterate over skeletons.
- AT_TEST("yacc.c")
- AT_TEST("glr.c")
- AT_TEST("lalr1.cc")
- AT_TEST("glr.cc")
+ AT_TEST([yacc.c])
+ AT_TEST([glr.c])
+ AT_TEST([lalr1.cc])
+ AT_TEST([glr.cc])
  
  m4_popdef([AT_TEST])