bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: merge maint into master


From: Akim Demaille
Subject: FYI: merge maint into master
Date: Mon, 25 Jun 2012 09:48:53 +0200

commit 6cf3716c3166d6d41cdbeea45d018b1760184421
Merge: 6a0655d 230a3db
Author: Akim Demaille <address@hidden>
Date:   Mon Jun 25 09:26:48 2012 +0200

    Merge remote-tracking branch 'origin/maint'
    
    * origin/maint:
      tests: more uniformity.
      tests: handle locations in a more generic way.
      tests: handle locations in the generic yyerror functions.
      tests: fix AT_CHECK_CALC.
      tests: improve infrastructure
      tests: factor.
      skeletons: minor style changes
      tests: AT_LANG.
      c skeletons: factor the declaration of yylloc and yylval.
      news: condemn YYPARSE_PARAM and YYLEX_PARAM.
      maint: regen.
    
    Conflicts:
        tests/calc.at
        tests/local.at
        tests/regression.at

diff --git a/NEWS b/NEWS
index 03ab157..0dfc63f 100644
--- a/NEWS
+++ b/NEWS
@@ -85,8 +85,10 @@ GNU Bison NEWS
 ** Future changes:
 
   The next major release will drop support for generating parsers in K&R C,
-  and remove the definition of yystype (removal announced since Bison
-  1.875).
+  and remove the definitions of yystype and yyltype (removal announced since
+  Bison 1.875).  YYPARSE_PARAM and YYLEX_PARAM, which were deprecated in
+  favor of %parse-param and %lex-param (introduced in Bison 1.875 too), will
+  no longer be supported.
 
 ** The generated header is included (yacc.c)
 
@@ -1282,6 +1284,33 @@ GNU Bison NEWS
   - "parsing stack overflow..." -> "parser stack overflow"
     GLR parsers now report "parser stack overflow" as per the Bison manual.
 
+** %parse-param and %lex-param
+  The macros YYPARSE_PARAM and YYLEX_PARAM provide a means to pass
+  additional context to yyparse and yylex.  They suffer from several
+  shortcomings:
+
+  - a single argument only can be added,
+  - their types are weak (void *),
+  - this context is not passed to anciliary functions such as yyerror,
+  - only yacc.c parsers support them.
+
+  The new %parse-param/%lex-param directives provide a more precise control.
+  For instance:
+
+    %parse-param {int *nastiness}
+    %lex-param   {int *nastiness}
+    %parse-param {int *randomness}
+
+  results in the following signatures:
+
+    int yylex   (int *nastiness);
+    int yyparse (int *nastiness, int *randomness);
+
+  or, if both %pure-parser and %locations are used:
+
+    int yylex   (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness);
+    int yyparse (int *nastiness, int *randomness);
+
 ** Bison now warns if it detects conflicting outputs to the same file,
   e.g., it generates a warning for "bison -d -o foo.h foo.y" since
   that command outputs both code and header to foo.h.
diff --git a/data/c.m4 b/data/c.m4
index 2601d56..9bd8295 100644
--- a/data/c.m4
+++ b/data/c.m4
@@ -574,8 +574,8 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
 
 # b4_declare_yylstype
 # ------------------
-# Declaration that might either go into the header (if --defines)
-# or open coded in the parser body.  Declare YYSTYPE and YYLTYPE.
+# Declarations that might either go into the header (if --defines) or
+# in the parser body.  Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
 m4_define([b4_declare_yylstype],
 [[#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 ]m4_ifdef([b4_stype],
@@ -603,6 +603,9 @@ typedef struct YYLTYPE
 # define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
 #endif]])
+
+b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval;
+]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[]dnl
 ])
 
 # b4_declare_yydebug
diff --git a/data/glr.c b/data/glr.c
index f4efca2..3d4120c 100644
--- a/data/glr.c
+++ b/data/glr.c
@@ -195,17 +195,17 @@ b4_copyright([Skeleton implementation for Bison GLR 
parsers in C],
 
 ]b4_identification
 
-b4_percent_code_get([[top]])[]dnl
-m4_if(b4_prefix, [yy], [],
-[/* Substitute the variable and function names.  */
-#define yyparse b4_prefix[]parse
-#define yylex   b4_prefix[]lex
-#define yyerror b4_prefix[]error
-#define yylval  b4_prefix[]lval
-#define yychar  b4_prefix[]char
-#define yydebug b4_prefix[]debug
-#define yynerrs b4_prefix[]nerrs
-#define yylloc  b4_prefix[]lloc])[
+b4_percent_code_get([[top]])[
+]m4_if(b4_prefix, [yy], [],
+[[/* Substitute the variable and function names.  */
+#define yyparse ]b4_prefix[parse
+#define yylex   ]b4_prefix[lex
+#define yyerror ]b4_prefix[error
+#define yylval  ]b4_prefix[lval
+#define yychar  ]b4_prefix[char
+#define yydebug ]b4_prefix[debug
+#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
+#define yylloc  ]b4_prefix[lloc]])])[
 
 /* Copy the first part of user declarations.  */
 ]b4_user_pre_prologue[
@@ -2624,8 +2624,6 @@ b4_copyright([Skeleton interface for Bison GLR parsers in 
C],
 
 ]b4_cpp_guard_open([b4_spec_defines_file])[
 ]b4_shared_declarations[
-]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval;
-]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[
 ]b4_cpp_guard_close([b4_spec_defines_file])[
 ]])])
 m4_divert_pop(0)
diff --git a/data/yacc.c b/data/yacc.c
index 56be747..0c442ae 100644
--- a/data/yacc.c
+++ b/data/yacc.c
@@ -317,8 +317,8 @@ m4_if(b4_prefix, [yy], [],
 #define yylval          ]b4_prefix[lval
 #define yychar          ]b4_prefix[char
 #define yydebug         ]b4_prefix[debug
-#define yynerrs         ]b4_prefix[nerrs
-]b4_locations_if([[#define yylloc          ]b4_prefix[lloc]])])[
+#define yynerrs         ]b4_prefix[nerrs]b4_locations_if([[
+#define yylloc          ]b4_prefix[lloc]])])[
 
 /* Copy the first part of user declarations.  */
 ]b4_user_pre_prologue[
@@ -1999,8 +1999,6 @@ b4_copyright([Bison interface for Yacc-like parsers in 
C])[
 
 ]b4_cpp_guard_open([b4_spec_defines_file])[
 ]b4_shared_declarations[
-]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval;
-]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[
 ]b4_cpp_guard_close([b4_spec_defines_file])[
 ]])dnl b4_defines_if
 m4_divert_pop(0)
diff --git a/doc/bison.texinfo b/doc/bison.texinfo
index 3f24b9a..d1223bd 100644
--- a/doc/bison.texinfo
+++ b/doc/bison.texinfo
@@ -6265,7 +6265,7 @@ For instance:
 @end example
 
 @noindent
-results in the following signature:
+results in the following signatures:
 
 @example
 int yylex   (scanner_mode *mode, environment_type *env);
diff --git a/src/output.c b/src/output.c
index e8cff20..4fe11cc 100644
--- a/src/output.c
+++ b/src/output.c
@@ -586,8 +587,8 @@ output_skeleton (void)
   char *m4sugar = xconcatenated_filename (datadir, "m4sugar/m4sugar.m4", NULL);
   char *m4bison = xconcatenated_filename (datadir, "bison.m4", NULL);
   char *skel = (IS_PATH_WITH_DIR (skeleton)
-               ? xstrdup (skeleton)
-               : xconcatenated_filename (datadir, skeleton, NULL));
+                ? xstrdup (skeleton)
+                : xconcatenated_filename (datadir, skeleton, NULL));
 
   /* Test whether m4sugar.m4 is readable, to check for proper
      installation.  A faulty installation can cause deadlock, so a
diff --git a/tests/actions.at b/tests/actions.at
index 84529be..4af5615 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -150,14 +150,8 @@ two: { $$.val = 2; } ;
 sum: { printf ("%d\n", $0.val + $-1.val + $-2.val); } ;
 
 %%
-
-static int
-yylex (void)
-{
-  return 0;
-}
-
 ]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE()[
 int
 main (void)
 {
@@ -211,8 +205,8 @@ m4_ifval([$6], [%union
 }])
 AT_LALR1_CC_IF([%define global_tokens_and_yystype])
 m4_ifval([$6], [[%code provides {]], [[%code {]])
-AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])
-[static int yylex (]AT_LEX_FORMALS[);
+AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
+]AT_YYLEX_DECLARE[
 ]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE])
 [}
 
@@ -315,8 +309,8 @@ thing:
 /* Alias to ARGV[1]. */
 const char *source = YY_NULL;
 
-static int
-yylex (]AT_LEX_FORMALS[)
+static
+]AT_YYLEX_PROTOTYPE[
 {
   static unsigned int counter = 0;
 
@@ -680,7 +674,7 @@ Reading a token: Next token is token 'd' (1.4-1.4: <> 
printer for 'd' @ 4)
 Shifting token 'd' (1.4-1.4: <> printer for 'd' @ 4)
 Entering state 6
 Reading a token: Now at end of input.
-syntax error, unexpected $end, expecting 'e'
+1.5-4: syntax error, unexpected $end, expecting 'e'
 Error: popping token 'd' (1.4-1.4: <> printer for 'd' @ 4)
 Stack now 0 1 3 5
 Error: popping token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
diff --git a/tests/calc.at b/tests/calc.at
index 5c6c4cc..0a9f9e1 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -110,15 +110,15 @@ main (int argc, const char **argv)
 m4_pushdef([AT_CALC_LEX],
 [[#include <ctype.h>
 
-int ]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[);
-static int get_char (]AT_LEX_FORMALS[);
-static void unget_char (]AT_LEX_PRE_FORMALS[ int c);
+]AT_YYLEX_DECLARE_EXTERN[
+static int get_char (]AT_YYLEX_FORMALS[);
+static void unget_char (]AT_YYLEX_PRE_FORMALS[ int c);
 
 ]AT_LOCATION_IF([
 static YYLTYPE last_yylloc;
 ])[
 static int
-get_char (]AT_LEX_FORMALS[)
+get_char (]AT_YYLEX_FORMALS[)
 {
   int res = getc (input);
   ]AT_USE_LEX_ARGS[;
@@ -136,7 +136,7 @@ get_char (]AT_LEX_FORMALS[)
 }
 
 static void
-unget_char (]AT_LEX_PRE_FORMALS[ int c)
+unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
 {
   ]AT_USE_LEX_ARGS[;
 ]AT_LOCATION_IF([
@@ -147,26 +147,26 @@ unget_char (]AT_LEX_PRE_FORMALS[ int c)
 }
 
 static int
-read_signed_integer (]AT_LEX_FORMALS[)
+read_signed_integer (]AT_YYLEX_FORMALS[)
 {
-  int c = get_char (]AT_LEX_ARGS[);
+  int c = get_char (]AT_YYLEX_ARGS[);
   int sign = 1;
   int n = 0;
 
   ]AT_USE_LEX_ARGS[;
   if (c == '-')
     {
-      c = get_char (]AT_LEX_ARGS[);
+      c = get_char (]AT_YYLEX_ARGS[);
       sign = -1;
     }
 
   while (isdigit (c))
     {
       n = 10 * n + (c - '0');
-      c = get_char (]AT_LEX_ARGS[);
+      c = get_char (]AT_YYLEX_ARGS[);
     }
 
-  unget_char (]AT_LEX_PRE_ARGS[ c);
+  unget_char (]AT_YYLEX_PRE_ARGS[ c);
 
   return sign * n;
 }
@@ -178,8 +178,7 @@ read_signed_integer (]AT_LEX_FORMALS[)
 | blanks and tabs, returns 0 for EOF.                            |
 `---------------------------------------------------------------*/
 
-int
-]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[)
+]AT_YYLEX_PROTOTYPE[
 {
   static int init = 1;
   int c;
@@ -201,13 +200,13 @@ int
       AT_LOC_FIRST_LINE   = AT_LOC_LAST_LINE;
 ])[
     }
-  while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t');
+  while ((c = get_char (]AT_YYLEX_ARGS[)) == ' ' || c == '\t');
 
   /* process numbers   */
   if (c == '.' || isdigit (c))
     {
-      unget_char (]AT_LEX_PRE_ARGS[ c);
-      ]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[);
+      unget_char (]AT_YYLEX_PRE_ARGS[ c);
+      ]AT_VAL[.ival = read_signed_integer (]AT_YYLEX_ARGS[);
       return ]AT_TOKEN_PREFIX[NUM;
     }
 
@@ -288,14 +287,11 @@ FILE *input;
 static int power (int base, int exponent);
 
 ]AT_SKEL_CC_IF(,
-[/* yyerror receives the location if:
-   - %location & %pure & %glr
-   - %location & %pure & %yacc & %parse-param. */
-static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])
+[static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])
                      AT_PARAM_IF([semantic_value *result, int *count, ])
                      const char *s
                      );])[
-int yylex (]AT_LEX_FORMALS[);
+]AT_YYLEX_DECLARE_EXTERN[
 }
 
 ]AT_SKEL_CC_IF([AT_LOCATION_IF([AT_LOCATION_TYPE_IF([], [
@@ -376,14 +372,7 @@ power (int base, int exponent)
     return o;
   }
 ]])
-
-/* A C++ error reporting function.  */
-void
-AT_NAME_PREFIX::parser::error (AT_LOCATION_IF([const location_type& l, ])const 
std::string& m)
-{
-  std::cerr << AT_LOCATION_IF([l << ": " << ])m << std::endl;
-}
-],
+AT_YYERROR_DEFINE],
 [/* A C error reporting function.  */
 static void
 yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])
@@ -517,16 +506,15 @@ AT_CHECK([cat stderr], 0, [expout])
 ])
 
 
-# AT_CHECK_CALC([BISON-OPTIONS, [EXPECTED-TO-FAIL]])
-# --------------------------------------------------
+# AT_CHECK_CALC([BISON-OPTIONS])
+# ------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # BISON-OPTIONS, and performs several tests over the parser.
-# However, if EXPECTED-TO-FAIL is nonempty, this test is expected to fail.
 m4_define([AT_CHECK_CALC],
-[# We use integers to avoid dependencies upon the precision of doubles.
-AT_SETUP([Calculator $1])
+[m4_ifval([$2], [m4_fatal([$0: expected a single argument])])
 
-m4_ifval([$2], [AT_CHECK([exit 77])])
+# We use integers to avoid dependencies upon the precision of doubles.
+AT_SETUP([Calculator $1])
 
 AT_BISON_OPTION_PUSHDEFS([$1])
 
diff --git a/tests/cxx-type.at b/tests/cxx-type.at
index 746d05a..e172033 100644
--- a/tests/cxx-type.at
+++ b/tests/cxx-type.at
@@ -23,15 +23,15 @@ AT_BANNER([[C++ Type Syntax (GLR).]])
 # and with RESOLVE1 and RESOLVE2 as annotations on the conflicted rule for
 # stmt.  Then compile the result.
 m4_define([_AT_TEST_GLR_CXXTYPES],
-[
-AT_BISON_OPTION_PUSHDEFS([$1])
+[AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
 
 AT_DATA_GRAMMAR([types.y],
 [[/* Simplified C++ Type and Expression Grammar.  */
 
 $1
 
-%{
+%code requires
+{
   #include <stdio.h>
   union Node {
     struct {
@@ -51,33 +51,22 @@ $1
     } term;
   };
   typedef union Node Node;
+  #define YYSTYPE Node *
+}
+
+%code
+{
   static Node *new_nterm (char const *, Node *, Node *, Node *);
   static Node *new_term (char *);
   static void free_node (Node *);
   static char *node_to_string (Node *);
-  #define YYSTYPE Node *
 ]m4_bmatch([$2], [stmtMerge],
 [ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[
   #define YYINITDEPTH 10
   #define YYSTACKEXPANDABLE 1
-  struct YYLTYPE;
-#if YYPURE
-# if YYLSP_NEEDED
-#  define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp
-#  define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s
-# else
-#  define LEX_PARAMETERS YYSTYPE *lvalp
-# endif
-#endif
-#ifndef LEX_PARAMETERS
-# define LEX_PARAMETERS void
-#endif
-#ifndef ERROR_PARAMETERS
-# define ERROR_PARAMETERS char const *s
-#endif
-  int yylex (LEX_PARAMETERS);
-  void yyerror (ERROR_PARAMETERS);
-%}
+  ]AT_YYERROR_DECLARE[
+  ]AT_YYLEX_DECLARE[
+}
 
 %token TYPENAME ID
 
@@ -144,8 +133,9 @@ main (int argc, char **argv)
   return yyparse ();
 }
 
-int
-yylex (LEX_PARAMETERS)
+]AT_YYERROR_DEFINE[
+
+]AT_YYLEX_PROTOTYPE[
 {
   char buffer[256];
   int c;
@@ -181,11 +171,9 @@ yylex (LEX_PARAMETERS)
           break;
         default:
           {
-            int tok;
-#if YYLSP_NEEDED
+            int tok;]AT_LOCATION_IF([[
             yylloc.first_line = yylloc.last_line = lineNum;
-            yylloc.first_column = colNum;
-#endif
+            yylloc.first_column = colNum;]])[
             if (isalpha (c))
               {
                 i = 0;
@@ -210,27 +198,14 @@ yylex (LEX_PARAMETERS)
                 colNum += 1;
                 tok = c;
                 yylval = YY_NULL;
-              }
-#if YYLSP_NEEDED
-            yylloc.last_column = colNum-1;
-#endif
+              }]AT_LOCATION_IF([[
+            yylloc.last_column = colNum-1;]])[
             return tok;
           }
         }
     }
 }
 
-void
-yyerror (ERROR_PARAMETERS)
-{
-#if YYPURE && YYLSP_NEEDED
-  /* Pacify GCC by using llocp.  */
-  if (! llocp)
-    abort ();
-#endif
-  fprintf (stderr, "%s\n", s);
-}
-
 static Node *
 new_nterm (char const *form, Node *child0, Node *child1, Node *child2)
 {
@@ -351,7 +326,7 @@ AT_BISON_OPTION_POPDEFS
 ])
 
 m4_define([_AT_RESOLVED_GLR_OUTPUT],
-[[[+(z,q)
+[[+(z,q)
 <declare>(T,x)
 <init-declare>(T,x,y)
 =(x,y)
@@ -360,10 +335,10 @@ m4_define([_AT_RESOLVED_GLR_OUTPUT],
 <init-declare>(T,y,+(z,q))
 <error>
 +(z,q)
-]]])
+]])
 
 m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC],
-[[[3.0-3.5: +(z,q)
+[[3.0-3.5: +(z,q)
 5.0-5.3: <declare>(T,x)
 7.0-7.7: <init-declare>(T,x,y)
 9.0-9.5: =(x,y)
@@ -372,10 +347,10 @@ m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC],
 15.0-15.13: <init-declare>(T,y,+(z,q))
 17.0-17.15: <error>
 19.0-19.5: +(z,q)
-]]])
+]])
 
 m4_define([_AT_AMBIG_GLR_OUTPUT],
-[[[+(z,q)
+[[+(z,q)
 <declare>(T,x)
 <init-declare>(T,x,y)
 =(x,y)
@@ -384,10 +359,10 @@ m4_define([_AT_AMBIG_GLR_OUTPUT],
 <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
 <error>
 +(z,q)
-]]])
+]])
 
 m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC],
-[[[3.0-3.5: +(z,q)
+[[3.0-3.5: +(z,q)
 5.0-5.3: <declare>(T,x)
 7.0-7.7: <init-declare>(T,x,y)
 9.0-9.5: =(x,y)
@@ -396,15 +371,23 @@ m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC],
 15.0-15.13: <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
 17.0-17.15: <error>
 19.0-19.5: +(z,q)
-]]])
+]])
 
 m4_define([_AT_GLR_STDERR],
-[[[syntax error
-]]])
+[[syntax error
+]])
+
+m4_define([_AT_GLR_STDERR_WITH_LOC],
+[[17.5-4: syntax error
+]])
 
 m4_define([_AT_VERBOSE_GLR_STDERR],
-[[[syntax error, unexpected ID, expecting '=' or '+' or ')'
-]]])
+[[syntax error, unexpected ID, expecting '=' or '+' or ')'
+]])
+
+m4_define([_AT_VERBOSE_GLR_STDERR_WITH_LOC],
+[[17.5-4: syntax error, unexpected ID, expecting '=' or '+' or ')'
+]])
 
 ## ---------------------------------------------------- ##
 ## Compile the grammar described in the documentation.  ##
@@ -414,59 +397,59 @@ AT_SETUP([GLR: Resolve ambiguity, impure, no locations])
 _AT_TEST_GLR_CXXTYPES([],
                       [%dprec 1], [%dprec 2])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR)
+                [_AT_RESOLVED_GLR_OUTPUT], [_AT_GLR_STDERR])
 AT_CLEANUP
 
 AT_SETUP([GLR: Resolve ambiguity, impure, locations])
 _AT_TEST_GLR_CXXTYPES([%locations],[%dprec 1],[%dprec 2])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
+                [_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
 AT_CLEANUP
 
 AT_SETUP([GLR: Resolve ambiguity, pure, no locations])
 _AT_TEST_GLR_CXXTYPES([%define api.pure],
                       [%dprec 1], [%dprec 2])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR)
+                [_AT_RESOLVED_GLR_OUTPUT], [_AT_GLR_STDERR])
 AT_CLEANUP
 
 AT_SETUP([GLR: Resolve ambiguity, pure, locations])
 _AT_TEST_GLR_CXXTYPES([%define api.pure %locations],
                       [%dprec 1], [%dprec 2])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
+                [_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
 AT_CLEANUP
 
 AT_SETUP([GLR: Merge conflicting parses, impure, no locations])
 _AT_TEST_GLR_CXXTYPES([],
                       [%merge <stmtMerge>], [%merge <stmtMerge>])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR)
+                [_AT_AMBIG_GLR_OUTPUT], [_AT_GLR_STDERR])
 AT_CLEANUP
 
 AT_SETUP([GLR: Merge conflicting parses, impure, locations])
 _AT_TEST_GLR_CXXTYPES([%locations],
                       [%merge <stmtMerge>], [%merge <stmtMerge>])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
+                [_AT_AMBIG_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
 AT_CLEANUP
 
 AT_SETUP([GLR: Merge conflicting parses, pure, no locations])
 _AT_TEST_GLR_CXXTYPES([%define api.pure],
                       [%merge <stmtMerge>], [%merge <stmtMerge>])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR)
+                [_AT_AMBIG_GLR_OUTPUT], [_AT_GLR_STDERR])
 AT_CLEANUP
 AT_SETUP([GLR: Merge conflicting parses, pure, locations])
 _AT_TEST_GLR_CXXTYPES([%define api.pure %locations],
                       [%merge <stmtMerge>],[%merge <stmtMerge>])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
+                [_AT_AMBIG_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
 AT_CLEANUP
 
 AT_SETUP([GLR: Verbose messages, resolve ambiguity, impure, no locations])
 _AT_TEST_GLR_CXXTYPES([%error-verbose],
                       [%merge <stmtMerge>], [%merge <stmtMerge>])
 AT_PARSER_CHECK([[./types test-input]], 0,
-                _AT_AMBIG_GLR_OUTPUT, _AT_VERBOSE_GLR_STDERR)
+                [_AT_AMBIG_GLR_OUTPUT], [_AT_VERBOSE_GLR_STDERR])
 AT_CLEANUP
diff --git a/tests/glr-regression.at b/tests/glr-regression.at
index 67c6070..479303d 100644
--- a/tests/glr-regression.at
+++ b/tests/glr-regression.at
@@ -35,8 +35,8 @@ AT_DATA_GRAMMAR([glr-regr1.y],
 
 #define YYSTYPE int
 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
-]AT_YYLEX_DECLARE[
 ]AT_YYERROR_DECLARE[
+]AT_YYLEX_DECLARE[
 %}
 
 
@@ -81,12 +81,12 @@ yylex (void)
     {
       int ch;
       if (feof (stdin))
-        abort ();
+       abort ();
       ch = getchar ();
       if (ch == EOF)
-        return 0;
+       return 0;
       else if (ch == 'B' || ch == 'P')
-        return ch;
+       return ch;
     }
 }
 ]])
@@ -128,8 +128,8 @@ AT_DATA_GRAMMAR([glr-regr2a.y],
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
-  ]AT_YYLEX_DECLARE[
   ]AT_YYERROR_DECLARE[
+  ]AT_YYLEX_DECLARE[
 %}
 
 %glr-parser
@@ -339,7 +339,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Duplicate representation of merged trees.  See                            ##
+## Duplicate representation of merged trees.  See                           ##
 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>.     ##
 ## ------------------------------------------------------------------------- ##
 
@@ -430,7 +430,7 @@ AT_CLEANUP
 
 
 ## -------------------------------------------------------------------------- 
##
-## User destructor for unresolved GLR semantic value.  See                    
##
+## User destructor for unresolved GLR semantic value.  See                   ##
 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>.   
##
 ## -------------------------------------------------------------------------- 
##
 
@@ -490,7 +490,7 @@ AT_CLEANUP
 
 
 ## -------------------------------------------------------------------------- 
##
-## User destructor after an error during a split parse.  See                  
##
+## User destructor after an error during a split parse.  See                 ##
 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>.   
##
 ## -------------------------------------------------------------------------- 
##
 
@@ -519,18 +519,8 @@ AT_DATA_GRAMMAR([glr-regr6.y],
 start: 'a' | 'a' ;
 
 %%
-
-static int
-yylex (void)
-{
-  static char const input[] = "a";
-  static size_t toknum;
-  if (! (toknum < sizeof input))
-    abort ();
-  return input[toknum++];
-}
-
 ]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE(a)[
 int
 main (void)
 {
@@ -554,7 +544,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Duplicated user destructor for lookahead.  See                            ##
+## Duplicated user destructor for lookahead.  See                           ##
 ## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>.  ##
 ## ------------------------------------------------------------------------- ##
 
@@ -642,7 +632,7 @@ AT_CLEANUP
 
 ## ------------------------------------------------------------------------- ##
 ## Incorrect default location for empty right-hand sides.  Adapted from bug  ##
-## report by Claudia Hermann.                                                ##
+## report by Claudia Hermann.                                               ##
 ## See http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00069.html and ##
 ## http://lists.gnu.org/archive/html/bug-bison/2005-10/msg00072.html         ##
 ## ------------------------------------------------------------------------- ##
@@ -657,7 +647,6 @@ AT_DATA_GRAMMAR([glr-regr8.y],
   #include <stdlib.h>
   ]AT_YYERROR_DECLARE[
   ]AT_YYLEX_DECLARE[
-  ]AT_YYERROR_DECLARE[
 %}
 
 %token T_CONSTANT
@@ -669,25 +658,25 @@ AT_DATA_GRAMMAR([glr-regr8.y],
 %%
 
 
-PortClause      : T_PORT InterfaceDeclaration T_PORT
-                { printf("%d/%d - %d/%d - %d/%d\n",
-                         @1.first_column, @1.last_column,
-                         @2.first_column, @2.last_column,
-                         @3.first_column, @3.last_column); }
-        ;
+PortClause     : T_PORT InterfaceDeclaration T_PORT
+               { printf("%d/%d - %d/%d - %d/%d\n",
+                        @1.first_column, @1.last_column,
+                        @2.first_column, @2.last_column,
+                        @3.first_column, @3.last_column); }
+       ;
 
-InterfaceDeclaration    : OptConstantWord       %dprec 1
-        | OptSignalWord %dprec 2
-        ;
+InterfaceDeclaration   : OptConstantWord       %dprec 1
+       | OptSignalWord %dprec 2
+       ;
 
-OptConstantWord : /* empty */
-        | T_CONSTANT
-        ;
+OptConstantWord        : /* empty */
+       | T_CONSTANT
+       ;
 
-OptSignalWord   : /* empty */
-                { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
-        | T_SIGNAL
-        ;
+OptSignalWord  : /* empty */
+               { printf("empty: %d/%d\n", @$.first_column, @$.last_column); }
+       | T_SIGNAL
+       ;
 
 %%
 
@@ -738,7 +727,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## No users destructors if stack 0 deleted.  See                             ##
+## No users destructors if stack 0 deleted.  See                            ##
 ## <http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html>.  ##
 ## ------------------------------------------------------------------------- ##
 
@@ -816,7 +805,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Corrupted semantic options if user action cuts parse.                     ##
+## Corrupted semantic options if user action cuts parse.                    ##
 ## ------------------------------------------------------------------------- ##
 
 AT_SETUP([Corrupted semantic options if user action cuts parse])
@@ -845,16 +834,8 @@ start:
   ;
 
 %%
-
 ]AT_YYERROR_DEFINE[
-static int
-yylex (void)
-{
-  static int called;
-  if (called++)
-    abort ();
-  return 0;
-}
+]AT_YYLEX_DEFINE()[
 
 int
 main (void)
@@ -878,7 +859,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Undesirable destructors if user action cuts parse.                        ##
+## Undesirable destructors if user action cuts parse.                       ##
 ## ------------------------------------------------------------------------- ##
 
 AT_SETUP([Undesirable destructors if user action cuts parse])
@@ -936,7 +917,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Leaked semantic values if user action cuts parse.                         ##
+## Leaked semantic values if user action cuts parse.                        ##
 ## ------------------------------------------------------------------------- ##
 
 AT_SETUP([Leaked semantic values if user action cuts parse])
@@ -1064,7 +1045,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Incorrect lookahead during deterministic GLR.  See                        ##
+## Incorrect lookahead during deterministic GLR.  See                       ##
 ## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00017.html> and  ##
 ## <http://lists.gnu.org/archive/html/bison-patches/2006-01/msg00060.html>.  ##
 ## ------------------------------------------------------------------------- ##
@@ -1161,10 +1142,10 @@ print_lookahead (char const *reduction)
     {
       printf ("'%c', yylval='", yychar);
       if (yylval.value > ' ')
-        printf ("%c", yylval.value);
+       printf ("%c", yylval.value);
       printf ("', yylloc=(%d,%d),(%d,%d)",
-              yylloc.first_line, yylloc.first_column,
-              yylloc.last_line, yylloc.last_column);
+             yylloc.first_line, yylloc.first_column,
+             yylloc.last_line, yylloc.last_column);
     }
   printf ("\n");
 }
@@ -1199,7 +1180,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Incorrect lookahead during nondeterministic GLR.                          ##
+## Incorrect lookahead during nondeterministic GLR.                         ##
 ## ------------------------------------------------------------------------- ##
 
 AT_SETUP([Incorrect lookahead during nondeterministic GLR])
@@ -1260,7 +1241,7 @@ merge:
   | conflict defstate_look 'a' nonconflict2 'b' defstate_shift %dprec 2 {
     USE ($3); USE ($5);
     print_lookahead ("merge <- conflict defstate_look 'a' nonconflict2 'b'"
-                      " defstate_shift");
+                     " defstate_shift");
   }
   ;
 
@@ -1307,7 +1288,7 @@ alt1:
     USE ($1);
     if (yychar != 'd' && yychar != YYEOF)
       {
-        fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
+       fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
       }
   }
   ;
@@ -1316,7 +1297,7 @@ alt2:
     USE ($1);
     if (yychar != 'd' && yychar != YYEOF)
       {
-        fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
+       fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
       }
   }
   ;
@@ -1325,7 +1306,7 @@ alt3:
     USE ($1);
     if (yychar != 'd' && yychar != YYEOF)
       {
-        fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
+       fprintf (stderr, "Incorrect lookahead during stack explosion.\n");
       }
   }
   ;
@@ -1333,8 +1314,8 @@ no_look:
   {
     if (yychar != YYEMPTY)
       {
-        fprintf (stderr,
-                 "Found lookahead where shouldn't during stack explosion.\n");
+       fprintf (stderr,
+                "Found lookahead where shouldn't during stack explosion.\n");
       }
   }
   ;
@@ -1367,10 +1348,10 @@ print_lookahead (char const *reduction)
     {
       printf ("'%c', yylval='", yychar);
       if (yylval.value > ' ')
-        printf ("%c", yylval.value);
+       printf ("%c", yylval.value);
       printf ("', yylloc=(%d,%d),(%d,%d)",
-              yylloc.first_line, yylloc.first_column,
-              yylloc.last_line, yylloc.last_column);
+             yylloc.first_line, yylloc.first_column,
+             yylloc.last_line, yylloc.last_column);
     }
   printf ("\n");
 }
@@ -1416,7 +1397,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Leaked semantic values when reporting ambiguity.                          ##
+## Leaked semantic values when reporting ambiguity.                         ##
 ## ------------------------------------------------------------------------- ##
 
 AT_SETUP([Leaked semantic values when reporting ambiguity])
@@ -1468,16 +1449,8 @@ ambiguity1: ;
 ambiguity2: ;
 
 %%
-
 ]AT_YYERROR_DEFINE[
-static int
-yylex (void)
-{
-  static int called;
-  if (called++)
-    abort ();
-  return 0;
-}
+]AT_YYLEX_DEFINE()[
 
 int
 main (void)
@@ -1506,7 +1479,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Leaked lookahead after nondeterministic parse syntax error.               ##
+## Leaked lookahead after nondeterministic parse syntax error.              ##
 ## ------------------------------------------------------------------------- ##
 
 AT_SETUP([Leaked lookahead after nondeterministic parse syntax error])
@@ -1573,7 +1546,7 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------------------- ##
-## Uninitialized location when reporting ambiguity.                          ##
+## Uninitialized location when reporting ambiguity.                         ##
 ## ------------------------------------------------------------------------- ##
 
 AT_SETUP([Uninitialized location when reporting ambiguity])
@@ -1675,7 +1648,7 @@ AT_DATA_GRAMMAR([glr-regr18.y],
 %{
   #include <stdlib.h>
   ]AT_YYERROR_DECLARE[
-  static int yylex ();
+  ]AT_YYLEX_DECLARE[
 %}
 
 %union {
@@ -1695,7 +1668,6 @@ sym3: %merge<merge> { $$ = 0; } ;
 %type <type3> sym3;
 
 %%
-
 ]AT_YYERROR_DEFINE[
 ]AT_YYLEX_DEFINE()[
 int
diff --git a/tests/java.at b/tests/java.at
index b6ea163..ec0f4a8 100644
--- a/tests/java.at
+++ b/tests/java.at
@@ -32,6 +32,7 @@ AT_BANNER([[Java Calculator.]])
 m4_define([_AT_DATA_JAVA_CALC_Y],
 [m4_if([$1$2$3], $[1]$[2]$[3], [],
        [m4_fatal([$0: Invalid arguments: address@hidden)])dnl
+AT_BISON_OPTION_PUSHDEFS([%language "Java" $4])
 AT_DATA([Calc.y],
 [[/* Infix notation calculator--calc */
 %language "Java"
@@ -122,20 +123,8 @@ AT_LOCATION_IF([[
   public Position getEndPos() {
     return yypos;
   }
-
-  public void yyerror (Calc.Location l, String s)
-  {
-    if (l == null)
-      System.err.println (s);
-    else
-      System.err.println (l + ": " + s);
-  }
-]], [[
-  public void yyerror (String s)
-  {
-    System.err.println (s);
-  }
 ]])[
+  ]AT_YYERROR_DEFINE[
 
   Integer yylval;
 
@@ -211,6 +200,7 @@ class Position {
 }
 
 ]])
+AT_BISON_OPTION_POPDEFS
 ])# _AT_DATA_JAVA_CALC_Y
 
 
@@ -224,7 +214,7 @@ m4_define([AT_DATA_JAVA_CALC_Y],
 
 # _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT,
 #                           [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
-# ---------------------------------------------------------
+# --------------------------------------------------------------
 # Run `calc' on INPUT, and expect a `syntax error' message.
 #
 # If INPUT starts with a slash, it is used as absolute input file name,
diff --git a/tests/local.at b/tests/local.at
index f43ffde..649e994 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -17,7 +17,6 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# We want a recent Autotest.
 m4_version_prereq([2.58])
 
 
@@ -108,6 +107,10 @@ 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])])
+m4_pushdef([AT_LANG],
+[AT_SKEL_JAVA_IF([java],
+                 [AT_SKEL_CC_IF([c++],
+                                [c])])])
 m4_pushdef([AT_GLR_IF],
 [m4_bmatch([$3], [%glr-parser\|%skeleton "glr\..*"], [$1], [$2])])
 m4_pushdef([AT_LALR1_CC_IF],
@@ -135,11 +138,11 @@ m4_pushdef([AT_GLR_OR_PARAM_IF],
 [m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])])
 m4_pushdef([AT_NAME_PREFIX],
 [m4_bmatch([$3], [%name-prefix ".*"],
-           [m4_bregexp([$3], [name-prefix "\([^""]*\)"], [\1])],
+           [m4_bregexp([$3], [%name-prefix "\([^""]*\)"], [\1])],
            [yy])])
 m4_pushdef([AT_API_PREFIX],
-[m4_bmatch([$3], [%define api\.prefix ".*"],
-           [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
+[m4_bmatch([$3], [\(%define api\.prefix\|%name-prefix\) ".*"],
+           [m4_bregexp([$3], [\(%define api\.prefix\|%name-prefix\) 
"\([^""]*\)"], [\2])],
            [yy])])
 m4_pushdef([AT_TOKEN_PREFIX],
 [m4_bmatch([$3], [%define api.tokens.prefix ".*"],
@@ -165,24 +168,24 @@ m4_pushdef([AT_PURE_LEX_IF],
 AT_PURE_LEX_IF(
 [m4_pushdef([AT_LOC], [(*llocp)])
  m4_pushdef([AT_VAL], [(*lvalp)])
- m4_pushdef([AT_LEX_FORMALS],
+ m4_pushdef([AT_YYLEX_FORMALS],
             [YYSTYPE *lvalp[]AT_LOCATION_IF([, YYLTYPE *llocp])])
- m4_pushdef([AT_LEX_ARGS],
+ m4_pushdef([AT_YYLEX_ARGS],
             [lvalp[]AT_LOCATION_IF([, llocp])])
  m4_pushdef([AT_USE_LEX_ARGS],
             [(void) lvalp;AT_LOCATION_IF([(void) llocp])])
- m4_pushdef([AT_LEX_PRE_FORMALS],
-            [AT_LEX_FORMALS, ])
- m4_pushdef([AT_LEX_PRE_ARGS],
-            [AT_LEX_ARGS, ])
+ m4_pushdef([AT_YYLEX_PRE_FORMALS],
+           [AT_YYLEX_FORMALS, ])
+ m4_pushdef([AT_YYLEX_PRE_ARGS],
+           [AT_YYLEX_ARGS, ])
 ],
 [m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]])
  m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]])
- m4_pushdef([AT_LEX_FORMALS],     [void])
- m4_pushdef([AT_LEX_ARGS],        [])
+ m4_pushdef([AT_YYLEX_FORMALS],     [void])
+ m4_pushdef([AT_YYLEX_ARGS],        [])
  m4_pushdef([AT_USE_LEX_ARGS],    [])
- m4_pushdef([AT_LEX_PRE_FORMALS], [])
- m4_pushdef([AT_LEX_PRE_ARGS],    [])
+ m4_pushdef([AT_YYLEX_PRE_FORMALS], [])
+ m4_pushdef([AT_YYLEX_PRE_ARGS],    [])
 ])
 
 # Handle the different types of location components.
@@ -201,11 +204,11 @@ AT_GLR_IF([AT_KEYWORDS([glr])])
 # AT_BISON_OPTION_POPDEFS
 # -----------------------
 m4_define([AT_BISON_OPTION_POPDEFS],
-[m4_popdef([AT_LEX_PRE_ARGS])
-m4_popdef([AT_LEX_PRE_FORMALS])
+[m4_popdef([AT_YYLEX_PRE_ARGS])
+m4_popdef([AT_YYLEX_PRE_FORMALS])
 m4_popdef([AT_USE_LEX_ARGS])
-m4_popdef([AT_LEX_ARGS])
-m4_popdef([AT_LEX_FORMALS])
+m4_popdef([AT_YYLEX_ARGS])
+m4_popdef([AT_YYLEX_FORMALS])
 m4_popdef([AT_VAL])
 m4_popdef([AT_LOC])
 m4_popdef([AT_PURE_LEX_IF])
@@ -222,6 +225,7 @@ m4_popdef([AT_LEXPARAM_IF])
 m4_popdef([AT_YACC_IF])
 m4_popdef([AT_GLR_IF])
 m4_popdef([AT_SKEL_CC_IF])
+m4_popdef([AT_LANG])
 m4_popdef([AT_SKEL_JAVA_IF])
 m4_popdef([AT_GLR_CC_IF])
 m4_popdef([AT_LALR1_CC_IF])
@@ -277,12 +281,17 @@ m4_define([AT_DATA_GRAMMAR],
 $2])
 ])
 
+# AT_YYLEX_PROTOTYPE
 # AT_YYLEX_DECLARE_EXTERN
 # AT_YYLEX_DECLARE
 # AT_YYLEX_DEFINE(INPUT-STRING, [ACTION])
 # ---------------------------------------
+m4_define([AT_YYLEX_PROTOTYPE],
+[int AT_API_PREFIX[]lex (]AT_YYLEX_FORMALS[)[]dnl
+])
+
 m4_define([AT_YYLEX_DECLARE_EXTERN],
-[int AT_API_PREFIX[]lex (void);dnl
+[AT_YYLEX_PROTOTYPE;dnl
 ])
 
 m4_define([AT_YYLEX_DECLARE],
@@ -291,8 +300,8 @@ m4_define([AT_YYLEX_DECLARE],
 
 m4_define([AT_YYLEX_DEFINE],
 [[#include <stdlib.h> /* abort */
-static int
-]AT_API_PREFIX[lex (void)
+static
+]AT_YYLEX_PROTOTYPE[
 {
   static char const input[] = "$1";
   static size_t toknum = 0;
@@ -307,36 +316,71 @@ static int
 }]dnl
 ])
 
+# AT_YYERROR_PROTOTYPE
 # AT_YYERROR_DECLARE_EXTERN
 # AT_YYERROR_DECLARE
 # AT_YYERROR_DEFINE
 # -------------------------
-# Beware that must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS
-# pair.
+# 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([YYLTYPE *llocp, ])[const char *msg]])[]dnl
+])
+
+m4_define([AT_YYERROR_PROTOTYPE],
+[m4_case(AT_LANG,
+[c], [[void ]AT_API_PREFIX[error (]AT_YYERROR_FORMALS[)]])[]dnl
+])
+
 m4_define([AT_YYERROR_DECLARE_EXTERN],
-[void AT_API_PREFIX[]error (const char *msg);dnl
+[m4_case(AT_LANG,
+[c], [AT_YYERROR_PROTOTYPE;])[]dnl
 ])
 
 m4_define([AT_YYERROR_DECLARE],
-[static AT_YYERROR_DECLARE_EXTERN[]dnl
+[m4_case(AT_LANG,
+[c], [static AT_YYERROR_DECLARE_EXTERN])[]dnl
 ])
 
 m4_define([AT_YYERROR_DEFINE],
-[AT_SKEL_JAVA_IF([[public void yyerror (String msg)
-{
-  System.err.println (msg);
-}]], [AT_SKEL_CC_IF([[void
-yy::parser::error (]AT_LOCATION_IF([[const yy::location &, ]])[std::string 
const &msg)
-{
-  std::cerr << msg << std::endl;
-}]], [[#include <stdio.h>
-static void
-]AT_API_PREFIX[error (char const *msg)
+[m4_case(AT_LANG,
+[c], [[#include <stdio.h>
+/* 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);
+  fprintf (stderr, ": ");]])[
   fprintf (stderr, "%s\n", msg);
+}]],
+[c++], [[/* A C++ error reporting function.  */
+void
+]AT_NAME_PREFIX[::parser::error (]AT_LOCATION_IF([[const location_type& l, 
]])[const std::string& m)
+{  std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
+}]],
+[java], [AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s)
+{
+    if (l == null)
+      System.err.println (s);
+    else
+      System.err.println (l + ": " + s);
+  }
+]], [[
+  public void yyerror (String s)
+  {
+    System.err.println (s);
 }]])])dnl
 ])
 
+
 ## --------------- ##
 ## Running Bison.  ##
 ## --------------- ##
@@ -519,11 +563,20 @@ AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS m4_bmatch([$1], [[.]], 
[], [$LDFLAGS ])-o $1
 # is not installed.
 m4_define([AT_JAVA_COMPILE],
 [AT_KEYWORDS(java)
-AT_CHECK([[test -n "$CONF_JAVA" || exit 77
-           test -n "$CONF_JAVAC" || exit 77]])
+AT_SKIP_IF([[test -z "$CONF_JAVA$CONF_JAVAC"]])
 AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
          [[0]], [ignore], [ignore])])
 
+# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c]
+# --------------------------------------------
+m4_define([AT_LANG_COMPILE],
+[m4_case(AT_LANG,
+[c],    [AT_COMPILE([$1], [$2])],
+[c++],  [AT_COMPILE_CXX([$1], [$2])],
+[java], [AT_JAVA_COMPILE([$1.java], [$2])],
+        [m4_fatal([unknown language: ]m4_defn([AT_LANG]))])[]dnl
+])
+
 # AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2])
 # -------------------------------------------
 # Compile OUTPUT.y to OUTPUT.c, OUTPUT.cc, or OUTPUT.java, and then
@@ -531,31 +584,29 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
 # OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or
 # OUTPUT.java along with it.  Relies on AT_SKEL_CC_IF and
 # AT_SKEL_JAVA_IF.
-m4_define([AT_FULL_COMPILE], [
-  AT_SKEL_JAVA_IF([
-    AT_BISON_CHECK([-o $1.java $1.y])
-    AT_JAVA_COMPILE([$1.java],
+m4_define([AT_FULL_COMPILE],
+[m4_case(AT_LANG,
+[java],
+  [AT_BISON_CHECK([-o $1.java $1.y])
+   AT_LANG_COMPILE([$1],
                     m4_join([ ],
                             [$1.java],
                             m4_ifval($2, [[$1-$2.java]]),
-                            m4_ifval($3, [[$1-$3.java]])))
-  ], [
-    AT_SKEL_CC_IF([
-      AT_BISON_CHECK([-o $1.cc $1.y])
-      AT_COMPILE_CXX([$1],
+                           m4_ifval($3, [[$1-$3.java]])))],
+[c++],
+  [AT_BISON_CHECK([-o $1.cc $1.y])
+   AT_LANG_COMPILE([$1],
                      m4_join([ ],
                              [$1.cc],
                              m4_ifval($2, [[$1-$2.cc]]),
-                             m4_ifval($3, [[$1-$3.cc]])))
-    ], [
-      AT_BISON_CHECK([-o $1.c $1.y])
-      AT_COMPILE([$1],
+                           m4_ifval($3, [[$1-$3.cc]])))],
+[c],
+  [AT_BISON_CHECK([-o $1.c $1.y])
+   AT_LANG_COMPILE([$1],
                   m4_join([ ],
                           [$1.c],
                           m4_ifval($2, [[$1-$2.c]]),
-                          m4_ifval($3, [[$1-$3.c]])))
-    ])
-  ])
+                           m4_ifval($3, [[$1-$3.c]])))])
 ])
 
 
diff --git a/tests/output.at b/tests/output.at
index b7bdb51..bb432fc 100644
--- a/tests/output.at
+++ b/tests/output.at
@@ -188,6 +188,7 @@ AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [-o foo.y],
 m4_define([AT_CHECK_OUTPUT_FILE_NAME],
 [AT_SETUP([Output file name: $1])
 
+AT_BISON_OPTION_PUSHDEFS
 # Skip if platform doesn't support file name.  For example, Cygwin
 # doesn't support file names containing ":" or "\".
 AT_CHECK([[touch "]AS_ESCAPE([$1[.tmp]])[" || exit 77]])
@@ -195,8 +196,8 @@ AT_CHECK([[touch "]AS_ESCAPE([$1[.tmp]])[" || exit 77]])
 AT_DATA_GRAMMAR([glr.y],
 [[%glr-parser
 %code {
-  int yylex (void);
-  void yyerror (const char *);
+]AT_YYERROR_DECLARE_EXTERN[
+]AT_YYLEX_DECLARE_EXTERN[
 }
 %%
 start: {};
@@ -217,6 +218,7 @@ AT_CHECK([ls "AS_ESCAPE([$1.c])" "AS_ESCAPE([$1.h])"], [], 
[ignore])
 AT_COMPILE_CXX([cxx.o], [-c "AS_ESCAPE([$1.c])"])
 $2
 
+AT_BISON_OPTION_POPDEFS
 AT_CLEANUP
 ])
 
diff --git a/tests/push.at b/tests/push.at
index 21322f0..057807d 100644
--- a/tests/push.at
+++ b/tests/push.at
@@ -24,17 +24,18 @@ AT_BANNER([[Push Parsing Tests]])
 AT_SETUP([[Memory Leak for Early Deletion]])
 
 # Requires Valgrind.
-
+AT_BISON_OPTION_PUSHDEFS
 AT_DATA_GRAMMAR([[input.y]],
 [[
 %{
   #include <assert.h>
   #include <stdio.h>
   #define YYINITDEPTH 1
-  void yyerror (char const *msg);
+]AT_YYERROR_DECLARE[
 %}
 
-%define api.pure %define api.push-pull push
+%define api.pure
+%define api.push-pull push
 
 %%
 
@@ -42,11 +43,7 @@ start: 'a' 'b' 'c' ;
 
 %%
 
-void
-yyerror (char const *msg)
-{
-  fprintf (stderr, "%s\n", msg);
-}
+]AT_YYERROR_DEFINE[
 
 int
 main (void)
@@ -71,6 +68,7 @@ main (void)
   return 0;
 }
 ]])
+AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o input.c input.y]])
 AT_COMPILE([[input]])
@@ -85,13 +83,14 @@ AT_CLEANUP
 AT_SETUP([[Multiple impure instances]])
 
 m4_pushdef([AT_MULTIPLE_IMPURE_INSTANCES_CHECK], [
+AT_BISON_OPTION_PUSHDEFS([%define api.push-pull $1])
 AT_DATA_GRAMMAR([[input.y]],
 [[
 %{
   #include <assert.h>
   #include <stdio.h>
-  void yyerror (char const *msg);
-  int yylex (void);
+]AT_YYERROR_DECLARE[
+]m4_if([$1], [[both]], [AT_YYLEX_DECLARE([])])[
 %}
 
 %define api.push-pull ]$1[
@@ -101,28 +100,16 @@ AT_DATA_GRAMMAR([[input.y]],
 start: ;
 
 %%
-
-void
-yyerror (char const *msg)
-{
-  fprintf (stderr, "%s\n", msg);
-}
-
-int
-yylex (void)
-{
-  return 0;
-}
+]AT_YYERROR_DEFINE[
+]m4_if([$1], [[both]], [AT_YYLEX_DEFINE([])])[
 
 int
 main (void)
 {
-  yypstate *ps;
   int i;
-
   for (i = 0; i < 2; ++i)
     {
-      ps = yypstate_new ();
+      yypstate *ps = yypstate_new ();
       assert (ps);
       assert (yypstate_new () == YY_NULL);
       ]m4_if([$1], [[both]], [[assert (yyparse () == 2)]])[;
@@ -140,6 +127,7 @@ main (void)
 AT_BISON_CHECK([[-o input.c input.y]])
 AT_COMPILE([[input]])
 AT_PARSER_CHECK([[./input]])
+AT_BISON_OPTION_POPDEFS
 ])
 
 AT_MULTIPLE_IMPURE_INSTANCES_CHECK([[both]])
@@ -155,12 +143,14 @@ AT_CLEANUP
 
 AT_SETUP([[Unsupported Skeletons]])
 
+AT_BISON_OPTION_PUSHDEFS
 AT_DATA([[input.y]],
 [[%glr-parser
 %define api.push-pull push
 %%
 start: ;
 ]])
+AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[input.y]], [[1]], [],
 [[input.y:2.9-21: %define variable 'api.push-pull' is not used
diff --git a/tests/regression.at b/tests/regression.at
index fd08800..bc129b7 100644
--- a/tests/regression.at
+++ b/tests/regression.at
@@ -462,11 +462,7 @@ AT_DATA_GRAMMAR([input.y],
 %%
 exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!";
 %%
-void
-yyerror (char const *s)
-{
-  fprintf (stderr, "%s\n", s);
-}
+]AT_YYERROR_DEFINE[
 
 int
 yylex (void)
@@ -892,15 +888,9 @@ member: STRING
    | INVALID
    ;
 %%
-AT_LALR1_CC_IF(
-[/* A C++ error reporting function. */
-void
-yy::parser::error (const std::string& m)
-{
-  std::cerr << m << std::endl;
-}
-
-int
+AT_YYERROR_DEFINE[
+]AT_LALR1_CC_IF(
+[int
 yyparse ()
 {
   yy::parser parser;
@@ -909,12 +899,7 @@ yyparse ()
 #endif
   return parser.parse ();
 }
-],
-[static void
-yyerror (const char *s)
-{
-  fprintf (stderr, "%s\n", s);
-}])
+])
 
 static int
 yylex (AT_LALR1_CC_IF([int *lval], [void]))
diff --git a/tests/torture.at b/tests/torture.at
index 061467d..a8837b2 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -56,7 +56,7 @@ print <<EOF;
 %{
 #include <stdio.h>
 #include <stdlib.h>
-
+#define MAX $max
 ]AT_YYLEX_DECLARE[
 ]AT_YYERROR_DECLARE[
 %}
@@ -90,20 +90,21 @@ for my $size (1 .. $max)
   {
     use Text::Wrap;
     print wrap ("| ", "   ",
-                (map { "\"$_\"" } (1 .. $size)),
-                " END \n"),
-                  "    { \$\$ = $size; }\n";
+               (map { "\"$_\"" } (1 .. $size)),
+               " END \n"),
+                 "    { \$\$ = $size; }\n";
   };
 print ";\n";
 
-print <<EOF;
+print <<\EOF;
 %%
+]AT_YYERROR_DEFINE[
 static int
 yylex (void)
 {
   static int inner = 1;
   static int outer = 0;
-  if (outer > $max)
+  if (outer > MAX)
     return 0;
   else if (inner > outer)
     {
@@ -113,13 +114,6 @@ yylex (void)
     }
   return inner++;
 }
-
-static void
-yyerror (const char *msg)
-{
-  fprintf (stderr, "%s\\n", msg);
-}
-
 int
 main (void)
 {
@@ -173,7 +167,7 @@ print <<EOF;
 %{
 #include <stdio.h>
 #include <stdlib.h>
-
+#define MAX $max
 ]AT_YYLEX_DECLARE[
 ]AT_YYERROR_DECLARE[
 %}
@@ -193,28 +187,23 @@ EOF
 use Text::Wrap;
 print
   wrap ("exp: ", "  ",
-        (map { "\"$_\"" } (1 .. $max)), ";"),
+       (map { "\"$_\"" } (1 .. $max)), ";"),
   "\n";
 
-print <<EOF;
+print <<\EOF;
 %%
+]AT_YYERROR_DEFINE[
 static int
 yylex (void)
 {
   static int counter = 1;
-  if (counter <= $max)
+  if (counter <= MAX)
     return counter++;
-  if (counter++ != $max + 1)
+  if (counter++ != MAX + 1)
     abort ();
   return 0;
 }
 
-static void
-yyerror (const char *msg)
-{
-  fprintf (stderr, "%s\\n", msg);
-}
-
 int
 main (void)
 {
@@ -282,7 +271,7 @@ print <<EOF;
 # include <stdio.h>
 # include <stdlib.h>
 # include <assert.h>
-
+# define MAX $max
 ]AT_YYLEX_DECLARE[
 ]AT_YYERROR_DECLARE[
 %}
@@ -297,8 +286,8 @@ EOF
 
 print
   wrap ("%type <val> ",
-        "            ",
-        map { "n$_" } (1 .. $max)),
+       "            ",
+       map { "n$_" } (1 .. $max)),
   "\n";
 
 print "%token\n";
@@ -329,17 +318,18 @@ for my $count (1 .. $max)
     print "n$count: token { \$\$ = $count; };\n";
   };
 
-print <<EOF;
+print <<\EOF;
 %%
+]AT_YYERROR_DEFINE[
 static int
 yylex (void)
 {
   static int return_token = 1;
   static int counter = 1;
-  if (counter > $max)
+  if (counter > MAX)
     {
-      if (counter++ != $max + 1)
-        abort ();
+      if (counter++ != MAX + 1)
+       abort ();
       return 0;
     }
   if (return_token)
@@ -351,12 +341,6 @@ yylex (void)
   return counter++;
 }
 
-static void
-yyerror (const char *msg)
-{
-  fprintf (stderr, "%s\\n", msg);
-}
-
 int
 main (void)
 {
@@ -437,8 +421,8 @@ main (int argc, const char **argv)
     abort ();
   yylval_init = strtol (argv[1], &endp, 10);
   if (! (argv[1] != endp
-         && 0 <= yylval_init && yylval_init <= INT_MAX
-         && errno != ERANGE))
+        && 0 <= yylval_init && yylval_init <= INT_MAX
+        && errno != ERANGE))
     abort ();
   yydebug = 1;
   {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]