c: no longer require stdio.h when locations are enabled
authorAkim Demaille <akim@lrde.epita.fr>
Fri, 25 Jan 2013 12:51:33 +0000 (13:51 +0100)
committerAkim Demaille <akim@lrde.epita.fr>
Fri, 25 Jan 2013 15:45:17 +0000 (16:45 +0100)
Recent changes (in 2.7) introduced a dependency on both FILE and
fprintf, which are "available" only in %debug mode.  This was to
define yy_location_print_, which is used only in %debug mode by the
parser, but massively used by the test suite to output the locations
in yyerror.

Break this dependency: the test suite should define its own routines
to display the locations.  Eventually Bison will provide the user with
a means to display locations, but not yet.

* data/c.m4 (b4_yy_location_print_define): Use YYFPRINTF instead of
fprintf directly.
* data/yacc.c (b4_yy_location_print_define): Invoke it only in %debug
mode, so that stdio.h is included (needed for FILE*), and YYFPRINTF
is defined.

* tests/local.at (AT_YYERROR_DECLARE, AT_YYERROR_DEFINE): Declare
and define location_print and LOCATION_PRINT.

* tests/actions.at, tests/existing.at, tests/glr-regression.at,
* tests/input.at, tests/named-refs.at, tests/regression.at: Adjust
to use them.
Fix the expected line numbers (as the prologue's length has changed).

NEWS
data/c.m4
data/glr.c
data/yacc.c
tests/actions.at
tests/existing.at
tests/glr-regression.at
tests/input.at
tests/local.at
tests/named-refs.at
tests/regression.at

diff --git a/NEWS b/NEWS
index f4314c4..c94af17 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,11 @@ GNU Bison NEWS
   This is has been fixed: yylval, yynerrs, yychar, and yylloc are now valid
   identifiers for user-provided variables.
 
+*** stdio.h is no longer needed when locations are enabled (yacc.c)
+
+  Changes in Bison 2.7 introduced a dependency on FILE and fprintf when
+  locations are enabled.  This is fixed.
+
 ** Diagnostics reported by Bison
 
   Most of these features were contributed by Théophile Ranquet and Victor
index ba62b72..3ddaa11 100644 (file)
--- a/data/c.m4
+++ b/data/c.m4
@@ -631,25 +631,25 @@ __attribute__((__unused__))
   int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
   if (0 <= yylocp->first_line)
     {
-      res += fprintf (yyo, "%d", yylocp->first_line);
+      res += YYFPRINTF (yyo, "%d", yylocp->first_line);
       if (0 <= yylocp->first_column)
-        res += fprintf (yyo, ".%d", yylocp->first_column);
+        res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
     }
   if (0 <= yylocp->last_line)
     {
       if (yylocp->first_line < yylocp->last_line)
         {
-          res += fprintf (yyo, "-%d", yylocp->last_line);
+          res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
           if (0 <= end_col)
-            res += fprintf (yyo, ".%d", end_col);
+            res += YYFPRINTF (yyo, ".%d", end_col);
         }
       else if (0 <= end_col && yylocp->first_column < end_col)
-        res += fprintf (yyo, "-%d", end_col);
+        res += YYFPRINTF (yyo, "-%d", end_col);
     }
   return res;
  }
 
-#  define YY_LOCATION_PRINT(File, Loc)                                   \
+#  define YY_LOCATION_PRINT(File, Loc)          \
   yy_location_print_ (File, &(Loc))
 
 # else
index be305f2..7ab3823 100644 (file)
@@ -396,7 +396,6 @@ dnl We probably ought to introduce a type for confl.
 ]b4_yylloc_default_define[
 # define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
 ]])[
-]b4_yy_location_print_define[
 
 ]b4_pure_if(
 [
@@ -437,6 +436,8 @@ typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
 #  define YYFPRINTF fprintf
 # endif
 
+]b4_yy_location_print_define[
+
 # define YYDPRINTF(Args)                        \
   do {                                          \
     if (yydebug)                                \
index ba72c24..88277a9 100644 (file)
@@ -676,7 +676,6 @@ while (0)
 ]b4_yylloc_default_define[
 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
 ]])[
-]b4_yy_location_print_define[
 
 /* Enable debugging if requested.  */
 #if ]b4_api_PREFIX[DEBUG
@@ -692,6 +691,8 @@ do {                                            \
     YYFPRINTF Args;                             \
 } while (0)
 
+]b4_yy_location_print_define[
+
 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
 do {                                                                      \
   if (yydebug)                                                            \
index 75e5d16..80b5239 100644 (file)
@@ -32,10 +32,10 @@ AT_BISON_OPTION_PUSHDEFS
 AT_DATA_GRAMMAR([[input.y]],
 [[%define parse.error verbose
 %debug
-%{
+%code {
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
-%}
+}
 %%
 exp:     { putchar ('0'); }
      '1' { putchar ('1'); }
@@ -92,7 +92,7 @@ AT_DATA_GRAMMAR([[input.y]],
 }
 %%
 exp: { ]AT_SKEL_CC_IF([[std::cerr << @$ << std::endl]],
-                      [[YY_LOCATION_PRINT(stderr, @$); fputc ('\n', stderr)]])[; }
+                      [[LOCATION_PRINT(stderr, @$); fputc ('\n', stderr)]])[; }
 %%
 ]AT_YYERROR_DEFINE[
 
@@ -146,7 +146,7 @@ AT_TEST([glr.cc])
 AT_TEST([yacc.c], [%define api.pure full],
 [[%{
 # define YYLTYPE int
-# define YY_LOCATION_PRINT(Stream, Loc)      \
+# define LOCATION_PRINT(Stream, Loc)      \
    (void) (Loc)
 # define YYLLOC_DEFAULT(Current, Rhs, N)    \
   (Current) = ((Rhs)[N ? 1 : 0])
@@ -157,7 +157,7 @@ AT_TEST([yacc.c], [%define api.pure full],
 AT_TEST([yacc.c], [%define api.pure full],
 [[%{
 # define YYLTYPE int
-# define YY_LOCATION_PRINT(Stream, Loc)      \
+# define LOCATION_PRINT(Stream, Loc)      \
     fprintf ((Stream), "%d", (Loc))
 # define YYLLOC_DEFAULT(Current, Rhs, N)    \
   (Current) = ((Rhs)[N ? 1 : 0])
@@ -190,8 +190,6 @@ AT_DATA_GRAMMAR([[input.y]],
 ]$3[
 %code
 {
-# include <stdio.h>
-# include <stdlib.h> /* getenv */
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
 }
@@ -212,7 +210,7 @@ main (void)
   loc.]AT_LAST_LINE[ = L2;            \
   loc.]AT_LAST_COLUMN[ = C2;          \
   ]AT_SKEL_CC_IF([std::cout << loc],
-                 [YY_LOCATION_PRINT(stdout, loc)])[;\
+                 [LOCATION_PRINT(stdout, loc)])[;\
   putchar ('\n');
 
   TEST(1, 1, 1, 1);
@@ -259,11 +257,11 @@ AT_BISON_OPTION_PUSHDEFS
 AT_DATA_GRAMMAR([[input.y]],
 [[%define parse.error verbose
 %debug
-%{
+%code {
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
 # define USE(Var)
-%}
+}
 
 %union
 {
@@ -309,7 +307,6 @@ AT_PARSER_CHECK([./input], 0,
 AT_DATA_GRAMMAR([[input.y]],
 [[
 %{
-# include <stdio.h>
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
   typedef struct { int val; } stype;
@@ -764,13 +761,11 @@ AT_DATA_GRAMMAR([[input.y]],
 %debug
 %locations
 
-%{
-# include <stdio.h>
-# include <stdlib.h>
+%code {
 ]AT_YYLEX_DECLARE[
 ]AT_YYERROR_DECLARE[
 # define USE(SYM)
-%}
+}
 
 %printer {
   fprintf (yyoutput, "<*> printer should not be called.\n");
@@ -805,8 +800,8 @@ start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ;
 ]])
 
 AT_BISON_CHECK([-o input.c input.y], [], [],
-[[input.y:23.3-5: warning: useless %destructor for type <*> [-Wother]
-input.y:23.3-5: warning: useless %printer for type <*> [-Wother]
+[[input.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
+input.y:30.3-5: warning: useless %printer for type <*> [-Wother]
 ]])
 AT_COMPILE([input])
 AT_PARSER_CHECK([./input --debug], 1,
@@ -859,8 +854,6 @@ AT_DATA_GRAMMAR([[input.y]],
 %debug
 
 %{
-# include <stdio.h>
-# include <stdlib.h>
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
 # define USE(SYM)
@@ -988,13 +981,11 @@ AT_DATA_GRAMMAR([[input]]$1[[.y]],
 %debug
 %locations
 
-%{
-# include <stdio.h>
-# include <stdlib.h>
+%code {
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
 # define USE(SYM)
-%}
+}
 
 %destructor {
   fprintf (yyoutput, "<]]not_kind[[> destructor should not be called.\n");
@@ -1022,7 +1013,7 @@ AT_DATA_GRAMMAR([[input]]$1[[.y]],
 start: { $$ = 'S'; } ;
 
 %%
-
+#include <stdlib.h> // abort
 static int
 yylex (void)
 {
@@ -1041,11 +1032,11 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([-o input$1.c input$1.y], [], [],
 [m4_if([$1], [0],
-[[input0.y:23.3-5: warning: useless %destructor for type <*> [-Wother]
-input0.y:23.3-5: warning: useless %printer for type <*> [-Wother]
+[[input0.y:30.3-5: warning: useless %destructor for type <*> [-Wother]
+input0.y:30.3-5: warning: useless %printer for type <*> [-Wother]
 ]],
-[[input1.y:23.3-4: warning: useless %destructor for type <> [-Wother]
-input1.y:23.3-4: warning: useless %printer for type <> [-Wother]
+[[input1.y:30.3-4: warning: useless %destructor for type <> [-Wother]
+input1.y:30.3-4: warning: useless %printer for type <> [-Wother]
 ]])])
 
 AT_COMPILE([input$1])
@@ -1056,7 +1047,7 @@ AT_PARSER_CHECK([./input$1 --debug], 0,
 ]],
 [[Starting parse
 Entering state 0
-Reducing stack by rule 1 (line 42):
+Reducing stack by rule 1 (line 49):
 -> $$ = nterm start (1.1: <]]kind[[> for 'S' @ 1)
 Stack now 0
 Entering state 1
@@ -1131,8 +1122,8 @@ start:
 AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([-o input.c input.y], [], [],
-[[input.y:21.6-8: warning: useless %destructor for type <*> [-Wother]
-input.y:21.6-8: warning: useless %printer for type <*> [-Wother]
+[[input.y:23.6-8: warning: useless %destructor for type <*> [-Wother]
+input.y:23.6-8: warning: useless %printer for type <*> [-Wother]
 ]])
 AT_COMPILE([input])
 AT_PARSER_CHECK([./input --debug], [1], [],
@@ -1229,8 +1220,8 @@ start: { USE($$); } ;
 AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([-o input.c input.y], [], [],
-[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
-input.y:22.3-4: warning: useless %printer for type <> [-Wother]
+[[input.y:24.3-4: warning: useless %destructor for type <> [-Wother]
+input.y:24.3-4: warning: useless %printer for type <> [-Wother]
 ]])
 AT_COMPILE([input])
 
@@ -1249,14 +1240,12 @@ AT_DATA_GRAMMAR([[input.y]],
 [[%debug /* So that %printer is actually compiled.  */
 
 %{
-# include <stdio.h>
-# include <stdlib.h>
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
 # define USE(SYM)
 # define YYLTYPE int
 # define YYLLOC_DEFAULT(Current, Rhs, N) (void)(Rhs)
-# define YY_LOCATION_PRINT(File, Loc)
+# define LOCATION_PRINT(File, Loc)
 %}
 
 %printer { fprintf (yyoutput, "%d", @$); } <>
index 5c32ecd..0209c35 100644 (file)
@@ -1953,7 +1953,7 @@ dnl without being followed by "of".)
 [[VARIABLE, '=', LABEL, LEFT, DOT_X]],
 
 dnl BISON-STDERR
-[[input.y:470.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path [-Wother]
+[[input.y:471.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path [-Wother]
 ]],
 
 dnl LAST-STATE
index 96e215c..918bc8d 100644 (file)
@@ -1643,10 +1643,10 @@ sym3: %merge<merge> { $$ = 0; } ;
 AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [],
-[[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
-glr-regr18.y: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
+[[glr-regr18.y:28.18-24: error: result type clash on merge function 'merge': <type2> != <type1>
+glr-regr18.y:27.18-24:     previous declaration
+glr-regr18.y:29.13-19: error: result type clash on merge function 'merge': <type3> != <type2>
+glr-regr18.y:28.18-24:     previous declaration
 ]])
 
 AT_CLEANUP
@@ -1699,14 +1699,14 @@ Entering state 1
 Reading a token: Next token is token 'b' ()
 Shifting token 'b' ()
 Entering state 3
-Reducing stack 0 by rule 3 (line 25):
+Reducing stack 0 by rule 3 (line 27):
    $1 = token 'b' ()
 -> $$ = nterm b ()
 Entering state 4
 Reading a token: Next token is token 'c' ()
 Shifting token 'c' ()
 Entering state 6
-Reducing stack 0 by rule 4 (line 26):
+Reducing stack 0 by rule 4 (line 28):
 -> $$ = nterm d ()
 Entering state 7
 Reading a token: Now at end of input.
index ac5a1fb..9a3d87e 100644 (file)
@@ -972,13 +972,13 @@ AT_BISON_OPTION_POPDEFS
 # POSIX Yacc accept periods, but not dashes.
 AT_BISON_CHECK([--yacc -Wno-error input.y], [], [],
 [[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH [-Wyacc]
-input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
+input.y:20.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
 ]])
 
 # So warn about them.
 AT_BISON_CHECK([-Wyacc input.y], [], [],
 [[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH [-Wyacc]
-input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
+input.y:20.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
 ]])
 
 # Dashes are fine for GNU Bison.
index 10179cb..39de663 100644 (file)
@@ -417,12 +417,51 @@ m4_define([AT_YYERROR_DECLARE_EXTERN],
 
 m4_define([AT_YYERROR_DECLARE],
 [m4_case(AT_LANG,
-[c], [static AT_YYERROR_DECLARE_EXTERN])[]dnl
+[c], [#include <stdio.h>
+]AT_LOCATION_IF([[
+#if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
+static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
+# ifndef LOCATION_PRINT
+#  define LOCATION_PRINT(File, Loc) location_print (File, &(Loc))
+# endif
+#endif
+]])[
+static AT_YYERROR_DECLARE_EXTERN])[]dnl
 ])
 
 m4_define([AT_YYERROR_DEFINE],
 [m4_case(AT_LANG,
-[c], [[#include <stdio.h>
+[c], [[
+]AT_LOCATION_IF([[
+# if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
+/* Print *YYLOCP on YYO. */
+__attribute__((__unused__))
+static unsigned
+location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp)
+{
+  unsigned res = 0;
+  int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+  if (0 <= yylocp->first_line)
+    {
+      res += fprintf (yyo, "%d", yylocp->first_line);
+      if (0 <= yylocp->first_column)
+        res += fprintf (yyo, ".%d", yylocp->first_column);
+    }
+  if (0 <= yylocp->last_line)
+    {
+      if (yylocp->first_line < yylocp->last_line)
+        {
+          res += fprintf (yyo, "-%d", yylocp->last_line);
+          if (0 <= end_col)
+            res += fprintf (yyo, ".%d", end_col);
+        }
+      else if (0 <= end_col && yylocp->first_column < end_col)
+        res += fprintf (yyo, "-%d", end_col);
+    }
+  return res;
+}
+#endif
+]])[
 /* A C error reporting function.  */
 static
 ]AT_YYERROR_PROTOTYPE[
@@ -430,7 +469,7 @@ static
               [[^,]+[^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[);
+  LOCATION_PRINT (stderr, ]AT_LOC[);
   fprintf (stderr, ": ");]])[
   fprintf (stderr, "%s\n", msg);
 }]],
@@ -884,7 +923,6 @@ AT_SETUP([$1])
 AT_BISON_OPTION_PUSHDEFS([$4])
 AT_DATA_GRAMMAR([[input.y]],
 [[%code {
-  #include <stdio.h>
   ]AT_YYERROR_DECLARE[
   ]AT_YYLEX_DECLARE[
 }
@@ -907,11 +945,7 @@ yylex (void)
   return *inputp++;
 }
 
-int
-main (void)
-{
-  return yyparse ();
-}
+]AT_MAIN_DEFINE[
 ]])
 
 # In some versions of Autoconf, AT_CHECK invokes AS_ESCAPE before
index ec44e04..1b76c80 100644 (file)
@@ -188,7 +188,9 @@ AT_CLEANUP
 
 
 
-#######################################################################
+## ------------------------------------ ##
+## Undefined and ambiguous references.  ##
+## ------------------------------------ ##
 
 
 AT_SETUP([Undefined and ambiguous references])
@@ -250,44 +252,47 @@ exp:
 ]])
 
 AT_BISON_CHECK([-fcaret -o test.c test.y], 1, [],
-[[test.y:50.51-60: error: invalid reference: '$<ival>lo9'
+[[test.y:52.51-60: error: invalid reference: '$<ival>lo9'
  | exp[x] '+' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>lo9 + $r; }
                                                    ^^^^^^^^^^
-test.y:50.3-68:      symbol not found in production: lo9
+test.y:52.3-68:      symbol not found in production: lo9
  | exp[x] '+' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>lo9 + $r; }
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-test.y:51.51-60: warning: misleading reference: '$<ival>exp' [-Wother]
+test.y:53.51-60: warning: misleading reference: '$<ival>exp' [-Wother]
  | exp[x] '-' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>exp - $r; }
                                                    ^^^^^^^^^^
-test.y:42.1-3:       refers to: $exp at $$
+test.y:44.1-3:       refers to: $exp at $$
  exp:
  ^^^
-test.y:51.7:         possibly meant: $x, hiding $exp at $1
+test.y:53.7:         possibly meant: $x, hiding $exp at $1
  | exp[x] '-' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>exp - $r; }
        ^
-test.y:51.41:        possibly meant: $r, hiding $exp at $4
+test.y:53.41:        possibly meant: $r, hiding $exp at $4
  | exp[x] '-' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>exp - $r; }
                                          ^
-test.y:52.51-52: error: $l of 'exp' has no declared type
+test.y:54.51-52: error: $l of 'exp' has no declared type
  | exp[x] '*' { $<ival>$ = $x; } [l] exp[r] { $$ = $l * $r; }
                                                    ^^
-test.y:55.40-43: error: invalid reference: '$r12'
+test.y:57.40-43: error: invalid reference: '$r12'
  | exp[l] '^' exp[r]  { $$ = power ($l, $r12); }
                                         ^^^^
-test.y:55.3-47:      symbol not found in production: r12
+test.y:57.3-47:      symbol not found in production: r12
  | exp[l] '^' exp[r]  { $$ = power ($l, $r12); }
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-test.y:56.29-33: error: invalid reference: '$expo'
+test.y:58.29-33: error: invalid reference: '$expo'
  | '(' exp ')'        { $$ = $expo;           }
                              ^^^^^
-test.y:56.3-46:      symbol not found in production: expo
+test.y:58.3-46:      symbol not found in production: expo
  | '(' exp ')'        { $$ = $expo;           }
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ]])
 AT_BISON_OPTION_POPDEFS
 AT_CLEANUP
 
-#######################################################################
+
+## ----------------------- ##
+## Misleading references.  ##
+## ----------------------- ##
 
 AT_SETUP([Misleading references])
 AT_DATA_GRAMMAR([test.y],
index 4222b40..26df108 100644 (file)
@@ -130,7 +130,6 @@ AT_SETUP([Early token definitions without --yacc])
 AT_BISON_OPTION_PUSHDEFS
 AT_DATA_GRAMMAR([input.y],
 [[%{
-#include <stdio.h>
 ]AT_YYERROR_DECLARE_EXTERN[
 ]AT_YYLEX_DECLARE_EXTERN[
 void print_my_token (void);
@@ -141,6 +140,7 @@ void print_my_token (void);
   int val;
 };
 %{
+#include <stdio.h>
 void
 print_my_token (void)
 {
@@ -446,8 +446,6 @@ AT_BISON_OPTION_PUSHDEFS
 # Bison managed, when fed with '%token 'f' "f"' to #define 'f'!
 AT_DATA_GRAMMAR([input.y],
 [%{
-#include <stdlib.h>
-#include <stdio.h>
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
 %}
@@ -920,8 +918,7 @@ m4_define([_AT_DATA_EXPECT2_Y],
 [%{
 static int yylex (AT_LALR1_CC_IF([int *], [void]));
 AT_LALR1_CC_IF([[#include <cstdlib>]],
-[[#include <stdlib.h>
-#include <stdio.h>
+[[
 ]AT_YYERROR_DECLARE])[
 %}
 $1
@@ -999,13 +996,11 @@ AT_SETUP([Braced code in declaration in rules section])
 AT_BISON_OPTION_PUSHDEFS([%debug])
 AT_DATA_GRAMMAR([input.y],
 [[%{
-#include <stdio.h>
 ]AT_YYERROR_DECLARE[
 ]AT_YYLEX_DECLARE[
 %}
 %debug
 %error-verbose
-
 %%
 
 start:
@@ -1123,11 +1118,10 @@ AT_SETUP([[Token number in precedence declaration]])
 # we lost this in Bison 1.50.
 AT_BISON_OPTION_PUSHDEFS
 AT_DATA_GRAMMAR([input.y],
-[[%{
-  #include <stdio.h>
+[[%code {
   ]AT_YYERROR_DECLARE[
   ]AT_YYLEX_DECLARE[
-%}
+}
 
 %error-verbose
 %right END 0
@@ -1153,8 +1147,8 @@ sr_conflict:
 AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o input.c input.y]], [[0]],,
-[[input.y:23.5-19: warning: rule useless in parser due to conflicts: start: start [-Wother]
-input.y:27.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" [-Wother]
+[[input.y:24.5-19: warning: rule useless in parser due to conflicts: start: start [-Wother]
+input.y:28.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" [-Wother]
 ]])
 AT_COMPILE([[input]])
 AT_PARSER_CHECK([[./input]])
@@ -1197,7 +1191,6 @@ AT_SETUP([[parse.error=verbose and YYSTACK_USE_ALLOCA]])
 AT_BISON_OPTION_PUSHDEFS
 AT_DATA_GRAMMAR([input.y],
 [[%code {
-  #include <stdio.h>
   ]AT_YYERROR_DECLARE[
   ]AT_YYLEX_DECLARE[
   #define YYSTACK_USE_ALLOCA 1
@@ -1272,7 +1265,6 @@ AT_SETUP([[parse.error=verbose overflow]])
 AT_BISON_OPTION_PUSHDEFS
 AT_DATA_GRAMMAR([input.y],
 [[%code {
-  #include <stdio.h>
   ]AT_YYERROR_DECLARE[
   ]AT_YYLEX_DECLARE[
 
@@ -1386,7 +1378,6 @@ AT_BISON_OPTION_PUSHDEFS([%debug $1])
 
 AT_DATA_GRAMMAR([input.y],
 [[%code {
-  #include <stdio.h>
   ]AT_YYERROR_DECLARE[
   int yylex (]AT_PURE_IF([[YYSTYPE *]], [[void]])[);
 }
@@ -1473,7 +1464,6 @@ m4_pushdef([AT_LAC_CHECK],
 [AT_BISON_OPTION_PUSHDEFS([%debug])
 AT_DATA_GRAMMAR([input.y],
 [[%code {
-  #include <stdio.h>
   ]AT_YYERROR_DECLARE[
   ]AT_YYLEX_DECLARE[
   #define YYMAXDEPTH 8
@@ -1547,10 +1537,9 @@ AT_CLEANUP
 m4_pushdef([AT_TEST],
 [AT_SETUP([[Lex and parse params: $1]])
 
+## FIXME: Improve parsing of parse-param.
 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
@@ -1565,9 +1554,6 @@ AT_DATA_GRAMMAR([input.y],
 }
 
 %{
-#include <stdio.h>
-#include <stdlib.h>
-
   ]AT_YYERROR_DECLARE[
   ]AT_YYLEX_DECLARE[
 %}
@@ -1609,3 +1595,33 @@ AT_TEST([lalr1.cc])
 AT_TEST([glr.cc])
 
 m4_popdef([AT_TEST])
+
+
+## ----------------------- ##
+## stdio.h is not needed.  ##
+## ----------------------- ##
+
+# At some point, by accident, yy_location_print_ was using fprintf and
+# FILE which are from stdio.h, which we do not require.
+AT_SETUP([[stdio.h is not needed]])
+
+AT_BISON_OPTION_PUSHDEFS
+
+AT_DATA_GRAMMAR([input.y],
+[[%locations
+%code
+{
+  static int yylex (void) { return 0; }
+  static void yyerror (const char* msg) { (void) msg; }
+}
+%%
+exp: {}
+%%
+]AT_MAIN_DEFINE[
+]])
+
+AT_FULL_COMPILE([input])
+
+AT_BISON_OPTION_POPDEFS
+
+AT_CLEANUP