]> git.saurik.com Git - bison.git/commitdiff
Merge remote-tracking branch 'origin/maint'
authorTheophile Ranquet <ranquet@lrde.epita.fr>
Thu, 6 Dec 2012 10:43:02 +0000 (11:43 +0100)
committerTheophile Ranquet <ranquet@lrde.epita.fr>
Thu, 6 Dec 2012 12:38:43 +0000 (13:38 +0100)
* origin/maint:
  misc: pacify the Tiny C Compiler
  cpp: make the check of Flex version portable
  misc: require getline
  c++: support wide strings for file names
  doc: document carets
  tests: enhance existing tests with carets
  errors: show carets
  getargs: add support for --flags/-f

Conflicts:
doc/bison.texi
m4/.gitignore
src/complain.c
src/flex-scanner.h
src/getargs.c
src/getargs.h
src/gram.c
src/main.c
tests/headers.at

21 files changed:
1  2 
NEWS
THANKS
bootstrap.conf
data/location.cc
doc/bison.texi
lib/.gitignore
m4/.gitignore
src/complain.c
src/flex-scanner.h
src/getargs.c
src/getargs.h
src/gram.c
src/location.c
src/location.h
src/main.c
tests/actions.at
tests/conflicts.at
tests/input.at
tests/named-refs.at
tests/reduce.at
tests/regression.at

diff --combined NEWS
index e9b7fd9bed5fceb40b2e4b7d833c2c54df8f89cc,0c3d025e1b19c8a4dd6399ef8a6f57bc92ce8d32..eabdcc6ecb6d885df77d1a8ffbc221383f3e6f5f
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -2,251 -2,24 +2,264 @@@ 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 ?.? (????-??-??) [?]
 +
  ** %language is no longer an experimental feature.
  
    The introduction of this feature, in 2.4, was four years ago. The --language
    option and the %language directive are no longer experimental.
  
+ ** New format for error reports: carets
+   Caret errors have been added to Bison, for example (taken from the
+   documentation):
+     input.y:3.20-23: error: ambiguous reference: '$exp'
+      exp: exp '+' exp { $exp = $1 + $2; };
+                         ^^^^
+   The default behaviour for now is still not to display these unless explictly
+   asked with -fall of -fcaret. However, in a later release, it will be made the
+   default behavior (but may still be deactivated with -fno-caret).
  ** New value for %define variable: api.pure full
  
    The %define variable api.pure requests a pure (reentrant) parser. However,
  
  * 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.
@@@ -2247,8 -2020,8 +2260,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 909a6e004bd1b0a9e38a3dee6e5ca22885c676f3,9a64012caf7d35335c5500b341c0437b4e858c27..dbe54791e383d85b72e1553b7a0aa5f02c8f3ca0
--- 1/THANKS
--- 2/THANKS
+++ b/THANKS
@@@ -68,6 -68,7 +68,7 @@@ Lie Yan                   lie.yan@kaust
  Magnus Fromreide          magfr@lysator.liu.se
  Marc Autret               autret_m@epita.fr
  Marc Mendiola             mmendiol@usc.edu
+ Mark Boyall               wolfeinstein@gmail.com
  Martin Jacobs             martin.jacobs@arcor.de
  Martin Mokrejs            mmokrejs@natur.cuni.cz
  Martin Nylin              martin.nylin@linuxmail.org
@@@ -75,7 -76,6 +76,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
@@@ -96,7 -96,6 +97,7 @@@ Peter Fales               psfales@lucen
  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 bootstrap.conf
index cddc571b6dedd3462c28b20387c4ca22611a298e,9dccd00144e3cf9b0af245f0c36c65f9416d3f42..feff5ff0817f34e80c425aff4e09763f9615b10e
@@@ -20,12 -20,13 +20,14 @@@ gnulib_modules=
    argmatch assert calloc-posix close closeout config-h c-strcase
    configmake
    dirname
-   error extensions fdl fopen-safer getopt-gnu
+   error extensions fdl fopen-safer
+   getline
+   getopt-gnu
    gettext git-version-gen gitlog-to-changelog
    gpl-3.0 hash inttypes isnan javacomp-script
 -  javaexec-script ldexpl malloc-gnu mbschr mbsrchr
 +  javaexec-script ldexpl malloc-gnu
    mbswidth
 +  non-recursive-gnulib-prefix-hack
    obstack
    obstack-printf
    perror progname
    spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp
    unistd unistd-safer unlocked-io update-copyright unsetenv verify
    warnings
 -  xalloc xalloc-die xmemdup0 xstrndup
 +  xalloc
 +  xalloc-die
 +  xconcat-filename
 +  xmemdup0
 +  xstrndup
  
    fprintf-posix printf-posix snprintf-posix sprintf-posix
    vsnprintf-posix vsprintf-posix
@@@ -49,8 -46,9 +51,8 @@@
  XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
   --from-code=UTF-8\\\
   --flag=asprintf:2:c-format\\\
 - --flag=complain:1:c-format --flag=complain_at:2:c-format\\\
 - --flag=fatal:1:c-format --flag=fatal_at:2:c-format\\\
 - --flag=warn:1:c-format  --flag=warn_at:2:c-format\\\
 + --flag=complain:3:c-format\\\
 + --flag=complain_indent:4:c-format\\\
   --flag=unexpected_end:2:c-format\\\
  '
  XGETTEXT_OPTIONS_RUNTIME=$XGETTEXT_OPTIONS'\\\
@@@ -78,9 -76,6 +80,9 @@@ gnulib_tool_option_extras='--symlink --
  
  bootstrap_post_import_hook()
  {
 +  # Massage lib/gnulib.mk before using it later in the bootstrapping process.
 +  build-aux/prefix-gnulib-mk --lib-name=$gnulib_name lib/$gnulib_mk
 +
    # Ensure that ChangeLog exists, for automake.
    test -f ChangeLog || touch ChangeLog
  }
diff --combined data/location.cc
index b49028f9559ac6ec0236486def75ea0fa92451c8,4082e09d1821829ee33b52cb548e83a6ef14ada4..631247a7961bb2d94028203352a9074be719b8a5
@@@ -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/>.
  
 +m4_pushdef([b4_copyright_years],
 +           [2002-2012])
  
 -b4_output_begin([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[
 -
 -]b4_namespace_open[
 -  /// Abstract a position.
 +# b4_position_define
 +# ------------------
 +# Define class position.
 +m4_define([b4_position_define],
 +[[  /// Abstract a position.
    class position
    {
    public:
     ** \param ostr the destination output stream
     ** \param pos a reference to the position to redirect
     */
-   inline std::ostream&
-   operator<< (std::ostream& ostr, const position& pos)
+   template <typename YYChar>
+   inline std::basic_ostream<YYChar>&
+   operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
    {
      if (pos.filename)
        ostr << *pos.filename << ':';
      return ostr << pos.line << '.' << pos.column;
    }
 +]])
  
 -]b4_namespace_close[
 -]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
 -b4_output_end()
 -
 -
 -b4_output_begin([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:
     **
     ** Avoid duplicate information.
     */
-   inline std::ostream& operator<< (std::ostream& ostr, const location& loc)
+   template <typename YYChar>
+   inline std::basic_ostream<YYChar>&
+   operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
    {
      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([
 +b4_output_begin([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])
 +b4_output_end()
 +
 +
 +b4_output_begin([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])
  b4_output_end()
 +])
 +
 +
 +m4_popdef([b4_copyright_years])
diff --combined doc/bison.texi
index 874e68e17a4ba78827d54c668c6727fd69fff55a,06af0884350e6b775cdb87fc19fd8502d25dc3af..28af1ae65e390c4e793ba46fb223a4e01bfef242
@@@ -135,8 -135,7 +135,8 @@@ Writing GLR Parser
  
  * Simple GLR Parsers::     Using GLR parsers on unambiguous grammars.
  * Merging GLR Parses::     Using GLR parsers to resolve ambiguities.
 -* GLR Semantic Actions::   Deferred semantic actions have special concerns.
 +* GLR Semantic Actions::   Considerations for semantic values and deferred actions.
 +* Semantic Predicates::    Controlling a parse with arbitrary computations.
  * Compiler Requirements::  GLR parsers require a modern C compiler.
  
  Examples
@@@ -163,9 -162,9 +163,9 @@@ Reverse Polish Notation Calculato
  
  Grammar Rules for @code{rpcalc}
  
 -* Rpcalc Input::
 -* Rpcalc Line::
 -* Rpcalc Expr::
 +* Rpcalc Input::            Explanation of the @code{input} nonterminal
 +* Rpcalc Line::             Explanation of the @code{line} nonterminal
 +* Rpcalc Expr::             Explanation of the @code{expr} nonterminal
  
  Location Tracking Calculator: @code{ltcalc}
  
@@@ -178,8 -177,6 +178,8 @@@ Multi-Function Calculator: @code{mfcalc
  * Mfcalc Declarations::    Bison declarations for multi-function calculator.
  * Mfcalc Rules::           Grammar rules for the calculator.
  * Mfcalc Symbol Table::    Symbol table management subroutines.
 +* Mfcalc Lexer::           The lexical analyzer.
 +* Mfcalc Main::            The controlling function.
  
  Bison Grammar Files
  
@@@ -276,8 -273,7 +276,8 @@@ The Bison Parser Algorith
  Operator Precedence
  
  * Why Precedence::    An example showing why precedence is needed.
 -* Using Precedence::  How to specify precedence in Bison grammars.
 +* Using Precedence::  How to specify precedence and associativity.
 +* Precedence Only::   How to specify precedence only.
  * Precedence Examples::  How these features are used in the previous example.
  * How Precedence::    How they work.
  * Non Operators::     Using precedence for general conflicts.
@@@ -777,8 -773,7 +777,8 @@@ merged result
  @menu
  * Simple GLR Parsers::     Using GLR parsers on unambiguous grammars.
  * Merging GLR Parses::     Using GLR parsers to resolve ambiguities.
 -* GLR Semantic Actions::   Deferred semantic actions have special concerns.
 +* GLR Semantic Actions::   Considerations for semantic values and deferred actions.
 +* Semantic Predicates::    Controlling a parse with arbitrary computations.
  * Compiler Requirements::  GLR parsers require a modern C compiler.
  @end menu
  
@@@ -896,7 -891,10 +896,7 @@@ parses a vastly simplified form of Pasc
  @end group
  
  %%
 -
 -@group
  type_decl: TYPE ID '=' type ';' ;
 -@end group
  
  @group
  type:
@@@ -1143,10 -1141,6 +1143,10 @@@ the offending merge
  @node GLR Semantic Actions
  @subsection GLR Semantic Actions
  
 +The nature of GLR parsing and the structure of the generated
 +parsers give rise to certain restrictions on semantic values and actions.
 +
 +@subsubsection Deferred semantic actions
  @cindex deferred semantic actions
  By definition, a deferred semantic action is not performed at the same time as
  the associated reduction.
@@@ -1180,7 -1174,6 +1180,7 @@@ For example, if a semantic action migh
  to invoke @code{yyclearin} (@pxref{Action Features}) or to attempt to free
  memory referenced by @code{yylval}.
  
 +@subsubsection YYERROR
  @findex YYERROR
  @cindex GLR parsers and @code{YYERROR}
  Another Bison feature requiring special consideration is @code{YYERROR}
  initiate error recovery.
  During deterministic GLR operation, the effect of @code{YYERROR} is
  the same as its effect in a deterministic parser.
 -In a deferred semantic action, its effect is undefined.
 -@c The effect is probably a syntax error at the split point.
 +The effect in a deferred action is similar, but the precise point of the
 +error is undefined;  instead, the parser reverts to deterministic operation,
 +selecting an unspecified stack on which to continue with a syntax error.
 +In a semantic predicate (see @ref{Semantic Predicates}) during nondeterministic
 +parsing, @code{YYERROR} silently prunes
 +the parse that invoked the test.
 +
 +@subsubsection Restrictions on semantic values and locations
 +GLR parsers require that you use POD (Plain Old Data) types for
 +semantic values and location types when using the generated parsers as
 +C++ code.
 +
 +@node Semantic Predicates
 +@subsection Controlling a Parse with Arbitrary Predicates
 +@findex %?
 +@cindex Semantic predicates in GLR parsers
 +
 +In addition to the @code{%dprec} and @code{%merge} directives,
 +GLR parsers
 +allow you to reject parses on the basis of arbitrary computations executed
 +in user code, without having Bison treat this rejection as an error
 +if there are alternative parses. (This feature is experimental and may
 +evolve.  We welcome user feedback.)  For example,
 +
 +@example
 +widget:
 +  %?@{  new_syntax @} "widget" id new_args  @{ $$ = f($3, $4); @}
 +| %?@{ !new_syntax @} "widget" id old_args  @{ $$ = f($3, $4); @}
 +;
 +@end example
  
 -Also, see @ref{Location Default Action, ,Default Action for Locations}, which
 -describes a special usage of @code{YYLLOC_DEFAULT} in GLR parsers.
 +@noindent
 +is one way to allow the same parser to handle two different syntaxes for
 +widgets.  The clause preceded by @code{%?} is treated like an ordinary
 +action, except that its text is treated as an expression and is always
 +evaluated immediately (even when in nondeterministic mode).  If the
 +expression yields 0 (false), the clause is treated as a syntax error,
 +which, in a nondeterministic parser, causes the stack in which it is reduced
 +to die.  In a deterministic parser, it acts like YYERROR.
 +
 +As the example shows, predicates otherwise look like semantic actions, and
 +therefore you must be take them into account when determining the numbers
 +to use for denoting the semantic values of right-hand side symbols.
 +Predicate actions, however, have no defined value, and may not be given
 +labels.
 +
 +There is a subtle difference between semantic predicates and ordinary
 +actions in nondeterministic mode, since the latter are deferred.
 +For example, we could try to rewrite the previous example as
 +
 +@example
 +widget:
 +  @{ if (!new_syntax) YYERROR; @}
 +    "widget" id new_args  @{ $$ = f($3, $4); @}
 +|  @{ if (new_syntax) YYERROR; @}
 +    "widget" id old_args   @{ $$ = f($3, $4); @}
 +;
 +@end example
 +
 +@noindent
 +(reversing the sense of the predicate tests to cause an error when they are
 +false).  However, this
 +does @emph{not} have the same effect if @code{new_args} and @code{old_args}
 +have overlapping syntax.
 +Since the mid-rule actions testing @code{new_syntax} are deferred,
 +a GLR parser first encounters the unresolved ambiguous reduction
 +for cases where @code{new_args} and @code{old_args} recognize the same string
 +@emph{before} performing the tests of @code{new_syntax}.  It therefore
 +reports an error.
 +
 +Finally, be careful in writing predicates: deferred actions have not been
 +evaluated, so that using them in a predicate will have undefined effects.
  
  @node Compiler Requirements
  @subsection Considerations when Compiling GLR Parsers
@@@ -1528,13 -1454,11 +1528,13 @@@ The source code for this calculator is 
  Here are the C and Bison declarations for the reverse polish notation
  calculator.  As in C, comments are placed between @samp{/*@dots{}*/}.
  
 +@comment file: rpcalc.y
  @example
  /* Reverse polish notation calculator.  */
  
  %@{
    #define YYSTYPE double
 +  #include <stdio.h>
    #include <math.h>
    int yylex (void);
    void yyerror (char const *);
@@@ -1579,7 -1503,6 +1579,7 @@@ type for numeric constants
  
  Here are the grammar rules for the reverse polish notation calculator.
  
 +@comment file: rpcalc.y
  @example
  @group
  input:
@@@ -1628,9 -1551,9 +1628,9 @@@ main job of most actions.  The semanti
  rule are referred to as @code{$1}, @code{$2}, and so on.
  
  @menu
 -* Rpcalc Input::
 -* Rpcalc Line::
 -* Rpcalc Expr::
 +* Rpcalc Input::            Explanation of the @code{input} nonterminal
 +* Rpcalc Line::             Explanation of the @code{line} nonterminal
 +* Rpcalc Expr::             Explanation of the @code{expr} nonterminal
  @end menu
  
  @node Rpcalc Input
@@@ -1794,7 -1717,6 +1794,7 @@@ A token type code of zero is returned i
  
  Here is the code for the lexical analyzer:
  
 +@comment file: rpcalc.y
  @example
  @group
  /* The lexical analyzer returns a double floating point
@@@ -1843,7 -1765,6 +1843,7 @@@ In keeping with the spirit of this exam
  kept to the bare minimum.  The only requirement is that it call
  @code{yyparse} to start the process of parsing.
  
 +@comment file: rpcalc.y
  @example
  @group
  int
@@@ -1864,9 -1785,10 +1864,9 @@@ always @code{"syntax error"}).  It is u
  @code{yyerror} (@pxref{Interface, ,Parser C-Language Interface}), so
  here is the definition we will use:
  
 +@comment file: rpcalc.y
  @example
 -@group
  #include <stdio.h>
 -@end group
  
  @group
  /* Called by yyparse on error.  */
@@@ -1947,15 -1869,15 +1947,15 @@@ example session using @code{rpcalc}
  @example
  $ @kbd{rpcalc}
  @kbd{4 9 +}
 -13
 +@result{} 13
  @kbd{3 7 + 3 4 5 *+-}
 --13
 +@result{} -13
  @kbd{3 7 + 3 4 5 * + - n}              @r{Note the unary minus, @samp{n}}
 -13
 +@result{} 13
  @kbd{5 6 / 4 n +}
 --3.166666667
 +@result{} -3.166666667
  @kbd{3 4 ^}                            @r{Exponentiation}
 -81
 +@result{} 81
  @kbd{^D}                               @r{End-of-file indicator}
  $
  @end example
@@@ -1989,8 -1911,8 +1989,8 @@@ parentheses nested to arbitrary depth
  %token NUM
  %left '-' '+'
  %left '*' '/'
 -%left NEG     /* negation--unary minus */
 -%right '^'    /* exponentiation */
 +%precedence NEG   /* negation--unary minus */
 +%right '^'        /* exponentiation */
  @end group
  
  %% /* The grammar follows.  */
@@@ -2033,16 -1955,15 +2033,16 @@@ In the second section (Bison declaratio
  types and says they are left-associative operators.  The declarations
  @code{%left} and @code{%right} (right associativity) take the place of
  @code{%token} which is used to declare a token type name without
 -associativity.  (These tokens are single-character literals, which
 +associativity/precedence.  (These tokens are single-character literals, which
  ordinarily don't need to be declared.  We declare them here to specify
 -the associativity.)
 +the associativity/precedence.)
  
  Operator precedence is determined by the line ordering of the
  declarations; the higher the line number of the declaration (lower on
  the page or screen), the higher the precedence.  Hence, exponentiation
  has the highest precedence, unary minus (@code{NEG}) is next, followed
 -by @samp{*} and @samp{/}, and so on.  @xref{Precedence, ,Operator
 +by @samp{*} and @samp{/}, and so on.  Unary minus is not associative,
 +only precedence matters (@code{%precedence}. @xref{Precedence, ,Operator
  Precedence}.
  
  The other important new feature is the @code{%prec} in the grammar
@@@ -2146,7 -2067,7 +2146,7 @@@ the same as the declarations for the in
  
  %left '-' '+'
  %left '*' '/'
 -%left NEG
 +%precedence NEG
  %right '^'
  
  %% /* The grammar follows.  */
@@@ -2347,23 -2268,19 +2347,23 @@@ to create named variables, store value
  Here is a sample session with the multi-function calculator:
  
  @example
 +@group
  $ @kbd{mfcalc}
  @kbd{pi = 3.141592653589}
 -3.1415926536
 +@result{} 3.1415926536
 +@end group
 +@group
  @kbd{sin(pi)}
 -0.0000000000
 +@result{} 0.0000000000
 +@end group
  @kbd{alpha = beta1 = 2.3}
 -2.3000000000
 +@result{} 2.3000000000
  @kbd{alpha}
 -2.3000000000
 +@result{} 2.3000000000
  @kbd{ln(alpha)}
 -0.8329091229
 +@result{} 0.8329091229
  @kbd{exp(ln(beta1))}
 -2.3000000000
 +@result{} 2.3000000000
  $
  @end example
  
@@@ -2373,8 -2290,6 +2373,8 @@@ Note that multiple assignment and neste
  * Mfcalc Declarations::    Bison declarations for multi-function calculator.
  * Mfcalc Rules::           Grammar rules for the calculator.
  * Mfcalc Symbol Table::    Symbol table management subroutines.
 +* Mfcalc Lexer::           The lexical analyzer.
 +* Mfcalc Main::            The controlling function.
  @end menu
  
  @node Mfcalc Declarations
@@@ -2386,9 -2301,8 +2386,9 @@@ Here are the C and Bison declarations f
  @example
  @group
  %@{
 -  #include <math.h>  /* For math functions, cos(), sin(), etc.  */
 -  #include "calc.h"  /* Contains definition of `symrec'.  */
 +  #include <stdio.h>  /* For printf, etc. */
 +  #include <math.h>   /* For pow, used in the grammar.  */
 +  #include "calc.h"   /* Contains definition of `symrec'.  */
    int yylex (void);
    void yyerror (char const *);
  %@}
  %right '='
  %left '-' '+'
  %left '*' '/'
 -%left NEG     /* negation--unary minus */
 -%right '^'    /* exponentiation */
 +%precedence NEG /* negation--unary minus */
 +%right '^'      /* exponentiation */
  @end group
  @end example
  
@@@ -2525,11 -2439,23 +2525,11 @@@ symrec *getsym (char const *)
  @end group
  @end example
  
 -The new version of @code{main} includes a call to @code{init_table}, a
 -function that initializes the symbol table.  Here it is, and
 -@code{init_table} as well:
 +The new version of @code{main} will call @code{init_table} to initialize
 +the symbol table:
  
  @comment file: mfcalc.y: 3
  @example
 -#include <stdio.h>
 -
 -@group
 -/* Called by yyparse on error.  */
 -void
 -yyerror (char const *s)
 -@{
 -  fprintf (stderr, "%s\n", s);
 -@}
 -@end group
 -
  @group
  struct init
  @{
  @group
  struct init const arith_fncts[] =
  @{
 -  "sin",  sin,
 -  "cos",  cos,
 -  "atan", atan,
 -  "ln",   log,
 -  "exp",  exp,
 -  "sqrt", sqrt,
 -  0, 0
 +  @{ "atan", atan @},
 +  @{ "cos",  cos  @},
 +  @{ "exp",  exp  @},
 +  @{ "ln",   log  @},
 +  @{ "sin",  sin  @},
 +  @{ "sqrt", sqrt @},
 +  @{ 0, 0 @},
  @};
  @end group
  
@@@ -2558,7 -2484,6 +2558,7 @@@ symrec *sym_table
  
  @group
  /* Put arithmetic functions in table.  */
 +static
  void
  init_table (void)
  @{
      @}
  @}
  @end group
 -
 -@group
 -int
 -main (void)
 -@{
 -  init_table ();
 -  return yyparse ();
 -@}
 -@end group
  @end example
  
  By simply editing the initialization list and adding the necessary include
@@@ -2609,16 -2543,13 +2609,16 @@@ getsym (char const *sym_name
    symrec *ptr;
    for (ptr = sym_table; ptr != (symrec *) 0;
         ptr = (symrec *)ptr->next)
 -    if (strcmp (ptr->name,sym_name) == 0)
 +    if (strcmp (ptr->name, sym_name) == 0)
        return ptr;
    return 0;
  @}
  @end group
  @end example
  
 +@node Mfcalc Lexer
 +@subsection The @code{mfcalc} Lexer
 +
  The function @code{yylex} must now recognize variables, numeric values, and
  the single-character arithmetic operators.  Strings of alphanumeric
  characters with a leading letter are recognized as either variables or
@@@ -2636,7 -2567,9 +2636,7 @@@ operators in @code{yylex}
  
  @comment file: mfcalc.y: 3
  @example
 -@group
  #include <ctype.h>
 -@end group
  
  @group
  int
@@@ -2673,6 -2606,7 +2673,6 @@@ yylex (void
        symrec *s;
        int i;
  @end group
 -
        if (!symbuf)
          symbuf = (char *) malloc (length + 1);
  
  @end group
  @end example
  
 +@node Mfcalc Main
 +@subsection The @code{mfcalc} Main
 +
  The error reporting function is unchanged, and the new version of
  @code{main} includes a call to @code{init_table} and sets the @code{yydebug}
  on user demand (@xref{Tracing, , Tracing Your Parser}, for details):
@@@ -3388,7 -3319,9 +3388,7 @@@ one of your tokens with a @code{%token
  A Bison grammar rule has the following general form:
  
  @example
 -@group
  @var{result}: @var{components}@dots{};
 -@end group
  @end example
  
  @noindent
@@@ -3399,7 -3332,9 +3399,7 @@@ are put together by this rule (@pxref{S
  For example,
  
  @example
 -@group
  exp: exp '+' exp;
 -@end group
  @end example
  
  @noindent
@@@ -3703,7 -3638,9 +3703,7 @@@ difference with tools like Flex, for wh
  following example, the action is triggered only when @samp{b} is found:
  
  @example
 -@group
  a-or-b: 'a'|'b'   @{ a_or_b_found = 1; @};
 -@end group
  @end example
  
  @cindex default action
@@@ -4367,8 -4304,7 +4367,8 @@@ Bison will convert this into a @code{#d
  the parser, so that the function @code{yylex} (if it is in this file)
  can use the name @var{name} to stand for this token type's code.
  
 -Alternatively, you can use @code{%left}, @code{%right}, or
 +Alternatively, you can use @code{%left}, @code{%right},
 +@code{%precedence}, or
  @code{%nonassoc} instead of @code{%token}, if you wish to specify
  associativity and precedence.  @xref{Precedence Decl, ,Operator
  Precedence}.
@@@ -4444,8 -4380,7 +4444,8 @@@ of ``$end''
  @cindex declaring operator precedence
  @cindex operator precedence, declaring
  
 -Use the @code{%left}, @code{%right} or @code{%nonassoc} declaration to
 +Use the @code{%left}, @code{%right}, @code{%nonassoc}, or
 +@code{%precedence} declaration to
  declare a token and specify its precedence and associativity, all at
  once.  These are called @dfn{precedence declarations}.
  @xref{Precedence, ,Operator Precedence}, for general information on
@@@ -4481,10 -4416,6 +4481,10 @@@ left-associativity (grouping @var{x} wi
  means that @samp{@var{x} @var{op} @var{y} @var{op} @var{z}} is
  considered a syntax error.
  
 +@code{%precedence} gives only precedence to the @var{symbols}, and
 +defines no associativity at all.  Use this to define precedence only,
 +and leave any potential conflict due to associativity enabled.
 +
  @item
  The precedence of an operator determines how it nests with other operators.
  All the tokens declared in a single precedence declaration have equal
@@@ -4950,7 -4881,7 +4950,7 @@@ statically allocated variables for comm
  including @code{yylval} and @code{yylloc}.)
  
  Alternatively, you can generate a pure, reentrant parser.  The Bison
 -declaration @code{%define api.pure} says that you want the parser to be
 +declaration @samp{%define api.pure} says that you want the parser to be
  reentrant.  It looks like this:
  
  @example
@@@ -5054,14 -4985,14 +5054,14 @@@ for use by the next invocation of the @
  
  Bison also supports both the push parser interface along with the pull parser
  interface in the same generated parser.  In order to get this functionality,
 -you should replace the @code{%define api.push-pull push} declaration with the
 -@code{%define api.push-pull both} declaration.  Doing this will create all of
 +you should replace the @samp{%define api.push-pull push} declaration with the
 +@samp{%define api.push-pull both} declaration.  Doing this will create all of
  the symbols mentioned earlier along with the two extra symbols, @code{yyparse}
  and @code{yypull_parse}.  @code{yyparse} can be used exactly as it normally
  would be used.  However, the user should note that it is implemented in the
  generated parser by calling @code{yypull_parse}.
  This makes the @code{yyparse} function that is generated with the
 -@code{%define api.push-pull both} declaration slower than the normal
 +@samp{%define api.push-pull both} declaration slower than the normal
  @code{yyparse} function.  If the user
  calls the @code{yypull_parse} function it will parse the rest of the input
  stream.  It is possible to @code{yypush_parse} tokens to select a subgrammar
@@@ -5077,9 -5008,9 +5077,9 @@@ yypull_parse (ps); /* Will call the lex
  yypstate_delete (ps);
  @end example
  
 -Adding the @code{%define api.pure full} declaration does exactly the same thing
 -to the generated parser with @code{%define api.push-pull both} as it did for
 -@code{%define api.push-pull push}.
 +Adding the @samp{%define api.pure} declaration does exactly the same thing to
 +the generated parser with @samp{%define api.push-pull both} as it did for
 +@samp{%define api.push-pull push}.
  
  @node Decl Summary
  @subsection Bison Declaration Summary
@@@ -5152,8 -5083,10 +5152,8 @@@ default location or at the location spe
  @end deffn
  
  @deffn {Directive} %debug
 -In the parser implementation file, define the macro @code{YYDEBUG} (or
 -@code{@var{prefix}DEBUG} with @samp{%define api.prefix @var{prefix}}, see
 -@ref{Multiple Parsers, ,Multiple Parsers in the Same Program}) to 1 if it is
 -not already defined, so that the debugging facilities are compiled.
 +Instrument the parser for traces.  Obsoleted by @samp{%define
 +parse.trace}.
  @xref{Tracing, ,Tracing Your Parser}.
  @end deffn
  
@@@ -5247,22 -5180,6 +5247,22 @@@ grammar does not use it, using @samp{%l
  accurate syntax error messages.
  @end deffn
  
 +@deffn {Directive} %name-prefix "@var{prefix}"
 +Rename the external symbols used in the parser so that they start with
 +@var{prefix} instead of @samp{yy}.  The precise list of symbols renamed
 +in C parsers
 +is @code{yyparse}, @code{yylex}, @code{yyerror}, @code{yynerrs},
 +@code{yylval}, @code{yychar}, @code{yydebug}, and
 +(if locations are used) @code{yylloc}.  If you use a push parser,
 +@code{yypush_parse}, @code{yypull_parse}, @code{yypstate},
 +@code{yypstate_new} and @code{yypstate_delete} will
 +also be renamed.  For example, if you use @samp{%name-prefix "c_"}, the
 +names become @code{c_parse}, @code{c_lex}, and so on.
 +For C++ parsers, see the @samp{%define api.namespace} documentation in this
 +section.
 +@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
 +@end deffn
 +
  @ifset defaultprec
  @deffn {Directive} %no-default-prec
  Do not assign a precedence to rules lacking an explicit @code{%prec}
@@@ -5286,7 -5203,7 +5286,7 @@@ Specify @var{file} for the parser imple
  @end deffn
  
  @deffn {Directive} %pure-parser
 -Deprecated version of @code{%define api.pure} (@pxref{%define
 +Deprecated version of @samp{%define api.pure} (@pxref{%define
  Summary,,api.pure}), for which Bison is more careful to warn about
  unreasonable usage.
  @end deffn
@@@ -5409,59 -5326,7 +5409,59 @@@ Summary,,%skeleton})
  Unaccepted @var{variable}s produce an error.
  Some of the accepted @var{variable}s are:
  
 -@itemize @bullet
 +@table @code
 +@c ================================================== api.namespace
 +@item api.namespace
 +@findex %define api.namespace
 +@itemize
 +@item Languages(s): C++
 +
 +@item Purpose: Specify the namespace for the parser class.
 +For example, if you specify:
 +
 +@example
 +%define api.namespace "foo::bar"
 +@end example
 +
 +Bison uses @code{foo::bar} verbatim in references such as:
 +
 +@example
 +foo::bar::parser::semantic_type
 +@end example
 +
 +However, to open a namespace, Bison removes any leading @code{::} and then
 +splits on any remaining occurrences:
 +
 +@example
 +namespace foo @{ namespace bar @{
 +  class position;
 +  class location;
 +@} @}
 +@end example
 +
 +@item Accepted Values:
 +Any absolute or relative C++ namespace reference without a trailing
 +@code{"::"}.  For example, @code{"foo"} or @code{"::foo::bar"}.
 +
 +@item Default Value:
 +The value specified by @code{%name-prefix}, which defaults to @code{yy}.
 +This usage of @code{%name-prefix} is for backward compatibility and can
 +be confusing since @code{%name-prefix} also specifies the textual prefix
 +for the lexical analyzer function.  Thus, if you specify
 +@code{%name-prefix}, it is best to also specify @samp{%define
 +api.namespace} so that @code{%name-prefix} @emph{only} affects the
 +lexical analyzer function.  For example, if you specify:
 +
 +@example
 +%define api.namespace "foo"
 +%name-prefix "bar::"
 +@end example
 +
 +The parser namespace is @code{foo} and @code{yylex} is referenced as
 +@code{bar::lex}.
 +@end itemize
 +@c namespace
 +
  @c ================================================== api.location.type
  @item @code{api.location.type}
  @findex %define api.location.type
  @end itemize
  
  @c ================================================== api.prefix
 -@item @code{api.prefix}
 +@item api.prefix
  @findex %define api.prefix
  
  @itemize @bullet
  @end itemize
  
  @c ================================================== api.pure
 -@item @code{api.pure}
 +@item api.pure
  @findex %define api.pure
  
  @itemize @bullet
@@@ -5542,12 -5407,10 +5542,12 @@@ Reporting Function @code{yyerror}}
  
  @item History: the @code{full} value was introduced in Bison 2.7
  @end itemize
 +@c api.pure
 +
  
 -@c ================================================== api.push-pull
  
 -@item @code{api.push-pull}
 +@c ================================================== api.push-pull
 +@item api.push-pull
  @findex %define api.push-pull
  
  @itemize @bullet
@@@ -5562,78 -5425,11 +5562,78 @@@ More user feedback will help to stabili
  
  @item Default Value: @code{pull}
  @end itemize
 +@c api.push-pull
 +
  
 -@c ================================================== lr.default-reductions
  
 -@item @code{lr.default-reductions}
 -@findex %define lr.default-reductions
 +@c ================================================== api.token.constructor
 +@item api.token.constructor
 +@findex %define api.token.constructor
 +
 +@itemize @bullet
 +@item Language(s):
 +C++
 +
 +@item Purpose:
 +When variant-based semantic values are enabled (@pxref{C++ Variants}),
 +request that symbols be handled as a whole (type, value, and possibly
 +location) in the scanner.  @xref{Complete Symbols}, for details.
 +
 +@item Accepted Values:
 +Boolean.
 +
 +@item Default Value:
 +@code{false}
 +@item History:
 +introduced in Bison 2.8
 +@end itemize
 +@c api.token.constructor
 +
 +
 +@c ================================================== api.token.prefix
 +@item api.token.prefix
 +@findex %define api.token.prefix
 +
 +@itemize
 +@item Languages(s): all
 +
 +@item Purpose:
 +Add a prefix to the token names when generating their definition in the
 +target language.  For instance
 +
 +@example
 +%token FILE for ERROR
 +%define api.token.prefix "TOK_"
 +%%
 +start: FILE for ERROR;
 +@end example
 +
 +@noindent
 +generates the definition of the symbols @code{TOK_FILE}, @code{TOK_for},
 +and @code{TOK_ERROR} in the generated source files.  In particular, the
 +scanner must use these prefixed token names, while the grammar itself
 +may still use the short names (as in the sample rule given above).  The
 +generated informational files (@file{*.output}, @file{*.xml},
 +@file{*.dot}) are not modified by this prefix.  See @ref{Calc++ Parser}
 +and @ref{Calc++ Scanner}, for a complete example.
 +
 +@item Accepted Values:
 +Any string.  Should be a valid identifier prefix in the target language,
 +in other words, it should typically be an identifier itself (sequence of
 +letters, underscores, and ---not at the beginning--- digits).
 +
 +@item Default Value:
 +empty
 +@item History:
 +introduced in Bison 2.8
 +@end itemize
 +@c api.token.prefix
 +
 +
 +@c ================================================== lr.default-reduction
 +
 +@item lr.default-reduction
 +@findex %define lr.default-reduction
  
  @itemize @bullet
  @item Language(s): all
@@@ -5649,15 -5445,12 +5649,15 @@@ feedback will help to stabilize it.
  @item @code{accepting} if @code{lr.type} is @code{canonical-lr}.
  @item @code{most} otherwise.
  @end itemize
 +@item History:
 +introduced as @code{lr.default-reduction} in 2.5, renamed as
 +@code{lr.default-reduction} in 2.8.
  @end itemize
  
 -@c ============================================ lr.keep-unreachable-states
 +@c ============================================ lr.keep-unreachable-state
  
 -@item @code{lr.keep-unreachable-states}
 -@findex %define lr.keep-unreachable-states
 +@item lr.keep-unreachable-state
 +@findex %define lr.keep-unreachable-state
  
  @itemize @bullet
  @item Language(s): all
@@@ -5666,14 -5459,10 +5666,14 @@@ remain in the parser tables.  @xref{Unr
  @item Accepted Values: Boolean
  @item Default Value: @code{false}
  @end itemize
 +introduced as @code{lr.keep_unreachable_states} in 2.3b, renamed as
 +@code{lr.keep-unreachable-states} in 2.5, and as
 +@code{lr.keep-unreachable-state} in 2.8.
 +@c lr.keep-unreachable-state
  
  @c ================================================== lr.type
  
 -@item @code{lr.type}
 +@item lr.type
  @findex %define lr.type
  
  @itemize @bullet
@@@ -5688,62 -5477,62 +5688,62 @@@ More user feedback will help to stabili
  @item Default Value: @code{lalr}
  @end itemize
  
 -@c ================================================== namespace
  
 -@item @code{namespace}
 +@c ================================================== namespace
 +@item namespace
  @findex %define namespace
 +Obsoleted by @code{api.namespace}
 +@c namespace
  
 -@itemize
 -@item Languages(s): C++
  
 -@item Purpose: Specify the namespace for the parser class.
 -For example, if you specify:
 +@c ================================================== parse.assert
 +@item parse.assert
 +@findex %define parse.assert
  
 -@smallexample
 -%define namespace "foo::bar"
 -@end smallexample
 +@itemize
 +@item Languages(s): C++
  
 -Bison uses @code{foo::bar} verbatim in references such as:
 +@item Purpose: Issue runtime assertions to catch invalid uses.
 +In C++, when variants are used (@pxref{C++ Variants}), symbols must be
 +constructed and
 +destroyed properly.  This option checks these constraints.
  
 -@smallexample
 -foo::bar::parser::semantic_type
 -@end smallexample
 +@item Accepted Values: Boolean
  
 -However, to open a namespace, Bison removes any leading @code{::} and then
 -splits on any remaining occurrences:
 +@item Default Value: @code{false}
 +@end itemize
 +@c parse.assert
  
 -@smallexample
 -namespace foo @{ namespace bar @{
 -  class position;
 -  class location;
 -@} @}
 -@end smallexample
 -
 -@item Accepted Values: Any absolute or relative C++ namespace reference without
 -a trailing @code{"::"}.
 -For example, @code{"foo"} or @code{"::foo::bar"}.
 -
 -@item Default Value: The value specified by @code{%name-prefix}, which defaults
 -to @code{yy}.
 -This usage of @code{%name-prefix} is for backward compatibility and can be
 -confusing since @code{%name-prefix} also specifies the textual prefix for the
 -lexical analyzer function.
 -Thus, if you specify @code{%name-prefix}, it is best to also specify
 -@code{%define namespace} so that @code{%name-prefix} @emph{only} affects the
 -lexical analyzer function.
 -For example, if you specify:
  
 -@smallexample
 -%define namespace "foo"
 -%name-prefix "bar::"
 -@end smallexample
 +@c ================================================== parse.error
 +@item parse.error
 +@findex %define parse.error
 +@itemize
 +@item Languages(s):
 +all
 +@item Purpose:
 +Control the kind of error messages passed to the error reporting
 +function.  @xref{Error Reporting, ,The Error Reporting Function
 +@code{yyerror}}.
 +@item Accepted Values:
 +@itemize
 +@item @code{simple}
 +Error messages passed to @code{yyerror} are simply @w{@code{"syntax
 +error"}}.
 +@item @code{verbose}
 +Error messages report the unexpected token, and possibly the expected ones.
 +However, this report can often be incorrect when LAC is not enabled
 +(@pxref{LAC}).
 +@end itemize
  
 -The parser namespace is @code{foo} and @code{yylex} is referenced as
 -@code{bar::lex}.
 +@item Default Value:
 +@code{simple}
  @end itemize
 +@c parse.error
 +
  
  @c ================================================== parse.lac
 -@item @code{parse.lac}
 +@item parse.lac
  @findex %define parse.lac
  
  @itemize
@@@ -5754,50 -5543,7 +5754,50 @@@ syntax error handling.  @xref{LAC}
  @item Accepted Values: @code{none}, @code{full}
  @item Default Value: @code{none}
  @end itemize
 +@c parse.lac
 +
 +@c ================================================== parse.trace
 +@item parse.trace
 +@findex %define parse.trace
 +
 +@itemize
 +@item Languages(s): C, C++, Java
 +
 +@item Purpose: Require parser instrumentation for tracing.
 +@xref{Tracing, ,Tracing Your Parser}.
 +
 +In C/C++, define the macro @code{YYDEBUG} (or @code{@var{prefix}DEBUG} with
 +@samp{%define api.prefix @var{prefix}}), see @ref{Multiple Parsers,
 +,Multiple Parsers in the Same Program}) to 1 in the parser implementation
 +file if it is not already defined, so that the debugging facilities are
 +compiled.
 +
 +@item Accepted Values: Boolean
 +
 +@item Default Value: @code{false}
 +@end itemize
 +@c parse.trace
 +
 +@c ================================================== variant
 +@item variant
 +@findex %define variant
 +
 +@itemize @bullet
 +@item Language(s):
 +C++
 +
 +@item Purpose:
 +Request variant-based semantic values.
 +@xref{C++ Variants}.
 +
 +@item Accepted Values:
 +Boolean.
 +
 +@item Default Value:
 +@code{false}
  @end itemize
 +@c variant
 +@end table
  
  
  @node %code Summary
@@@ -5843,7 -5589,7 +5843,7 @@@ file
  Not all qualifiers are accepted for all target languages.  Unaccepted
  qualifiers produce an error.  Some of the accepted qualifiers are:
  
 -@itemize @bullet
 +@table @code
  @item requires
  @findex %code requires
  
@@@ -5907,7 -5653,7 +5907,7 @@@ parser implementation file.  For exampl
  @item Location(s): The parser Java file after any Java package directive and
  before any class definitions.
  @end itemize
 -@end itemize
 +@end table
  
  Though we say the insertion locations are language-dependent, they are
  technically skeleton-dependent.  Writers of non-standard skeletons
@@@ -6069,10 -5815,10 +6069,10 @@@ If you use a reentrant parser, you can 
  parameter information to it in a reentrant way.  To do so, use the
  declaration @code{%parse-param}:
  
 -@deffn {Directive} %parse-param @{@var{argument-declaration}@}
 +@deffn {Directive} %parse-param @{@var{argument-declaration}@} @dots{}
  @findex %parse-param
 -Declare that an argument declared by the braced-code
 -@var{argument-declaration} is an additional @code{yyparse} argument.
 +Declare that one or more
 +@var{argument-declaration} are additional @code{yyparse} arguments.
  The @var{argument-declaration} is used when declaring
  functions or prototypes.  The last identifier in
  @var{argument-declaration} must be the argument name.
  Here's an example.  Write this in the parser:
  
  @example
 -%parse-param @{int *nastiness@}
 -%parse-param @{int *randomness@}
 +%parse-param @{int *nastiness@} @{int *randomness@}
  @end example
  
  @noindent
@@@ -6132,8 -5879,8 +6132,8 @@@ int  yyparse (int *randomness)
  More user feedback will help to stabilize it.)
  
  You call the function @code{yypush_parse} to parse a single token.  This
 -function is available if either the @code{%define api.push-pull push} or
 -@code{%define api.push-pull both} declaration is used.
 +function is available if either the @samp{%define api.push-pull push} or
 +@samp{%define api.push-pull both} declaration is used.
  @xref{Push Decl, ,A Push Parser}.
  
  @deftypefun int yypush_parse (yypstate *yyps)
@@@ -6150,7 -5897,7 +6150,7 @@@ required to finish parsing the grammar
  More user feedback will help to stabilize it.)
  
  You call the function @code{yypull_parse} to parse the rest of the input
 -stream.  This function is available if the @code{%define api.push-pull both}
 +stream.  This function is available if the @samp{%define api.push-pull both}
  declaration is used.
  @xref{Push Decl, ,A Push Parser}.
  
@@@ -6166,8 -5913,8 +6166,8 @@@ The value returned by @code{yypull_pars
  More user feedback will help to stabilize it.)
  
  You call the function @code{yypstate_new} to create a new parser instance.
 -This function is available if either the @code{%define api.push-pull push} or
 -@code{%define api.push-pull both} declaration is used.
 +This function is available if either the @samp{%define api.push-pull push} or
 +@samp{%define api.push-pull both} declaration is used.
  @xref{Push Decl, ,A Push Parser}.
  
  @deftypefun {yypstate*} yypstate_new (void)
@@@ -6185,8 -5932,8 +6185,8 @@@ allocated
  More user feedback will help to stabilize it.)
  
  You call the function @code{yypstate_delete} to delete a parser instance.
 -function is available if either the @code{%define api.push-pull push} or
 -@code{%define api.push-pull both} declaration is used.
 +function is available if either the @samp{%define api.push-pull push} or
 +@samp{%define api.push-pull both} declaration is used.
  @xref{Push Decl, ,A Push Parser}.
  
  @deftypefun void yypstate_delete (yypstate *yyps)
@@@ -6399,59 -6146,36 +6399,59 @@@ textual locations, then the type @code{
  this case, omit the second argument; @code{yylex} will be called with
  only one argument.
  
 -
 -If you wish to pass the additional parameter data to @code{yylex}, use
 +If you wish to pass additional arguments to @code{yylex}, use
  @code{%lex-param} just like @code{%parse-param} (@pxref{Parser
 -Function}).
 +Function}).  To pass additional arguments to both @code{yylex} and
 +@code{yyparse}, use @code{%param}.
  
 -@deffn {Directive} lex-param @{@var{argument-declaration}@}
 +@deffn {Directive} %lex-param @{@var{argument-declaration}@} @dots{}
  @findex %lex-param
 -Declare that the braced-code @var{argument-declaration} is an
 -additional @code{yylex} argument declaration.
 +Specify that @var{argument-declaration} are additional @code{yylex} argument
 +declarations.  You may pass one or more such declarations, which is
 +equivalent to repeating @code{%lex-param}.
 +@end deffn
 +
 +@deffn {Directive} %param @{@var{argument-declaration}@} @dots{}
 +@findex %param
 +Specify that @var{argument-declaration} are additional
 +@code{yylex}/@code{yyparse} argument declaration.  This is equivalent to
 +@samp{%lex-param @{@var{argument-declaration}@} @dots{} %parse-param
 +@{@var{argument-declaration}@} @dots{}}.  You may pass one or more
 +declarations, which is equivalent to repeating @code{%param}.
  @end deffn
  
  @noindent
  For instance:
  
  @example
 -%lex-param   @{int *nastiness@}
 +%lex-param   @{scanner_mode *mode@}
 +%parse-param @{parser_mode *mode@}
 +%param       @{environment_type *env@}
  @end example
  
  @noindent
 -results in the following signature:
 +results in the following signatures:
  
  @example
 -int yylex (int *nastiness);
 +int yylex   (scanner_mode *mode, environment_type *env);
 +int yyparse (parser_mode *mode, environment_type *env);
 +@end example
 +
 +If @samp{%define api.pure full} is added:
 +
 +@example
 +int yylex   (YYSTYPE *lvalp, scanner_mode *mode, environment_type *env);
 +int yyparse (parser_mode *mode, environment_type *env);
  @end example
  
  @noindent
 -If @code{%define api.pure full} (or just @code{%define api.pure}) is added:
 +and finally, if both @samp{%define api.pure full} and @code{%locations} are
 +used:
  
  @example
 -int yylex (YYSTYPE *lvalp, int *nastiness);
 +int yylex   (YYSTYPE *lvalp, YYLTYPE *llocp,
 +             scanner_mode *mode, environment_type *env);
 +int yyparse (parser_mode *mode, environment_type *env);
  @end example
  
  @node Error Reporting
  @cindex parse error
  @cindex syntax error
  
 -The Bison parser detects a @dfn{syntax error} or @dfn{parse error}
 +The Bison parser detects a @dfn{syntax error} (or @dfn{parse error})
  whenever it reads a token which cannot satisfy any syntax rule.  An
  action in the grammar can also explicitly proclaim an error, using the
  macro @code{YYERROR} (@pxref{Action Features, ,Special Features for Use
@@@ -6473,8 -6197,8 +6473,8 @@@ called by @code{yyparse} whenever a syn
  receives one argument.  For a syntax error, the string is normally
  @w{@code{"syntax error"}}.
  
 -@findex %error-verbose
 -If you invoke the directive @code{%error-verbose} in the Bison declarations
 +@findex %define parse.error
 +If you invoke @samp{%define parse.error verbose} in the Bison declarations
  section (@pxref{Bison Declarations, ,The Bison Declarations Section}), then
  Bison provides a more verbose and specific error message string instead of
  just plain @w{@code{"syntax error"}}.  However, that message sometimes
@@@ -6990,7 -6714,9 +6990,7 @@@ rules.  Here is a complete Bison gramma
  the conflict:
  
  @example
 -@group
  %%
 -@end group
  @group
  stmt:
    expr
@@@ -7022,8 -6748,7 +7022,8 @@@ shift and when to reduce
  
  @menu
  * Why Precedence::    An example showing why precedence is needed.
 -* Using Precedence::  How to specify precedence in Bison grammars.
 +* Using Precedence::  How to specify precedence and associativity.
 +* Precedence Only::   How to specify precedence only.
  * Precedence Examples::  How these features are used in the previous example.
  * How Precedence::    How they work.
  * Non Operators::     Using precedence for general conflicts.
@@@ -7080,9 -6805,8 +7080,9 @@@ makes right-associativity
  @node Using Precedence
  @subsection Specifying Operator Precedence
  @findex %left
 -@findex %right
  @findex %nonassoc
 +@findex %precedence
 +@findex %right
  
  Bison allows you to specify these choices with the operator precedence
  declarations @code{%left} and @code{%right}.  Each such declaration
@@@ -7092,63 -6816,13 +7092,63 @@@ those operators left-associative and th
  them right-associative.  A third alternative is @code{%nonassoc}, which
  declares that it is a syntax error to find the same operator twice ``in a
  row''.
 +The last alternative, @code{%precedence}, allows to define only
 +precedence and no associativity at all.  As a result, any
 +associativity-related conflict that remains will be reported as an
 +compile-time error.  The directive @code{%nonassoc} creates run-time
 +error: using the operator in a associative way is a syntax error.  The
 +directive @code{%precedence} creates compile-time errors: an operator
 +@emph{can} be involved in an associativity-related conflict, contrary to
 +what expected the grammar author.
  
  The relative precedence of different operators is controlled by the
 -order in which they are declared.  The first @code{%left} or
 -@code{%right} declaration in the file declares the operators whose
 +order in which they are declared.  The first precedence/associativity
 +declaration in the file declares the operators whose
  precedence is lowest, the next such declaration declares the operators
  whose precedence is a little higher, and so on.
  
 +@node Precedence Only
 +@subsection Specifying Precedence Only
 +@findex %precedence
 +
 +Since POSIX Yacc defines only @code{%left}, @code{%right}, and
 +@code{%nonassoc}, which all defines precedence and associativity, little
 +attention is paid to the fact that precedence cannot be defined without
 +defining associativity.  Yet, sometimes, when trying to solve a
 +conflict, precedence suffices.  In such a case, using @code{%left},
 +@code{%right}, or @code{%nonassoc} might hide future (associativity
 +related) conflicts that would remain hidden.
 +
 +The dangling @code{else} ambiguity (@pxref{Shift/Reduce, , Shift/Reduce
 +Conflicts}) can be solved explicitly.  This shift/reduce conflicts occurs
 +in the following situation, where the period denotes the current parsing
 +state:
 +
 +@example
 +if @var{e1} then if  @var{e2} then @var{s1} . else @var{s2}
 +@end example
 +
 +The conflict involves the reduction of the rule @samp{IF expr THEN
 +stmt}, which precedence is by default that of its last token
 +(@code{THEN}), and the shifting of the token @code{ELSE}.  The usual
 +disambiguation (attach the @code{else} to the closest @code{if}),
 +shifting must be preferred, i.e., the precedence of @code{ELSE} must be
 +higher than that of @code{THEN}.  But neither is expected to be involved
 +in an associativity related conflict, which can be specified as follows.
 +
 +@example
 +%precedence THEN
 +%precedence ELSE
 +@end example
 +
 +The unary-minus is another typical example where associativity is
 +usually over-specified, see @ref{Infix Calc, , Infix Notation
 +Calculator: @code{calc}}.  The @code{%left} directive is traditionally
 +used to declare the precedence of @code{NEG}, which is more than needed
 +since it also defines its associativity.  While this is harmless in the
 +traditional example, who knows how @code{NEG} might be used in future
 +evolutions of the grammar@dots{}
 +
  @node Precedence Examples
  @subsection Precedence Examples
  
@@@ -7209,8 -6883,8 +7209,8 @@@ instance as follows
  
  @example
  @group
 -%nonassoc "then"
 -%nonassoc "else"
 +%precedence "then"
 +%precedence "else"
  @end group
  @end example
  
@@@ -7223,7 -6897,7 +7223,7 @@@ use right associativity
  @end example
  
  Neither solution is perfect however.  Since Bison does not provide, so far,
 -support for ``scoped'' precedence, both force you to declare the precedence
 +``scoped'' precedence, both force you to declare the precedence
  of these keywords with respect to the other operators your grammar.
  Therefore, instead of being warned about new conflicts you would be unaware
  of (e.g., a shift/reduce conflict due to @samp{if test then 1 else 2 + 3}
@@@ -7243,8 -6917,8 +7243,8 @@@ outlandish at first, but it is really v
  sign typically has a very high precedence as a unary operator, and a
  somewhat lower precedence (lower than multiplication) as a binary operator.
  
 -The Bison precedence declarations, @code{%left}, @code{%right} and
 -@code{%nonassoc}, can only be used once for a given token; so a token has
 +The Bison precedence declarations
 +can only be used once for a given token; so a token has
  only one precedence declared in this way.  For context-dependent
  precedence, you need to use an additional mechanism: the @code{%prec}
  modifier for rules.
@@@ -7401,8 -7075,8 +7401,8 @@@ sequence
  Here is another common error that yields a reduce/reduce conflict:
  
  @example
 -sequence:
  @group
 +sequence:
    /* empty */
  | sequence words
  | sequence redirects
@@@ -7492,8 -7166,8 +7492,8 @@@ relies on precedences: use @code{%prec
  rule:
  
  @example
 -%nonassoc "word"
 -%nonassoc "sequence"
 +%precedence "word"
 +%precedence "sequence"
  %%
  @group
  sequence:
@@@ -7542,16 -7216,15 +7542,16 @@@ param_spec
  | name_list ':' type
  ;
  @end group
 +
  @group
  return_spec:
    type
  | name ':' type
  ;
  @end group
 -@group
 +
  type: "id";
 -@end group
 +
  @group
  name: "id";
  name_list:
@@@ -7625,19 -7298,14 +7625,19 @@@ contexts to have different sets of acti
  rather than the one for @code{name}.
  
  @example
 +@group
  param_spec:
    type
  | name_list ':' type
  ;
 +@end group
 +
 +@group
  return_spec:
    type
  | "id" ':' type
  ;
 +@end group
  @end example
  
  For a more detailed exposition of LALR(1) parsers and parser
@@@ -7650,9 -7318,9 +7650,9 @@@ The default behavior of Bison's LR-base
  historical reasons, but that behavior is often not robust.  For example, in
  the previous section, we discussed the mysterious conflicts that can be
  produced by LALR(1), Bison's default parser table construction algorithm.
 -Another example is Bison's @code{%error-verbose} directive, which instructs
 -the generated parser to produce verbose syntax error messages, which can
 -sometimes contain incorrect information.
 +Another example is Bison's @code{%define parse.error verbose} directive,
 +which instructs the generated parser to produce verbose syntax error
 +messages, which can sometimes contain incorrect information.
  
  In this section, we explore several modern features of Bison that allow you
  to tune fundamental aspects of the generated LR-based parsers.  Some of
@@@ -7742,8 -7410,7 +7742,8 @@@ There are at least two scenarios where 
  
  @cindex GLR with LALR
  When employing GLR parsers (@pxref{GLR Parsers}), if you do not resolve any
 -conflicts statically (for example, with @code{%left} or @code{%prec}), then
 +conflicts statically (for example, with @code{%left} or @code{%precedence}),
 +then
  the parser explores all potential parses of any given input.  In this case,
  the choice of parser table construction algorithm is guaranteed not to alter
  the language accepted by the parser.  LALR parser tables are the smallest
@@@ -7800,7 -7467,7 +7800,7 @@@ and the benefits of IELR, @pxref{Biblio
  @node Default Reductions
  @subsection Default Reductions
  @cindex default reductions
 -@findex %define lr.default-reductions
 +@findex %define lr.default-reduction
  @findex %nonassoc
  
  After parser table construction, Bison identifies the reduction with the
@@@ -7882,9 -7549,9 +7882,9 @@@ token for which there is a conflict.  T
  split the parse instead.
  
  To adjust which states have default reductions enabled, use the
 -@code{%define lr.default-reductions} directive.
 +@code{%define lr.default-reduction} directive.
  
 -@deffn {Directive} {%define lr.default-reductions} @var{where}
 +@deffn {Directive} {%define lr.default-reduction} @var{where}
  Specify the kind of states that are permitted to contain default reductions.
  The accepted values of @var{where} are:
  @itemize
@@@ -8007,7 -7674,7 +8007,7 @@@ parser community for years, for the pub
  
  @node Unreachable States
  @subsection Unreachable States
 -@findex %define lr.keep-unreachable-states
 +@findex %define lr.keep-unreachable-state
  @cindex unreachable states
  
  If there exists no sequence of transitions from the parser's start state to
@@@ -8020,7 -7687,7 +8020,7 @@@ resolution because they are useless in 
  keeping unreachable states is sometimes useful when trying to understand the
  relationship between the parser and the grammar.
  
 -@deffn {Directive} {%define lr.keep-unreachable-states} @var{value}
 +@deffn {Directive} {%define lr.keep-unreachable-state} @var{value}
  Request that Bison allow unreachable states to remain in the parser tables.
  @var{value} must be a Boolean.  The default is @code{false}.
  @end deffn
@@@ -8177,14 -7844,12 +8177,14 @@@ that allows variable-length arrays.  Th
  
  Do not allow @code{YYINITDEPTH} to be greater than @code{YYMAXDEPTH}.
  
 -@c FIXME: C++ output.
 -Because of semantic differences between C and C++, the deterministic
 -parsers in C produced by Bison cannot grow when compiled
 -by C++ compilers.  In this precise case (compiling a C parser as C++) you are
 -suggested to grow @code{YYINITDEPTH}.  The Bison maintainers hope to fix
 -this deficiency in a future release.
 +You can generate a deterministic parser containing C++ user code from
 +the default (C) skeleton, as well as from the C++ skeleton
 +(@pxref{C++ Parsers}).  However, if you do use the default skeleton
 +and want to allow the parsing stack to grow,
 +be careful not to use semantic types or location types that require
 +non-trivial copy constructors.
 +The C skeleton bypasses these constructors when copying data to
 +new, larger stacks.
  
  @node Error Recovery
  @chapter Error Recovery
@@@ -9152,19 -8817,12 +9152,19 @@@ otherwise it defines @code{YYDEBUG} to 
  @item the directive @samp{%debug}
  @findex %debug
  Add the @code{%debug} directive (@pxref{Decl Summary, ,Bison Declaration
 -Summary}).  This is a Bison extension, especially useful for languages that
 -don't use a preprocessor.  Unless POSIX and Yacc portability matter to you,
 -this is the preferred solution.
 +Summary}).  This Bison extension is maintained for backward
 +compatibility with previous versions of Bison.
 +
 +@item the variable @samp{parse.trace}
 +@findex %define parse.trace
 +Add the @samp{%define parse.trace} directive (@pxref{%define
 +Summary,,parse.trace}), or pass the @option{-Dparse.trace} option
 +(@pxref{Bison Options}).  This is a Bison extension, which is especially
 +useful for languages that don't use a preprocessor.  Unless POSIX and Yacc
 +portability matter to you, this is the preferred solution.
  @end table
  
 -We suggest that you always enable the debug option so that debugging is
 +We suggest that you always enable the trace option so that debugging is
  always possible.
  
  @findex YYFPRINTF
@@@ -9563,10 -9221,6 +9563,10 @@@ unexpected number of conflicts is an er
  conflicts is not reported, so @option{-W} and @option{--warning} then have
  no effect on the conflict report.
  
 +@item deprecated
 +Deprecated constructs whose support will be removed in future versions of
 +Bison.
 +
  @item other
  All warnings not categorized above.  These warnings are enabled by default.
  
@@@ -9579,33 -9233,62 +9579,83 @@@ All the warnings
  @item none
  Turn off all the warnings.
  @item error
 -Treat warnings as errors.
 +See @option{-Werror}, below.
  @end table
  
  A category can be turned off by prefixing its name with @samp{no-}.  For
  instance, @option{-Wno-yacc} will hide the warnings about
  POSIX Yacc incompatibilities.
  
 +@item -Werror[=@var{category}]
 +@itemx -Wno-error[=@var{category}]
 +Enable warnings falling in @var{category}, and treat them as errors.  If no
 +@var{category} is given, it defaults to making all enabled warnings into errors.
 +
 +@var{category} is the same as for @option{--warnings}, with the exception that
 +it may not be prefixed with @samp{no-} (see above).
 +
 +Prefixed with @samp{no}, it deactivates the error treatment for this
 +@var{category}. However, the warning itself won't be disabled, or enabled, by
 +this option.
 +
 +Note that the precedence of the @samp{=} and @samp{,} operators is such that
 +the following commands are @emph{not} equivalent, as the first will not treat
 +S/R conflicts as errors.
 +
 +@example
 +$ bison -Werror=yacc,conflicts-sr input.y
 +$ bison -Werror=yacc,error=conflicts-sr input.y
 +@end example
++
+ @item -f [@var{feature}]
+ @itemx --feature[=@var{feature}]
+ Activate miscellaneous @var{feature}. @var{feature} can be one of:
+ @table @code
+ @item caret
+ @itemx diagnostics-show-caret
+ Show caret errors, in a manner similar to GCC's
+ @option{-fdiagnostics-show-caret}, or Clang's @option{-fcaret-diagnotics}. The
+ location provided with the message is used to quote the corresponding line of
+ the source file, underlining the important part of it with carets (^). Here is
+ an example, using the following file @file{input.y}:
+ @example
+ %type <ival> exp
+ %%
+ exp: exp '+' exp @{ $exp = $1 + $2; @};
+ @end example
+ When invoked with @option{-fcaret}, Bison will report:
+ @example
+ @group
+ input.y:3.20-23: error: ambiguous reference: '$exp'
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+                     ^^^^
+ @end group
+ @group
+ input.y:3.1-3:       refers to: $exp at $$
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+  ^^^
+ @end group
+ @group
+ input.y:3.6-8:       refers to: $exp at $1
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+       ^^^
+ @end group
+ @group
+ input.y:3.14-16:     refers to: $exp at $3
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+               ^^^
+ @end group
+ @group
+ input.y:3.32-33: error: $2 of 'exp' has no declared type
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+                                 ^^
+ @end group
+ @end example
+ @end table
  @end table
  
  @noindent
@@@ -9848,18 -9531,17 +9898,18 @@@ The C++ deterministic parser is selecte
  
  When run, @command{bison} will create several entities in the @samp{yy}
  namespace.
 -@findex %define namespace
 -Use the @samp{%define namespace} directive to change the namespace
 -name, see @ref{%define Summary,,namespace}.  The various classes are
 -generated in the following files:
 +@findex %define api.namespace
 +Use the @samp{%define api.namespace} directive to change the namespace name,
 +see @ref{%define Summary,,api.namespace}.  The various classes are generated
 +in the following files:
  
  @table @file
  @item position.hh
  @itemx location.hh
  The definition of the classes @code{position} and @code{location}, used for
 -location tracking.  These files are not generated if the @code{%define}
 -variable @code{api.location.type} is defined.  @xref{C++ Location Values}.
 +location tracking when enabled.  These files are not generated if the
 +@code{%define} variable @code{api.location.type} is defined.  @xref{C++
 +Location Values}.
  
  @item stack.hh
  An auxiliary class @code{stack} used by the parser.
@@@ -9885,22 -9567,11 +9935,22 @@@ for a complete and accurate documentati
  @c - YYSTYPE
  @c - Printer and destructor
  
 +Bison supports two different means to handle semantic values in C++.  One is
 +alike the C interface, and relies on unions (@pxref{C++ Unions}).  As C++
 +practitioners know, unions are inconvenient in C++, therefore another
 +approach is provided, based on variants (@pxref{C++ Variants}).
 +
 +@menu
 +* C++ Unions::             Semantic values cannot be objects
 +* C++ Variants::           Using objects as semantic values
 +@end menu
 +
 +@node C++ Unions
 +@subsubsection C++ Unions
 +
  The @code{%union} directive works as for C, see @ref{Union Decl, ,The
  Collection of Value Types}.  In particular it produces a genuine
 -@code{union}@footnote{In the future techniques to allow complex types
 -within pseudo-unions (similar to Boost variants) might be implemented to
 -alleviate these issues.}, which have a few specific features in C++.
 +@code{union}, which have a few specific features in C++.
  @itemize @minus
  @item
  The type @code{YYSTYPE} is defined but its use is discouraged: rather
@@@ -9917,98 -9588,6 +9967,98 @@@ reclaimed automatically: using the @cod
  only means to avoid leaks.  @xref{Destructor Decl, , Freeing Discarded
  Symbols}.
  
 +@node C++ Variants
 +@subsubsection C++ Variants
 +
 +Starting with version 2.6, Bison provides a @emph{variant} based
 +implementation of semantic values for C++.  This alleviates all the
 +limitations reported in the previous section, and in particular, object
 +types can be used without pointers.
 +
 +To enable variant-based semantic values, set @code{%define} variable
 +@code{variant} (@pxref{%define Summary,, variant}).  Once this defined,
 +@code{%union} is ignored, and instead of using the name of the fields of the
 +@code{%union} to ``type'' the symbols, use genuine types.
 +
 +For instance, instead of
 +
 +@example
 +%union
 +@{
 +  int ival;
 +  std::string* sval;
 +@}
 +%token <ival> NUMBER;
 +%token <sval> STRING;
 +@end example
 +
 +@noindent
 +write
 +
 +@example
 +%token <int> NUMBER;
 +%token <std::string> STRING;
 +@end example
 +
 +@code{STRING} is no longer a pointer, which should fairly simplify the user
 +actions in the grammar and in the scanner (in particular the memory
 +management).
 +
 +Since C++ features destructors, and since it is customary to specialize
 +@code{operator<<} to support uniform printing of values, variants also
 +typically simplify Bison printers and destructors.
 +
 +Variants are stricter than unions.  When based on unions, you may play any
 +dirty game with @code{yylval}, say storing an @code{int}, reading a
 +@code{char*}, and then storing a @code{double} in it.  This is no longer
 +possible with variants: they must be initialized, then assigned to, and
 +eventually, destroyed.
 +
 +@deftypemethod {semantic_type} {T&} build<T> ()
 +Initialize, but leave empty.  Returns the address where the actual value may
 +be stored.  Requires that the variant was not initialized yet.
 +@end deftypemethod
 +
 +@deftypemethod {semantic_type} {T&} build<T> (const T& @var{t})
 +Initialize, and copy-construct from @var{t}.
 +@end deftypemethod
 +
 +
 +@strong{Warning}: We do not use Boost.Variant, for two reasons.  First, it
 +appeared unacceptable to require Boost on the user's machine (i.e., the
 +machine on which the generated parser will be compiled, not the machine on
 +which @command{bison} was run).  Second, for each possible semantic value,
 +Boost.Variant not only stores the value, but also a tag specifying its
 +type.  But the parser already ``knows'' the type of the semantic value, so
 +that would be duplicating the information.
 +
 +Therefore we developed light-weight variants whose type tag is external (so
 +they are really like @code{unions} for C++ actually).  But our code is much
 +less mature that Boost.Variant.  So there is a number of limitations in
 +(the current implementation of) variants:
 +@itemize
 +@item
 +Alignment must be enforced: values should be aligned in memory according to
 +the most demanding type.  Computing the smallest alignment possible requires
 +meta-programming techniques that are not currently implemented in Bison, and
 +therefore, since, as far as we know, @code{double} is the most demanding
 +type on all platforms, alignments are enforced for @code{double} whatever
 +types are actually used.  This may waste space in some cases.
 +
 +@item
 +Our implementation is not conforming with strict aliasing rules.  Alias
 +analysis is a technique used in optimizing compilers to detect when two
 +pointers are disjoint (they cannot ``meet'').  Our implementation breaks
 +some of the rules that G++ 4.4 uses in its alias analysis, so @emph{strict
 +alias analysis must be disabled}.  Use the option
 +@option{-fno-strict-aliasing} to compile the generated parser.
 +
 +@item
 +There might be portability issues we are not aware of.
 +@end itemize
 +
 +As far as we know, these limitations @emph{can} be alleviated.  All it takes
 +is some time and/or some talented C++ hacker willing to contribute to Bison.
  
  @node C++ Location Values
  @subsection C++ Location Values
@@@ -10031,8 -9610,8 +10081,8 @@@ In this section @code{uint} is an abbre
  genuine code only the latter is used.
  
  @menu
 -* C++ position::                One point in the source file
 -* C++ location::                Two points in the source file
 +* C++ position::         One point in the source file
 +* C++ location::         Two points in the source file
  * User Defined Location Type::  Required interface for locations
  @end menu
  
@@@ -10213,7 -9792,7 +10263,7 @@@ additional argument for its constructor
  
  @defcv {Type} {parser} {semantic_type}
  @defcvx {Type} {parser} {location_type}
 -The types for semantics value and locations.
 +The types for semantic values and locations (if enabled).
  @end defcv
  
  @defcv {Type} {parser} {token}
@@@ -10224,27 -9803,11 +10274,27 @@@ use @code{yy::parser::token::FOO}.  Th
  (@pxref{Calc++ Scanner}).
  @end defcv
  
 +@defcv {Type} {parser} {syntax_error}
 +This class derives from @code{std::runtime_error}.  Throw instances of it
 +from the scanner or from the user actions to raise parse errors.  This is
 +equivalent with first
 +invoking @code{error} to report the location and message of the syntax
 +error, and then to invoke @code{YYERROR} to enter the error-recovery mode.
 +But contrary to @code{YYERROR} which can only be invoked from user actions
 +(i.e., written in the action itself), the exception can be thrown from
 +function invoked from the user action.
 +@end defcv
 +
  @deftypemethod {parser} {} parser (@var{type1} @var{arg1}, ...)
  Build a new parser object.  There are no arguments by default, unless
  @samp{%parse-param @{@var{type1} @var{arg1}@}} was used.
  @end deftypemethod
  
 +@deftypemethod {syntax_error} {} syntax_error (const location_type& @var{l}, const std::string& @var{m})
 +@deftypemethodx {syntax_error} {} syntax_error (const std::string& @var{m})
 +Instantiate a syntax-error exception.
 +@end deftypemethod
 +
  @deftypemethod {parser} {int} parse ()
  Run the syntactic analysis, and return 0 on success, 1 otherwise.
  
@@@ -10267,11 -9830,9 +10317,11 @@@ or nonzero, full tracing
  @end deftypemethod
  
  @deftypemethod {parser} {void} error (const location_type& @var{l}, const std::string& @var{m})
 +@deftypemethodx {parser} {void} error (const std::string& @var{m})
  The definition for this member function must be supplied by the user:
  the parser uses it to report a parser error occurring at @var{l},
 -described by @var{m}.
 +described by @var{m}.  If location tracking is not enabled, the second
 +signature is used.
  @end deftypemethod
  
  
  
  The parser invokes the scanner by calling @code{yylex}.  Contrary to C
  parsers, C++ parsers are always pure: there is no point in using the
 -@code{%define api.pure full} directive.  Therefore the interface is as follows.
 +@samp{%define api.pure} directive.  The actual interface with @code{yylex}
 +depends whether you use unions, or variants.
 +
 +@menu
 +* Split Symbols::         Passing symbols as two/three components
 +* Complete Symbols::      Making symbols a whole
 +@end menu
 +
 +@node Split Symbols
 +@subsubsection Split Symbols
 +
 +The interface is as follows.
  
  @deftypemethod {parser} {int} yylex (semantic_type* @var{yylval}, location_type* @var{yylloc}, @var{type1} @var{arg1}, ...)
 -Return the next token.  Its type is the return value, its semantic
 -value and location being @var{yylval} and @var{yylloc}.  Invocations of
 +@deftypemethodx {parser} {int} yylex (semantic_type* @var{yylval}, @var{type1} @var{arg1}, ...)
 +Return the next token.  Its type is the return value, its semantic value and
 +location (if enabled) being @var{yylval} and @var{yylloc}.  Invocations of
  @samp{%lex-param @{@var{type1} @var{arg1}@}} yield additional arguments.
  @end deftypemethod
  
 +Note that when using variants, the interface for @code{yylex} is the same,
 +but @code{yylval} is handled differently.
 +
 +Regular union-based code in Lex scanner typically look like:
 +
 +@example
 +[0-9]+   @{
 +           yylval.ival = text_to_int (yytext);
 +           return yy::parser::INTEGER;
 +         @}
 +[a-z]+   @{
 +           yylval.sval = new std::string (yytext);
 +           return yy::parser::IDENTIFIER;
 +         @}
 +@end example
 +
 +Using variants, @code{yylval} is already constructed, but it is not
 +initialized.  So the code would look like:
 +
 +@example
 +[0-9]+   @{
 +           yylval.build<int>() = text_to_int (yytext);
 +           return yy::parser::INTEGER;
 +         @}
 +[a-z]+   @{
 +           yylval.build<std::string> = yytext;
 +           return yy::parser::IDENTIFIER;
 +         @}
 +@end example
 +
 +@noindent
 +or
 +
 +@example
 +[0-9]+   @{
 +           yylval.build(text_to_int (yytext));
 +           return yy::parser::INTEGER;
 +         @}
 +[a-z]+   @{
 +           yylval.build(yytext);
 +           return yy::parser::IDENTIFIER;
 +         @}
 +@end example
 +
 +
 +@node Complete Symbols
 +@subsubsection Complete Symbols
 +
 +If you specified both @code{%define variant} and
 +@code{%define api.token.constructor},
 +the @code{parser} class also defines the class @code{parser::symbol_type}
 +which defines a @emph{complete} symbol, aggregating its type (i.e., the
 +traditional value returned by @code{yylex}), its semantic value (i.e., the
 +value passed in @code{yylval}, and possibly its location (@code{yylloc}).
 +
 +@deftypemethod {symbol_type} {} symbol_type (token_type @var{type},  const semantic_type& @var{value}, const location_type& @var{location})
 +Build a complete terminal symbol which token type is @var{type}, and which
 +semantic value is @var{value}.  If location tracking is enabled, also pass
 +the @var{location}.
 +@end deftypemethod
 +
 +This interface is low-level and should not be used for two reasons.  First,
 +it is inconvenient, as you still have to build the semantic value, which is
 +a variant, and second, because consistency is not enforced: as with unions,
 +it is still possible to give an integer as semantic value for a string.
 +
 +So for each token type, Bison generates named constructors as follows.
 +
 +@deftypemethod {symbol_type} {} make_@var{token} (const @var{value_type}& @var{value}, const location_type& @var{location})
 +@deftypemethodx {symbol_type} {} make_@var{token} (const location_type& @var{location})
 +Build a complete terminal symbol for the token type @var{token} (not
 +including the @code{api.token.prefix}) whose possible semantic value is
 +@var{value} of adequate @var{value_type}.  If location tracking is enabled,
 +also pass the @var{location}.
 +@end deftypemethod
 +
 +For instance, given the following declarations:
 +
 +@example
 +%define api.token.prefix "TOK_"
 +%token <std::string> IDENTIFIER;
 +%token <int> INTEGER;
 +%token COLON;
 +@end example
 +
 +@noindent
 +Bison generates the following functions:
 +
 +@example
 +symbol_type make_IDENTIFIER(const std::string& v,
 +                            const location_type& l);
 +symbol_type make_INTEGER(const int& v,
 +                         const location_type& loc);
 +symbol_type make_COLON(const location_type& loc);
 +@end example
 +
 +@noindent
 +which should be used in a Lex-scanner as follows.
 +
 +@example
 +[0-9]+   return yy::parser::make_INTEGER(text_to_int (yytext), loc);
 +[a-z]+   return yy::parser::make_IDENTIFIER(yytext, loc);
 +":"      return yy::parser::make_COLON(loc);
 +@end example
 +
 +Tokens that do not have an identifier are not accessible: you cannot simply
 +use characters such as @code{':'}, they must be declared with @code{%token}.
  
  @node A Complete C++ Example
  @subsection A Complete C++ Example
  
  This section demonstrates the use of a C++ parser with a simple but
  complete example.  This example should be available on your system,
 -ready to compile, in the directory @dfn{../bison/examples/calc++}.  It
 +ready to compile, in the directory @dfn{.../bison/examples/calc++}.  It
  focuses on the use of Bison, therefore the design of the various C++
  classes is very naive: no accessors, no encapsulation of members etc.
  We will use a Lex scanner, and more precisely, a Flex scanner, to
 -demonstrate the various interaction.  A hand written scanner is
 +demonstrate the various interactions.  A hand-written scanner is
  actually easier to interface with.
  
  @menu
@@@ -10484,8 -9926,11 +10534,8 @@@ factor both as follows
  @comment file: calc++-driver.hh
  @example
  // Tell Flex the lexer's prototype ...
 -# define YY_DECL                                        \
 -  yy::calcxx_parser::token_type                         \
 -  yylex (yy::calcxx_parser::semantic_type* yylval,      \
 -         yy::calcxx_parser::location_type* yylloc,      \
 -         calcxx_driver& driver)
 +# define YY_DECL \
 +  yy::calcxx_parser::symbol_type yylex (calcxx_driver& driver)
  // ... and declare it for the parser's sake.
  YY_DECL;
  @end example
@@@ -10509,8 -9954,8 +10559,8 @@@ public
  @end example
  
  @noindent
 -To encapsulate the coordination with the Flex scanner, it is useful to
 -have two members function to open and close the scanning phase.
 +To encapsulate the coordination with the Flex scanner, it is useful to have
 +member functions to open and close the scanning phase.
  
  @comment file: calc++-driver.hh
  @example
@@@ -10525,13 -9970,9 +10575,13 @@@ Similarly for the parser itself
  
  @comment file: calc++-driver.hh
  @example
 -  // Run the parser.  Return 0 on success.
 +  // Run the parser on file F.
 +  // Return 0 on success.
    int parse (const std::string& f);
 +  // The name of the file being parsed.
 +  // Used later to pass the file name to the location tracker.
    std::string file;
 +  // Whether parser traces should be generated.
    bool trace_parsing;
  @end example
  
@@@ -10613,35 -10054,19 +10663,35 @@@ the grammar for
  %define parser_class_name "calcxx_parser"
  @end example
  
 +@noindent
 +@findex %define api.token.constructor
 +@findex %define variant
 +This example will use genuine C++ objects as semantic values, therefore, we
 +require the variant-based interface.  To make sure we properly use it, we
 +enable assertions.  To fully benefit from type-safety and more natural
 +definition of ``symbol'', we enable @code{api.token.constructor}.
 +
 +@comment file: calc++-parser.yy
 +@example
 +%define api.token.constructor
 +%define parse.assert
 +%define variant
 +@end example
 +
  @noindent
  @findex %code requires
 -Then come the declarations/inclusions needed to define the
 -@code{%union}.  Because the parser uses the parsing driver and
 -reciprocally, both cannot include the header of the other.  Because the
 +Then come the declarations/inclusions needed by the semantic values.
 +Because the parser uses the parsing driver and reciprocally, both would like
 +to include the header of the other, which is, of course, insane.  This
 +mutual dependency will be broken using forward declarations.  Because the
  driver's header needs detailed knowledge about the parser class (in
 -particular its inner types), it is the parser's header which will simply
 -use a forward declaration of the driver.
 -@xref{%code Summary}.
 +particular its inner types), it is the parser's header which will use a
 +forward declaration of the driver.  @xref{%code Summary}.
  
  @comment file: calc++-parser.yy
  @example
 -%code requires @{
 +%code requires
 +@{
  # include <string>
  class calcxx_driver;
  @}
@@@ -10655,14 -10080,15 +10705,14 @@@ global variables
  @comment file: calc++-parser.yy
  @example
  // The parsing context.
 -%parse-param @{ calcxx_driver& driver @}
 -%lex-param   @{ calcxx_driver& driver @}
 +%param @{ calcxx_driver& driver @}
  @end example
  
  @noindent
 -Then we request the location tracking feature, and initialize the
 +Then we request location tracking, and initialize the
  first location's file name.  Afterward new locations are computed
  relatively to the previous locations: the file name will be
 -automatically propagated.
 +propagated.
  
  @comment file: calc++-parser.yy
  @example
  @end example
  
  @noindent
 -Use the two following directives to enable parser tracing and verbose error
 +Use the following two directives to enable parser tracing and verbose error
  messages.  However, verbose error messages can contain incorrect information
  (@pxref{LAC}).
  
  @comment file: calc++-parser.yy
  @example
 -%debug
 -%error-verbose
 -@end example
 -
 -@noindent
 -Semantic values cannot use ``real'' objects, but only pointers to
 -them.
 -
 -@comment file: calc++-parser.yy
 -@example
 -// Symbols.
 -%union
 -@{
 -  int          ival;
 -  std::string *sval;
 -@};
 +%define parse.trace
 +%define parse.error verbose
  @end example
  
  @noindent
@@@ -10692,8 -10132,7 +10742,8 @@@ The code between @samp{%code @{} and @s
  
  @comment file: calc++-parser.yy
  @example
 -%code @{
 +%code
 +@{
  # include "calc++-driver.hh"
  @}
  @end example
  
  @noindent
  The token numbered as 0 corresponds to end of file; the following line
 -allows for nicer error messages referring to ``end of file'' instead
 -of ``$end''.  Similarly user friendly named are provided for each
 -symbol.  Note that the tokens names are prefixed by @code{TOKEN_} to
 -avoid name clashes.
 +allows for nicer error messages referring to ``end of file'' instead of
 +``$end''.  Similarly user friendly names are provided for each symbol.  To
 +avoid name clashes in the generated files (@pxref{Calc++ Scanner}), prefix
 +tokens with @code{TOK_} (@pxref{%define Summary,,api.token.prefix}).
  
  @comment file: calc++-parser.yy
  @example
 -%token        END      0 "end of file"
 -%token        ASSIGN     ":="
 -%token <sval> IDENTIFIER "identifier"
 -%token <ival> NUMBER     "number"
 -%type  <ival> exp
 +%define api.token.prefix "TOK_"
 +%token
 +  END  0  "end of file"
 +  ASSIGN  ":="
 +  MINUS   "-"
 +  PLUS    "+"
 +  STAR    "*"
 +  SLASH   "/"
 +  LPAREN  "("
 +  RPAREN  ")"
 +;
  @end example
  
  @noindent
 -To enable memory deallocation during error recovery, use
 -@code{%destructor}.
 +Since we use variant-based semantic values, @code{%union} is not used, and
 +both @code{%type} and @code{%token} expect genuine types, as opposed to type
 +tags.
  
 -@c FIXME: Document %printer, and mention that it takes a braced-code operand.
  @comment file: calc++-parser.yy
  @example
 -%printer    @{ yyoutput << *$$; @} "identifier"
 -%destructor @{ delete $$; @} "identifier"
 +%token <std::string> IDENTIFIER "identifier"
 +%token <int> NUMBER "number"
 +%type  <int> exp
 +@end example
  
 -%printer    @{ yyoutput << $$; @} <ival>
 +@noindent
 +No @code{%destructor} is needed to enable memory deallocation during error
 +recovery; the memory, for strings for instance, will be reclaimed by the
 +regular destructors.  All the values are printed using their
 +@code{operator<<} (@pxref{Printer Decl, , Printing Semantic Values}).
 +
 +@comment file: calc++-parser.yy
 +@example
 +%printer @{ yyoutput << $$; @} <*>;
  @end example
  
  @noindent
 -The grammar itself is straightforward.
 +The grammar itself is straightforward (@pxref{Location Tracking Calc, ,
 +Location Tracking Calculator: @code{ltcalc}}).
  
  @comment file: calc++-parser.yy
  @example
@@@ -10759,18 -10181,17 +10809,18 @@@ assignments
  | assignments assignment @{@};
  
  assignment:
 -     "identifier" ":=" exp
 -       @{ driver.variables[*$1] = $3; delete $1; @};
 -
 -%left '+' '-';
 -%left '*' '/';
 -exp: exp '+' exp   @{ $$ = $1 + $3; @}
 -   | exp '-' exp   @{ $$ = $1 - $3; @}
 -   | exp '*' exp   @{ $$ = $1 * $3; @}
 -   | exp '/' exp   @{ $$ = $1 / $3; @}
 -   | "identifier"  @{ $$ = driver.variables[*$1]; delete $1; @}
 -   | "number"      @{ $$ = $1; @};
 +  "identifier" ":=" exp @{ driver.variables[$1] = $3; @};
 +
 +%left "+" "-";
 +%left "*" "/";
 +exp:
 +  exp "+" exp   @{ $$ = $1 + $3; @}
 +| exp "-" exp   @{ $$ = $1 - $3; @}
 +| exp "*" exp   @{ $$ = $1 * $3; @}
 +| exp "/" exp   @{ $$ = $1 / $3; @}
 +| "(" exp ")"   @{ std::swap ($$, $2); @}
 +| "identifier"  @{ $$ = driver.variables[$1]; @}
 +| "number"      @{ std::swap ($$, $1); @};
  %%
  @end example
  
@@@ -10781,7 -10202,7 +10831,7 @@@ driver
  @comment file: calc++-parser.yy
  @example
  void
 -yy::calcxx_parser::error (const yy::calcxx_parser::location_type& l,
 +yy::calcxx_parser::error (const location_type& l,
                            const std::string& m)
  @{
    driver.error (l, m);
@@@ -10797,22 -10218,24 +10847,22 @@@ parser's to get the set of defined toke
  @comment file: calc++-scanner.ll
  @example
  %@{ /* -*- C++ -*- */
 -# include <cstdlib>
  # include <cerrno>
  # include <climits>
 +# include <cstdlib>
  # include <string>
  # include "calc++-driver.hh"
  # include "calc++-parser.hh"
  
 -/* Work around an incompatibility in flex (at least versions
 -   2.5.31 through 2.5.33): it generates code that does
 -   not conform to C89.  See Debian bug 333231
 -   <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
 +// Work around an incompatibility in flex (at least versions
 +// 2.5.31 through 2.5.33): it generates code that does
 +// not conform to C89.  See Debian bug 333231
 +// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
  # undef yywrap
  # define yywrap() 1
  
 -/* By default yylex returns int, we use token_type.
 -   Unfortunately yyterminate by default returns 0, which is
 -   not of token_type.  */
 -#define yyterminate() return token::END
 +// The location of the current token.
 +static yy::location loc;
  %@}
  @end example
  
  Because there is no @code{#include}-like feature we don't need
  @code{yywrap}, we don't need @code{unput} either, and we parse an
  actual file, this is not an interactive session with the user.
 -Finally we enable the scanner tracing features.
 +Finally, we enable scanner tracing.
  
  @comment file: calc++-scanner.ll
  @example
@@@ -10840,8 -10263,8 +10890,8 @@@ blank [ \t
  @noindent
  The following paragraph suffices to track locations accurately.  Each
  time @code{yylex} is invoked, the begin position is moved onto the end
 -position.  Then when a pattern is matched, the end position is
 -advanced of its width.  In case it matched ends of lines, the end
 +position.  Then when a pattern is matched, its width is added to the end
 +column.  When matching ends of lines, the end
  cursor is adjusted, and each time blanks are matched, the begin cursor
  is moved onto the end cursor to effectively ignore the blanks
  preceding tokens.  Comments would be treated equally.
  @example
  @group
  %@{
 -# define YY_USER_ACTION  yylloc->columns (yyleng);
 +  // Code run each time a pattern is matched.
 +  # define YY_USER_ACTION  loc.columns (yyleng);
  %@}
  @end group
  %%
 +@group
  %@{
 -  yylloc->step ();
 +  // Code run each time yylex is called.
 +  loc.step ();
  %@}
 -@{blank@}+   yylloc->step ();
 -[\n]+      yylloc->lines (yyleng); yylloc->step ();
 +@end group
 +@{blank@}+   loc.step ();
 +[\n]+      loc.lines (yyleng); loc.step ();
  @end example
  
  @noindent
 -The rules are simple, just note the use of the driver to report errors.
 -It is convenient to use a typedef to shorten
 -@code{yy::calcxx_parser::token::identifier} into
 -@code{token::identifier} for instance.
 +The rules are simple.  The driver is used to report errors.
  
  @comment file: calc++-scanner.ll
  @example
 -%@{
 -  typedef yy::calcxx_parser::token token;
 -%@}
 -           /* Convert ints to the actual type of tokens.  */
 -[-+*/]     return yy::calcxx_parser::token_type (yytext[0]);
 -":="       return token::ASSIGN;
 +"-"      return yy::calcxx_parser::make_MINUS(loc);
 +"+"      return yy::calcxx_parser::make_PLUS(loc);
 +"*"      return yy::calcxx_parser::make_STAR(loc);
 +"/"      return yy::calcxx_parser::make_SLASH(loc);
 +"("      return yy::calcxx_parser::make_LPAREN(loc);
 +")"      return yy::calcxx_parser::make_RPAREN(loc);
 +":="     return yy::calcxx_parser::make_ASSIGN(loc);
 +
 +@group
  @{int@}      @{
    errno = 0;
    long n = strtol (yytext, NULL, 10);
    if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
 -    driver.error (*yylloc, "integer is out of range");
 -  yylval->ival = n;
 -  return token::NUMBER;
 +    driver.error (loc, "integer is out of range");
 +  return yy::calcxx_parser::make_NUMBER(n, loc);
  @}
 -@{id@}       yylval->sval = new std::string (yytext); return token::IDENTIFIER;
 -.          driver.error (*yylloc, "invalid character");
 +@end group
 +@{id@}       return yy::calcxx_parser::make_IDENTIFIER(yytext, loc);
 +.          driver.error (loc, "invalid character");
 +<<EOF>>    return yy::calcxx_parser::make_END(loc);
  %%
  @end example
  
  @noindent
 -Finally, because the scanner related driver's member function depend
 +Finally, because the scanner-related driver's member-functions depend
  on the scanner's data, it is simpler to implement them in this file.
  
  @comment file: calc++-scanner.ll
@@@ -10937,7 -10355,6 +10987,7 @@@ The top level file, @file{calc++.cc}, p
  int
  main (int argc, char *argv[])
  @{
 +  int res = 0;
    calcxx_driver driver;
    for (int i = 1; i < argc; ++i)
      if (argv[i] == std::string ("-p"))
        driver.trace_scanning = true;
      else if (!driver.parse (argv[i]))
        std::cout << driver.result << std::endl;
 +    else
 +      res = 1;
 +  return res;
  @}
  @end group
  @end example
@@@ -10993,7 -10407,8 +11043,7 @@@ You can create documentation for genera
  Contrary to C parsers, Java parsers do not use global variables; the
  state of the parser is always local to an instance of the parser class.
  Therefore, all Java parsers are ``pure'', and the @code{%pure-parser}
 -and @code{%define api.pure full} directives does not do anything when used in
 -Java.
 +and @code{%define api.pure} directives do nothing when used in Java.
  
  Push parsers are currently unsupported in Java and @code{%define
  api.push-pull} have no effect.
@@@ -11005,23 -10420,15 +11055,23 @@@ No header file can be generated for Jav
  @code{%defines} directive or the @option{-d}/@option{--defines} options.
  
  @c FIXME: Possible code change.
 -Currently, support for debugging and verbose errors are always compiled
 -in.  Thus the @code{%debug} and @code{%token-table} directives and the
 +Currently, support for tracing is always compiled
 +in.  Thus the @samp{%define parse.trace} and @samp{%token-table}
 +directives and the
  @option{-t}/@option{--debug} and @option{-k}/@option{--token-table}
  options have no effect.  This may change in the future to eliminate
 -unused code in the generated parser, so use @code{%debug} and
 -@code{%verbose-error} explicitly if needed.  Also, in the future the
 +unused code in the generated parser, so use @samp{%define parse.trace}
 +explicitly
 +if needed.  Also, in the future the
  @code{%token-table} directive might enable a public interface to
  access the token names and codes.
  
 +Getting a ``code too large'' error from the Java compiler means the code
 +hit the 64KB bytecode per method limitation of the Java class file.
 +Try reducing the amount of code in actions and static initializers;
 +otherwise, report a bug so that the parser skeleton will be improved.
 +
 +
  @node Java Semantic Values
  @subsection Java Semantic Values
  @c - No %union, specify type in %type/%token.
@@@ -11040,7 -10447,7 +11090,7 @@@ semantic values' types (class names) sh
  By default, the semantic stack is declared to have @code{Object} members,
  which means that the class types you specify can be of any class.
  To improve the type safety of the parser, you can declare the common
 -superclass of all the semantic values using the @code{%define stype}
 +superclass of all the semantic values using the @samp{%define stype}
  directive.  For example, after the following declaration:
  
  @example
@@@ -11118,22 -10525,20 +11168,22 @@@ properly, the position class should ove
  The name of the generated parser class defaults to @code{YYParser}.  The
  @code{YY} prefix may be changed using the @code{%name-prefix} directive
  or the @option{-p}/@option{--name-prefix} option.  Alternatively, use
 -@code{%define parser_class_name "@var{name}"} to give a custom name to
 +@samp{%define parser_class_name "@var{name}"} to give a custom name to
  the class.  The interface of this class is detailed below.
  
  By default, the parser class has package visibility.  A declaration
 -@code{%define public} will change to public visibility.  Remember that,
 +@samp{%define public} will change to public visibility.  Remember that,
  according to the Java language specification, the name of the @file{.java}
  file should match the name of the class in this case.  Similarly, you can
  use @code{abstract}, @code{final} and @code{strictfp} with the
  @code{%define} declaration to add other modifiers to the parser class.
 +A single @samp{%define annotations "@var{annotations}"} directive can
 +be used to add any number of annotations to the parser class.
  
  The Java package name of the parser class can be specified using the
 -@code{%define package} directive.  The superclass and the implemented
 +@samp{%define package} directive.  The superclass and the implemented
  interfaces of the parser class can be specified with the @code{%define
 -extends} and @code{%define implements} directives.
 +extends} and @samp{%define implements} directives.
  
  The parser class defines an inner class, @code{Location}, that is used
  for location tracking (see @ref{Java Location Values}), and a inner
@@@ -11142,33 -10547,30 +11192,33 @@@ these inner class/interface, and the me
  below, all the other members and fields are preceded with a @code{yy} or
  @code{YY} prefix to avoid clashes with user code.
  
 -@c FIXME: The following constants and variables are still undocumented:
 -@c @code{bisonVersion}, @code{bisonSkeleton} and @code{errorVerbose}.
 -
  The parser class can be extended using the @code{%parse-param}
  directive. Each occurrence of the directive will add a @code{protected
  final} field to the parser class, and an argument to its constructor,
  which initialize them automatically.
  
 -Token names defined by @code{%token} and the predefined @code{EOF} token
 -name are added as constant fields to the parser class.
 -
  @deftypeop {Constructor} {YYParser} {} YYParser (@var{lex_param}, @dots{}, @var{parse_param}, @dots{})
  Build a new parser object with embedded @code{%code lexer}.  There are
 -no parameters, unless @code{%parse-param}s and/or @code{%lex-param}s are
 -used.
 +no parameters, unless @code{%param}s and/or @code{%parse-param}s and/or
 +@code{%lex-param}s are used.
 +
 +Use @code{%code init} for code added to the start of the constructor
 +body. This is especially useful to initialize superclasses. Use
 +@samp{%define init_throws} to specify any uncaught exceptions.
  @end deftypeop
  
  @deftypeop {Constructor} {YYParser} {} YYParser (Lexer @var{lexer}, @var{parse_param}, @dots{})
  Build a new parser object using the specified scanner.  There are no
 -additional parameters unless @code{%parse-param}s are used.
 +additional parameters unless @code{%param}s and/or @code{%parse-param}s are
 +used.
  
  If the scanner is defined by @code{%code lexer}, this constructor is
  declared @code{protected} and is called automatically with a scanner
 -created with the correct @code{%lex-param}s.
 +created with the correct @code{%param}s and/or @code{%lex-param}s.
 +
 +Use @code{%code init} for code added to the start of the constructor
 +body. This is especially useful to initialize superclasses. Use
 +@samp{%define init_throws} to specify any uncaught exceptions.
  @end deftypeop
  
  @deftypemethod {YYParser} {boolean} parse ()
@@@ -11176,21 -10578,6 +11226,21 @@@ Run the syntactic analysis, and return 
  @code{false} otherwise.
  @end deftypemethod
  
 +@deftypemethod {YYParser} {boolean} getErrorVerbose ()
 +@deftypemethodx {YYParser} {void} setErrorVerbose (boolean @var{verbose})
 +Get or set the option to produce verbose error messages.  These are only
 +available with @samp{%define parse.error verbose}, which also turns on
 +verbose error messages.
 +@end deftypemethod
 +
 +@deftypemethod {YYParser} {void} yyerror (String @var{msg})
 +@deftypemethodx {YYParser} {void} yyerror (Position @var{pos}, String @var{msg})
 +@deftypemethodx {YYParser} {void} yyerror (Location @var{loc}, String @var{msg})
 +Print an error message using the @code{yyerror} method of the scanner
 +instance in use. The @code{Location} and @code{Position} parameters are
 +available only if location tracking is active.
 +@end deftypemethod
 +
  @deftypemethod {YYParser} {boolean} recovering ()
  During the syntactic analysis, return @code{true} if recovering
  from a syntax error.
@@@ -11209,11 -10596,6 +11259,11 @@@ Get or set the tracing level.  Currentl
  or nonzero, full tracing.
  @end deftypemethod
  
 +@deftypecv {Constant} {YYParser} {String} {bisonVersion}
 +@deftypecvx {Constant} {YYParser} {String} {bisonSkeleton}
 +Identify the Bison version and skeleton used to generate this parser.
 +@end deftypecv
 +
  
  @node Java Scanner Interface
  @subsection Java Scanner Interface
  There are two possible ways to interface a Bison-generated Java parser
  with a scanner: the scanner may be defined by @code{%code lexer}, or
  defined elsewhere.  In either case, the scanner has to implement the
 -@code{Lexer} inner interface of the parser class.
 +@code{Lexer} inner interface of the parser class.  This interface also
 +contain constants for all user-defined token names and the predefined
 +@code{EOF} token.
  
  In the first case, the body of the scanner class is placed in
  @code{%code lexer} blocks.  If you want to pass parameters from the
@@@ -11253,7 -10633,7 +11303,7 @@@ Return the next token.  Its type is th
  value and location are saved and returned by the their methods in the
  interface.
  
 -Use @code{%define lex_throws} to specify any uncaught exceptions.
 +Use @samp{%define lex_throws} to specify any uncaught exceptions.
  Default is @code{java.io.IOException}.
  @end deftypemethod
  
@@@ -11270,7 -10650,7 +11320,7 @@@ The return type can be changed using @c
  @deftypemethod {Lexer} {Object} getLVal ()
  Return the semantic value of the last token that yylex returned.
  
 -The return type can be changed using @code{%define stype
 +The return type can be changed using @samp{%define stype
  "@var{class-name}".}
  @end deftypemethod
  
  The following special constructs can be uses in Java actions.
  Other analogous C action features are currently unavailable for Java.
  
 -Use @code{%define throws} to specify any uncaught exceptions from parser
 +Use @samp{%define throws} to specify any uncaught exceptions from parser
  actions, and initial actions specified by @code{%initial-action}.
  
  @defvar $@var{n}
@@@ -11298,7 -10678,7 +11348,7 @@@ Like @code{$@var{n}} but specifies a al
  @defvar $$
  The semantic value for the grouping made by the current rule.  As a
  value, this is in the base type (@code{Object} or as specified by
 -@code{%define stype}) as in not cast to the declared subtype because
 +@samp{%define stype}) as in not cast to the declared subtype because
  casts are not allowed on the left-hand side of Java assignments.
  Use an explicit Java cast if the correct subtype is needed.
  @xref{Java Semantic Values}.
@@@ -11345,12 -10725,11 +11395,12 @@@ operation
  @xref{Error Recovery}.
  @end deftypefn
  
 -@deftypefn  {Function} {protected void} yyerror (String msg)
 -@deftypefnx {Function} {protected void} yyerror (Position pos, String msg)
 -@deftypefnx {Function} {protected void} yyerror (Location loc, String msg)
 +@deftypefn  {Function} {void} yyerror (String @var{msg})
 +@deftypefnx {Function} {void} yyerror (Position @var{loc}, String @var{msg})
 +@deftypefnx {Function} {void} yyerror (Location @var{loc}, String @var{msg})
  Print an error message using the @code{yyerror} method of the scanner
 -instance in use.
 +instance in use. The @code{Location} and @code{Position} parameters are
 +available only if location tracking is active.
  @end deftypefn
  
  
@@@ -11394,7 -10773,7 +11444,7 @@@ The prologue declarations have a differ
  @item @code{%code imports}
  blocks are placed at the beginning of the Java source code.  They may
  include copyright notices.  For a @code{package} declarations, it is
 -suggested to use @code{%define package} instead.
 +suggested to use @samp{%define package} instead.
  
  @item unqualified @code{%code}
  blocks are placed inside the parser class.
@@@ -11435,7 -10814,7 +11485,7 @@@ constructor that @emph{creates} a lexer
  
  @deffn {Directive} %name-prefix "@var{prefix}"
  The prefix of the parser class name @code{@var{prefix}Parser} if
 -@code{%define parser_class_name} is not used.  Default is @code{YY}.
 +@samp{%define parser_class_name} is not used.  Default is @code{YY}.
  @xref{Java Bison Interface}.
  @end deffn
  
@@@ -11466,11 -10845,6 +11516,11 @@@ Code inserted just after the @code{pack
  @xref{Java Differences}.
  @end deffn
  
 +@deffn {Directive} {%code init} @{ @var{code} @dots{} @}
 +Code inserted at the beginning of the parser constructor body.
 +@xref{Java Parser Interface}.
 +@end deffn
 +
  @deffn {Directive} {%code lexer} @{ @var{code} @dots{} @}
  Code added to the body of a inner lexer class within the parser class.
  @xref{Java Scanner Interface}.
@@@ -11483,7 -10857,7 +11533,7 @@@ Code (after the second @code{%%}) appen
  @end deffn
  
  @deffn {Directive} %@{ @var{code} @dots{} %@}
 -Not supported.  Use @code{%code import} instead.
 +Not supported.  Use @code{%code imports} instead.
  @xref{Java Differences}.
  @end deffn
  
@@@ -11492,11 -10866,6 +11542,11 @@@ Whether the parser class is declared @c
  @xref{Java Bison Interface}.
  @end deffn
  
 +@deffn {Directive} {%define annotations} "@var{annotations}"
 +The Java annotations for the parser class.  Default is none.
 +@xref{Java Bison Interface}.
 +@end deffn
 +
  @deffn {Directive} {%define extends} "@var{superclass}"
  The superclass of the parser class.  Default is none.
  @xref{Java Bison Interface}.
@@@ -11513,12 -10882,6 +11563,12 @@@ Default is none
  @xref{Java Bison Interface}.
  @end deffn
  
 +@deffn {Directive} {%define init_throws} "@var{exceptions}"
 +The exceptions thrown by @code{%code init} from the parser class
 +constructor.  Default is none.
 +@xref{Java Parser Interface}.
 +@end deffn
 +
  @deffn {Directive} {%define lex_throws} "@var{exceptions}"
  The exceptions thrown by the @code{yylex} method of the lexer, a
  comma-separated list.  Default is @code{java.io.IOException}.
@@@ -12038,19 -11401,6 +12088,19 @@@ the grammar file.  @xref{Grammar Outlin
  Grammar}.
  @end deffn
  
 +@deffn {Directive} %?@{@var{expression}@}
 +Predicate actions.  This is a type of action clause that may appear in
 +rules. The expression is evaluated, and if false, causes a syntax error.  In
 +GLR parsers during nondeterministic operation,
 +this silently causes an alternative parse to die.  During deterministic
 +operation, it is the same as the effect of YYERROR.
 +@xref{Semantic Predicates}.
 +
 +This feature is experimental.
 +More user feedback will help to determine whether it should become a permanent
 +feature.
 +@end deffn
 +
  @deffn {Construct} /*@dots{}*/
  Comment delimiters, as in C.
  @end deffn
@@@ -12160,8 -11510,8 +12210,8 @@@ token is reset to the token that origin
  @end deffn
  
  @deffn {Directive} %error-verbose
 -Bison declaration to request verbose, specific error message strings
 -when @code{yyerror} is called.  @xref{Error Reporting}.
 +An obsolete directive standing for @samp{%define parse.error verbose}
 +(@pxref{Error Reporting, ,The Error Reporting Function @code{yyerror}}).
  @end deffn
  
  @deffn {Directive} %file-prefix "@var{prefix}"
@@@ -12184,12 -11534,12 +12234,12 @@@ Specify the programming language for th
  @end deffn
  
  @deffn {Directive} %left
 -Bison declaration to assign left associativity to token(s).
 +Bison declaration to assign precedence and left associativity to token(s).
  @xref{Precedence Decl, ,Operator Precedence}.
  @end deffn
  
 -@deffn {Directive} %lex-param @{@var{argument-declaration}@}
 -Bison declaration to specifying an additional parameter that
 +@deffn {Directive} %lex-param @{@var{argument-declaration}@} @dots{}
 +Bison declaration to specifying additional arguments that
  @code{yylex} should accept.  @xref{Pure Calling,, Calling Conventions
  for Pure Parsers}.
  @end deffn
@@@ -12234,7 -11584,7 +12284,7 @@@ parser implementation file.  @xref{Dec
  @end deffn
  
  @deffn {Directive} %nonassoc
 -Bison declaration to assign nonassociativity to token(s).
 +Bison declaration to assign precedence and nonassociativity to token(s).
  @xref{Precedence Decl, ,Operator Precedence}.
  @end deffn
  
@@@ -12243,15 -11593,10 +12293,15 @@@ Bison declaration to set the name of th
  @xref{Decl Summary}.
  @end deffn
  
 -@deffn {Directive} %parse-param @{@var{argument-declaration}@}
 -Bison declaration to specifying an additional parameter that
 -@code{yyparse} should accept.  @xref{Parser Function,, The Parser
 -Function @code{yyparse}}.
 +@deffn {Directive} %param @{@var{argument-declaration}@} @dots{}
 +Bison declaration to specify additional arguments that both
 +@code{yylex} and @code{yyparse} should accept.  @xref{Parser Function,, The
 +Parser Function @code{yyparse}}.
 +@end deffn
 +
 +@deffn {Directive} %parse-param @{@var{argument-declaration}@} @dots{}
 +Bison declaration to specify additional arguments that @code{yyparse}
 +should accept.  @xref{Parser Function,, The Parser Function @code{yyparse}}.
  @end deffn
  
  @deffn {Directive} %prec
@@@ -12259,13 -11604,8 +12309,13 @@@ Bison declaration to assign a precedenc
  @xref{Contextual Precedence, ,Context-Dependent Precedence}.
  @end deffn
  
 +@deffn {Directive} %precedence
 +Bison declaration to assign precedence to token(s), but no associativity
 +@xref{Precedence Decl, ,Operator Precedence}.
 +@end deffn
 +
  @deffn {Directive} %pure-parser
 -Deprecated version of @code{%define api.pure} (@pxref{%define
 +Deprecated version of @samp{%define api.pure} (@pxref{%define
  Summary,,api.pure}), for which Bison is more careful to warn about
  unreasonable usage.
  @end deffn
@@@ -12276,7 -11616,7 +12326,7 @@@ Require a Version of Bison}
  @end deffn
  
  @deffn {Directive} %right
 -Bison declaration to assign right associativity to token(s).
 +Bison declaration to assign precedence and right associativity to token(s).
  @xref{Precedence Decl, ,Operator Precedence}.
  @end deffn
  
@@@ -12381,16 -11721,17 +12431,16 @@@ instead
  
  @deffn {Function} yyerror
  User-supplied function to be called by @code{yyparse} on error.
 -@xref{Error Reporting, ,The Error
 -Reporting Function @code{yyerror}}.
 +@xref{Error Reporting, ,The Error Reporting Function @code{yyerror}}.
  @end deffn
  
  @deffn {Macro} YYERROR_VERBOSE
 -An obsolete macro that you define with @code{#define} in the prologue
 -to request verbose, specific error message strings
 -when @code{yyerror} is called.  It doesn't matter what definition you
 -use for @code{YYERROR_VERBOSE}, just whether you define it.
 -Supported by the C skeletons only; using
 -@code{%error-verbose} is preferred.  @xref{Error Reporting}.
 +An obsolete macro used in the @file{yacc.c} skeleton, that you define
 +with @code{#define} in the prologue to request verbose, specific error
 +message strings when @code{yyerror} is called.  It doesn't matter what
 +definition you use for @code{YYERROR_VERBOSE}, just whether you define
 +it.  Using @samp{%define parse.error verbose} is preferred
 +(@pxref{Error Reporting, ,The Error Reporting Function @code{yyerror}}).
  @end deffn
  
  @deffn {Macro} YYFPRINTF
@@@ -12501,6 -11842,13 +12551,6 @@@ parse a single token.  @xref{Push Parse
  More user feedback will help to stabilize it.)
  @end deffn
  
 -@deffn {Macro} YYPARSE_PARAM
 -An obsolete macro for specifying the name of a parameter that
 -@code{yyparse} should accept.  The use of this macro is deprecated, and
 -is supported only for Yacc like parsers.  @xref{Pure Calling,, Calling
 -Conventions for Pure Parsers}.
 -@end deffn
 -
  @deffn {Macro} YYRECOVERING
  The expression @code{YYRECOVERING ()} yields 1 when the parser
  is recovering from a syntax error, and 0 otherwise.
diff --combined lib/.gitignore
index ba37d129a39e3ddcdcb50559cb030dadf013fa77,2e92c2ffd8eb4ddaa510e6c99d1e447bc84f05f4..74cb3083bf5b6b4f0406b2df1b84d3753a7a7f12
@@@ -35,8 -35,6 +35,8 @@@
  /close.c
  /closeout.c
  /closeout.h
 +/concat-filename.c
 +/concat-filename.h
  /config.charset
  /config.h
  /config.in.h
@@@ -64,7 -62,6 +64,7 @@@
  /fd-hook.h
  /fd-safer-flag.c
  /fd-safer.c
 +/filename.h
  /float+.h
  /float.c
  /float.h
  /isnanf.c
  /isnanl-nolibm.h
  /isnanl.c
--/iswblank.c
  /itold.c
  /ldexpl.c
  /localcharset.c
  /malloc.c
  /math.h
  /math.in.h
--/mbchar.c
--/mbchar.h
  /mbrtowc.c
 -/mbschr.c
  /mbsinit.c
 -/mbsrchr.c
  /mbswidth.c
  /mbswidth.h
--/mbuiter.h
  /memchr.c
  /memchr.valgrind
  /msvc-inval.c
  /nonblocking.h
  /obstack.c
  /obstack.h
 +/obstack_printf.c
  /open.c
  /pathmax.h
  /perror.c
  /stripslash.c
  /strndup.c
  /strnlen.c
--/strnlen1.c
--/strnlen1.h
  /strtol.c
  /strtoul.c
  /strverscmp.c
  /sys_socket.in.h
  /sys_stat.h
  /sys_stat.in.h
 +/sys_types.in.h
  /sys_wait.h
  /sys_wait.in.h
  /sysexits.in.h
  /xalloc-die.c
  /xalloc-oversized.h
  /xalloc.h
 +/xconcat-filename.c
  /xmalloc.c
 +/xmemdup0.c
 +/xmemdup0.h
  /xsize.h
  /xstrndup.c
  /xstrndup.h
 -/xmemdup0.c
 -/xmemdup0.h
 -/sys_types.in.h
 -/obstack_printf.c
  /binary-io.c
 -/mbuiter.c
  /xsize.c
--/bitrotate.c
--/math.c
--/sig-handler.c
--/stdio.c
--/unistd.c
--/wctype-h.c
+ /getdelim.c
+ /getline.c
diff --combined m4/.gitignore
index 80193dbb1778cd0db3a88e4f1188ea0eb0aa5201,8b665097b182d45cfcb0889fff21c0e66e6badb7..242ac2a7a7d60827b0f1b6fafb129afc59a2c816
@@@ -50,7 -50,6 +50,7 @@@
  /include_next.m4
  /intdiv0.m4
  /intl.m4
 +/intl.m4~
  /intldir.m4
  /intlmacosx.m4
  /intmax.m4
@@@ -63,7 -62,7 +63,6 @@@
  /isnand.m4
  /isnanf.m4
  /isnanl.m4
--/iswblank.m4
  /javacomp.m4
  /javaexec.m4
  /largefile.m4
@@@ -82,8 -81,8 +81,6 @@@
  /longlong.m4
  /malloc.m4
  /math_h.m4
--/mbchar.m4
--/mbiter.m4
  /mbrtowc.m4
  /mbsinit.m4
  /mbstate_t.m4
  /perror.m4
  /pipe2.m4
  /po.m4
 +/po.m4~
  /posix_spawn.m4
  /printf-frexp.m4
  /printf-frexpl.m4
  /xstrndup.m4
  /obstack-printf.m4
  /extern-inline.m4
 +/non-recursive-gnulib-prefix-hack.m4
+ /getdelim.m4
+ /getline.m4
++/inline.m4
diff --combined src/complain.c
index 2e4e71afb92e1deac07c1d9e7bd69643fd746c2a,ede0ccf4f5cb122d601e329dc5eeaafb1a5997d7..ee1b4a19ae13e103924c5797efe65bba72359474
  #include "files.h"
  #include "getargs.h"
  
 -bool complaint_issued;
 +warnings warnings_flag =
 +  Wconflicts_sr | Wconflicts_rr | Wdeprecated  | Wother;
 +
 +warnings errors_flag;
 +
 +err_status complaint_status = status_none;
  static unsigned *indent_ptr = 0;
  
 -\f
 +void
 +warnings_print_categories (warnings warn_flags)
 +{
 +  if (! (warn_flags & silent))
 +    {
 +      char const *warn_names[] =
 +        {
 +          "midrule-values",
 +          "yacc",
 +          "conflicts-sr",
 +          "conflicts-rr",
 +          "deprecated",
 +          "other"
 +        };
 +
 +      bool any = false;
 +      int i;
 +      for (i = 0; i < ARRAY_CARDINALITY (warn_names); ++i)
 +        if (warn_flags & 1 << i)
 +          {
 +            bool err = warn_flags & errors_flag;
 +            fprintf (stderr, "%s-W", any ? ", " : " [");
 +            fprintf (stderr, "%s%s", err ? "error=" : "" , warn_names[i]);
 +            any = true;
 +          }
 +      if (any)
 +        fprintf (stderr, "]");
 +    }
 +}
  
  /** Report an error message.
   *
   * \param loc     the location, defaulting to the current file,
   *                or the program name.
 + * \param flags   the category for this message.
   * \param prefix  put before the message (e.g., "warning").
   * \param message the error message, a printf format string.  Iff it
   *                ends with ": ", then no trailing newline is printed,
   */
  static
  void
 -error_message (location *loc,
 -             const char *prefix,
 -             const char *message, va_list args)
 +error_message (const location *loc, warnings flags, const char *prefix,
 +               const char *message, va_list args)
  {
    unsigned pos = 0;
  
    if (loc)
      pos += location_print (stderr, *loc);
    else
 -    pos += fprintf(stderr, "%s", current_file ? current_file : program_name);
 -  pos += fprintf(stderr, ": ");
 +    pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
 +  pos += fprintf (stderr, ": ");
  
    if (indent_ptr)
      {
 +      if (*indent_ptr)
 +        prefix = NULL;
        if (!*indent_ptr)
          *indent_ptr = pos;
        else if (*indent_ptr > pos)
      fprintf (stderr, "%s: ", prefix);
  
    vfprintf (stderr, message, args);
 +  warnings_print_categories (flags);
    {
      size_t l = strlen (message);
-     if (l < 2 || message[l-2] != ':' || message[l-1] != ' ')
+     if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
        {
          putc ('\n', stderr);
          fflush (stderr);
+         if (loc && feature_flag & feature_caret)
+           location_caret (stderr, *loc);
        }
    }
+   fflush (stderr);
  }
  
 -/** Wrap error_message() with varargs handling. */
 -#define ERROR_MESSAGE(Loc, Prefix, Message)   \
 -{                                             \
 -  va_list args;                                       \
 -  va_start (args, Message);                   \
 -  error_message (Loc, Prefix, Message, args); \
 -  va_end (args);                              \
 -}
 -
 -
 -/*--------------------------------.
 -| Report a warning, and proceed.  |
 -`--------------------------------*/
 -
 -void
 -set_warning_issued (void)
 -{
 -  static bool warning_issued = false;
 -  if (!warning_issued && (warnings_flag & warnings_error))
 -    {
 -      fprintf (stderr, "%s: warnings being treated as errors\n", program_name);
 -      complaint_issued = true;
 -    }
 -  warning_issued = true;
 -}
 -
 -void
 -warn_at (location loc, const char *message, ...)
 -{
 -  if (!(warnings_flag & warnings_other))
 -    return;
 -  set_warning_issued ();
 -  ERROR_MESSAGE (&loc, _("warning"), message);
 -}
 -
 -void
 -warn_at_indent (location loc, unsigned *indent,
 -                const char *message, ...)
 -{
 -  if (!(warnings_flag & warnings_other))
 -    return;
 -  set_warning_issued ();
 -  indent_ptr = indent;
 -  ERROR_MESSAGE (&loc, *indent ? NULL : _("warning"), message);
 -}
 -
 -void
 -warn (const char *message, ...)
 +/** Raise a complaint. That can be a fatal error, a complaint or just a
 +    warning.  */
 +static inline void
 +complains (const location *loc, warnings flags, const char *message,
 +           va_list args)
  {
 -  if (!(warnings_flag & warnings_other))
 -    return;
 -  set_warning_issued ();
 -  ERROR_MESSAGE (NULL, _("warning"), message);
 +  const char* prefix =
 +    flags & fatal ? _("fatal error")
 +    : flags & (errors_flag | complaint) ? _("error")
 +    : _("warning");
 +
 +  if ((flags & complaint) && complaint_status < status_complaint)
 +    complaint_status = status_complaint;
 +  else if ((flags & (warnings_flag & errors_flag)) && ! complaint_status)
 +    complaint_status = status_warning_as_error;
 +  if (flags & (warnings_flag | fatal | complaint))
 +    error_message (loc, flags, prefix, message, args);
 +  if (flags & fatal)
 +    exit (EXIT_FAILURE);
  }
  
 -
 -/*-----------------------------------------------------------.
 -| An error has occurred, but we can proceed, and die later.  |
 -`-----------------------------------------------------------*/
 -
  void
 -complain_at (location loc, const char *message, ...)
 +complain (location const *loc, warnings flags, const char *message, ...)
  {
 -  ERROR_MESSAGE (&loc, _("error"), message);
 -  complaint_issued = true;
 +  va_list args;
 +  va_start (args, message);
 +  complains (loc, flags, message, args);
 +  va_end (args);
  }
  
  void
 -complain_at_indent (location loc, unsigned *indent,
 -                    const char *message, ...)
 +complain_indent (location const *loc, warnings flags, unsigned *indent,
 +                 const char *message, ...)
  {
 +  va_list args;
    indent_ptr = indent;
 -  ERROR_MESSAGE (&loc, *indent ? NULL : _("error"), message);
 -  complaint_issued = true;
 +  va_start (args, message);
 +  complains (loc, flags, message, args);
 +  va_end (args);
  }
  
  void
 -complain (const char *message, ...)
 -{
 -  ERROR_MESSAGE (NULL, _("error"), message);
 -  complaint_issued = true;
 -}
 -
 -
 -/*--------------------------------------------------------------.
 -| An incompatibility with POSIX Yacc: mapped either to warn* or |
 -| complain* depending on yacc_flag.                             |
 -`--------------------------------------------------------------*/
 -
 -void
 -yacc_at (location loc, const char *message, ...)
 +complain_args (location const *loc, warnings w, unsigned *indent,
 +               int argc, char *argv[])
  {
 -  if (yacc_flag)
 -    {
 -      ERROR_MESSAGE (&loc, NULL, message);
 -      complaint_issued = true;
 -    }
 -  else if (warnings_flag & warnings_yacc)
 -    {
 -      set_warning_issued ();
 -      ERROR_MESSAGE (&loc, _("warning"), message);
 -    }
 -}
 -
 -void
 -midrule_value_at (location loc, const char *message, ...)
 -{
 -  if (!(warnings_flag & warnings_midrule_values))
 -    return;
 -  set_warning_issued ();
 -  ERROR_MESSAGE (&loc, _("warning"), message);
 -}
 -
 -/*-------------------------------------------------.
 -| A severe error has occurred, we cannot proceed.  |
 -`-------------------------------------------------*/
 -
 -void
 -fatal_at (location loc, const char *message, ...)
 -{
 -  ERROR_MESSAGE (&loc, _("fatal error"), message);
 -  exit (EXIT_FAILURE);
 -}
 -
 -void
 -fatal (const char *message, ...)
 -{
 -  ERROR_MESSAGE (NULL, _("fatal error"), message);
 -  exit (EXIT_FAILURE);
 +  switch (argc)
 +  {
 +  case 1:
 +    complain_indent (loc, w, indent, "%s", _(argv[0]));
 +    break;
 +  case 2:
 +    complain_indent (loc, w, indent, _(argv[0]), argv[1]);
 +    break;
 +  case 3:
 +    complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2]);
 +    break;
 +  case 4:
 +    complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2], argv[3]);
 +    break;
 +  case 5:
 +    complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2], argv[3],
 +                     argv[4]);
 +    break;
 +  default:
 +    complain (loc, fatal, "too many arguments for complains");
 +    break;
 +  }
  }
diff --combined src/flex-scanner.h
index c1e07eae0b2e67b8bded18ad7fad25779454ff28,028082ec22abb2bd87fee4e88eb5b8d6b7ea6d1c..9b80744de6df88cdd886a67f574fbb5731c809bb
  
  /* Whether this version of Flex is (strictly) greater than
     Major.Minor.Subminor.  */
- #define FLEX_VERSION_GT(Major, Minor, Subminor)                         \
  (defined YY_FLEX_MAJOR_VERSION                                        \
-    && (Major < YY_FLEX_MAJOR_VERSION                                    \
       || (Major == YY_FLEX_MAJOR_VERSION                               \
-            && (defined YY_FLEX_MINOR_VERSION                            \
-                && (Minor < YY_FLEX_MINOR_VERSION                        \
                   || (Minor == YY_FLEX_MINOR_VERSION                   \
-                        && defined YY_FLEX_SUBMINOR_VERSION              \
-                        && Subminor < YY_FLEX_SUBMINOR_VERSION))))))
+ #ifdef YY_FLEX_SUBMINOR_VERSION
# define FLEX_VERSION               \
+   (YY_FLEX_MAJOR_VERSION) * 1000000 \
+ (YY_FLEX_MINOR_VERSION) * 1000    \
+ + (YY_FLEX_SUBMINOR_VERSION)
+ #else
# define FLEX_VERSION               \
+   (YY_FLEX_MAJOR_VERSION) * 1000000 \
+ + (YY_FLEX_MINOR_VERSION) * 1000
+ #endif
  /* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used.  */
- #if ! FLEX_VERSION_GT (2, 5, 31)
+ # if FLEX_VERSION <= 2005031
  int   FLEX_PREFIX (get_lineno) (void);
  FILE *FLEX_PREFIX (get_in) (void);
  FILE *FLEX_PREFIX (get_out) (void);
@@@ -65,7 -65,7 +65,7 @@@ int   FLEX_PREFIX (lex_destroy) (void)
     versions according to the Flex manual) leak memory if yylex_destroy is not
     invoked.  However, yylex_destroy is not defined before Flex 2.5.9, so give
     an implementation here that at least appears to work with Flex 2.5.4.  */
- #if ! FLEX_VERSION_GT (2, 5, 9)
+ #if FLEX_VERSION <= 2005009
  # define yylex_destroy() yy_delete_buffer (YY_CURRENT_BUFFER)
  #endif
  
  
  static struct obstack obstack_for_string;
  
 -# define STRING_GROW   \
 +# define STRING_GROW                                    \
    obstack_grow (&obstack_for_string, yytext, yyleng)
  
 -# define STRING_FINISH                                        \
 -  do {                                                        \
 -    obstack_1grow (&obstack_for_string, '\0');                \
 -    last_string = obstack_finish (&obstack_for_string);       \
 -  } while (0)
 +# define STRING_FINISH                                  \
 +  (last_string = obstack_finish0 (&obstack_for_string))
  
 -# define STRING_FREE \
 +# define STRING_FREE                                    \
    obstack_free (&obstack_for_string, last_string)
  
  #endif
diff --combined src/getargs.c
index 77c1cbfbebd70b7c7d1afb4e2686eb94c2e0cb06,ab2a28e828739c44dd90381367f8dc7414556fd8..0d43186f23c2713573e79368b12044216df0b117
  #include <c-strcase.h>
  #include <configmake.h>
  #include <error.h>
 -
 -/* Hack to get <getopt.h> to declare getopt with a prototype.  */
 -#if lint && ! defined __GNU_LIBRARY__
 -# define __GNU_LIBRARY__
 -# define HACK_FOR___GNU_LIBRARY___PROTOTYPE 1
 -#endif
 -
  #include <getopt.h>
 -
 -#ifdef HACK_FOR___GNU_LIBRARY___PROTOTYPE
 -# undef __GNU_LIBRARY__
 -# undef HACK_FOR___GNU_LIBRARY___PROTOTYPE
 -#endif
 -
  #include <progname.h>
  
  #include "complain.h"
  #include "quote.h"
  #include "uniqstr.h"
  
 -bool debug;
  bool defines_flag;
  bool graph_flag;
  bool xml_flag;
 -bool locations_flag;
  bool no_lines_flag;
  bool token_table_flag;
 -bool yacc_flag;       /* for -y */
 -
 -bool error_verbose = false;
 +bool yacc_flag; /* for -y */
  
  bool nondeterministic_parser = false;
  bool glr_parser = false;
  
+ int feature_flag = feature_none;
  int report_flag = report_none;
  int trace_flag = trace_none;
 -int warnings_flag = warnings_conflicts_sr | warnings_conflicts_rr
 -                    | warnings_other;
  
  static struct bison_language const valid_languages[] = {
    { "c", "c-skel.m4", ".c", ".h", true },
@@@ -62,82 -82,50 +63,82 @@@ int language_prio = default_prio
  struct bison_language const *language = &valid_languages[0];
  const char *include = NULL;
  
 -
 -/** Decode an option's set of keys.
 +/** Decode an option's key.
   *
   *  \param option   option being decoded.
   *  \param keys     array of valid subarguments.
   *  \param values   array of corresponding (int) values.
   *  \param all      the all value.
   *  \param flags    the flags to update
 - *  \param args     comma separated list of effective subarguments to decode.
 - *                  If 0, then activate all the flags.
 + *  \param arg      the subarguments to decode.
 + *                  If null, then activate all the flags.
 + *  \param no       length of the potential "no-" prefix.
 + *                  Can be 0 or 3. If 3, negate the action of the subargument.
 + *  \param err      length of a potential "error=".
 + *                  Can be 0 or 6. If 6, treat the subargument as a CATEGORY
   *
   *  If VALUE != 0 then KEY sets flags and no-KEY clears them.
   *  If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
   *  flags from \c all.  Thus no-none = all and no-all = none.
   */
  static void
 -flags_argmatch (const char *option,
 -              const char * const keys[], const int values[],
 -              int all, int *flags, char *args)
 +flag_argmatch (const char *option,
 +               const char * const keys[], const int values[],
 +               int all, int *flags, char *arg, size_t no, size_t err)
  {
 -  if (args)
 +  int value = 0;
 +  if (!err || arg[no + err++] != '\0')
 +    value = XARGMATCH (option, arg + no + err, keys, values);
 +
 +  if (value)
      {
 -      args = strtok (args, ",");
 -      while (args)
 -      {
 -        int no = strncmp (args, "no-", 3) == 0 ? 3 : 0;
 -        int value = XARGMATCH (option, args + no, keys, values);
 -        if (value == 0)
 -          {
 -            if (no)
 -              *flags |= all;
 -            else
 -              *flags &= ~all;
 -          }
 -        else
 -          {
 -            if (no)
 -              *flags &= ~value;
 -            else
 -              *flags |= value;
 -          }
 -        args = strtok (NULL, ",");
 -      }
 +      if (no)
 +        *flags &= ~value;
 +      else
 +        {
 +          if (err)
 +            warnings_flag |= value;
 +          *flags |= value;
 +        }
      }
 +  else
 +    {
 +      /* With a simpler 'if (no)' version, -Werror means -Werror=all
 +         (or rather, -Werror=no-none, but that syntax is invalid).
 +         The difference is:
 +         - Werror activates all errors, but not the warnings
 +         - Werror=all activates errors, and all warnings */
 +      if (no ? !err : err)
 +        *flags |= all;
 +      else
 +        *flags &= ~all;
 +    }
 +}
 +/** Decode an option's set of keys.
 + *
 + *  \param option   option being decoded.
 + *  \param keys     array of valid subarguments.
 + *  \param values   array of corresponding (int) values.
 + *  \param all      the all value.
 + *  \param flags    the flags to update
 + *  \param args     comma separated list of effective subarguments to decode.
 + *                  If 0, then activate all the flags.
 + */
 +static void
 +flags_argmatch (const char *option,
 +                const char * const keys[], const int values[],
 +                int all, int *flags, char *args)
 +{
 +  if (args)
 +    for (args = strtok (args, ","); args; args = strtok (NULL, ","))
 +      {
 +        size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
 +        size_t err = STRPREFIX_LIT ("error", args + no) ? 5 : 0;
 +
 +        flag_argmatch (option, keys,
 +                       values, all, err ? &errors_flag : flags,
 +                       args, no, err);
 +      }
    else
      *flags |= all;
  }
   *
   *  \param FlagName  the flag familly to update.
   *  \param Args      the effective sub arguments to decode.
 + *  \param All       the "all" value.
   *
   *  \arg FlagName_args   the list of keys.
   *  \arg FlagName_types  the list of values.
 - *  \arg FlagName_all    the all value.
   *  \arg FlagName_flag   the flag to update.
   */
 -#define FLAGS_ARGMATCH(FlagName, Args)                                        \
 +#define FLAGS_ARGMATCH(FlagName, Args, All)                             \
    flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
 -                FlagName ## _all, &FlagName ## _flag, Args)
 +                  All, &FlagName ## _flag, Args)
  
  
  /*----------------------.
@@@ -250,7 -238,6 +251,7 @@@ static const char * const warnings_args
    "yacc            - incompatibilities with POSIX Yacc",
    "conflicts-sr    - S/R conflicts",
    "conflicts-rr    - R/R conflicts",
 +  "deprecated      - obsolete constructs",
    "other           - all other warnings",
    "all             - all of the above",
    "error           - warnings are errors",
  
  static const int warnings_types[] =
  {
 -  warnings_none,
 -  warnings_midrule_values,
 -  warnings_yacc,
 -  warnings_conflicts_sr,
 -  warnings_conflicts_rr,
 -  warnings_other,
 -  warnings_all,
 -  warnings_error
 +  Wnone,
 +  Wmidrule_values,
 +  Wyacc,
 +  Wconflicts_sr,
 +  Wconflicts_rr,
 +  Wdeprecated,
 +  Wother,
 +  Wall,
 +  Werror
  };
  
  ARGMATCH_VERIFY (warnings_args, warnings_types);
  
+ /*-----------------------.
+ | --feature's handling.  |
+ `-----------------------*/
+ static const char * const feature_args[] =
+ {
+   "none",
+   "caret", "diagnostics-show-caret",
+   "all",
+   0
+ };
+ static const int feature_types[] =
+ {
+   feature_none,
+   feature_caret, feature_caret,
+   feature_all
+ };
+ ARGMATCH_VERIFY (feature_args, feature_types);
  /*-------------------------------------------.
  | Display the help message and exit STATUS.  |
  `-------------------------------------------*/
@@@ -283,13 -290,13 +305,13 @@@ usage (int status
  {
    if (status != 0)
      fprintf (stderr, _("Try `%s --help' for more information.\n"),
 -           program_name);
 +             program_name);
    else
      {
        /* For ../build-aux/cross-options.pl to work, use the format:
 -              ^  -S, --long[=ARGS] (whitespace)
 -       A --long option is required.
 -       Otherwise, add exceptions to ../build-aux/cross-options.pl.  */
 +                ^  -S, --long[=ARGS] (whitespace)
 +         A --long option is required.
 +         Otherwise, add exceptions to ../build-aux/cross-options.pl.  */
  
        printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
        fputs (_("\
@@@ -315,6 -322,7 +337,7 @@@ Operation modes:\n
        --print-datadir        output directory containing skeletons and XSLT\n\
    -y, --yacc                 emulate POSIX Yacc\n\
    -W, --warnings[=CATEGORY]  report the warnings falling in CATEGORY\n\
+   -f, --feature[=FEATURE]    activate miscellaneous features\n\
  \n\
  "), stdout);
  
  Parser:\n\
    -L, --language=LANGUAGE          specify the output programming language\n\
    -S, --skeleton=FILE              specify the skeleton to use\n\
 -  -t, --debug                      instrument the parser for debugging\n\
 +  -t, --debug                      instrument the parser for tracing\n\
 +                                   same as `-Dparse.trace'\n\
        --locations                  enable location support\n\
    -D, --define=NAME[=VALUE]        similar to '%define NAME \"VALUE\"'\n\
    -F, --force-define=NAME[=VALUE]  override '%define NAME \"VALUE\"'\n\
                                     deprecated by '-Dapi.prefix=PREFIX'\n\
    -l, --no-lines                   don't generate '#line' directives\n\
    -k, --token-table                include a table of token names\n\
- \n\
  "), stdout);
+       putc ('\n', stdout);
  
        /* Keep -d and --defines separate so that ../build-aux/cross-options.pl
         * won't assume that -d also takes an argument.  */
@@@ -348,21 -355,21 +371,21 @@@ Output:\n
    -g, --graph[=FILE]         also output a graph of the automaton\n\
    -x, --xml[=FILE]           also output an XML report of the automaton\n\
                               (the XML schema is experimental)\n\
- \n\
  "), stdout);
+       putc ('\n', stdout);
  
        fputs (_("\
  Warning categories include:\n\
 -  `midrule-values'  unset or unused midrule values\n\
 -  `yacc'            incompatibilities with POSIX Yacc\n\
 -  `conflicts-sr'    S/R conflicts (enabled by default)\n\
 -  `conflicts-rr'    R/R conflicts (enabled by default)\n\
 -  `deprecated'      obsolete constructs\n\
 -  `other'           all other warnings (enabled by default)\n\
 -  `all'             all the warnings\n\
 -  `no-CATEGORY'     turn off warnings in CATEGORY\n\
 -  `none'            turn off all the warnings\n\
 -  `error'           treat warnings as errors\n\
 +  `midrule-values'    unset or unused midrule values\n\
 +  `yacc'              incompatibilities with POSIX Yacc\n\
 +  `conflicts-sr'      S/R conflicts (enabled by default)\n\
 +  `conflicts-rr'      R/R conflicts (enabled by default)\n\
 +  `deprecated'        obsolete constructs\n\
 +  `other'             all other warnings (enabled by default)\n\
 +  `all'               all the warnings\n\
 +  `no-CATEGORY'       turn off warnings in CATEGORY\n\
 +  `none'              turn off all the warnings\n\
 +  `error[=CATEGORY]'  treat warnings as errors\n\
  "), stdout);
        putc ('\n', stdout);
  
@@@ -375,6 -382,14 +398,14 @@@ THINGS is a list of comma separated wor
    `all'          include all the above information\n\
    `none'         disable the report\n\
  "), stdout);
+       putc ('\n', stdout);
+       fputs (_("\
+ FEATURE is a list of comma separated words that can include:\n\
+   `caret'        show errors with carets\n\
+   `all'          all of the above\n\
+   `none'         disable all of the above\n\
+   "), stdout);
  
        putc ('\n', stdout);
        printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
           Note we still output for 'C' so that it gets included in the
           man page.  */
        const char *lc_messages = setlocale (LC_MESSAGES, NULL);
 -      if (lc_messages && strcmp (lc_messages, "en_"))
 +      if (lc_messages && !STREQ (lc_messages, "en_"))
          /* TRANSLATORS: Replace LANG_CODE in this URL with your language
             code <http://translationproject.org/team/LANG_CODE.html> to
             form one of the URLs at http://translationproject.org/team/.
@@@ -416,14 -431,14 +447,14 @@@ version (void
    putc ('\n', stdout);
  
    fprintf (stdout,
 -         _("Copyright (C) %d Free Software Foundation, Inc.\n"),
 -         PACKAGE_COPYRIGHT_YEAR);
 +           _("Copyright (C) %d Free Software Foundation, Inc.\n"),
 +           PACKAGE_COPYRIGHT_YEAR);
  
    fputs (_("\
  This is free software; see the source for copying conditions.  There is NO\n\
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
  "),
 -       stdout);
 +         stdout);
  }
  
  
@@@ -440,8 -455,7 +471,8 @@@ skeleton_arg (char const *arg, int prio
        skeleton = arg;
      }
    else if (prio == skeleton_prio)
 -    complain_at (loc, _("multiple skeleton declarations are invalid"));
 +    complain (&loc, complaint,
 +              _("multiple skeleton declarations are invalid"));
  }
  
  void
@@@ -466,7 -480,7 +497,7 @@@ language_argmatch (char const *arg, in
    else
      return;
  
 -  complain_at (loc, msg, quotearg_colon (arg));
 +  complain (&loc, complaint, msg, quotearg_colon (arg));
  }
  
  /*----------------------.
@@@ -485,6 -499,7 +516,7 @@@ static char const short_options[] 
    "W::"
    "b:"
    "d"
+   "f::"
    "e"
    "g::"
    "h"
@@@ -512,41 -527,42 +544,42 @@@ enu
  static struct option const long_options[] =
  {
    /* Operation modes. */
 -  { "help",            no_argument,     0,   'h' },
 -  { "version",         no_argument,     0,   'V' },
 -  { "print-localedir", no_argument,     0,   PRINT_LOCALEDIR_OPTION },
 -  { "print-datadir",   no_argument,     0,   PRINT_DATADIR_OPTION   },
 +  { "help",            no_argument,       0,   'h' },
 +  { "version",         no_argument,       0,   'V' },
 +  { "print-localedir", no_argument,       0,   PRINT_LOCALEDIR_OPTION },
 +  { "print-datadir",   no_argument,       0,   PRINT_DATADIR_OPTION   },
    { "warnings",        optional_argument, 0,   'W' },
  
    /* Parser. */
 -  { "name-prefix",   required_argument,         0,   'p' },
 +  { "name-prefix",   required_argument,   0,   'p' },
    { "include",       required_argument,   0,   'I' },
  
    /* Output. */
 -  { "file-prefix", required_argument, 0,   'b' },
 -  { "output",    required_argument,   0,   'o' },
 -  { "output-file", required_argument, 0,   'o' },
 -  { "graph",     optional_argument,   0,   'g' },
 +  { "file-prefix", required_argument,   0,   'b' },
 +  { "output",      required_argument,   0,   'o' },
 +  { "output-file", required_argument,   0,   'o' },
 +  { "graph",       optional_argument,   0,   'g' },
    { "xml",         optional_argument,   0,   'x' },
 -  { "report",    required_argument,   0,   'r' },
 +  { "report",      required_argument,   0,   'r' },
    { "report-file", required_argument,   0,   REPORT_FILE_OPTION },
 -  { "verbose",           no_argument,         0,   'v' },
 +  { "verbose",     no_argument,         0,   'v' },
  
    /* Hidden. */
    { "trace",         optional_argument,   0,     'T' },
  
    /* Output.  */
    { "defines",     optional_argument,   0,   'd' },
+   { "feature",     optional_argument,   0,   'f' },
  
    /* Operation modes.  */
    { "fixed-output-files", no_argument,  0,   'y' },
 -  { "yacc",             no_argument,  0,   'y' },
 +  { "yacc",               no_argument,  0,   'y' },
  
    /* Parser.  */
 -  { "debug",        no_argument,               0,   't' },
 -  { "define",       required_argument,         0,   'D' },
 +  { "debug",          no_argument,               0,   't' },
 +  { "define",         required_argument,         0,   'D' },
    { "force-define",   required_argument,         0,   'F' },
 -  { "locations",      no_argument,             0, LOCATIONS_OPTION },
 +  { "locations",      no_argument,               0, LOCATIONS_OPTION },
    { "no-lines",       no_argument,               0,   'l' },
    { "raw",            no_argument,               0,     0 },
    { "skeleton",       required_argument,         0,   'S' },
@@@ -583,21 -599,21 +616,21 @@@ getargs (int argc, char *argv[]
    int c;
  
    while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
 -       != -1)
 +         != -1)
      switch (c)
        {
          /* ASCII Sorting for short options (i.e., upper case then
             lower case), and then long-only options.  */
  
        case 0:
 -      /* Certain long options cause getopt_long to return 0.  */
 -      break;
 +        /* Certain long options cause getopt_long to return 0.  */
 +        break;
  
        case 'D': /* -DNAME[=VALUE]. */
        case 'F': /* -FNAME[=VALUE]. */
          {
            char* name = optarg;
 -          char* value = mbschr (optarg, '=');
 +          char* value = strchr (optarg, '=');
            if (value)
              *value++ = 0;
            muscle_percent_define_insert (name, command_line_location (),
                                          c == 'D' ? MUSCLE_PERCENT_DEFINE_D
                                                   : MUSCLE_PERCENT_DEFINE_F);
          }
 -      break;
 +        break;
  
        case 'I':
 -      include = AS_FILE_NAME (optarg);
 -      break;
 +        include = AS_FILE_NAME (optarg);
 +        break;
  
        case 'L':
 -      language_argmatch (optarg, command_line_prio,
 -                         command_line_location ());
 -      break;
 +        language_argmatch (optarg, command_line_prio,
 +                           command_line_location ());
 +        break;
  
        case 'S':
 -      skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
 -                    command_line_location ());
 -      break;
 +        skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
 +                      command_line_location ());
 +        break;
  
        case 'T':
 -      FLAGS_ARGMATCH (trace, optarg);
 -      break;
 +        FLAGS_ARGMATCH (trace, optarg, trace_all);
 +        break;
  
        case 'V':
 -      version ();
 -      exit (EXIT_SUCCESS);
 +        version ();
 +        exit (EXIT_SUCCESS);
  
 -        FLAGS_ARGMATCH (feature, optarg);
+       case 'f':
++        FLAGS_ARGMATCH (feature, optarg, feature_all);
+         break;
        case 'W':
 -      FLAGS_ARGMATCH (warnings, optarg);
 -      break;
 +        FLAGS_ARGMATCH (warnings, optarg, Wall);
 +        break;
  
        case 'b':
 -      spec_file_prefix = AS_FILE_NAME (optarg);
 -      break;
 +        spec_file_prefix = AS_FILE_NAME (optarg);
 +        break;
  
        case 'd':
          /* Here, the -d and --defines options are differentiated.  */
          break;
  
        case 'g':
 -      graph_flag = true;
 -      if (optarg)
 +        graph_flag = true;
 +        if (optarg)
            {
              free (spec_graph_file);
              spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
            }
 -      break;
 +        break;
  
        case 'h':
 -      usage (EXIT_SUCCESS);
 +        usage (EXIT_SUCCESS);
  
        case 'k':
 -      token_table_flag = true;
 -      break;
 +        token_table_flag = true;
 +        break;
  
        case 'l':
 -      no_lines_flag = true;
 -      break;
 +        no_lines_flag = true;
 +        break;
  
        case 'o':
 -      spec_outfile = AS_FILE_NAME (optarg);
 -      break;
 +        spec_outfile = AS_FILE_NAME (optarg);
 +        break;
  
        case 'p':
 -      spec_name_prefix = optarg;
 -      break;
 +        spec_name_prefix = optarg;
 +        break;
  
        case 'r':
 -      FLAGS_ARGMATCH (report, optarg);
 -      break;
 +        FLAGS_ARGMATCH (report, optarg, report_all);
 +        break;
  
        case 't':
 -      debug = true;
 -      break;
 +        muscle_percent_define_insert ("parse.trace",
 +                                      command_line_location (), "",
 +                                      MUSCLE_PERCENT_DEFINE_D);
 +        break;
  
        case 'v':
 -      report_flag |= report_states;
 -      break;
 +        report_flag |= report_states;
 +        break;
  
        case 'x':
 -      xml_flag = true;
 -      if (optarg)
 +        xml_flag = true;
 +        if (optarg)
            {
              free (spec_xml_file);
              spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
            }
 -      break;
 +        break;
  
        case 'y':
 -      yacc_flag = true;
 -      break;
 +        warnings_flag |= Wyacc;
 +        errors_flag |= Wyacc;
 +        yacc_flag = true;
 +        break;
  
        case LOCATIONS_OPTION:
 -      locations_flag = true;
 -      break;
 +        muscle_percent_define_ensure ("locations",
 +                                      command_line_location (), true);
 +        break;
  
        case PRINT_LOCALEDIR_OPTION:
 -      printf ("%s\n", LOCALEDIR);
 -      exit (EXIT_SUCCESS);
 +        printf ("%s\n", LOCALEDIR);
 +        exit (EXIT_SUCCESS);
  
        case PRINT_DATADIR_OPTION:
 -      printf ("%s\n", compute_pkgdatadir ());
 -      exit (EXIT_SUCCESS);
 +        printf ("%s\n", pkgdatadir ());
 +        exit (EXIT_SUCCESS);
  
        case REPORT_FILE_OPTION:
          free (spec_verbose_file);
 -      spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
 -      break;
 +        spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
 +        break;
  
        default:
 -      usage (EXIT_FAILURE);
 +        usage (EXIT_FAILURE);
        }
  
    if (argc - optind != 1)
diff --combined src/getargs.h
index 4eb3981220476ba8e219421f628e024a0aab0f38,b2126fc21319bc85a02471b85637f400f368518b..3c081fe321b826d77fa029b38af8f01cdb8ed43a
@@@ -34,12 -34,16 +34,12 @@@ extern int skeleton_prio
  /* for -I */
  extern char const *include;
  
 -extern bool debug;                    /* for -t */
 -extern bool defines_flag;             /* for -d */
 -extern bool graph_flag;                       /* for -g */
 -extern bool xml_flag;                 /* for -x */
 -extern bool locations_flag;
 -extern bool no_lines_flag;            /* for -l */
 -extern bool token_table_flag;         /* for -k */
 -extern bool yacc_flag;                        /* for -y */
 -
 -extern bool error_verbose;
 +extern bool defines_flag;               /* for -d */
 +extern bool graph_flag;                 /* for -g */
 +extern bool xml_flag;                   /* for -x */
 +extern bool no_lines_flag;              /* for -l */
 +extern bool token_table_flag;           /* for -k */
 +extern bool yacc_flag;                  /* for -y */
  
  
  /* GLR_PARSER is true if the input file says to use the GLR
@@@ -108,6 -112,36 +108,18 @@@ enum trac
  /** What debug items bison displays during its run.  */
  extern int trace_flag;
  
 -/*-------------.
 -| --warnings.  |
 -`-------------*/
 -
 -enum warnings
 -  {
 -    warnings_none             = 0,      /**< Issue no warnings.  */
 -    warnings_error            = 1 << 0, /**< Warnings are treated as errors.  */
 -    warnings_midrule_values   = 1 << 1, /**< Unset or unused midrule values.  */
 -    warnings_yacc             = 1 << 2, /**< POSIXME.  */
 -    warnings_conflicts_sr     = 1 << 3, /**< S/R conflicts.  */
 -    warnings_conflicts_rr     = 1 << 4, /**< R/R conflicts.  */
 -    warnings_other            = 1 << 5, /**< All other warnings.  */
 -    warnings_all              = ~warnings_error /**< All above warnings.  */
 -  };
 -/** What warnings are issued.  */
 -extern int warnings_flag;
 -
+ /*-------------.
+ | --features.  |
+ `-------------*/
+ enum feature
+   {
+     feature_none  = 0,         /**< No additional feature.  */
+     feature_caret = 1 << 0,    /**< Enhance the output of errors with carets.  */
+     feature_all   = ~0         /**< All above features.  */
+   };
+ /** What additional features to use.  */
+ extern int feature_flag;
  
  /** Process the command line arguments.
   *
diff --combined src/gram.c
index f58ac3b5aea2fc1964e4cb566f8284e9140127f6,5730e596026729c24c2cec1f7bd4f85527d92a8b..dbcf8a213188c548bc2d65ed72dffb24d8b461ec
@@@ -76,7 -76,7 +76,7 @@@ rule_lhs_print (rule *r, symbol *previo
      {
        int n;
        for (n = strlen (previous_lhs->tag); n > 0; --n)
 -      fputc (' ', out);
 +        fputc (' ', out);
        fputc ('|', out);
      }
  }
@@@ -87,10 -87,10 +87,10 @@@ rule_lhs_print_xml (rule *r, FILE *out
    xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
  }
  
 -int
 +size_t
  rule_rhs_length (rule *r)
  {
 -  int res = 0;
 +  size_t res = 0;
    item_number *rhsp;
    for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
      ++res;
@@@ -104,11 -104,12 +104,11 @@@ rule_rhs_print (rule *r, FILE *out
      {
        item_number *rp;
        for (rp = r->rhs; *rp >= 0; rp++)
 -      fprintf (out, " %s", symbols[*rp]->tag);
 -      fputc ('\n', out);
 +        fprintf (out, " %s", symbols[*rp]->tag);
      }
    else
      {
 -      fprintf (out, " /* %s */\n", _("empty"));
 +      fprintf (out, " /* %s */", _("empty"));
      }
  }
  
@@@ -120,8 -121,8 +120,8 @@@ rule_rhs_print_xml (rule *r, FILE *out
        item_number *rp;
        xml_puts (out, level, "<rhs>");
        for (rp = r->rhs; *rp >= 0; rp++)
 -      xml_printf (out, level + 1, "<symbol>%s</symbol>",
 -                  xml_escape (symbols[*rp]->tag));
 +        xml_printf (out, level + 1, "<symbol>%s</symbol>",
 +                    xml_escape (symbols[*rp]->tag));
        xml_puts (out, level, "</rhs>");
      }
    else
      }
  }
  
 -void
 +static void
  rule_print (rule *r, FILE *out)
  {
    fprintf (out, "%s:", r->lhs->tag);
@@@ -162,7 -163,7 +162,7 @@@ ritem_longest_rhs (void
      {
        int length = rule_rhs_length (&rules[r]);
        if (length > max)
 -      max = length;
 +        max = length;
      }
  
    return max;
  
  void
  grammar_rules_partial_print (FILE *out, const char *title,
 -                           rule_filter filter)
 +                             rule_filter filter)
  {
    rule_number r;
    bool first = true;
    for (r = 0; r < nrules + nuseless_productions; r++)
      {
        if (filter && !filter (&rules[r]))
 -      continue;
 +        continue;
        if (first)
 -      fprintf (out, "%s\n\n", title);
 +        fprintf (out, "%s\n\n", title);
        else if (previous_lhs && previous_lhs != rules[r].lhs)
 -      fputc ('\n', out);
 +        fputc ('\n', out);
        first = false;
        rule_lhs_print (&rules[r], previous_lhs, out);
        rule_rhs_print (&rules[r], out);
 +      fprintf (out, "\n");
        previous_lhs = rules[r].lhs;
      }
    if (!first)
@@@ -210,7 -210,7 +210,7 @@@ grammar_rules_print_xml (FILE *out, in
    for (r = 0; r < nrules + nuseless_productions; r++)
      {
        if (first)
 -      xml_puts (out, level + 1, "<rules>");
 +        xml_puts (out, level + 1, "<rules>");
        first = false;
        {
          char const *usefulness;
@@@ -243,8 -243,8 +243,8 @@@ grammar_dump (FILE *out, const char *ti
  {
    fprintf (out, "%s\n\n", title);
    fprintf (out,
 -         "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
 -         ntokens, nvars, nsyms, nrules, nritems);
 +           "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
 +           ntokens, nvars, nsyms, nrules, nritems);
  
  
    fprintf (out, "Variables\n---------\n\n");
  
      for (i = ntokens; i < nsyms; i++)
        fprintf (out, "%5d  %5d   %5d  %s\n",
 -             i,
 -             symbols[i]->prec, symbols[i]->assoc,
 -             symbols[i]->tag);
 +               i,
 +               symbols[i]->prec, symbols[i]->assoc,
 +               symbols[i]->tag);
      fprintf (out, "\n\n");
    }
  
      fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
      for (i = 0; i < nrules + nuseless_productions; i++)
        {
 -      rule *rule_i = &rules[i];
 -      item_number *rp = NULL;
 -      unsigned int rhs_itemno = rule_i->rhs - ritem;
 -      unsigned int rhs_count = 0;
 -      /* Find the last RHS index in ritems. */
 -      for (rp = rule_i->rhs; *rp >= 0; ++rp)
 -        ++rhs_count;
 -      fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u)   %2d ->",
 -               i,
 -               rule_i->prec ? rule_i->prec->prec : 0,
 -               rule_i->prec ? rule_i->prec->assoc : 0,
 -               rule_i->useful,
 -               rhs_itemno,
 -               rhs_itemno + rhs_count - 1,
 -               rule_i->lhs->number);
 -      /* Dumped the RHS. */
 -      for (rp = rule_i->rhs; *rp >= 0; rp++)
 -        fprintf (out, " %3d", *rp);
 -      fprintf (out, "  [%d]\n", item_number_as_rule_number (*rp));
 +        rule *rule_i = &rules[i];
 +        item_number *rp = NULL;
 +        unsigned int rhs_itemno = rule_i->rhs - ritem;
 +        unsigned int rhs_count = 0;
 +        /* Find the last RHS index in ritems. */
 +        for (rp = rule_i->rhs; *rp >= 0; ++rp)
 +          ++rhs_count;
 +        fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u)   %2d ->",
 +                 i,
 +                 rule_i->prec ? rule_i->prec->prec : 0,
 +                 rule_i->prec ? rule_i->prec->assoc : 0,
 +                 rule_i->useful,
 +                 rhs_itemno,
 +                 rhs_itemno + rhs_count - 1,
 +                 rule_i->lhs->number);
 +        /* Dumped the RHS. */
 +        for (rp = rule_i->rhs; *rp >= 0; rp++)
 +          fprintf (out, " %3d", *rp);
 +        fprintf (out, "  [%d]\n", item_number_as_rule_number (*rp));
        }
    }
    fprintf (out, "\n\n");
      rule_number r;
      for (r = 0; r < nrules + nuseless_productions; r++)
        {
 -      fprintf (out, "%-5d  ", r);
 -      rule_print (&rules[r], out);
 +        fprintf (out, "%-5d  ", r);
 +        rule_print (&rules[r], out);
 +        fprintf (out, "\n");
        }
    }
    fprintf (out, "\n\n");
  void
  grammar_rules_useless_report (const char *message)
  {
 -  rule_number r;
 -  for (r = 0; r < nrules ; ++r)
 -    if (!rules[r].useful)
 -      {
 -        if (feature_flag & feature_caret)
 -          warn_at (rules[r].location, "%s", message);
 -        else
 +  warnings w = Wother;
 +  if (warnings_flag & w)
 +    {
 +      rule_number r;
 +      for (r = 0; r < nrules ; ++r)
 +        if (!rules[r].useful)
            {
-             complain (&rules[r].location, w | silent, "%s: ", message);
-             rule_print (&rules[r], stderr);
-             warnings_print_categories (w);
-             fprintf (stderr, "\n");
 -            warn_at (rules[r].location, "%s: ", message);
 -            if (warnings_flag & warnings_other)
++            if (feature_flag & feature_caret)
++              complain (&rules[r].location, w, "%s", message);
++            else
+               {
++                complain (&rules[r].location, w | silent, "%s: ", message);
+                 rule_print (&rules[r], stderr);
 -                fflush (stderr);
++                warnings_print_categories (w);
++                fprintf (stderr, "\n");
+               }
            }
 -      }
 +    }
  }
  
  void
diff --combined src/location.c
index c27ad1449f3a5983cd5e4e11f58b6922c0128108,6e5306c62019a7cf5a9576527d0b83d9ac4d881f..1a7d65c221db7504731e7654111af0672d5373ba
@@@ -42,7 -42,7 +42,7 @@@ add_column_width (int column, char cons
    if (buf)
      {
        if (INT_MAX / 2 <= bufsize)
 -      return INT_MAX;
 +        return INT_MAX;
        width = mbsnwidth (buf, bufsize, 0);
      }
    else
@@@ -69,19 -69,19 +69,19 @@@ location_compute (location *loc, bounda
      switch (*p)
        {
        case '\n':
 -      line += line < INT_MAX;
 -      column = 1;
 -      p0 = p + 1;
 -      break;
 +        line += line < INT_MAX;
 +        column = 1;
 +        p0 = p + 1;
 +        break;
  
        case '\t':
 -      column = add_column_width (column, p0, p - p0);
 -      column = add_column_width (column, NULL, 8 - ((column - 1) & 7));
 -      p0 = p + 1;
 -      break;
 +        column = add_column_width (column, p0, p - p0);
 +        column = add_column_width (column, NULL, 8 - ((column - 1) & 7));
 +        p0 = p + 1;
 +        break;
  
        default:
 -      break;
 +        break;
        }
  
    cur->line = line;
@@@ -90,9 -90,9 +90,9 @@@
    loc->end = *cur;
  
    if (line == INT_MAX && loc->start.line != INT_MAX)
 -    warn_at (*loc, _("line number overflow"));
 +    complain (loc, Wother, _("line number overflow"));
    if (column == INT_MAX && loc->start.column != INT_MAX)
 -    warn_at (*loc, _("column number overflow"));
 +    complain (loc, Wother, _("column number overflow"));
  }
  
  
@@@ -138,16 -138,99 +138,99 @@@ location_print (FILE *out, location loc
    return res;
  }
  
+ /* Persistant data used by location_caret to avoid reopening and rereading the
+    same file all over for each error.  */
+ struct caret_info
+ {
+   FILE* source;
+   size_t line;
+   size_t offset;
+ };
+ static struct caret_info caret_info = { NULL, 1, 0 };
+ /* Free any allocated ressources and close any open file handles that are
+    left-over by the usage of location_caret.  */
+ void
+ cleanup_caret ()
+ {
+   if (caret_info.source)
+     fclose (caret_info.source);
+ }
+ /* Output to OUT the line and caret corresponding to location LOC.  */
+ void
+ location_caret (FILE *out, location loc)
+ {
+   /* FIXME: find a way to support X-file locations, and only open once each
+      file. That would make the procedure future-proof.  */
+   if (! (caret_info.source
+          || (caret_info.source = fopen (loc.start.file, "r")))
+       || loc.start.column == -1 || loc.start.line == -1)
+     return;
+   /* If the line we want to quote is seekable (the same line as the previous
+      location), just seek it. If it was before, we lost track of it, so
+      return to the start of file.  */
+   if (caret_info.line <= loc.start.line)
+     fseek (caret_info.source, caret_info.offset, SEEK_SET);
+   else
+     {
+       caret_info.line = 1;
+       caret_info.offset = 0;
+       fseek (caret_info.source, caret_info.offset, SEEK_SET);
+     }
+   /* Advance to the line's position, keeping track of the offset.  */
+   {
+     int i;
+     for (i = caret_info.line; i < loc.start.line; caret_info.offset++)
+       if (fgetc (caret_info.source) == '\n')
+         ++i;
+   }
+   caret_info.line = loc.start.line;
+   /* Read the actual line.  Don't update the offset, so that we keep a pointer
+      to the start of the line.  */
+   {
+     ssize_t len = 0;
+     char *buf = NULL;
+     if ((len = getline (&buf, (size_t*) &len, caret_info.source)) != -1)
+       {
+         /* The caret of a multiline location ends with the first line.  */
+         int end = loc.start.line != loc.end.line ? len : loc.end.column;
+         if (len)
+           {
+             int i = loc.start.column;
+             /* Quote the file, indent by a single column.  */
+             fputc (' ', out);
+             fwrite (buf, 1, len, out);
+             /* Print the caret, with the same indent as above.  */
+             fputc (' ', out);
+             fprintf (out, "%*s", loc.start.column - 1, "");
+             do {
+               fputc ('^', out);
+             } while (++i < end);
+           }
+         fputc ('\n', out);
+         free (buf);
+       }
+   }
+ }
  void
  boundary_set_from_string (boundary *bound, char *loc_str)
  {
    /* Must search in reverse since the file name field may
     * contain `.' or `:'.  */
 -  char *delim = mbsrchr (loc_str, '.');
 +  char *delim = strrchr (loc_str, '.');
    aver (delim);
    *delim = '\0';
    bound->column = atoi (delim+1);
 -  delim = mbsrchr (loc_str, ':');
 +  delim = strrchr (loc_str, ':');
    aver (delim);
    *delim = '\0';
    bound->line = atoi (delim+1);
diff --combined src/location.h
index 369125b7cee7bbc6000acade29090d2f60f74cb0,c1859aeb57f9b325a3b53535bbc57f46c8042b97..7026d82f0a9054faf2c39c502023eda0f0a60ebd
@@@ -73,8 -73,8 +73,8 @@@ static inline boo
  equal_boundaries (boundary a, boundary b)
  {
    return (a.column == b.column
 -        && a.line == b.line
 -        && UNIQSTR_EQ (a.file, b.file));
 +          && a.line == b.line
 +          && UNIQSTR_EQ (a.file, b.file));
  }
  
  /* A location, that is, a region of source code.  */
@@@ -96,12 -96,19 +96,19 @@@ extern location const empty_location
  /* Set *LOC and adjust scanner cursor to account for token TOKEN of
     size SIZE.  */
  void location_compute (location *loc,
 -                     boundary *cur, char const *token, size_t size);
 +                       boundary *cur, char const *token, size_t size);
  
  /* Print location to file. Return number of actually printed
     characters.  */
  unsigned location_print (FILE *out, location loc);
  
+ /* Free any allocated ressources and close any open file handles that are
+    left-over by the usage of location_caret.  */
+ void cleanup_caret (void);
+ /* Output to OUT the line and caret corresponding to location LOC.  */
+ void location_caret (FILE *out, location loc);
  /* Return -1, 0, 1, depending whether a is before, equal, or
     after b.  */
  static inline int
diff --combined src/main.c
index 39b39c7a5902f6bc33e844c65c3ffe9e9823a762,184d789dd7a7cf2a640017f569dd8c48392062c2..5386aa717f21d7d7ddc55c7e66f3131b712e4edc
@@@ -66,7 -66,7 +66,7 @@@ main (int argc, char *argv[]
  
    {
      char const *cp = getenv ("LC_CTYPE");
 -    if (cp && !strcmp (cp, "C"))
 +    if (cp && STREQ (cp, "C"))
        set_custom_quoting (&quote_quoting_options, "'", "'");
      else
        set_quoting_style (&quote_quoting_options, locale_quoting_style);
@@@ -94,7 -94,7 +94,7 @@@
    reader ();
    timevar_pop (TV_READER);
  
 -  if (complaint_issued)
 +  if (complaint_status == status_complaint)
      goto finish;
  
    /* Find useless nonterminals and productions and reduce the grammar. */
       declarations.  */
    timevar_push (TV_CONFLICTS);
    conflicts_solve ();
 -  if (!muscle_percent_define_flag_if ("lr.keep-unreachable-states"))
 +  if (!muscle_percent_define_flag_if ("lr.keep-unreachable-state"))
      {
        state_number *old_to_new = xnmalloc (nstates, sizeof *old_to_new);
        state_number nstates_old = nstates;
    tables_generate ();
    timevar_pop (TV_ACTIONS);
  
 -  grammar_rules_useless_report
 -    (_("rule useless in parser due to conflicts"));
 +  grammar_rules_useless_report (_("rule useless in parser due to conflicts"));
  
    /* Output file names. */
    compute_output_file_names ();
  
    /* Stop if there were errors, to avoid trashing previous output
       files.  */
 -  if (complaint_issued)
 +  if (complaint_status == status_complaint)
      goto finish;
  
    /* Lookahead tokens are no longer needed. */
    timevar_stop (TV_TOTAL);
    timevar_print (stderr);
  
 -  return complaint_issued ? EXIT_FAILURE : EXIT_SUCCESS;
+   cleanup_caret ();
 +  return complaint_status ? EXIT_FAILURE : EXIT_SUCCESS;
  }
diff --combined tests/actions.at
index 6d160efdc9667f1a1487b8cf98253c39ec6654c9,ba46fe36c346d67bfe80fc124ac7f0389a0a538e..cd7a58b6799740c44ad17f5074436c0a8e185727
@@@ -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[
@@@ -257,7 -257,7 +257,7 @@@ AT_SETUP([Exotic Dollars]
  
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA_GRAMMAR([[input.y]],
 -[[%error-verbose
 +[[%define parse.error verbose
  %debug
  %{
  ]AT_YYERROR_DECLARE[
@@@ -313,7 -313,7 +313,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;
@@@ -481,7 -481,7 +481,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");
      }
  ;
@@@ -737,7 -737,7 +737,7 @@@ m4_define([AT_CHECK_PRINTER_AND_DESTRUC
  
  $3
  _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4],
 -[%error-verbose
 +[%define parse.error verbose
  %debug
  %verbose
  %locations
@@@ -748,13 -748,13 +748,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
  
@@@ -818,10 -818,7 +818,10 @@@ main (void
  }
  ]])
  
 -AT_BISON_CHECK([-o input.c input.y])
 +AT_BISON_CHECK([-o input.c input.y], [], [],
 +[[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.
@@@ -869,7 -866,7 +869,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
  
  %{
@@@ -933,10 -930,7 +933,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.
@@@ -995,16 -989,16 +995,16 @@@ 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
  
@@@ -1065,17 -1059,8 +1065,17 @@@ 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:23.3-5: warning: useless %destructor for type <*> [-Wother]
 +input0.y:23.3-5: 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.
@@@ -1098,10 -1083,8 +1098,10 @@@ 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
  
@@@ -1161,10 -1144,7 +1161,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
@@@ -1263,10 -1243,7 +1263,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
@@@ -1323,12 -1300,19 +1323,27 @@@ 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]
  ]])
  
 -[[input.y:33.3-23: warning: unset value: $$
+ AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
 -input.y:30.3-35.37: warning: unused value: $3
++[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
++ %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
++                                                                      ^^^
++input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
++ %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
++                                                                      ^^^
++input.y:33.3-23: warning: unset value: $$ [-Wother]
+    {           @$ = 4; } // Only used.
+    ^^^^^^^^^^^^^^^^^^^^^
++input.y:30.3-35.37: warning: unused value: $3 [-Wother]
+    {           @$ = 1; } // Not set or used.
+    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ]])
  AT_COMPILE([input])
  AT_PARSER_CHECK([./input], 1,,
  [[Starting parse
@@@ -1427,9 -1411,8 +1442,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
  {
@@@ -1521,7 -1506,10 +1536,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)
@@@ -1559,37 -1547,37 +1574,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
@@@ -1606,41 -1594,41 +1621,41 @@@ 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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:8.48:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:9.48:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:10.48:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:11.48:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:12.48:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:13.48:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:20.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:21.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:22.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:23.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:24.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:25.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:31.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:32.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:33.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:34.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:35.1:     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: a ';' might be needed at the end of action code [-Wdeprecated]
  input.y:36.1:     future versions of Bison will not add the ';'
  ]])
  
diff --combined tests/conflicts.at
index 8b04449c732998197477f2fc2ebace711c6a66ba,5653b481f4f93248a176c332074385dcc4c45862..c7ed2fe42a8990ddbe67494a50f09aa637b34997
@@@ -1,6 -1,7 +1,6 @@@
  # Exercising Bison on conflicts.                         -*- Autotest -*-
  
 -# Copyright (C) 2002-2005, 2007, 2009-2012 Free Software Foundation,
 -# Inc.
 +# Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc.
  
  # This program is free software: you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
@@@ -37,9 -38,15 +37,15 @@@ e: 'e' | /* Nothing. */
  ]])
  
  AT_BISON_CHECK([-o input.c input.y], 0, [],
 -[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */
 +[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother]
  ]])
  
 -[[input.y:4.9: warning: rule useless in parser due to conflicts
+ AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
++[[input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
+  e: 'e' | /* Nothing. */;
+          ^
+ ]])
  AT_CLEANUP
  
  
@@@ -117,10 -124,10 +123,10 @@@ AT_NONASSOC_AND_EOF_CHECK([], [[incorre
  
  # We must disable default reductions in inconsistent states in order to
  # have an explicit list of all expected tokens.
 -AT_NONASSOC_AND_EOF_CHECK([[-Dlr.default-reductions=consistent]],
 +AT_NONASSOC_AND_EOF_CHECK([[-Dlr.default-reduction=consistent]],
                            [[correct]])
  
 -# lr.default-reductions=consistent happens to work for this test case.
 +# lr.default-reduction=consistent happens to work for this test case.
  # However, for other grammars, lookahead sets can be merged for
  # different left contexts, so it is still possible to have an incorrect
  # expected list.  Canonical LR is almost a general solution (that is, it
@@@ -141,11 -148,11 +147,11 @@@ AT_CLEANU
  
  
  
 -## -------------------------------------- ##
 -## %error-verbose and consistent errors.  ##
 -## -------------------------------------- ##
 +## ------------------------------------------- ##
 +## parse.error=verbose and consistent errors.  ##
 +## ------------------------------------------- ##
  
 -AT_SETUP([[%error-verbose and consistent errors]])
 +AT_SETUP([[parse.error=verbose and consistent errors]])
  
  m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
  
@@@ -163,6 -170,7 +169,6 @@@ AT_SKEL_JAVA_IF([AT_DATA], [AT_DATA_GRA
  }]], [[
  
  %code {]AT_SKEL_CC_IF([[
 -  #include <cassert>
    #include <string>]], [[
    #include <assert.h>
    #include <stdio.h>
  
  ]$1[
  
 -%error-verbose
 +%define parse.error verbose
  
  %%
  
@@@ -310,12 -318,12 +316,12 @@@ AT_CONSISTENT_ERRORS_CHECK([[%define lr
  
  # Even canonical LR doesn't foresee the error for 'a'!
  AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
 -                             %define lr.default-reductions consistent]],
 +                             %define lr.default-reduction consistent]],
                             [AT_PREVIOUS_STATE_GRAMMAR],
                             [AT_PREVIOUS_STATE_INPUT],
                             [[$end]], [[ab]])
  AT_CONSISTENT_ERRORS_CHECK([[%define lr.type ielr
 -                             %define lr.default-reductions accepting]],
 +                             %define lr.default-reduction accepting]],
                             [AT_PREVIOUS_STATE_GRAMMAR],
                             [AT_PREVIOUS_STATE_INPUT],
                             [[$end]], [[ab]])
@@@ -370,7 -378,7 +376,7 @@@ error-reduce
  ;
  
  consistent-reduction: /*empty*/ {
 -  assert (yychar == ]AT_SKEL_CC_IF([[yyempty_]], [[YYEMPTY]])[);
 +  assert (yychar == YYEMPTY);
    yylval = 0;
    yychar = 'b';
  } ;
@@@ -394,15 -402,19 +400,15 @@@ AT_CONSISTENT_ERRORS_CHECK([[%glr-parse
                             [AT_USER_ACTION_GRAMMAR],
                             [AT_USER_ACTION_INPUT],
                             [['b']], [[none]])
 -AT_CONSISTENT_ERRORS_CHECK([[%language "c++"]],
 -                           [AT_USER_ACTION_GRAMMAR],
 -                           [AT_USER_ACTION_INPUT],
 -                           [['b']], [[none]])
 -# No Java test because yychar cannot be manipulated by users.
 +# No C++ or Java test because yychar cannot be manipulated by users.
  
 -AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reductions consistent]],
 +AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reduction consistent]],
                             [AT_USER_ACTION_GRAMMAR],
                             [AT_USER_ACTION_INPUT],
                             [['b']], [[none]])
  
  # Canonical LR doesn't foresee the error for 'a'!
 -AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reductions accepting]],
 +AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reduction accepting]],
                             [AT_USER_ACTION_GRAMMAR],
                             [AT_USER_ACTION_INPUT],
                             [[$end]], [[a]])
@@@ -416,7 -428,7 +422,7 @@@ AT_CONSISTENT_ERRORS_CHECK([[%define pa
                             [AT_USER_ACTION_INPUT],
                             [['b']], [[none]])
  AT_CONSISTENT_ERRORS_CHECK([[%define parse.lac full
 -                             %define lr.default-reductions accepting]],
 +                             %define lr.default-reduction accepting]],
                             [AT_USER_ACTION_GRAMMAR],
                             [AT_USER_ACTION_INPUT],
                             [[$end]], [[none]])
@@@ -498,7 -510,7 +504,7 @@@ AT_BISON_OPTION_POPDEF
  # Show canonical LR's failure.
  AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]],
                 [[0]], [[]],
 -[[input.y: conflicts: 2 shift/reduce
 +[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
  ]])
  AT_COMPILE([[input]])
  AT_PARSER_CHECK([[./input]], [[1]], [[]],
  # It's corrected by LAC.
  AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \
                   -o input.c input.y]], [[0]], [[]],
 -[[input.y: conflicts: 2 shift/reduce
 +[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
  ]])
  AT_COMPILE([[input]])
  AT_PARSER_CHECK([[./input]], [[1]], [[]],
  # IELR is sufficient when LAC is used.
  AT_BISON_CHECK([[-Dlr.type=ielr -Dparse.lac=full -o input.c input.y]],
                 [[0]], [[]],
 -[[input.y: conflicts: 2 shift/reduce
 +[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
  ]])
  AT_COMPILE([[input]])
  AT_PARSER_CHECK([[./input]], [[1]], [[]],
@@@ -542,8 -554,8 +548,8 @@@ exp: exp OP exp | NUM
  ]])
  
  AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
 -[input.y: conflicts: 1 shift/reduce
 -])
 +[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +]])
  
  # Check the contents of the report.
  AT_CHECK([cat input.output], [],
@@@ -735,62 -747,6 +741,62 @@@ State 
  AT_CLEANUP
  
  
 +## ---------------------- ##
 +## %precedence suffices.  ##
 +## ---------------------- ##
 +
 +AT_SETUP([%precedence suffices])
 +
 +AT_DATA([input.y],
 +[[%precedence "then"
 +%precedence "else"
 +%%
 +stmt:
 +  "if" cond "then" stmt
 +| "if" cond "then" stmt "else" stmt
 +| "stmt"
 +;
 +
 +cond:
 +  "exp"
 +;
 +]])
 +
 +AT_BISON_CHECK([-o input.c input.y])
 +
 +AT_CLEANUP
 +
 +
 +## ------------------------------ ##
 +## %precedence does not suffice.  ##
 +## ------------------------------ ##
 +
 +AT_SETUP([%precedence does not suffice])
 +
 +AT_DATA([input.y],
 +[[%precedence "then"
 +%precedence "else"
 +%%
 +stmt:
 +  "if" cond "then" stmt
 +| "if" cond "then" stmt "else" stmt
 +| "stmt"
 +;
 +
 +cond:
 +  "exp"
 +| cond "then" cond
 +;
 +]])
 +
 +AT_BISON_CHECK([-o input.c input.y], 0, [],
 +[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond [-Wother]
 +]])
 +
 +AT_CLEANUP
 +
 +
  ## -------------------------------- ##
  ## Defaulted Conflicted Reduction.  ##
  ## -------------------------------- ##
@@@ -828,8 -784,8 +834,8 @@@ id : '0'
  ]])
  
  AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
 -[[input.y: conflicts: 1 reduce/reduce
 -input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0'
 +[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' [-Wother]
  ]])
  
  # Check the contents of the report.
@@@ -945,8 -901,9 +951,8 @@@ exp: exp OP exp | NUM
  ]])
  
  AT_BISON_CHECK([-o input.c input.y], 1, [],
 -[input.y: conflicts: 1 shift/reduce
 -input.y: error: expected 0 shift/reduce conflicts
 -])
 +[[input.y: error: shift/reduce conflicts: 1 found, 0 expected
 +]])
  AT_CLEANUP
  
  
@@@ -981,8 -938,9 +987,8 @@@ exp: exp OP exp | NUM
  ]])
  
  AT_BISON_CHECK([-o input.c input.y], 1, [],
 -[input.y: conflicts: 1 shift/reduce
 -input.y: error: expected 2 shift/reduce conflicts
 -])
 +[[input.y: error: shift/reduce conflicts: 1 found, 2 expected
 +]])
  AT_CLEANUP
  
  
@@@ -1000,8 -958,9 +1006,8 @@@ a: 'a'
  ]])
  
  AT_BISON_CHECK([-o input.c input.y], 1, [],
 -[input.y: conflicts: 1 reduce/reduce
 -input.y: error: expected 0 reduce/reduce conflicts
 -])
 +[[input.y: error: reduce/reduce conflicts: 1 found, 0 expected
 +]])
  AT_CLEANUP
  
  
@@@ -1043,7 -1002,7 +1049,7 @@@ e:   e '+' 
  ]])
  
  AT_BISON_CHECK([-o input.c input.y], 0, [],
 -[[input.y: conflicts: 4 shift/reduce
 +[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
  ]])
  AT_CLEANUP
  
@@@ -1145,15 -1104,14 +1151,15 @@@ reported_conflicts
  ]])
  
  AT_BISON_CHECK([[--report=all input.y]], 0, [],
 -[[input.y: conflicts: 1 shift/reduce, 1 reduce/reduce
 -input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1
 -input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2
 -input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */
 -input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
 -input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
 -input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a'
 -input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */
 +[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1 [-Wother]
 +input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2 [-Wother]
 +input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
 +input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
 +input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
 +input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
 +input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
  ]])
  
  AT_CHECK([[cat input.output]], 0,
@@@ -1293,17 -1251,16 +1299,17 @@@ State 
  ]])
  
  AT_DATA([[input-keep.y]],
 -[[%define lr.keep-unreachable-states
 +[[%define lr.keep-unreachable-state
  ]])
  AT_CHECK([[cat input.y >> input-keep.y]])
  
  AT_BISON_CHECK([[input-keep.y]], 0, [],
 -[[input-keep.y: conflicts: 2 shift/reduce, 2 reduce/reduce
 -input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */
 -input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */
 -input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a'
 -input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */
 +[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
 +input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
 +input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
 +input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
 +input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
 +input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
  ]])
  
  AT_CLEANUP
@@@ -1458,40 -1415,9 +1464,40 @@@ State 
  AT_CLEANUP
  
  
 -## --------------------------------- ##
 -## -W versus %expect and %expect-rr  ##
 -## --------------------------------- ##
 +## -------------------- ##
 +## %expect-rr non GLR.  ##
 +## -------------------- ##
 +
 +AT_SETUP([[%expect-rr non GLR]])
 +
 +AT_DATA([[1.y]],
 +[[%expect-rr 0
 +%%
 +exp: 'a'
 +]])
 +
 +AT_BISON_CHECK([[1.y]], [[0]], [],
 +[[1.y: warning: %expect-rr applies only to GLR parsers [-Wother]
 +]])
 +
 +AT_DATA([[2.y]],
 +[[%expect-rr 1
 +%%
 +exp: 'a' | 'a';
 +]])
 +
 +AT_BISON_CHECK([[2.y]], [[0]], [],
 +[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
 +2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 +2.y:3.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
 +]])
 +
 +AT_CLEANUP
 +
 +
 +## ---------------------------------- ##
 +## -W versus %expect and %expect-rr.  ##
 +## ---------------------------------- ##
  
  AT_SETUP([[-W versus %expect and %expect-rr]])
  
@@@ -1517,27 -1443,17 +1523,27 @@@ B: 
  ]])
  
  AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]],
 -[[sr-rr.y: conflicts: 1 shift/reduce, 1 reduce/reduce
 +[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
  ]])
  AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]],
 -[[sr-rr.y: conflicts: 1 reduce/reduce
 +[[sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
  ]])
  AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]],
 -[[sr-rr.y: conflicts: 1 shift/reduce
 +[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
  ]])
  
 -[for gram in sr-rr sr rr; do
 +[
 +# This is piece of code is rather complex for a simple task: try every
 +# combinaison of (0 or 1 real SR) x (0 or 1 real RR) x (don't %expect
 +# or %expect 0, 1, or 2 SR) x (don't %expect-rr or %expect-rr 0, 1, or 2
 +# RR).
 +
 +# Number and types of genuine conflicts in the grammar.
 +for gram in sr-rr sr rr; do
 +  # Number of expected s/r conflicts.
    for sr_exp_i in '' 0 1 2; do
 +    # Number of expected r/r conflicts.
      for rr_exp_i in '' 0 1 2; do
        test -z "$sr_exp_i" && test -z "$rr_exp_i" && continue
  
        echo "$directives" > $file
        cat $gram.y >> $file
  
 -      # Count actual conflicts.
 -      conflicts=
 -      sr_count=0
 -      rr_count=0
 -      if test $gram = sr || test $gram = sr-rr; then
 -        conflicts="1 shift/reduce"
 -        sr_count=1
 -      fi
 -      if test $gram = rr || test $gram = sr-rr; then
 -        if test -n "$conflicts"; then
 -          conflicts="$conflicts, "
 -        fi
 -        conflicts="${conflicts}1 reduce/reduce"
 -        rr_count=1
 -      fi
 +      # Number of found conflicts.
 +      case $gram in
 +        (sr)    sr_count=1; rr_count=0;;
 +        (rr)    sr_count=0; rr_count=1;;
 +        (sr-rr) sr_count=1; rr_count=1;;
 +      esac
 +
 +      # Update number of expected conflicts: if %expect is given then
 +      # %expect-rr defaults to 0, and vice-versa.  Leave empty if
 +      # nothing expected.
 +      case $sr_exp_i:$rr_exp_i in
 +        ?:) rr_exp_i=0;;
 +        :?) sr_exp_i=0;;
 +      esac
  
        # Run tests.
        if test $sr_count -eq $sr_exp && test $rr_count -eq $rr_exp; then
          ]AT_BISON_CHECK([[-Wnone $file]])[
          ]AT_BISON_CHECK([[-Werror $file]])[
        else
 -        echo "$file: conflicts: $conflicts" > experr
 -        if test $sr_count -ne $sr_exp; then
 -          if test $sr_exp -ne 1; then s=s; else s= ; fi
 -          echo "$file: error: expected $sr_exp shift/reduce conflict$s" >> experr
 -        fi
 -        if test $rr_count -ne $rr_exp; then
 -          if test $rr_exp -ne 1; then s=s; else s= ; fi
 -          echo "$file: error: expected $rr_exp reduce/reduce conflict$s" >> experr
 -        fi
 +        {
 +          if test -z "$sr_exp_i" && test "$sr_count" -ne 0; then
 +            echo "warning: $sr_count shift/reduce conflicts"
 +          elif test "$sr_exp_i" -ne "$sr_count"; then
 +            echo "error: shift/reduce conflicts: $sr_count found, $sr_exp_i expected"
 +          fi
 +          if test -z "$rr_exp_i" && test "$rr_count" -ne 0; then
 +            echo "warning: $rr_count reduce/reduce conflicts"
 +          elif test "$rr_exp_i" -ne "$rr_count"; then
 +            echo "error: reduce/reduce conflicts: $rr_count found, $rr_exp_i expected"
 +          fi
 +        } | sed -e "s/^/$file: /" > experr
          ]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[
          ]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[
        fi
diff --combined tests/input.at
index 7ba006366bc2cf9515a2ccd56114d0bd705019b7,cd0dd6ac2e3a45b2c3ef353c38c577a6d88e7017..7f5fb8875de873c561ddd6a74540e2a73a8d2bd0
@@@ -117,9 -117,9 +117,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, [
@@@ -170,39 -175,39 +170,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]
  ]]]))])
  
  
@@@ -257,29 -262,29 +257,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
  ]])
  
@@@ -328,123 -333,6 +328,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.  ##
@@@ -464,9 -352,9 +464,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]],
@@@ -481,8 -369,8 +481,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
@@@ -505,9 -393,9 +505,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
@@@ -685,7 -573,7 +685,7 @@@ yylex (void
  }
  ]])
  
 -# Pacify Emacs' font-lock-mode: "
 +# Pacify Emacs'font-lock-mode: "
  
  AT_DATA([main.c],
  [[typedef int value;
@@@ -764,8 -652,8 +764,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"
@@@ -808,15 -696,15 +808,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.
@@@ -889,10 -777,10 +889,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
@@@ -925,6 -813,25 +925,25 @@@ input.y:19.13-20.0: error: missing '}' 
  input.y:20.1: error: syntax error, unexpected end of file
  ]])
  
+ AT_BISON_CHECK([-fcaret -o input.c input.y], 1, [],
+ [[input.y:1.10-2.0: error: missing '"' at end of line
+  %token A "a
+           ^^
+ input.y:4.10-5.0: error: missing "'" at end of line
+  %token C '1
+           ^^
+ input.y:14.11-15.0: error: missing "'" at end of line
+  %type <f> 'a
+            ^^
+ input.y:16.11-17.0: error: missing '"' at end of line
+  %type <f> "a
+            ^^
+ input.y:19.13-20.0: error: missing '}' at end of file
+  %destructor { free ($$)
+              ^^^^^^^^^^^
+ input.y:20.1: error: syntax error, unexpected end of file
+ ]])
  AT_CLEANUP
  
  
  
  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],
  [[%%
@@@ -984,7 -891,7 +1003,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
@@@ -1157,6 -1064,18 +1176,18 @@@ AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y
  <command line>:1:      previous definition
  ]])
  
+ AT_DATA([[input-dg.y]],
+ [[%define var "gram"
+ %%
+ start: ;
+ ]])
+ AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
+ [[input-dg.y:1.9-11: error: %define variable 'var' redefined
+  %define var "gram"
+          ^^^
+ <command line>:2:      previous definition
+ ]])
  AT_DATA([[input-unused.y]],
  [[%%
  start: ;
@@@ -1196,15 -1115,15 +1227,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.
@@@ -1216,9 -1135,9 +1247,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
@@@ -1238,11 -1157,10 +1269,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]],
@@@ -1325,14 -1230,14 +1356,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[
  ]])])
  ])
  
@@@ -1381,10 -1286,10 +1412,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
  ]])
  
@@@ -1396,10 -1301,10 +1427,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
  ]])
  
@@@ -1411,10 -1316,10 +1442,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
  ]])
  
@@@ -1442,25 -1347,25 +1473,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
@@@ -1505,19 -1410,20 +1536,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]])
@@@ -1564,8 -1470,7 +1595,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;
@@@ -1574,14 -1479,14 +1605,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
@@@ -1604,7 -1509,6 +1635,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
      ;
    };
@@@ -1651,121 -1555,3 +1682,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/named-refs.at
index ea379222f80a46ebeb219e44ffdff2c3a6f43f63,46b0159c7650f7bba3ed5fadca639166ffa7a27e..75e73030a537a34f21af80c4458e030629659c35
@@@ -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        */
  
  %%
@@@ -69,7 -69,7 +69,7 @@@ exp
    {
      if ($l != $r)
        fprintf (stderr, "calc: error: %d != %d\n", $l, $r);
 -    $$ = $l;
 +   $$ = $l;
    }
  | exp[x] '+' { $<ival>$ = $x; } [l] exp[r]  { $$ = $<ival>l + $r;    }
  | exp[l] '-' exp[r]  { $$ = $l - $r;        }
@@@ -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        */
  
  %%
@@@ -234,7 -234,7 +234,7 @@@ exp
    {
      if ($l != $r)
        fprintf (stderr, "calc: error: %d != %d\n", $l, $r);
 -    $$ = $l;
 +   $$ = $l;
    }
  | exp[x] '+' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>lo9 + $r; }
  | exp[x] '-' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>exp - $r; }
  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
  ]])
@@@ -393,6 -393,127 +393,127 @@@ test.y:46.46-54: error: invalid referen
  test.y:45.12-46.65:  symbol not found in production: then
  test.y:45.41-46:     possibly meant: $[then-a].f at $4
  ]])
+ AT_BISON_CHECK([-fcaret -o test.c test.y], 1, [],
+ [[test.y:24.36-41: error: invalid reference: '$cond1'
+            { $if_stmt1 = new IfStmt($cond1, $then.f1, $else); };
+                                     ^^^^^^
+ test.y:23.11-24.62:  symbol not found in production: cond1
+  if_stmt1: IF expr[cond] THEN stmt[then] ELSE stmt.list[else] FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:26.43-53: error: invalid reference: '$stmt.field'
+            { $if_stmt2 = new IfStmt($cond, $stmt.field, 0); };
+                                            ^^^^^^^^^^^
+ test.y:25.11-26.60:  symbol not found in production: stmt
+  if_stmt2: IF expr[cond] THEN stmt[then] FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:25.35-38:     possibly meant: $then.field, hiding $stmt.field at $4
+  if_stmt2: IF expr[cond] THEN stmt[then] FI
+                                    ^^^^
+ test.y:28.43-52: error: invalid reference: '$stmt.list'
+            { $if_stmt3 = new IfStmt($cond, $stmt.list, 0); };
+                                            ^^^^^^^^^^
+ test.y:27.11-28.59:  symbol not found in production: stmt
+  if_stmt3: IF expr[cond] THEN stmt.list FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:27.30-38:     possibly meant: $[stmt.list] at $4
+  if_stmt3: IF expr[cond] THEN stmt.list FI
+                               ^^^^^^^^^
+ test.y:30.43-46: error: ambiguous reference: '$xyz'
+            { $if_stmt4 = new IfStmt($cond, $xyz, $cond); };
+                                            ^^^^
+ test.y:29.35-37:     refers to: $xyz at $4
+  if_stmt4: IF expr[cond] THEN stmt[xyz] ELSE stmt[xyz] FI
+                                    ^^^
+ test.y:29.50-52:     refers to: $xyz at $6
+  if_stmt4: IF expr[cond] THEN stmt[xyz] ELSE stmt[xyz] FI
+                                                   ^^^
+ test.y:32.43-52: error: invalid reference: '$stmt.list'
+            { $if_stmt5 = new IfStmt($cond, $stmt.list, $else); };
+                                            ^^^^^^^^^^
+ test.y:31.11-32.63:  symbol not found in production: stmt
+  if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:31.40-43:     possibly meant: $then, hiding $[stmt.list] at $4
+  if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+                                         ^^^^
+ test.y:31.61-64:     possibly meant: $else, hiding $[stmt.list] at $6
+  if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+                                                              ^^^^
+ test.y:34.43-58: error: invalid reference: '$stmt.list.field'
+            { $if_stmt6 = new IfStmt($cond, $stmt.list.field, $else); };
+                                            ^^^^^^^^^^^^^^^^
+ test.y:33.11-34.69:  symbol not found in production: stmt
+  if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:33.40-43:     possibly meant: $then.field, hiding $[stmt.list].field at $4
+  if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+                                         ^^^^
+ test.y:33.61-64:     possibly meant: $else.field, hiding $[stmt.list].field at $6
+  if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+                                                              ^^^^
+ test.y:36.43-54: error: invalid reference: '$[stmt.list]'
+            { $if_stmt7 = new IfStmt($cond, $[stmt.list].field, $else); };
+                                            ^^^^^^^^^^^^
+ test.y:35.11-36.71:  symbol not found in production: stmt.list
+  if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:35.40-43:     possibly meant: $then, hiding $[stmt.list] at $4
+  if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+                                         ^^^^
+ test.y:35.61-64:     possibly meant: $else, hiding $[stmt.list] at $6
+  if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+                                                              ^^^^
+ test.y:38.43-49: error: invalid reference: '$then.1'
+            { $if_stmt8 = new IfStmt($cond, $then.1, $else); };
+                                            ^^^^^^^
+ test.y:37.11-38.60:  symbol not found in production: then
+  if_stmt8: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:37.40-45:     possibly meant: $[then.1] at $4
+  if_stmt8: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
+                                         ^^^^^^
+ test.y:40.43-55: error: invalid reference: '$then.1.field'
+            { $if_stmt9 = new IfStmt($cond, $then.1.field, $else); };
+                                            ^^^^^^^^^^^^^
+ test.y:39.11-40.66:  symbol not found in production: then
+  if_stmt9: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
+            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:39.40-45:     possibly meant: $[then.1].field at $4
+  if_stmt9: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
+                                         ^^^^^^
+ test.y:42.44-50: error: invalid reference: '$stmt.x'
+            { $if_stmt10 = new IfStmt($cond, $stmt.x, 0); };
+                                             ^^^^^^^
+ test.y:41.12-42.57:  symbol not found in production: stmt
+  if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
+             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:41.36-41:     possibly meant: $[stmt.x].x, hiding $stmt.x at $4
+  if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
+                                     ^^^^^^
+ test.y:41.36-41:     possibly meant: $[stmt.x] at $4
+  if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
+                                     ^^^^^^
+ test.y:44.13-22: error: invalid reference: '$if-stmt-a'
+            { $if-stmt-a = new IfStmt($cond, $then, $else); };
+              ^^^^^^^^^^
+ test.y:43.12-44.59:  symbol not found in production: if
+  if-stmt-a: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:43.1-9:       possibly meant: $[if-stmt-a] at $$
+  if-stmt-a: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
+  ^^^^^^^^^
+ test.y:46.46-54: error: invalid reference: '$then-a.f'
+            { $[if-stmt-b] = new IfStmt($cond, $then-a.f, $else); };
+                                               ^^^^^^^^^
+ test.y:45.12-46.65:  symbol not found in production: then
+  if-stmt-b: IF expr[cond] THEN if-stmt-a[then-a] ELSE stmt.list[else] FI
+             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ test.y:45.41-46:     possibly meant: $[then-a].f at $4
+  if-stmt-b: IF expr[cond] THEN if-stmt-a[then-a] ELSE stmt.list[else] FI
+                                          ^^^^^^
+ ]])
  AT_CLEANUP
  
  #######################################################################
@@@ -573,7 -694,7 +694,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/reduce.at
index 2d9093f0f63efea5c4fa0d2b5ddb1dcda76fcaf9,47f923cfdd319bb216e9dd5fc755a57c047b7ee0..8ac894c0655f5cb67ccba9cfb98ebcf099d45dfe
@@@ -88,16 -88,16 +88,16 @@@ exp: useful
  ]])
  
  AT_BISON_CHECK([[input.y]], 0, [],
 -[[input.y: warning: 9 nonterminals useless in grammar
 -input.y:4.8-15: warning: nonterminal useless in grammar: useless1
 -input.y:5.8-15: warning: nonterminal useless in grammar: useless2
 -input.y:6.8-15: warning: nonterminal useless in grammar: useless3
 -input.y:7.8-15: warning: nonterminal useless in grammar: useless4
 -input.y:8.8-15: warning: nonterminal useless in grammar: useless5
 -input.y:9.8-15: warning: nonterminal useless in grammar: useless6
 -input.y:10.8-15: warning: nonterminal useless in grammar: useless7
 -input.y:11.8-15: warning: nonterminal useless in grammar: useless8
 -input.y:12.8-15: warning: nonterminal useless in grammar: useless9
 +[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
 +input.y:4.8-15: warning: nonterminal useless in grammar: useless1 [-Wother]
 +input.y:5.8-15: warning: nonterminal useless in grammar: useless2 [-Wother]
 +input.y:6.8-15: warning: nonterminal useless in grammar: useless3 [-Wother]
 +input.y:7.8-15: warning: nonterminal useless in grammar: useless4 [-Wother]
 +input.y:8.8-15: warning: nonterminal useless in grammar: useless5 [-Wother]
 +input.y:9.8-15: warning: nonterminal useless in grammar: useless6 [-Wother]
 +input.y:10.8-15: warning: nonterminal useless in grammar: useless7 [-Wother]
 +input.y:11.8-15: warning: nonterminal useless in grammar: useless8 [-Wother]
 +input.y:12.8-15: warning: nonterminal useless in grammar: useless9 [-Wother]
  ]])
  
  AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@@ -142,27 -142,86 +142,86 @@@ useless8: '8'
  useless9: '9';
  ]])
  
 -[[input.y: warning: 9 nonterminals useless in grammar
 -input.y: warning: 9 rules useless in grammar
 -input.y:6.1-8: warning: nonterminal useless in grammar: useless1
+ AT_BISON_CHECK([[-fcaret input.y]], 0, [],
 -input.y:7.1-8: warning: nonterminal useless in grammar: useless2
++[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
++input.y: warning: 9 rules useless in grammar [-Wother]
++input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
+  useless1: '1';
+  ^^^^^^^^
 -input.y:8.1-8: warning: nonterminal useless in grammar: useless3
++input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
+  useless2: '2';
+  ^^^^^^^^
 -input.y:9.1-8: warning: nonterminal useless in grammar: useless4
++input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
+  useless3: '3';
+  ^^^^^^^^
 -input.y:10.1-8: warning: nonterminal useless in grammar: useless5
++input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
+  useless4: '4';
+  ^^^^^^^^
 -input.y:11.1-8: warning: nonterminal useless in grammar: useless6
++input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
+  useless5: '5';
+  ^^^^^^^^
 -input.y:12.1-8: warning: nonterminal useless in grammar: useless7
++input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
+  useless6: '6';
+  ^^^^^^^^
 -input.y:13.1-8: warning: nonterminal useless in grammar: useless8
++input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
+  useless7: '7';
+  ^^^^^^^^
 -input.y:14.1-8: warning: nonterminal useless in grammar: useless9
++input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
+  useless8: '8';
+  ^^^^^^^^
 -input.y:6.11-13: warning: rule useless in grammar
++input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
+  useless9: '9';
+  ^^^^^^^^
 -input.y:7.11-13: warning: rule useless in grammar
++input.y:6.11-13: warning: rule useless in grammar [-Wother]
+  useless1: '1';
+            ^^^
 -input.y:8.11-13: warning: rule useless in grammar
++input.y:7.11-13: warning: rule useless in grammar [-Wother]
+  useless2: '2';
+            ^^^
 -input.y:9.11-13: warning: rule useless in grammar
++input.y:8.11-13: warning: rule useless in grammar [-Wother]
+  useless3: '3';
+            ^^^
 -input.y:10.11-13: warning: rule useless in grammar
++input.y:9.11-13: warning: rule useless in grammar [-Wother]
+  useless4: '4';
+            ^^^
 -input.y:11.11-13: warning: rule useless in grammar
++input.y:10.11-13: warning: rule useless in grammar [-Wother]
+  useless5: '5';
+            ^^^
 -input.y:12.11-13: warning: rule useless in grammar
++input.y:11.11-13: warning: rule useless in grammar [-Wother]
+  useless6: '6';
+            ^^^
 -input.y:13.11-13: warning: rule useless in grammar
++input.y:12.11-13: warning: rule useless in grammar [-Wother]
+  useless7: '7';
+            ^^^
 -input.y:14.11-13: warning: rule useless in grammar
++input.y:13.11-13: warning: rule useless in grammar [-Wother]
+  useless8: '8';
+            ^^^
++input.y:14.11-13: warning: rule useless in grammar [-Wother]
+  useless9: '9';
+            ^^^
+ ]])
  AT_BISON_CHECK([[input.y]], 0, [],
 -[[input.y: warning: 9 nonterminals useless in grammar
 -input.y: warning: 9 rules useless in grammar
 -input.y:6.1-8: warning: nonterminal useless in grammar: useless1
 -input.y:7.1-8: warning: nonterminal useless in grammar: useless2
 -input.y:8.1-8: warning: nonterminal useless in grammar: useless3
 -input.y:9.1-8: warning: nonterminal useless in grammar: useless4
 -input.y:10.1-8: warning: nonterminal useless in grammar: useless5
 -input.y:11.1-8: warning: nonterminal useless in grammar: useless6
 -input.y:12.1-8: warning: nonterminal useless in grammar: useless7
 -input.y:13.1-8: warning: nonterminal useless in grammar: useless8
 -input.y:14.1-8: warning: nonterminal useless in grammar: useless9
 -input.y:6.11-13: warning: rule useless in grammar: useless1: '1'
 -input.y:7.11-13: warning: rule useless in grammar: useless2: '2'
 -input.y:8.11-13: warning: rule useless in grammar: useless3: '3'
 -input.y:9.11-13: warning: rule useless in grammar: useless4: '4'
 -input.y:10.11-13: warning: rule useless in grammar: useless5: '5'
 -input.y:11.11-13: warning: rule useless in grammar: useless6: '6'
 -input.y:12.11-13: warning: rule useless in grammar: useless7: '7'
 -input.y:13.11-13: warning: rule useless in grammar: useless8: '8'
 -input.y:14.11-13: warning: rule useless in grammar: useless9: '9'
 +[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
 +input.y: warning: 9 rules useless in grammar [-Wother]
 +input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
 +input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
 +input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
 +input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
 +input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
 +input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
 +input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
 +input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
 +input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
 +input.y:6.11-13: warning: rule useless in grammar: useless1: '1' [-Wother]
 +input.y:7.11-13: warning: rule useless in grammar: useless2: '2' [-Wother]
 +input.y:8.11-13: warning: rule useless in grammar: useless3: '3' [-Wother]
 +input.y:9.11-13: warning: rule useless in grammar: useless4: '4' [-Wother]
 +input.y:10.11-13: warning: rule useless in grammar: useless5: '5' [-Wother]
 +input.y:11.11-13: warning: rule useless in grammar: useless6: '6' [-Wother]
 +input.y:12.11-13: warning: rule useless in grammar: useless7: '7' [-Wother]
 +input.y:13.11-13: warning: rule useless in grammar: useless8: '8' [-Wother]
 +input.y:14.11-13: warning: rule useless in grammar: useless9: '9' [-Wother]
  ]])
  
  AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@@ -238,14 -297,34 +297,34 @@@ non_productive: non_productive useless_
  %%
  ]])
  
 -[[not-reduced.y: warning: 2 nonterminals useless in grammar
 -not-reduced.y: warning: 3 rules useless in grammar
 -not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
+ AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
 -not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
++[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
++not-reduced.y: warning: 3 rules useless in grammar [-Wother]
++not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
+  not_reachable: useful  { /* A not reachable action. */ }
+  ^^^^^^^^^^^^^
 -not-reduced.y:11.6-57: warning: rule useless in grammar
++not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
+     | non_productive    { /* A non productive action. */ }
+       ^^^^^^^^^^^^^^
 -not-reduced.y:14.16-56: warning: rule useless in grammar
++not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
+     | non_productive    { /* A non productive action. */ }
+       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 -not-reduced.y:17.17-18.63: warning: rule useless in grammar
++not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
+  not_reachable: useful  { /* A not reachable action. */ }
+                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
+  non_productive: non_productive useless_token
+                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ]])
  AT_BISON_CHECK([[not-reduced.y]], 0, [],
 -[[not-reduced.y: warning: 2 nonterminals useless in grammar
 -not-reduced.y: warning: 3 rules useless in grammar
 -not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
 -not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
 -not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive
 -not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful
 -not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token
 +[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
 +not-reduced.y: warning: 3 rules useless in grammar [-Wother]
 +not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
 +not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
 +not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive [-Wother]
 +not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful [-Wother]
 +not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token [-Wother]
  ]])
  
  AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
@@@ -314,13 -393,13 +393,13 @@@ indirection: underivable
  ]])
  
  AT_BISON_CHECK([[input.y]], 0, [],
 -[[input.y: warning: 2 nonterminals useless in grammar
 -input.y: warning: 3 rules useless in grammar
 -input.y:5.15-25: warning: nonterminal useless in grammar: underivable
 -input.y:6.14-24: warning: nonterminal useless in grammar: indirection
 -input.y:5.15-25: warning: rule useless in grammar: exp: underivable
 -input.y:6.14-24: warning: rule useless in grammar: underivable: indirection
 -input.y:7.14-24: warning: rule useless in grammar: indirection: underivable
 +[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
 +input.y: warning: 3 rules useless in grammar [-Wother]
 +input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
 +input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
 +input.y:5.15-25: warning: rule useless in grammar: exp: underivable [-Wother]
 +input.y:6.14-24: warning: rule useless in grammar: underivable: indirection [-Wother]
 +input.y:7.14-24: warning: rule useless in grammar: indirection: underivable [-Wother]
  ]])
  
  AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@@ -350,8 -429,8 +429,8 @@@ exp: exp
  ]])
  
  AT_BISON_CHECK([[input.y]], 1, [],
 -[[input.y: warning: 2 nonterminals useless in grammar
 -input.y: warning: 2 rules useless in grammar
 +[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
 +input.y: warning: 2 rules useless in grammar [-Wother]
  input.y:3.1-3: fatal error: start symbol exp does not derive any sentence
  ]])
  
@@@ -396,7 -475,7 +475,7 @@@ AT_TEST_LR_TYPE([[Single State Split]]
  [[%left 'a'
  // Conflict resolution renders state 12 unreachable for canonical LR(1).  We
  // keep it so that the paser table diff is easier to code.
 -%define lr.keep-unreachable-states]],
 +%define lr.keep-unreachable-state]],
  [[
  S: 'a' A 'a' /* rule 1 */
   | 'b' A 'b' /* rule 2 */
@@@ -629,7 -708,7 +708,7 @@@ AT_TEST_LR_TYPE([[Lane Split]]
  [[%left 'a'
  // Conflict resolution renders state 16 unreachable for canonical LR(1).  We
  // keep it so that the paser table diff is easier to code.
 -%define lr.keep-unreachable-states]],
 +%define lr.keep-unreachable-state]],
  [[
  /* Similar to the last test case set but two states must be split.  */
  S: 'a' A 'a' /* rule 1 */
@@@ -873,7 -952,7 +952,7 @@@ AT_TEST_LR_TYPE([[Complex Lane Split]]
  [[%left 'a'
  // Conflict resolution renders state 16 unreachable for canonical LR(1).  We
  // keep it so that the paser table diff is easier to code.
 -%define lr.keep-unreachable-states]],
 +%define lr.keep-unreachable-state]],
  [[
  /* Similar to the last test case set but forseeing the S/R conflict from the
     first state that must be split is becoming difficult.  Imagine if B were
@@@ -1139,7 -1218,7 +1218,7 @@@ dnl PARSER-EXIT-VALUE, PARSER-STDOUT, P
  ]])])
  
  AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]],
 -[[%define lr.keep-unreachable-states]],
 +[[%define lr.keep-unreachable-state]],
  [[
  /* The partial state chart diagram below is for LALR(1).  State 0 is the start
     state.  States are iterated for successor construction in numerical order.
@@@ -1191,7 -1270,7 +1270,7 @@@ dnl INPU
  
  dnl BISON-STDERR
  [AT_COND_CASE([[LALR]],
 -[[input.y: conflicts: 1 reduce/reduce
 +[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
  ]], [])],
  
  dnl TABLES
@@@ -1443,28 -1522,28 +1522,28 @@@ dnl PARSER-EXIT-VALUE, PARSER-STDOUT, P
  
  
  ## ------------------------------- ##
 -## %define lr.default-reductions.  ##
 +## %define lr.default-reduction.  ##
  ## ------------------------------- ##
  
  # AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES)
  # -----------------------------------------------------
  m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS],
  [
 -AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reductions]],
 +AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reduction]],
                           [[most]], [[]],
                           [[]],
                           [$1], [$2], [[]], [$3])
 -AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions most]],
 +AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction most]],
                           [[most]], [[]],
 -                         [[%define lr.default-reductions most]],
 +                         [[%define lr.default-reduction most]],
                           [$1], [$2], [[]], [$3])
 -AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions consistent]],
 +AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction consistent]],
                           [[consistent]], [[]],
 -                         [[%define lr.default-reductions consistent]],
 +                         [[%define lr.default-reduction consistent]],
                           [$1], [$2], [[]], [$3])
 -AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions accepting]],
 +AT_TEST_TABLES_AND_PARSE([[%define lr.default-reduction accepting]],
                           [[accepting]], [[]],
 -                         [[%define lr.default-reductions accepting]],
 +                         [[%define lr.default-reduction accepting]],
                           [$1], [$2], [[]], [$3])
  ])
  
diff --combined tests/regression.at
index 769142008eda10acee2b8a347434a2312f9f9bc8,db6c3b9f03c5bba5f70f101e663a1a4d2b635824..c08059e5e4226d958077821b9b41048ad90016e7
@@@ -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,9 -478,17 +478,17 @@@ 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]
  ]])
 -[[input.y:22.8-14: warning: symbol SPECIAL redeclared
+ AT_BISON_CHECK([-fcaret -o input.c input.y], [[0]], [[]],
 -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]
+  %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
+         ^^^^^^^
++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]
+  %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ]])
  AT_COMPILE([input])
  
  # Checking the error message here guarantees that yytname, which does contain
@@@ -538,7 -546,7 +546,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 -556,12 +556,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 -767,15 +767,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 -789,32 +780,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 -828,6 +811,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 -947,11 +938,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 -1046,7 +1037,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 -1199,8 +1190,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 -1218,8 +1209,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 -1233,11 +1225,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 -1281,9 +1273,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 -1304,9 +1296,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 -1389,8 +1382,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 -1440,7 +1433,7 @@@ AT_DATA_GRAMMAR([input.y]
  }
  
  ]$1[
 -%error-verbose
 +%define parse.error verbose
  %token 'c'
  
  %%
@@@ -1461,7 -1476,7 +1469,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 -1552,7 +1545,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