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

Conflicts:
NEWS
gnulib
tests/named-refs.at
tests/regression.at

12 files changed:
1  2 
NEWS
THANKS
data/glr.cc
data/lalr1.cc
gnulib
tests/calc.at
tests/glr-regression.at
tests/headers.at
tests/input.at
tests/local.at
tests/named-refs.at
tests/regression.at

diff --combined NEWS
index cb845125c3e30bded6f05e8f162b7d886409e113,3d21470a0685fa0c929a3ae1508c0b3c1e15d7ba..b7a1a727d9d9b888ff410a3a7c62426d28fdfec6
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,56 -1,24 +1,75 @@@
  GNU Bison NEWS
  
 +* Noteworthy changes in release ?.? (????-??-??) [?]
 +
 +** Changes in the format of error messages
 +
 +  This used to be the format of many error reports:
 +
 +    foo.y:5.10-24: result type clash on merge function 'merge': <t3> != <t2>
 +    foo.y:4.13-27: previous declaration
 +
 +  It is now:
 +
 +    foo.y:5.10-25: result type clash on merge function 'merge': <t3> != <t2>
 +    foo.y:4.13-27:     previous declaration
 +
 +** Exception safety (lalr1.cc)
 +
 +  The parse function now catches exceptions, uses the %destructors to
 +  release memory (the lookahead symbol and the symbols pushed on the stack)
 +  before re-throwing the exception.
 +
 +  This feature is somewhat experimental.  User feedback would be
 +  appreciated.
 +
 +** New %define variable: api.location.type (glr.cc, lalr1.cc, lalr1.java)
 +
 +  The %define variable api.location.type defines the name of the type to use
 +  for locations.  When defined, Bison no longer generates the position.hh
 +  and location.hh files, nor does the parser will include them: the user is
 +  then responsible to define her type.
 +
 +  This can be used in programs with several parsers to factor their location
 +  and position files: let one of them generate them, and the others just use
 +  them.
 +
 +  This feature was actually introduced, but not documented, in Bison 2.5,
 +  under the name "location_type" (which is maintained for backward
 +  compatibility).
 +
 +  For consistency, lalr1.java's %define variables location_type and
 +  position_type are deprecated in favor of api.location.type and
 +  api.position.type.
 +
 +** Graphviz improvements
 +
 +  The graphical presentation of the states is more readable: their shape is
 +  now rectangular, the state number is clearly displayed, and the items are
 +  numbered and left-justified.
 +
 +  The reductions are now explicitly represented as transitions to other
 +  diamond shaped nodes.
 +
+ * Noteworthy changes in release ?.? (????-??-??) [?]
+   We consider compiler warnings about Bison generated parsers to be bugs.
+   Rather than working around them in your own project, please consider
+   reporting them to us.
+ ** Bug fixes
+   Warnings about uninitialized yylval and/or yylloc for push parsers with a
+   pure interface have been fixed for GCC 4.0 up to 4.8, and Clang 2.9 to
+   3.2.
+   Other issues in the test suite have been addressed.
+   Nul characters are correctly displayed in error messages.
+   When possible, yylloc is correctly initialized before calling yylex.  It
+   is no longer necessary to initialize it in the %initial-action.
  * Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
  
    Bison 2.6.3's --version was incorrect.  This release fixes this issue.
  
  * Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
  
 - Bison no longer executes user-specified M4 code when processing a grammar.
 +  Bison no longer executes user-specified M4 code when processing a grammar.
  
  ** Future Changes
  
@@@ -1956,8 -1924,7 +1975,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
 + LocalWords:  lang yyoutput dvi html ps POSIX lvalp llocp calc yyo fval Wmaybe
 + LocalWords:  yyvsp pragmas noreturn java's
  
  Local Variables:
  mode: outline
diff --combined THANKS
index 185097f748b6224eff460b4d5365da799eb7461e,77d35be7d8d460644ccb013a3a9fcf7469ee3622..21e7a1dd855ffc4e98cd6096629dab010d77cbe3
--- 1/THANKS
--- 2/THANKS
+++ b/THANKS
@@@ -64,6 -64,7 +64,7 @@@ Laurent Mascherpa         laurent.masch
  Lie Yan                   lie.yan@kaust.edu.sa
  Magnus Fromreide          magfr@lysator.liu.se
  Marc Autret               autret_m@epita.fr
+ Marc Mendiola             mmendiol@usc.edu
  Martin Jacobs             martin.jacobs@arcor.de
  Martin Mokrejs            mmokrejs@natur.cuni.cz
  Martin Nylin              martin.nylin@linuxmail.org
@@@ -80,7 -81,6 +81,7 @@@ Nicolas Tisserand         nicolas.tisse
  Noah Friedman             friedman@gnu.org
  Odd Arild Olsen           oao@fibula.no
  Oleg Smolsky              oleg.smolsky@pacific-simulators.co.nz
 +Oleksii Taran             oleksii.taran@gmail.com
  Paolo Bonzini             bonzini@gnu.org
  Pascal Bart               pascal.bart@epita.fr
  Paul Eggert               eggert@cs.ucla.edu
@@@ -88,6 -88,7 +89,7 @@@ Paul Hilfinger            Hilfinger@CS.
  Per Allansson             per@appgate.com
  Peter Fales               psfales@lucent.com
  Peter Hamorsky            hamo@upjs.sk
+ Peter Simons              simons@cryp.to
  Piotr Gackiewicz          gacek@intertel.com.pl
  Quoc Peyrot               chojin@lrde.epita.fr
  R Blake                   blakers@mac.com
@@@ -104,7 -105,6 +106,7 @@@ Shura                     debil_urod@ng
  Stefano Lattarini         stefano.lattarini@gmail.com
  Steve Murphy              murf@parsetree.com
  Sum Wu                    sum@geekhouse.org
 +Théophile Ranquet         theophile.ranquet@gmail.com
  Thiru Ramakrishnan        thiru.ramakrishnan@gmail.com
  Tim Josling               tej@melbpc.org.au
  Tim Landscheidt           tim@tim-landscheidt.de
@@@ -128,7 -128,6 +130,7 @@@ thank them!  Please, help us keeping th
  
  Local Variables:
  mode: text
 +coding: utf-8
  End:
  
  -----
diff --combined data/glr.cc
index 6527b0a2b4b72dcde32d99e4d33267d518e17def,104bf785b66d5fd9d20c51124a011b8e4306ac3c..0e53d61915833343458c5c49022fb35a397c0e3a
@@@ -54,7 -54,7 +54,7 @@@ b4_defines_if([]
                [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
  
  m4_include(b4_pkgdatadir/[c++.m4])
 -b4_percent_define_ifdef([[location_type]], [],
 +b4_percent_define_ifdef([[api.location.type]], [],
                          [m4_include(b4_pkgdatadir/[location.cc])])
  
  m4_define([b4_parser_class_name],
@@@ -87,12 -87,17 +87,17 @@@ m4_define([b4_yy_symbol_print_generate]
  ]b4_parse_param_use[]dnl
  [  yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
  }
- ]])
+ ]])[
  
 -]b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
+ # Hijack the initial action to initialize the locations.
++]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
+ [m4_define([b4_initial_action],
+ [yylloc.initialize ();]m4_ifdef([b4_initial_action], [
+ m4_defn([b4_initial_action])]))])])[
  
  # Hijack the post prologue to insert early definition of YYLLOC_DEFAULT
  # and declaration of yyerror.
- m4_append([b4_post_prologue],
]m4_append([b4_post_prologue],
  [b4_syncline([@oline@], [@ofile@])[
  ]b4_yylloc_default_define[
  #define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
@@@ -238,7 -243,7 +243,7 @@@ b4_copyright([Skeleton interface for Bi
  
  # include <string>
  # include <iostream>
 -]b4_percent_define_ifdef([[location_type]], [],
 +]b4_percent_define_ifdef([[api.location.type]], [],
                           [[# include "location.hh"]])[
  
  ]b4_YYDEBUG_define[
@@@ -262,7 -267,7 +267,7 @@@ b4_user_styp
      typedef ]b4_api_PREFIX[STYPE semantic_type;
  # endif
      /// Symbol locations.
 -    typedef ]b4_percent_define_get([[location_type]],
 +    typedef ]b4_percent_define_get([[api.location.type]],
                                     [[location]])[ location_type;
      /// Tokens.
      struct token
diff --combined data/lalr1.cc
index 46e58ae26fab6188a05e7fc5b7cd17d52a9766f1,2fe8d4cbd84de5f4a9b2f278aa70f3bb8e4b50a8..e45b2e1f860cf48ff9c66be677b5f20001008240
@@@ -24,7 -24,7 +24,7 @@@ m4_define([b4_parser_class_name]
  b4_defines_if([],
                [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
  
 -b4_percent_define_ifdef([[location_type]], [],
 +b4_percent_define_ifdef([[api.location.type]], [],
    [# Backward compatibility.
    m4_define([b4_location_constructors])
    m4_include(b4_pkgdatadir/[location.cc])])
@@@ -52,7 -52,7 +52,7 @@@ b4_copyright([Skeleton interface for Bi
  #include <string>
  #include <iostream>
  #include "stack.hh"
 -]b4_percent_define_ifdef([[location_type]], [],
 +]b4_percent_define_ifdef([[api.location.type]], [],
                           [[#include "location.hh"]])[
  
  ]b4_YYDEBUG_define[
@@@ -77,7 -77,7 +77,7 @@@ b4_user_styp
      typedef ]b4_api_PREFIX[STYPE semantic_type;
  #endif
      /// Symbol locations.
 -    typedef ]b4_percent_define_get([[location_type]],
 +    typedef ]b4_percent_define_get([[api.location.type]],
                                     [[location]])[ location_type;
      /// Tokens.
      struct token
  
      /// \brief Reclaim the memory associated to a symbol.
      /// \param yymsg        Why this token is reclaimed.
 +    ///                     If null, do not display the symbol, just free it.
      /// \param yytype       The symbol type.
      /// \param yyvaluep     Its semantic value.
      /// \param yylocationp  Its location.
@@@ -336,9 -335,9 +336,9 @@@ do {                                       
  #else /* !]b4_api_PREFIX[DEBUG */
  
  # define YYCDEBUG if (false) std::cerr
 -# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
 -# define YY_REDUCE_PRINT(Rule)
 -# define YY_STACK_PRINT()
 +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) YYUSE(Type)
 +# define YY_REDUCE_PRINT(Rule)        static_cast<void>(0)
 +# define YY_STACK_PRINT()             static_cast<void>(0)
  
  #endif /* !]b4_api_PREFIX[DEBUG */
  
      YYUSE (yymsg);
      YYUSE (yyvaluep);
  
 -    YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 +    if (yymsg)
 +      YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
  
      switch (yytype)
        {
      int yychar = yyempty_;
      int yytoken = 0;
  
-     /* State.  */
+     // State.
      int yyn;
      int yylen = 0;
      int yystate = 0;
  
-     /* Error handling.  */
+     // Error handling.
      int yynerrs_ = 0;
      int yyerrstatus_ = 0;
  
      /// Semantic value of the lookahead.
-     semantic_type yylval;
+     static semantic_type yyval_default;
+     semantic_type yylval = yyval_default;
      /// Location of the lookahead.
      location_type yylloc;
      /// The locations where the error started and ended.
  
      int yyresult;
  
 +    // FIXME: This shoud be completely indented.  It is not yet to
 +    // avoid gratuitous conflicts when merging into the master branch.
 +    try
 +      {
      YYCDEBUG << "Starting parse" << std::endl;
  
  ]m4_ifdef([b4_initial_action], [
@@@ -579,9 -574,9 +580,9 @@@ b4_dollar_popdef])[]dn
      /* Read a lookahead token.  */
      if (yychar == yyempty_)
        {
 -      YYCDEBUG << "Reading a token: ";
 -      yychar = ]b4_c_function_call([yylex], [int],
 -                                   [b4_api_PREFIX[STYPE*], [&yylval]][]dnl
 +        YYCDEBUG << "Reading a token: ";
 +        yychar = ]b4_c_function_call([yylex], [int],
 +                                     [b4_api_PREFIX[STYPE*], [&yylval]][]dnl
  b4_locations_if([, [[location*], [&yylloc]]])dnl
  m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
        }
      else
        yyval = yysemantic_stack_[0];
  
 +    // Compute the default @@$.
      {
        slice<location_type, location_stack_type> slice (yylocation_stack_, yylen);
        YYLLOC_DEFAULT (yyloc, slice, yylen);
      }
 +
 +    // Perform the reduction.
      YY_REDUCE_PRINT (yyn);
      switch (yyn)
        {
 -      ]b4_user_actions[
 -      default:
 -          break;
 +        ]b4_user_actions[
 +      default:
 +        break;
        }
 +
      /* User semantic actions sometimes alter yychar, and that requires
         that yytoken be updated with the new translation.  We take the
         approach of translating immediately before every use of yytoken.
      yyerror_range[1] = yylloc;
      if (yyerrstatus_ == 3)
        {
 -      /* If just tried and failed to reuse lookahead token after an
 -       error, discard it.  */
 -
 -      if (yychar <= yyeof_)
 -        {
 -        /* Return failure if at end of input.  */
 -        if (yychar == yyeof_)
 -          YYABORT;
 -        }
 -      else
 -        {
 -          yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc);
 -          yychar = yyempty_;
 -        }
 +        /* If just tried and failed to reuse lookahead token after an
 +           error, discard it.  */
 +        if (yychar <= yyeof_)
 +          {
 +            /* Return failure if at end of input.  */
 +            if (yychar == yyeof_)
 +              YYABORT;
 +          }
 +        else
 +          {
 +            yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc);
 +            yychar = yyempty_;
 +          }
        }
  
      /* Else will try to reuse lookahead token after shifting the error
  
        /* Pop the current state because it cannot handle the error token.  */
        if (yystate_stack_.height () == 1)
 -      YYABORT;
 +        YYABORT;
  
        yyerror_range[1] = yylocation_stack_[0];
        yydestruct_ ("Error: popping",
      /* Do not reclaim the symbols of the rule which action triggered
         this YYABORT or YYACCEPT.  */
      yypop_ (yylen);
 -    while (yystate_stack_.height () != 1)
 +    while (1 < yystate_stack_.height ())
        {
 -      yydestruct_ ("Cleanup: popping",
 -                 yystos_[yystate_stack_[0]],
 -                 &yysemantic_stack_[0],
 -                 &yylocation_stack_[0]);
 -      yypop_ ();
 +        yydestruct_ ("Cleanup: popping",
 +                     yystos_[yystate_stack_[0]],
 +                     &yysemantic_stack_[0],
 +                     &yylocation_stack_[0]);
 +        yypop_ ();
        }
  
      return yyresult;
 +    }
 +    catch (...)
 +      {
 +        YYCDEBUG << "Exception caught: cleaning lookahead and stack"
 +                 << std::endl;
 +        // Do not try to display the values of the reclaimed symbols,
 +        // as their printer might throw an exception.
 +        if (yychar != yyempty_)
 +          {
 +            /* Make sure we have latest lookahead translation.  See
 +               comments at user semantic actions for why this is
 +               necessary.  */
 +            yytoken = yytranslate_ (yychar);
 +            yydestruct_ (YY_NULL, yytoken, &yylval, &yylloc);
 +          }
 +
 +        while (1 < yystate_stack_.height ())
 +          {
 +            yydestruct_ (YY_NULL,
 +                         yystos_[yystate_stack_[0]],
 +                         &yysemantic_stack_[0],
 +                         &yylocation_stack_[0]);
 +            yypop_ ();
 +          }
 +        throw;
 +      }
    }
  
    // Generate an error message.
diff --combined gnulib
index 0e6a848c8cd1e9442e3794c7dcd2f535ea9797c6,0dbbe3f55352241d290403577dfebed802d6fd9a..daf7f8c02242c535d596231e2f655109b97fa2bc
--- 1/gnulib
--- 2/gnulib
+++ b/gnulib
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit 0e6a848c8cd1e9442e3794c7dcd2f535ea9797c6
 -Subproject commit 0dbbe3f55352241d290403577dfebed802d6fd9a
++Subproject commit daf7f8c02242c535d596231e2f655109b97fa2bc
diff --combined tests/calc.at
index 647d658964b45d72e0f7e5fc67cb11ca6074e8fa,062bb45ba2958c72926f8e75adeb47fa007ecec2..4ab725b38930879f0c39177fd451411015c82098
@@@ -178,18 -178,7 +178,7 @@@ read_signed_integer (]AT_YYLEX_FORMALS[
  
  ]AT_YYLEX_PROTOTYPE[
  {
-   static int init = 1;
    int c;
-   if (init)
-     {
-       init = 0;
- ]AT_LOCATION_IF([
-       AT_LOC_LAST_COLUMN = 1;
-       AT_LOC_LAST_LINE = 1;
- ])[
-     }
    /* Skip current token, then white spaces.  */
    do
      {
@@@ -261,6 -250,8 +250,8 @@@ AT_SKEL_CC_IF
  {
    semantic_value ival;
  };
+ %printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
+                           [[fprintf (yyoutput, "%d", $$)]])[; } <ival>;
  
  %code provides
  {
  FILE *input;
  static int power (int base, int exponent);
  
- ]AT_SKEL_CC_IF(,
- [static void yyerror (AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])
-                      AT_PARAM_IF([semantic_value *result, int *count, ])
-                      const char *s
-                      );])[
+ ]AT_YYERROR_DECLARE[
  ]AT_YYLEX_DECLARE_EXTERN[
  }
  
- ]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([], [[
- /* The lalr1.cc skeleton, for backward compatibility, defines
-    a constructor for position that initializes the filename.  The
-    glr.cc skeleton does not (and in fact cannot: location/position
-    are stored in a union, from which objects with constructors are
-    excluded in C++). */
- %initial-action {
-   @$.initialize ();
- }
- ]])])[
+ ]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([[
+ %initial-action
+ {
+   @$.first.l = @$.first.c = 1;
+   @$.last = @$.first;
+ }]])])[
  
  /* Bison Declarations */
  %token CALC_EOF 0 "end of input"
@@@ -365,27 -348,8 +348,8 @@@ power (int base, int exponent
        o << '-' << s.last.c - 1;
      return o;
    }
- ]])
- AT_YYERROR_DEFINE],
- [/* A C error reporting function.  */
- static void
- yyerror (AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])
-          AT_PARAM_IF([semantic_value *result, int *count, ])
-          const char *s)
- {
- AT_PARAM_IF([(void) result; (void) count;])
- AT_YYERROR_SEES_LOC_IF([
-   fprintf (stderr, "%d.%d",
-            AT_LOC_FIRST_LINE, AT_LOC_FIRST_COLUMN);
-   if (AT_LOC_FIRST_LINE != AT_LOC_LAST_LINE)
-     fprintf (stderr, "-%d.%d",
-              AT_LOC_LAST_LINE,  AT_LOC_LAST_COLUMN - 1);
-   else if (AT_LOC_FIRST_COLUMN != AT_LOC_LAST_COLUMN - 1)
-     fprintf (stderr, "-%d",
-              AT_LOC_LAST_COLUMN - 1);
-   fprintf (stderr, ": ");])
-   fprintf (stderr, "%s\n", s);
- }])[
+ ]])])[
+ ]AT_YYERROR_DEFINE[
  ]AT_DEFINES_IF([],
  [AT_CALC_LEX
  AT_CALC_MAIN])])
@@@ -550,7 -514,7 +514,7 @@@ _AT_CHECK_CALC([$1]
                 [842])
  
  # Some syntax errors.
- _AT_CHECK_CALC_ERROR([$1], [1], [0 0], [15],
+ _AT_CHECK_CALC_ERROR([$1], [1], [1 2], [15],
                       [1.3: syntax error, unexpected number])
  _AT_CHECK_CALC_ERROR([$1], [1], [1//2], [20],
                       [1.3: syntax error, unexpected '/', expecting number or '-' or '(' or '!'])
@@@ -594,10 -558,10 +558,10 @@@ calc: error: 4444 != 1]
  
  # The same, but this time exercising explicitly triggered syntax errors.
  # POSIX says the lookahead causing the error should not be discarded.
- _AT_CHECK_CALC_ERROR([$1], [0], [(!) + (0 0) = 1], [102],
+ _AT_CHECK_CALC_ERROR([$1], [0], [(!) + (1 2) = 1], [102],
  [1.10: syntax error, unexpected number
  calc: error: 2222 != 1])
- _AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (0 0) = 1], [113],
+ _AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (1 2) = 1], [113],
  [1.4: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
  1.12: syntax error, unexpected number
  calc: error: 2222 != 1])
@@@ -713,7 -677,7 +677,7 @@@ m4_define([AT_CHECK_CALC_LALR1_CC]
  [AT_CHECK_CALC([%language "C++" %defines %locations] $@)])
  
  AT_CHECK_CALC_LALR1_CC([])
 -AT_CHECK_CALC_LALR1_CC([%define location_type Span])
 +AT_CHECK_CALC_LALR1_CC([%define api.location.type Span])
  AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
  AT_CHECK_CALC_LALR1_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
  AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc])
@@@ -742,7 -706,7 +706,7 @@@ m4_define([AT_CHECK_CALC_GLR_CC]
  [AT_CHECK_CALC([%language "C++" %glr-parser %defines %locations] $@)])
  
  AT_CHECK_CALC_GLR_CC([])
 -AT_CHECK_CALC_GLR_CC([%define location_type Span])
 +AT_CHECK_CALC_GLR_CC([%define api.location.type Span])
  AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
  AT_CHECK_CALC_GLR_CC([%error-verbose %define api.prefix "calc" %verbose %yacc])
  
diff --combined tests/glr-regression.at
index aacc57c842eaf07acd05479da4fe8006f8515180,8570b19d77082c9a3da9b276157a6ff6f9da9535..ad93d40e1b5519379b9a8ad11ebd44c0f550f650
@@@ -1543,13 -1543,6 +1543,6 @@@ AT_DATA_GRAMMAR([glr-regr17.y]
    ]AT_YYLEX_DECLARE[
  %}
  
- %initial-action {
-   @$.first_line = 1;
-   @$.first_column = 1;
-   @$.last_line = 1;
-   @$.last_column = 1;
- }
  %%
  
  /* Tests the case of an empty RHS that has inherited the location of the
@@@ -1650,10 -1643,10 +1643,10 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
 -[glr-regr18.y:26.18-24: result type clash on merge function 'merge': <type2> != <type1>
 -glr-regr18.y:25.18-24: previous declaration
 -glr-regr18.y:27.13-19: result type clash on merge function 'merge': <type3> != <type2>
 -glr-regr18.y:26.18-24: previous declaration
 +[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
 +glr-regr18.y:25.18-24:     previous declaration
 +glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
 +glr-regr18.y:26.18-24:     previous declaration
  ])
  
  AT_CLEANUP
diff --combined tests/headers.at
index 96a755831b1c84f65939a33cdd1fc72f84b5e379,a60e3153d7f198dd893c5884faa4a0ee620b52f7..8a05d34d8ddfe1cb314aa430ced0d19a30093290
@@@ -131,7 -131,7 +131,7 @@@ AT_SETUP([Several parsers]
  # self-contained, and can be compiled by a C++ compiler.
  m4_pushdef([AT_TEST],
  [AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2])
 -AT_DATA_GRAMMAR([$1.AT_SKEL_CC_IF([yy], [y])],
 +AT_DATA_GRAMMAR([$1.y],
  [[%define api.prefix "$1_"
  $2
  %error-verbose
@@@ -161,7 -161,7 +161,7 @@@ exp
  ]AT_YYLEX_DEFINE(["$1"])[
  ]])
  
 -AT_BISON_CHECK([-d -o AT_SKEL_CC_IF([$1.cc $1.yy], [$1.c $1.y])])
 +AT_BISON_CHECK([-d -o $1.AT_SKEL_CC_IF([cc], [c]) $1.y])
  
  # Check there is no 'yy' left.
  # C++ output relies on namespaces and still uses yy a lot.
@@@ -240,9 -240,6 +240,6 @@@ AT_TEST([x7], [%define api.push-pull bo
  AT_TEST([x8], [%define api.pure %define api.push-pull both])
  #AT_TEST([x5], [%locations %language "c++" %glr-parser])
  
- AT_COMPILE_CXX([parser], [[x[1-8].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
- AT_CHECK([./parser], [0], [[expout]])
  # Check that the headers are self-contained, and protected against
  # multiple inclusions.  While at it, check they are sane for C++.
  for h in *.h *.hh
@@@ -256,6 -253,12 +253,12 @@@ EO
    AT_COMPILE_CXX([$h.o])
  done
  
+ # Do this late, so that other checks have been performed.
+ AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
+ AT_COMPILE_CXX([parser], [[x[1-8].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
+ AT_CHECK([./parser], [0], [[expout]])
  m4_popdef([AT_TEST])
  
  AT_CLEANUP
diff --combined tests/input.at
index 16a9308d1e80d31a7e18ddc45ac3e6733b10f637,2848562d9e4c6e1e56b2ba08a87afb38446f8f32..35812c807be1c4b4114d8c8d208ae3dd9ee9724e
@@@ -20,6 -20,67 +20,67 @@@ AT_BANNER([[Input Processing.]]
  # Mostly test that we are robust to mistakes.
  
  
 -[[input.y:1.1: invalid character: '\0'
 -input.y:1.1: invalid character: '\001'
 -input.y:1.1: invalid character: '\002'
 -input.y:1.1: invalid character: '\377'
 -input.y:1.2: invalid character: '?'
 -input.y:3.1: invalid character: '?'
 -input.y:4.14: invalid character: '}'
 -input.y:5.1: invalid character: '%'
 -input.y:5.2: invalid character: '&'
 -input.y:6.1-17: invalid directive: '%a-does-not-exist'
 -input.y:7.1: invalid character: '%'
 -input.y:7.2: invalid character: '-'
 -input.y:8.1-9.0: missing '%}' at end of file
 -input.y:8.1-9.0: syntax error, unexpected %{...%}
+ ## ---------------- ##
+ ## Invalid inputs.  ##
+ ## ---------------- ##
+ AT_SETUP([Invalid inputs])
+ AT_DATA([input.y],
+ [[\000\001\002\377?
+ %%
+ ?
+ default: 'a' }
+ %&
+ %a-does-not-exist
+ %-
+ %{
+ ]])
+ AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y || exit 77]])
+ AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:3.1-15: syntax error, unexpected %initial-action, expecting {...}
++[[input.y:1.1: error: invalid character: '\0'
++input.y:1.1: error: invalid character: '\001'
++input.y:1.1: error: invalid character: '\002'
++input.y:1.1: error: invalid character: '\377'
++input.y:1.2: error: invalid character: '?'
++input.y:3.1: error: invalid character: '?'
++input.y:4.14: error: invalid character: '}'
++input.y:5.1: error: invalid character: '%'
++input.y:5.2: error: invalid character: '&'
++input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
++input.y:7.1: error: invalid character: '%'
++input.y:7.2: error: invalid character: '-'
++input.y:8.1-9.0: error: missing '%}' at end of file
++input.y:8.1-9.0: error: syntax error, unexpected %{...%}
+ ]])
+ AT_CLEANUP
+ AT_SETUP([Invalid inputs with {}])
+ # We used to SEGV here.  See
+ # http://lists.gnu.org/archive/html/bug-bison/2005-07/msg00053.html
+ AT_DATA([input.y],
+ [[
+ %destructor
+ %initial-action
+ %lex-param
+ %parse-param
+ %printer
+ %union
+ ]])
+ AT_BISON_CHECK([input.y], [1], [],
++[[input.y:3.1-15: error: syntax error, unexpected %initial-action, expecting {...}
+ ]])
+ AT_CLEANUP
  ## ------------ ##
  ## Invalid $n.  ##
  ## ------------ ##
@@@ -33,8 -94,8 +94,8 @@@ exp: { @$ = @1 ; }
  ]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:2.13-14: integer out of range: '$1'
 -input.y:3.13-14: integer out of range: '@1'
 +[[input.y:2.13-14: error: integer out of range: '$1'
 +input.y:3.13-14: error: integer out of range: '@1'
  ]])
  
  AT_CLEANUP
@@@ -58,8 -119,8 +119,8 @@@ exp: foo { $$; } foo { $2; } fo
  ]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:5.12-13: $$ for the midrule at $2 of 'exp' has no declared type
 -input.y:5.24-25: $2 of 'exp' has no declared type
 +[[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
@@@ -205,30 -266,30 +266,30 @@@ start: 
  ]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:1.13-29: redeclaration for default tagged %destructor
 -input.y:1.13-29: previous declaration
 -input.y:2.10-24: redeclaration for default tagged %printer
 -input.y:2.10-24: previous declaration
 -input.y:4.13-29: redeclaration for default tagged %destructor
 -input.y:1.13-29: previous declaration
 -input.y:5.10-24: redeclaration for default tagged %printer
 -input.y:2.10-24: previous declaration
 -input.y:7.13-29: redeclaration for default tagless %destructor
 -input.y:7.13-29: previous declaration
 -input.y:8.10-24: redeclaration for default tagless %printer
 -input.y:8.10-24: previous declaration
 -input.y:10.13-29: redeclaration for default tagless %destructor
 -input.y:7.13-29: previous declaration
 -input.y:11.10-24: redeclaration for default tagless %printer
 -input.y:8.10-24: previous declaration
 -input.y:17.13-29: redeclaration for default tagged %destructor
 -input.y:4.13-29: previous declaration
 -input.y:18.10-24: redeclaration for default tagged %printer
 -input.y:5.10-24: previous declaration
 -input.y:20.13-29: redeclaration for default tagless %destructor
 -input.y:10.13-29: previous declaration
 -input.y:21.10-24: redeclaration for default tagless %printer
 -input.y:11.10-24: previous declaration
 +[[input.y:1.13-29: error: redeclaration for default tagged %destructor
 +input.y:1.13-29:     previous declaration
 +input.y:2.10-24: error: redeclaration for default tagged %printer
 +input.y:2.10-24:     previous declaration
 +input.y:4.13-29: error: redeclaration for default tagged %destructor
 +input.y:1.13-29:     previous declaration
 +input.y:5.10-24: error: redeclaration for default tagged %printer
 +input.y:2.10-24:     previous declaration
 +input.y:7.13-29: error: redeclaration for default tagless %destructor
 +input.y:7.13-29:     previous declaration
 +input.y:8.10-24: error: redeclaration for default tagless %printer
 +input.y:8.10-24:     previous declaration
 +input.y:10.13-29: error: redeclaration for default tagless %destructor
 +input.y:7.13-29:      previous declaration
 +input.y:11.10-24: error: redeclaration for default tagless %printer
 +input.y:8.10-24:      previous declaration
 +input.y:17.13-29: error: redeclaration for default tagged %destructor
 +input.y:4.13-29:      previous declaration
 +input.y:18.10-24: error: redeclaration for default tagged %printer
 +input.y:5.10-24:      previous declaration
 +input.y:20.13-29: error: redeclaration for default tagless %destructor
 +input.y:10.13-29:     previous declaration
 +input.y:21.10-24: error: redeclaration for default tagless %printer
 +input.y:11.10-24:     previous declaration
  ]])
  
  AT_CLEANUP
@@@ -256,22 -317,22 +317,22 @@@ start: 
  ]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:4.13-29: %destructor redeclaration for <field1>
 -input.y:1.13-29: previous declaration
 -input.y:4.13-29: %destructor redeclaration for <field1>
 -input.y:4.13-29: previous declaration
 -input.y:5.10-24: %printer redeclaration for <field2>
 -input.y:2.10-24: previous declaration
 -input.y:5.10-24: %printer redeclaration for <field2>
 -input.y:5.10-24: previous declaration
 -input.y:11.13-29: %destructor redeclaration for <field1>
 -input.y:4.13-29: previous declaration
 -input.y:11.13-29: %destructor redeclaration for <field2>
 -input.y:1.13-29: previous declaration
 -input.y:12.10-24: %printer redeclaration for <field1>
 -input.y:2.10-24: previous declaration
 -input.y:12.10-24: %printer redeclaration for <field2>
 -input.y:5.10-24: previous declaration
 +[[input.y:4.13-29: error: %destructor redeclaration for <field1>
 +input.y:1.13-29:     previous declaration
 +input.y:4.13-29: error: %destructor redeclaration for <field1>
 +input.y:4.13-29:     previous declaration
 +input.y:5.10-24: error: %printer redeclaration for <field2>
 +input.y:2.10-24:     previous declaration
 +input.y:5.10-24: error: %printer redeclaration for <field2>
 +input.y:5.10-24:     previous declaration
 +input.y:11.13-29: error: %destructor redeclaration for <field1>
 +input.y:4.13-29:      previous declaration
 +input.y:11.13-29: error: %destructor redeclaration for <field2>
 +input.y:1.13-29:      previous declaration
 +input.y:12.10-24: error: %printer redeclaration for <field1>
 +input.y:2.10-24:      previous declaration
 +input.y:12.10-24: error: %printer redeclaration for <field2>
 +input.y:5.10-24:      previous declaration
  ]])
  
  AT_CLEANUP
@@@ -368,14 -429,14 +429,14 @@@ exp: foo
  ]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:8.7-11: %type redeclaration for foo
 -input.y:3.7-11: previous declaration
 -input.y:10.13-17: %destructor redeclaration for foo
 -input.y:5.13-17: previous declaration
 -input.y:9.10-14: %printer redeclaration for foo
 -input.y:4.10-14: previous declaration
 -input.y:11.1-5: %left redeclaration for foo
 -input.y:6.1-5: previous declaration
 +[[input.y:8.7-11: error: %type redeclaration for foo
 +input.y:3.7-11:     previous declaration
 +input.y:10.13-17: error: %destructor redeclaration for foo
 +input.y:5.13-17:      previous declaration
 +input.y:9.10-14: error: %printer redeclaration for foo
 +input.y:4.10-14:     previous declaration
 +input.y:11.1-5: error: %left redeclaration for foo
 +input.y:6.1-5:      previous declaration
  ]])
  
  AT_CLEANUP
@@@ -394,7 -455,7 +455,7 @@@ AT_SETUP([Torturing the Scanner]
  AT_BISON_OPTION_PUSHDEFS
  AT_DATA([input.y], [])
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:1.1: syntax error, unexpected end of file
 +[[input.y:1.1: error: syntax error, unexpected end of file
  ]])
  
  
@@@ -402,7 -463,7 +463,7 @@@ AT_DATA([input.y]
  [{}
  ])
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:1.1-2: syntax error, unexpected {...}
 +[[input.y:1.1-2: error: syntax error, unexpected {...}
  ]])
  
  
@@@ -668,9 -729,9 +729,9 @@@ AT_DATA_GRAMMAR([input.y]
  start: .GOOD GOOD
  ]])
  AT_BISON_CHECK([-o input.c input.y], [1], [],
 -[[input.y:10.10: invalid character: '-'
 -input.y:11.10-16: invalid identifier: '1NV4L1D'
 -input.y:12.10: invalid character: '-'
 +[[input.y:10.10: error: invalid character: '-'
 +input.y:11.10-16: error: invalid identifier: '1NV4L1D'
 +input.y:12.10: error: invalid character: '-'
  ]])
  
  AT_CLEANUP
@@@ -692,10 -753,10 +753,10 @@@ start: DECIMAL_1 HEXADECIMAL_2
  ]])
  
  AT_BISON_CHECK([redecl.y], [1], [],
 -[[redecl.y:10.10-22: user token number 11259375 redeclaration for HEXADECIMAL_1
 -redecl.y:9.8-16: previous declaration for DECIMAL_1
 -redecl.y:12.10-18: user token number 16702650 redeclaration for DECIMAL_2
 -redecl.y:11.10-22: previous declaration for HEXADECIMAL_2
 +[[redecl.y:10.10-22: error: user token number 11259375 redeclaration for HEXADECIMAL_1
 +redecl.y:9.8-16:       previous declaration for DECIMAL_1
 +redecl.y:12.10-18: error: user token number 16702650 redeclaration for DECIMAL_2
 +redecl.y:11.10-22:     previous declaration for HEXADECIMAL_2
  ]])
  
  AT_DATA_GRAMMAR([too-large.y],
@@@ -707,8 -768,8 +768,8 @@@ start: TOO_LARGE_DEC TOO_LARGE_HE
  ]])
  
  AT_BISON_CHECK([too-large.y], [1], [],
 -[[too-large.y:9.22-42: integer out of range: '999999999999999999999'
 -too-large.y:10.24-44: integer out of range: '0xFFFFFFFFFFFFFFFFFFF'
 +[[too-large.y:9.22-42: error: integer out of range: '999999999999999999999'
 +too-large.y:10.24-44: error: integer out of range: '0xFFFFFFFFFFFFFFFFFFF'
  ]])
  
  AT_CLEANUP
@@@ -748,12 -809,12 +809,12 @@@ start: 
  ]])
  
  AT_BISON_CHECK([-o input.c input.y], 1, [],
 -[[input.y:1.10-2.0: missing '"' at end of line
 -input.y:4.10-5.0: missing "'" at end of line
 -input.y:14.11-15.0: missing "'" at end of line
 -input.y:16.11-17.0: missing '"' at end of line
 -input.y:19.13-20.0: missing '}' at end of file
 -input.y:20.1: syntax error, unexpected end of file
 +[[input.y:1.10-2.0: error: missing '"' at end of line
 +input.y:4.10-5.0: error: missing "'" at end of line
 +input.y:14.11-15.0: error: missing "'" at end of line
 +input.y:16.11-17.0: error: missing '"' at end of line
 +input.y:19.13-20.0: error: missing '}' at end of file
 +input.y:20.1: error: syntax error, unexpected end of file
  ]])
  
  AT_CLEANUP
@@@ -795,7 -856,7 +856,7 @@@ PREC: 
  ]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:3.1-4: rule given for PREC, which is a token
 +[[input.y:3.1-4: error: rule given for PREC, which is a token
  ]])
  
  AT_CLEANUP
@@@ -836,10 -897,10 +897,10 @@@ AT_DATA([input-c.y]
  start: ;
  ]])
  AT_BISON_CHECK([[input-c.y]], [[1]], [],
 -[[input-c.y:1.7: %code qualifier 'q' is not used
 -input-c.y:2.7-9: %code qualifier 'bad' is not used
 -input-c.y:3.7-9: %code qualifier 'bad' is not used
 -input-c.y:4.7-12: %code qualifier 'format' is not used
 +[[input-c.y:1.7: error: %code qualifier 'q' is not used
 +input-c.y:2.7-9: error: %code qualifier 'bad' is not used
 +input-c.y:3.7-9: error: %code qualifier 'bad' is not used
 +input-c.y:4.7-12: error: %code qualifier 'format' is not used
  ]])
  
  AT_DATA([input-c-glr.y],
  start: ;
  ]])
  AT_BISON_CHECK([[input-c-glr.y]], [[1]], [],
 -[[input-c-glr.y:1.7: %code qualifier 'q' is not used
 -input-c-glr.y:2.7-9: %code qualifier 'bad' is not used
 -input-c-glr.y:3.8-10: %code qualifier 'bad' is not used
 +[[input-c-glr.y:1.7: error: %code qualifier 'q' is not used
 +input-c-glr.y:2.7-9: error: %code qualifier 'bad' is not used
 +input-c-glr.y:3.8-10: error: %code qualifier 'bad' is not used
  ]])
  
  AT_DATA([input-c++.y],
  start: ;
  ]])
  AT_BISON_CHECK([[input-c++.y]], [[1]], [],
 -[[input-c++.y:1.7: %code qualifier 'q' is not used
 -input-c++.y:2.7-9: %code qualifier 'bad' is not used
 -input-c++.y:3.8: %code qualifier 'q' is not used
 +[[input-c++.y:1.7: error: %code qualifier 'q' is not used
 +input-c++.y:2.7-9: error: %code qualifier 'bad' is not used
 +input-c++.y:3.8: error: %code qualifier 'q' is not used
  ]])
  
  AT_DATA([input-c++-glr.y],
  start: ;
  ]])
  AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [],
 -[[input-c++-glr.y:1.7-9: %code qualifier 'bad' is not used
 -input-c++-glr.y:2.7: %code qualifier 'q' is not used
 -input-c++-glr.y:3.7: %code qualifier 'q' is not used
 +[[input-c++-glr.y:1.7-9: error: %code qualifier 'bad' is not used
 +input-c++-glr.y:2.7: error: %code qualifier 'q' is not used
 +input-c++-glr.y:3.7: error: %code qualifier 'q' is not used
  ]])
  
  AT_DATA([special-char-@@.y],
  start: ;
  ]])
  AT_BISON_CHECK([[special-char-@@.y]], [[1]], [],
 -[[special-char-@@.y:1.7-9: %code qualifier 'bad' is not used
 -special-char-@@.y:2.7: %code qualifier 'q' is not used
 -special-char-@@.y:3.7: %code qualifier 'q' is not used
 +[[special-char-@@.y:1.7-9: error: %code qualifier 'bad' is not used
 +special-char-@@.y:2.7: error: %code qualifier 'q' is not used
 +special-char-@@.y:3.7: error: %code qualifier 'q' is not used
  ]])
  
  AT_DATA([special-char-@:>@.y],
  start: ;
  ]])
  AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [],
 -[[special-char-@:>@.y:1.7-9: %code qualifier 'bad' is not used
 -special-char-@:>@.y:2.7: %code qualifier 'q' is not used
 -special-char-@:>@.y:3.7: %code qualifier 'q' is not used
 +[[special-char-@:>@.y:1.7-9: error: %code qualifier 'bad' is not used
 +special-char-@:>@.y:2.7: error: %code qualifier 'q' is not used
 +special-char-@:>@.y:3.7: error: %code qualifier 'q' is not used
  ]])
  
  AT_CLEANUP
@@@ -927,10 -988,10 +988,10 @@@ start: 
  ]])
  
  AT_BISON_CHECK([[input-redefined.y]], [[1]], [],
 -[[input-redefined.y:2.9-11: %define variable 'var' redefined
 -input-redefined.y:1.9-11: previous definition
 -input-redefined.y:3.10-12: %define variable 'var' redefined
 -input-redefined.y:2.9-11: previous definition
 +[[input-redefined.y:2.9-11: error: %define variable 'var' redefined
 +input-redefined.y:1.9-11:     previous definition
 +input-redefined.y:3.10-12: error: %define variable 'var' redefined
 +input-redefined.y:2.9-11:      previous definition
  ]])
  
  AT_DATA([input-unused.y],
@@@ -940,7 -1001,7 +1001,7 @@@ start: 
  ]])
  
  AT_BISON_CHECK([[input-unused.y]], [[1]], [],
 -[[input-unused.y:1.9-11: %define variable 'var' is not used
 +[[input-unused.y:1.9-11: error: %define variable 'var' is not used
  ]])
  
  AT_CLEANUP
@@@ -984,8 -1045,8 +1045,8 @@@ AT_DATA([[input-dg.y]]
  start: ;
  ]])
  AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
 -[[input-dg.y:1.9-11: %define variable 'var' redefined
 -<command line>:2: previous definition
 +[[input-dg.y:1.9-11: error: %define variable 'var' redefined
 +<command line>:2:      previous definition
  ]])
  
  AT_DATA([[input-unused.y]],
  start: ;
  ]])
  AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [],
 -[[<command line>:2: %define variable 'unused-d' is not used
 -<command line>:3: %define variable 'unused-f' is not used
 +[[<command line>:2: error: %define variable 'unused-d' is not used
 +<command line>:3: error: %define variable 'unused-f' is not used
  ]])
  
  AT_CLEANUP
@@@ -1014,7 -1075,7 +1075,7 @@@ start: 
  ]])
  
  AT_BISON_CHECK([[Input.y]], [1], [],
 -[[Input.y:2.9-14: invalid value for %define Boolean variable 'public'
 +[[Input.y:2.9-14: error: invalid value for %define Boolean variable 'public'
  ]])
  
  AT_CLEANUP
@@@ -1032,24 -1093,23 +1093,24 @@@ AT_DATA([[input.y]]
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [[1]], [[]],
 -[[input.y:1.9-29: 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-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'
  ]])
  
  # Back-end.
 +# FIXME: these should be indented, but we shouldn't mess with the m4 yet
  AT_DATA([[input.y]],
  [[%define api.push-pull neither
  %%
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [1], [],
 -[[input.y:1.9-21: 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'
 +[[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'
  ]])
  
  AT_CLEANUP
@@@ -1069,10 -1129,10 +1130,10 @@@ AT_DATA([[input.y]]
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [1], [],
 -[[input.y:1.9-21: 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'
 +[[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'
  ]])
  
  AT_DATA([[input.y]],
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [1], [],
 -[[input.y:1.9-34: invalid value for %define Boolean variable 'lr.keep-unreachable-states'
 +[[input.y:1.9-34: error: invalid value for %define Boolean variable 'lr.keep-unreachable-states'
  ]])
  
  AT_DATA([[input.y]],
  start: ;
  ]])
  AT_BISON_CHECK([[input.y]], [[1]], [],
 -[[input.y:1.9-15: %define variable 'foo_bar' is not used
 +[[input.y:1.9-15: error: %define variable 'foo_bar' is not used
  ]])
  
  AT_CLEANUP
@@@ -1115,7 -1175,7 +1176,7 @@@ start: 
  ]])
  
  AT_BISON_CHECK([[input.y]], [[1]], [],
 -[[input.y:1.9-16: %define variable 'api.pure' is not used
 +[[input.y:1.9-16: error: %define variable 'api.pure' is not used
  ]])
  ])
  
@@@ -1149,7 -1209,7 +1210,7 @@@ start: 
  
  AT_BISON_CHECK([[input.y]], [1], [],
  [m4_foreach([b4_arg], m4_dquote(m4_shift($@)),
 -[[input.y:3.9-17: ]b4_arg[
 +[[input.y:3.9-17: error: ]b4_arg[
  ]])])
  ])
  
@@@ -1200,9 -1260,9 +1261,9 @@@ AT_CHECK([[$PERL -e "print 'start: \'';
  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:3.8-4.0: missing "'" at end of line
 +empty.y:3.8-4.0: error: missing "'" at end of line
  empty.y:4.8: warning: empty character literal
 -empty.y:4.8: missing "'" at end of file
 +empty.y:4.8: error: missing "'" at end of file
  ]])
  
  AT_DATA([two.y],
@@@ -1215,9 -1275,9 +1276,9 @@@ AT_CHECK([[$PERL -e "print 'start: \'ab
  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:3.8-4.0: missing "'" at end of line
 +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: missing "'" at end of file
 +two.y:4.8-10: error: missing "'" at end of file
  ]])
  
  AT_DATA([three.y],
@@@ -1230,9 -1290,9 +1291,9 @@@ AT_CHECK([[$PERL -e "print 'start: \'ab
  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:3.8-4.0: missing "'" at end of line
 +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: missing "'" at end of file
 +three.y:4.8-11: error: missing "'" at end of file
  ]])
  
  AT_CLEANUP
@@@ -1258,30 -1318,30 +1319,30 @@@ AT_CHECK([[$PERL -e 'print "start: \"\\
             || exit 77]])
  
  AT_BISON_CHECK([input.y], [1], [],
 -[[input.y:2.9-12: invalid number after \-escape: 777
 +[[input.y:2.9-12: error: invalid number after \-escape: 777
  input.y:2.8-13: warning: empty character literal
 -input.y:2.16-17: invalid number after \-escape: 0
 +input.y:2.16-17: error: invalid number after \-escape: 0
  input.y:2.15-18: warning: empty character literal
 -input.y:2.21-25: invalid number after \-escape: xfff
 +input.y:2.21-25: error: invalid number after \-escape: xfff
  input.y:2.20-26: warning: empty character literal
 -input.y:2.29-31: invalid number after \-escape: x0
 +input.y:2.29-31: error: invalid number after \-escape: x0
  input.y:2.28-32: warning: empty character literal
 -input.y:3.9-14: invalid number after \-escape: uffff
 +input.y:3.9-14: error: invalid number after \-escape: uffff
  input.y:3.8-15: warning: empty character literal
 -input.y:3.18-23: invalid number after \-escape: u0000
 +input.y:3.18-23: error: invalid number after \-escape: u0000
  input.y:3.17-24: warning: empty character literal
 -input.y:3.27-36: invalid number after \-escape: Uffffffff
 +input.y:3.27-36: error: invalid number after \-escape: Uffffffff
  input.y:3.26-37: warning: empty character literal
 -input.y:3.40-49: invalid number after \-escape: U00000000
 +input.y:3.40-49: error: invalid number after \-escape: U00000000
  input.y:3.39-50: warning: empty character literal
 -input.y:4.9-10: invalid character after \-escape: ' '
 +input.y:4.9-10: error: invalid character after \-escape: ' '
  input.y:4.8-11: warning: empty character literal
 -input.y:4.14-15: invalid character after \-escape: A
 +input.y:4.14-15: error: invalid character after \-escape: A
  input.y:4.13-16: warning: empty character literal
 -input.y:5.9-16: invalid character after \-escape: \t
 -input.y:5.17: invalid character after \-escape: \f
 -input.y:5.18: invalid character after \-escape: \0
 -input.y:5.19: invalid character after \-escape: \001
 +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
 +input.y:5.19: error: invalid character after \-escape: \001
  ]])
  
  AT_CLEANUP
@@@ -1300,11 -1360,11 +1361,11 @@@ start: 
  # parse.lac.* options are useless if LAC isn't actually activated.
  AT_BISON_CHECK([[-Dparse.lac.es-capacity-initial=1 input.y]],
                 [[1]], [],
 -[[<command line>:2: %define variable 'parse.lac.es-capacity-initial' is not used
 +[[<command line>:2: error: %define variable 'parse.lac.es-capacity-initial' is not used
  ]])
  AT_BISON_CHECK([[-Dparse.lac.memory-trace=full input.y]],
                 [[1]], [],
 -[[<command line>:2: %define variable 'parse.lac.memory-trace' is not used
 +[[<command line>:2: error: %define variable 'parse.lac.memory-trace' is not used
  ]])
  
  AT_CLEANUP
@@@ -1358,7 -1418,7 +1419,7 @@@ m4_pushdef([AT_TEST]
  exp:;
  ]])
  AT_BISON_CHECK([[$2 input.y]], [[1]], [[]],
 -[[$3: '%name-prefix' and '%define api.prefix' cannot be used together
 +[[$3: error: '%name-prefix' and '%define api.prefix' cannot be used together
  ]])
  ])
  
diff --combined tests/local.at
index f172b2445055dc87b7d1deefff793024c3b5f865,88825210e7c0b5d39bed4b291a899eead3cd401f..e2fd1beb5a31e1febf0b0b8834df700e54bc312d
@@@ -119,6 -119,7 +119,7 @@@ m4_pushdef([AT_SKEL_CC_IF]
  [m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
  m4_pushdef([AT_SKEL_JAVA_IF],
  [m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])])
+ # The target language: "c", "c++", or "java".
  m4_pushdef([AT_LANG],
  [AT_SKEL_JAVA_IF([java],
                   [AT_SKEL_CC_IF([c++],
@@@ -137,9 -138,15 +138,15 @@@ m4_pushdef([AT_LEXPARAM_IF]
  m4_pushdef([AT_LOCATION_IF],
  [m4_bmatch([$3], [%locations], [$1], [$2])])
  m4_pushdef([AT_LOCATION_TYPE_IF],
 -[m4_bmatch([$3], [%define location_type], [$1], [$2])])
 +[m4_bmatch([$3], [%define \(api\.location\.type\|location_type\)], [$1], [$2])])
  m4_pushdef([AT_PARAM_IF],
  [m4_bmatch([$3], [%parse-param], [$1], [$2])])
+ # Comma-terminated list of formals parse-parameters.
+ # E.g., %parse-param { int x } {int y} -> "int x, int y, ".
+ m4_pushdef([AT_PARSE_PARAMS])
+ m4_bpatsubst([$3], [%parse-param { *\([^{}]*[^{} ]\) *}],
+              [m4_append([AT_PARSE_PARAMS], [\1, ])])
  m4_pushdef([AT_PURE_IF],
  [m4_bmatch([$3], [%define  *api\.pure\|%pure-parser],
             [m4_bmatch([$3], [%define  *api\.pure *"?false"?], [$2], [$1])],
@@@ -241,6 -248,7 +248,7 @@@ m4_popdef([AT_GLR_OR_PARAM_IF]
  m4_popdef([AT_PURE_AND_LOC_IF])
  m4_popdef([AT_LOCATION_TYPE_IF])
  m4_popdef([AT_LOCATION_IF])
+ m4_popdef([AT_PARSE_PARAMS])
  m4_popdef([AT_PARAM_IF])
  m4_popdef([AT_LEXPARAM_IF])
  m4_popdef([AT_YACC_IF])
@@@ -350,7 -358,7 +358,7 @@@ stati
  # Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
  m4_define([AT_YYERROR_FORMALS],
  [m4_case(AT_LANG,
- [c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])[const char *msg]])[]dnl
+ [c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])AT_PARSE_PARAMS [const char *msg]])[]dnl
  ])
  
  m4_define([AT_YYERROR_PROTOTYPE],
@@@ -374,16 -382,11 +382,11 @@@ m4_define([AT_YYERROR_DEFINE]
  /* A C error reporting function.  */
  static
  ]AT_YYERROR_PROTOTYPE[
- {
- ]AT_YYERROR_SEES_LOC_IF([[
-   fprintf (stderr, "%d.%d",
-            ]AT_LOC_FIRST_LINE[, ]AT_LOC_FIRST_COLUMN[);
-   if (]AT_LOC_FIRST_LINE[ != ]AT_LOC_LAST_LINE[)
-     fprintf (stderr, "-%d.%d",
-              ]AT_LOC_LAST_LINE[,  ]AT_LOC_LAST_COLUMN[ - 1);
-   else if (]AT_LOC_FIRST_COLUMN[ != ]AT_LOC_LAST_COLUMN[ - 1)
-     fprintf (stderr, "-%d",
-              ]AT_LOC_LAST_COLUMN[ - 1);
+ {]m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]),
+               [[^,]+[^A-Za-z_0-9]\([A-Za-z_][A-Za-z_0-9]*\), *], [
+   YYUSE(\1);])dnl
+ AT_YYERROR_SEES_LOC_IF([[
+   YY_LOCATION_PRINT (stderr, ]AT_LOC[);
    fprintf (stderr, ": ");]])[
    fprintf (stderr, "%s\n", msg);
  }]],
@@@ -680,6 -683,44 +683,44 @@@ m4_define([AT_FULL_COMPILE]
  ])
  
  
+ # AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
+ # --------------------------------
+ # Check that we can link together C and C++ objects.
+ m4_define([AT_SKIP_IF_CANNOT_LINK_C_AND_CXX],
+ [AT_DATA([c-and-cxx.h],
+ [[#ifdef __cplusplus
+ extern "C"
+ {
+ #endif
+   int fortytwo (void);
+ #ifdef __cplusplus
+ }
+ #endif
+ ]])
+ AT_DATA([c-only.c],
+ [[#include "c-and-cxx.h"
+ int
+ main (void)
+ {
+   return fortytwo () == 42 ? 0 : 1;
+ }
+ ]])
+ AT_DATA([cxx-only.cc],
+ [[#include "c-and-cxx.h"
+ int fortytwo ()
+ {
+   return 42;
+ }
+ ]])
+ AT_COMPILE([c-only.o], [c-only.c])
+ AT_COMPILE_CXX([cxx-only.o], [cxx-only.cc])
+ AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS $LDFLAGS c-only.o cxx-only.o -o c-and-cxx ||
+           exit 77], [ignore], [ignore])
+ AT_CHECK([./c-and-cxx])
+ ])
  ## ---------------------------- ##
  ## Running a generated parser.  ##
  ## ---------------------------- ##
diff --combined tests/named-refs.at
index d76e75f3a26164fb1e59d55518fd2c2b6b4a2591,744eab823e8087097e673ce6c473e0f0c3f3a1ba..9582c01d16260bd34f76d0f781bf1756ffc10c38
@@@ -251,16 -251,16 +251,16 @@@ exp
  ]])
  
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:50.51-60: invalid reference: '$<ival>lo9'
 +[[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:42.1-3:       warning: refers to: $exp at $$
 -test.y:51.7:         warning: possibly meant: $x, hiding $exp at $1
 -test.y:51.41:        warning: possibly meant: $r, hiding $exp at $4
 -test.y:52.51-52: $l of 'exp' has no declared type
 -test.y:55.46-49: invalid reference: '$r12'
 +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
 +test.y:52.51-52: error: $l of 'exp' has no declared type
 +test.y:55.46-49: error: invalid reference: '$r12'
  test.y:55.3-53:      symbol not found in production: r12
 -test.y:56.29-33: invalid reference: '$expo'
 +test.y:56.29-33: error: invalid reference: '$expo'
  test.y:56.3-46:      symbol not found in production: expo
  ]])
  AT_BISON_OPTION_POPDEFS
@@@ -278,8 -278,8 +278,8 @@@ 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.8-10:      warning: refers to: $foo at $1
 -test.y:11.12-18:     warning: possibly meant: $[foo.bar] at $2
 +test.y:11.8-10:      refers to: $foo at $1
 +test.y:11.12-18:     possibly meant: $[foo.bar] at $2
  ]])
  AT_CLEANUP
  
@@@ -353,43 -353,43 +353,43 @@@ factor:     '(' expr ')'  { $$ = $2; 
      ;
  ]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:24.36-41: invalid reference: '$cond1'
 +[[test.y:24.36-41: error: invalid reference: '$cond1'
  test.y:23.11-24.62:  symbol not found in production: cond1
 -test.y:26.43-53: invalid reference: '$stmt.field'
 +test.y:26.43-53: error: invalid reference: '$stmt.field'
  test.y:25.11-26.60:  symbol not found in production: stmt
  test.y:25.35-38:     possibly meant: $then.field, hiding $stmt.field at $4
 -test.y:28.43-52: invalid reference: '$stmt.list'
 +test.y:28.43-52: error: invalid reference: '$stmt.list'
  test.y:27.11-28.59:  symbol not found in production: stmt
  test.y:27.30-38:     possibly meant: $[stmt.list] at $4
 -test.y:30.43-46: ambiguous reference: '$xyz'
 +test.y:30.43-46: error: ambiguous reference: '$xyz'
  test.y:29.35-37:     refers to: $xyz at $4
  test.y:29.50-52:     refers to: $xyz at $6
 -test.y:32.43-52: invalid reference: '$stmt.list'
 +test.y:32.43-52: error: invalid reference: '$stmt.list'
  test.y:31.11-32.63:  symbol not found in production: stmt
  test.y:31.40-43:     possibly meant: $then, hiding $[stmt.list] at $4
  test.y:31.61-64:     possibly meant: $else, hiding $[stmt.list] at $6
 -test.y:34.43-58: invalid reference: '$stmt.list.field'
 +test.y:34.43-58: error: invalid reference: '$stmt.list.field'
  test.y:33.11-34.69:  symbol not found in production: stmt
  test.y:33.40-43:     possibly meant: $then.field, hiding $[stmt.list].field at $4
  test.y:33.61-64:     possibly meant: $else.field, hiding $[stmt.list].field at $6
 -test.y:36.43-54: invalid reference: '$[stmt.list]'
 +test.y:36.43-54: error: invalid reference: '$[stmt.list]'
  test.y:35.11-36.71:  symbol not found in production: stmt.list
  test.y:35.40-43:     possibly meant: $then, hiding $[stmt.list] at $4
  test.y:35.61-64:     possibly meant: $else, hiding $[stmt.list] at $6
 -test.y:38.43-49: invalid reference: '$then.1'
 +test.y:38.43-49: error: invalid reference: '$then.1'
  test.y:37.11-38.60:  symbol not found in production: then
  test.y:37.40-45:     possibly meant: $[then.1] at $4
 -test.y:40.43-55: invalid reference: '$then.1.field'
 +test.y:40.43-55: error: invalid reference: '$then.1.field'
  test.y:39.11-40.66:  symbol not found in production: then
  test.y:39.40-45:     possibly meant: $[then.1].field at $4
 -test.y:42.44-50: invalid reference: '$stmt.x'
 +test.y:42.44-50: error: invalid reference: '$stmt.x'
  test.y:41.12-42.57:  symbol not found in production: stmt
  test.y:41.36-41:     possibly meant: $[stmt.x].x, hiding $stmt.x at $4
  test.y:41.36-41:     possibly meant: $[stmt.x] at $4
 -test.y:44.13-22: invalid reference: '$if-stmt-a'
 +test.y:44.13-22: error: invalid reference: '$if-stmt-a'
  test.y:43.12-44.59:  symbol not found in production: if
  test.y:43.1-9:       possibly meant: $[if-stmt-a] at $$
 -test.y:46.46-54: invalid reference: '$then-a.f'
 +test.y:46.46-54: error: invalid reference: '$then-a.f'
  test.y:45.12-46.65:  symbol not found in production: then
  test.y:45.41-46:     possibly meant: $[then-a].f at $4
  ]])
@@@ -405,7 -405,7 +405,7 @@@ start: foo[] ba
    { s = $foo; }
  ]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:11.12: an identifier expected
 +[[test.y:11.12: error: an identifier expected
  ]])
  AT_CLEANUP
  
@@@ -419,7 -419,7 +419,7 @@@ start: foo[ a d ] ba
    { s = $foo; }
  ]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:11.15: unexpected identifier in bracketed name: 'd'
 +[[test.y:11.15: error: unexpected identifier in bracketed name: 'd'
  ]])
  AT_CLEANUP
  
@@@ -433,7 -433,7 +433,7 @@@ start: foo[/* comment */] ba
    { s = $foo; }
  ]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:11.25: an identifier expected
 +[[test.y:11.25: error: an identifier expected
  ]])
  AT_CLEANUP
  
@@@ -443,14 -443,19 +443,19 @@@ AT_SETUP([Stray symbols in brackets]
  AT_DATA_GRAMMAR([test.y],
  [[
  %%
- start: foo[ /* aaa */ *&-.+ ] bar
+ start: foo[ /* aaa */ *&-.+\000\001\002\377 ] bar
    { s = $foo; }
  ]])
+ AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' test.y || exit 77]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:11.23: invalid character in bracketed name: '*'
 -test.y:11.24: invalid character in bracketed name: '&'
 -test.y:11.25: invalid character in bracketed name: '-'
 -test.y:11.27: invalid character in bracketed name: '+'
 -test.y:11.28: invalid character in bracketed name: '\0'
 -test.y:11.28: invalid character in bracketed name: '\001'
 -test.y:11.28: invalid character in bracketed name: '\002'
 -test.y:11.28: invalid character in bracketed name: '\377'
 +[[test.y:11.23: error: invalid character in bracketed name: '*'
 +test.y:11.24: error: invalid character in bracketed name: '&'
 +test.y:11.25: error: invalid character in bracketed name: '-'
 +test.y:11.27: error: invalid character in bracketed name: '+'
++test.y:11.28: error: invalid character in bracketed name: '\0'
++test.y:11.28: error: invalid character in bracketed name: '\001'
++test.y:11.28: error: invalid character in bracketed name: '\002'
++test.y:11.28: error: invalid character in bracketed name: '\377'
  ]])
  AT_CLEANUP
  
@@@ -463,7 -468,7 +468,7 @@@ AT_DATA_GRAMMAR([test.y]
  start[a s]: foo;
  ]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:11.9: unexpected identifier in bracketed name: 's'
 +[[test.y:11.9: error: unexpected identifier in bracketed name: 's'
  ]])
  AT_CLEANUP
  
@@@ -510,37 -515,37 +515,37 @@@ sym_a: 'a'
  sym_b: 'b';
  ]])
  AT_BISON_CHECK([-o test.c test.y], 1, [],
 -[[test.y:12.22-31: invalid reference: '$sym.field'
 +[[test.y:12.22-31: error: invalid reference: '$sym.field'
  test.y:12.3-35:      symbol not found in production: sym
 -test.y:13.22-35: invalid reference: '$<aa>sym.field'
 +test.y:13.22-35: error: invalid reference: '$<aa>sym.field'
  test.y:13.3-39:      symbol not found in production: sym
 -test.y:14.22-33: invalid reference: '$[sym.field]'
 +test.y:14.22-33: error: invalid reference: '$[sym.field]'
  test.y:14.3-37:      symbol not found in production: sym.field
 -test.y:15.22-37: invalid reference: '$<aa>[sym.field]'
 +test.y:15.22-37: error: invalid reference: '$<aa>[sym.field]'
  test.y:15.3-41:      symbol not found in production: sym.field
 -test.y:16.22-25: invalid reference: '$sym'
 +test.y:16.22-25: error: invalid reference: '$sym'
  test.y:16.3-29:      symbol not found in production: sym
 -test.y:17.22-29: invalid reference: '$<aa>sym'
 +test.y:17.22-29: error: invalid reference: '$<aa>sym'
  test.y:17.3-33:      symbol not found in production: sym
 -test.y:18.22-27: invalid reference: '$[sym]'
 +test.y:18.22-27: error: invalid reference: '$[sym]'
  test.y:18.3-65:      symbol not found in production before $3: sym
 -test.y:18.52-61: invalid reference: '$<aa>[sym]'
 +test.y:18.52-61: error: invalid reference: '$<aa>[sym]'
  test.y:18.3-65:      symbol not found in production: sym
 -test.y:22.22-31: invalid reference: '$sym-field'
 +test.y:22.22-31: error: invalid reference: '$sym-field'
  test.y:22.3-35:      symbol not found in production: sym
 -test.y:23.22-35: invalid reference: '$<aa>sym-field'
 +test.y:23.22-35: error: invalid reference: '$<aa>sym-field'
  test.y:23.3-39:      symbol not found in production: sym
 -test.y:24.22-33: invalid reference: '$[sym-field]'
 +test.y:24.22-33: error: invalid reference: '$[sym-field]'
  test.y:24.3-37:      symbol not found in production: sym-field
 -test.y:25.22-37: invalid reference: '$<aa>[sym-field]'
 +test.y:25.22-37: error: invalid reference: '$<aa>[sym-field]'
  test.y:25.3-41:      symbol not found in production: sym-field
 -test.y:26.22-25: invalid reference: '$sym'
 +test.y:26.22-25: error: invalid reference: '$sym'
  test.y:26.3-29:      symbol not found in production: sym
 -test.y:27.22-29: invalid reference: '$<aa>sym'
 +test.y:27.22-29: error: invalid reference: '$<aa>sym'
  test.y:27.3-33:      symbol not found in production: sym
 -test.y:28.22-27: invalid reference: '$[sym]'
 +test.y:28.22-27: error: invalid reference: '$[sym]'
  test.y:28.3-65:      symbol not found in production before $3: sym
 -test.y:28.52-61: invalid reference: '$<aa>[sym]'
 +test.y:28.52-61: error: invalid reference: '$<aa>[sym]'
  test.y:28.3-65:      symbol not found in production: sym
  ]])
  AT_CLEANUP
@@@ -558,10 -563,10 +563,10 @@@ start
  .field: ;
  ]])
  AT_BISON_CHECK([[test.y]], [[1]], [],
 -[[test.y:4.12-18: invalid reference: '$.field'
 +[[test.y:4.12-18: error: invalid reference: '$.field'
  test.y:4.13:        syntax error after '$', expecting integer, letter, '_', '@<:@', or '$'
  test.y:4.3-8:       possibly meant: $[.field] at $1
 -test.y:5.12-18: invalid reference: '@.field'
 +test.y:5.12-18: error: invalid reference: '@.field'
  test.y:5.13:        syntax error after '@', expecting integer, letter, '_', '@<:@', or '$'
  ]])
  AT_DATA([[test.y]],
diff --combined tests/regression.at
index c44b9f8879cb042d696eabd54a52ba876ffa5a82,6cf226859bdf6610e78e1420ffd3812ad3bdab1b..b6bff17cb0743128f82bc74360e74f54b48baba4
@@@ -383,58 -383,6 +383,58 @@@ AT_CLEANU
  
  
  
 +## ---------------- ##
 +## Invalid inputs.  ##
 +## ---------------- ##
 +
 +
 +AT_SETUP([Invalid inputs])
 +
 +AT_DATA([input.y],
 +[[%%
 +?
 +default: 'a' }
 +%&
 +%a-does-not-exist
 +%-
 +%{
 +]])
 +
 +AT_BISON_CHECK([input.y], [1], [],
 +[[input.y:2.1: error: invalid character: '?'
 +input.y:3.14: error: invalid character: '}'
 +input.y:4.1: error: invalid character: '%'
 +input.y:4.2: error: invalid character: '&'
 +input.y:5.1-17: error: invalid directive: '%a-does-not-exist'
 +input.y:6.1: error: invalid character: '%'
 +input.y:6.2: error: invalid character: '-'
 +input.y:7.1-8.0: error: missing '%}' at end of file
 +input.y:7.1-8.0: error: syntax error, unexpected %{...%}
 +]])
 +
 +AT_CLEANUP
 +
 +
 +AT_SETUP([Invalid inputs with {}])
 +
 +AT_DATA([input.y],
 +[[
 +%destructor
 +%initial-action
 +%lex-param
 +%parse-param
 +%printer
 +%union
 +]])
 +
 +AT_BISON_CHECK([input.y], [1], [],
 +[[input.y:3.1-15: error: syntax error, unexpected %initial-action, expecting {...}
 +]])
 +
 +AT_CLEANUP
 +
 +
 +
  ## ------------------- ##
  ## Token definitions.  ##
  ## ------------------- ##
@@@ -1597,14 -1545,14 +1597,14 @@@ AT_CLEANU
  m4_pushdef([AT_TEST],
  [AT_SETUP([[Lex and parse params: $1]])
  
- AT_BISON_OPTION_PUSHDEFS([%locations %skeleton $1])
+ AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" %parse-param { int x } %parse-param { int y }])
  
  ## FIXME: Improve parsing of parse-param and use the generated
  ## yyerror.
  AT_DATA_GRAMMAR([input.y],
  [[%defines
  %locations
- %skeleton $1
+ %skeleton "$1"
  %union { int ival; }
  %parse-param { int x }
  // Spaces, tabs, and new lines.
  #include <stdio.h>
  #include <stdlib.h>
  
- ]AT_SKEL_CC_IF([], [[
- static
- void
- yyerror (int x, int y, const char *msg)
- {
-   fprintf (stderr, "x: %d, y: %d, %s\n", x, y, msg);
- }]])[
+   ]AT_YYERROR_DECLARE[
    ]AT_YYLEX_DECLARE[
  %}
  
  %%
  exp: 'a' { fprintf (stdout, "x: %d, y: %d\n", x, y); };
  %%
+ ]AT_YYERROR_DEFINE[
  ]AT_YYLEX_DEFINE(["a"])[
  
  ]AT_SKEL_CC_IF(
- [AT_YYERROR_DEFINE
- int
+ [int
  yyparse (int x, int y)
  {
    yy::parser parser(x, y);
@@@ -1661,9 -1601,9 +1653,9 @@@ AT_CLEANU
  ])
  
  ## FIXME: test Java, and iterate over skeletons.
- AT_TEST("yacc.c")
- AT_TEST("glr.c")
- AT_TEST("lalr1.cc")
- AT_TEST("glr.cc")
+ AT_TEST([yacc.c])
+ AT_TEST([glr.c])
+ AT_TEST([lalr1.cc])
+ AT_TEST([glr.cc])
  
  m4_popdef([AT_TEST])