Merge remote-tracking branch 'origin/maint'

* origin/maint:
  misc: pacify the Tiny C Compiler
  cpp: make the check of Flex version portable
  misc: require getline
  c++: support wide strings for file names
  doc: document carets
  tests: enhance existing tests with carets
  errors: show carets
  getargs: add support for --flags/-f

Conflicts:
	doc/bison.texi
	m4/.gitignore
	src/complain.c
	src/flex-scanner.h
	src/getargs.c
	src/getargs.h
	src/gram.c
	src/main.c
	tests/headers.at
This commit is contained in:
Theophile Ranquet
2012-12-06 11:43:02 +01:00
24 changed files with 519 additions and 43 deletions

13
NEWS
View File

@@ -247,6 +247,19 @@ GNU Bison NEWS
The introduction of this feature, in 2.4, was four years ago. The --language
option and the %language directive are no longer experimental.
** New format for error reports: carets
Caret errors have been added to Bison, for example (taken from the
documentation):
input.y:3.20-23: error: ambiguous reference: '$exp'
exp: exp '+' exp { $exp = $1 + $2; };
^^^^
The default behaviour for now is still not to display these unless explictly
asked with -fall of -fcaret. However, in a later release, it will be made the
default behavior (but may still be deactivated with -fno-caret).
** New value for %define variable: api.pure full
The %define variable api.pure requests a pure (reentrant) parser. However,

1
THANKS
View File

@@ -68,6 +68,7 @@ Lie Yan lie.yan@kaust.edu.sa
Magnus Fromreide magfr@lysator.liu.se
Marc Autret autret_m@epita.fr
Marc Mendiola mmendiol@usc.edu
Mark Boyall wolfeinstein@gmail.com
Martin Jacobs martin.jacobs@arcor.de
Martin Mokrejs mmokrejs@natur.cuni.cz
Martin Nylin martin.nylin@linuxmail.org

View File

@@ -20,7 +20,9 @@ gnulib_modules='
argmatch assert calloc-posix close closeout config-h c-strcase
configmake
dirname
error extensions fdl fopen-safer getopt-gnu
error extensions fdl fopen-safer
getline
getopt-gnu
gettext git-version-gen gitlog-to-changelog
gpl-3.0 hash inttypes isnan javacomp-script
javaexec-script ldexpl malloc-gnu

View File

@@ -1,3 +1,8 @@
# This file is expected to be used via gitlog-to-changelog's --amend=FILE
# option. It specifies what changes to make to each given SHA1's commit
# log and metadata, using Perl-eval'able expressions.
0db2648930e3b6c376a539aabe368aade83ee29a
s/--flags/--feature/;
s/flag_flag/feature_flag/;
s/\bflag\b/feature/;

View File

@@ -124,8 +124,9 @@ m4_define([b4_position_define],
** \param ostr the destination output stream
** \param pos a reference to the position to redirect
*/
inline std::ostream&
operator<< (std::ostream& ostr, const position& pos)
template <typename YYChar>
inline std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
{
if (pos.filename)
ostr << *pos.filename << ':';
@@ -248,7 +249,9 @@ m4_define([b4_location_define],
**
** Avoid duplicate information.
*/
inline std::ostream& operator<< (std::ostream& ostr, const location& loc)
template <typename YYChar>
inline std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
{
position last = loc.end - 1;
ostr << loc.begin;

View File

@@ -9606,6 +9606,56 @@ S/R conflicts as errors.
$ bison -Werror=yacc,conflicts-sr input.y
$ bison -Werror=yacc,error=conflicts-sr input.y
@end example
@item -f [@var{feature}]
@itemx --feature[=@var{feature}]
Activate miscellaneous @var{feature}. @var{feature} can be one of:
@table @code
@item caret
@itemx diagnostics-show-caret
Show caret errors, in a manner similar to GCC's
@option{-fdiagnostics-show-caret}, or Clang's @option{-fcaret-diagnotics}. The
location provided with the message is used to quote the corresponding line of
the source file, underlining the important part of it with carets (^). Here is
an example, using the following file @file{input.y}:
@example
%type <ival> exp
%%
exp: exp '+' exp @{ $exp = $1 + $2; @};
@end example
When invoked with @option{-fcaret}, Bison will report:
@example
@group
input.y:3.20-23: error: ambiguous reference: '$exp'
exp: exp '+' exp @{ $exp = $1 + $2; @};
^^^^
@end group
@group
input.y:3.1-3: refers to: $exp at $$
exp: exp '+' exp @{ $exp = $1 + $2; @};
^^^
@end group
@group
input.y:3.6-8: refers to: $exp at $1
exp: exp '+' exp @{ $exp = $1 + $2; @};
^^^
@end group
@group
input.y:3.14-16: refers to: $exp at $3
exp: exp '+' exp @{ $exp = $1 + $2; @};
^^^
@end group
@group
input.y:3.32-33: error: $2 of 'exp' has no declared type
exp: exp '+' exp @{ $exp = $1 + $2; @};
^^
@end group
@end example
@end table
@end table
@noindent

14
lib/.gitignore vendored
View File

@@ -101,7 +101,6 @@
/isnanf.c
/isnanl-nolibm.h
/isnanl.c
/iswblank.c
/itold.c
/ldexpl.c
/localcharset.c
@@ -109,13 +108,10 @@
/malloc.c
/math.h
/math.in.h
/mbchar.c
/mbchar.h
/mbrtowc.c
/mbsinit.c
/mbswidth.c
/mbswidth.h
/mbuiter.h
/memchr.c
/memchr.valgrind
/msvc-inval.c
@@ -215,8 +211,6 @@
/stripslash.c
/strndup.c
/strnlen.c
/strnlen1.c
/strnlen1.h
/strtol.c
/strtoul.c
/strverscmp.c
@@ -273,9 +267,5 @@
/xstrndup.h
/binary-io.c
/xsize.c
/bitrotate.c
/math.c
/sig-handler.c
/stdio.c
/unistd.c
/wctype-h.c
/getdelim.c
/getline.c

6
m4/.gitignore vendored
View File

@@ -63,7 +63,6 @@
/isnand.m4
/isnanf.m4
/isnanl.m4
/iswblank.m4
/javacomp.m4
/javaexec.m4
/largefile.m4
@@ -82,8 +81,6 @@
/longlong.m4
/malloc.m4
/math_h.m4
/mbchar.m4
/mbiter.m4
/mbrtowc.m4
/mbsinit.m4
/mbstate_t.m4
@@ -183,3 +180,6 @@
/obstack-printf.m4
/extern-inline.m4
/non-recursive-gnulib-prefix-hack.m4
/getdelim.m4
/getline.m4
/inline.m4

View File

@@ -110,12 +110,15 @@ error_message (const location *loc, warnings flags, const char *prefix,
warnings_print_categories (flags);
{
size_t l = strlen (message);
if (l < 2 || message[l-2] != ':' || message[l-1] != ' ')
if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
{
putc ('\n', stderr);
fflush (stderr);
if (loc && feature_flag & feature_caret)
location_caret (stderr, *loc);
}
}
fflush (stderr);
}
/** Raise a complaint. That can be a fatal error, a complaint or just a

View File

@@ -23,18 +23,18 @@
/* Whether this version of Flex is (strictly) greater than
Major.Minor.Subminor. */
#define FLEX_VERSION_GT(Major, Minor, Subminor) \
(defined YY_FLEX_MAJOR_VERSION \
&& (Major < YY_FLEX_MAJOR_VERSION \
|| (Major == YY_FLEX_MAJOR_VERSION \
&& (defined YY_FLEX_MINOR_VERSION \
&& (Minor < YY_FLEX_MINOR_VERSION \
|| (Minor == YY_FLEX_MINOR_VERSION \
&& defined YY_FLEX_SUBMINOR_VERSION \
&& Subminor < YY_FLEX_SUBMINOR_VERSION))))))
#ifdef YY_FLEX_SUBMINOR_VERSION
# define FLEX_VERSION \
(YY_FLEX_MAJOR_VERSION) * 1000000 \
+ (YY_FLEX_MINOR_VERSION) * 1000 \
+ (YY_FLEX_SUBMINOR_VERSION)
#else
# define FLEX_VERSION \
(YY_FLEX_MAJOR_VERSION) * 1000000 \
+ (YY_FLEX_MINOR_VERSION) * 1000
#endif
/* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used. */
#if ! FLEX_VERSION_GT (2, 5, 31)
# if FLEX_VERSION <= 2005031
int FLEX_PREFIX (get_lineno) (void);
FILE *FLEX_PREFIX (get_in) (void);
FILE *FLEX_PREFIX (get_out) (void);
@@ -65,7 +65,7 @@ int FLEX_PREFIX (lex_destroy) (void);
versions according to the Flex manual) leak memory if yylex_destroy is not
invoked. However, yylex_destroy is not defined before Flex 2.5.9, so give
an implementation here that at least appears to work with Flex 2.5.4. */
#if ! FLEX_VERSION_GT (2, 5, 9)
#if FLEX_VERSION <= 2005009
# define yylex_destroy() yy_delete_buffer (YY_CURRENT_BUFFER)
#endif

View File

@@ -46,6 +46,7 @@ bool yacc_flag; /* for -y */
bool nondeterministic_parser = false;
bool glr_parser = false;
int feature_flag = feature_none;
int report_flag = report_none;
int trace_flag = trace_none;
@@ -272,6 +273,27 @@ static const int warnings_types[] =
ARGMATCH_VERIFY (warnings_args, warnings_types);
/*-----------------------.
| --feature's handling. |
`-----------------------*/
static const char * const feature_args[] =
{
"none",
"caret", "diagnostics-show-caret",
"all",
0
};
static const int feature_types[] =
{
feature_none,
feature_caret, feature_caret,
feature_all
};
ARGMATCH_VERIFY (feature_args, feature_types);
/*-------------------------------------------.
| Display the help message and exit STATUS. |
`-------------------------------------------*/
@@ -315,6 +337,7 @@ Operation modes:\n\
--print-datadir output directory containing skeletons and XSLT\n\
-y, --yacc emulate POSIX Yacc\n\
-W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
-f, --feature[=FEATURE] activate miscellaneous features\n\
\n\
"), stdout);
@@ -331,8 +354,8 @@ Parser:\n\
deprecated by '-Dapi.prefix=PREFIX'\n\
-l, --no-lines don't generate '#line' directives\n\
-k, --token-table include a table of token names\n\
\n\
"), stdout);
putc ('\n', stdout);
/* Keep -d and --defines separate so that ../build-aux/cross-options.pl
* won't assume that -d also takes an argument. */
@@ -348,8 +371,8 @@ Output:\n\
-g, --graph[=FILE] also output a graph of the automaton\n\
-x, --xml[=FILE] also output an XML report of the automaton\n\
(the XML schema is experimental)\n\
\n\
"), stdout);
putc ('\n', stdout);
fputs (_("\
Warning categories include:\n\
@@ -375,6 +398,14 @@ THINGS is a list of comma separated words that can include:\n\
`all' include all the above information\n\
`none' disable the report\n\
"), stdout);
putc ('\n', stdout);
fputs (_("\
FEATURE is a list of comma separated words that can include:\n\
`caret' show errors with carets\n\
`all' all of the above\n\
`none' disable all of the above\n\
"), stdout);
putc ('\n', stdout);
printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
@@ -485,6 +516,7 @@ static char const short_options[] =
"W::"
"b:"
"d"
"f::"
"e"
"g::"
"h"
@@ -537,6 +569,7 @@ static struct option const long_options[] =
/* Output. */
{ "defines", optional_argument, 0, 'd' },
{ "feature", optional_argument, 0, 'f' },
/* Operation modes. */
{ "fixed-output-files", no_argument, 0, 'y' },
@@ -629,6 +662,10 @@ getargs (int argc, char *argv[])
version ();
exit (EXIT_SUCCESS);
case 'f':
FLAGS_ARGMATCH (feature, optarg, feature_all);
break;
case 'W':
FLAGS_ARGMATCH (warnings, optarg, Wall);
break;

View File

@@ -108,6 +108,18 @@ enum trace
/** What debug items bison displays during its run. */
extern int trace_flag;
/*-------------.
| --features. |
`-------------*/
enum feature
{
feature_none = 0, /**< No additional feature. */
feature_caret = 1 << 0, /**< Enhance the output of errors with carets. */
feature_all = ~0 /**< All above features. */
};
/** What additional features to use. */
extern int feature_flag;
/** Process the command line arguments.
*

View File

@@ -312,10 +312,15 @@ grammar_rules_useless_report (const char *message)
for (r = 0; r < nrules ; ++r)
if (!rules[r].useful)
{
complain (&rules[r].location, w | silent, "%s: ", message);
rule_print (&rules[r], stderr);
warnings_print_categories (w);
fprintf (stderr, "\n");
if (feature_flag & feature_caret)
complain (&rules[r].location, w, "%s", message);
else
{
complain (&rules[r].location, w | silent, "%s: ", message);
rule_print (&rules[r], stderr);
warnings_print_categories (w);
fprintf (stderr, "\n");
}
}
}
}

View File

@@ -103,7 +103,7 @@ conclude_red (struct obstack *out, int source, rule_number ruleno,
/* If no lookahead tokens were valid transitions, this reduction is
actually hidden, so cancel everything. */
if (first)
return (void) obstack_finish0 (out);
(void) obstack_finish0 (out);
else
{
char const *ed = enabled ? "" : "d";

View File

@@ -138,6 +138,89 @@ location_print (FILE *out, location loc)
return res;
}
/* Persistant data used by location_caret to avoid reopening and rereading the
same file all over for each error. */
struct caret_info
{
FILE* source;
size_t line;
size_t offset;
};
static struct caret_info caret_info = { NULL, 1, 0 };
/* Free any allocated ressources and close any open file handles that are
left-over by the usage of location_caret. */
void
cleanup_caret ()
{
if (caret_info.source)
fclose (caret_info.source);
}
/* Output to OUT the line and caret corresponding to location LOC. */
void
location_caret (FILE *out, location loc)
{
/* FIXME: find a way to support X-file locations, and only open once each
file. That would make the procedure future-proof. */
if (! (caret_info.source
|| (caret_info.source = fopen (loc.start.file, "r")))
|| loc.start.column == -1 || loc.start.line == -1)
return;
/* If the line we want to quote is seekable (the same line as the previous
location), just seek it. If it was before, we lost track of it, so
return to the start of file. */
if (caret_info.line <= loc.start.line)
fseek (caret_info.source, caret_info.offset, SEEK_SET);
else
{
caret_info.line = 1;
caret_info.offset = 0;
fseek (caret_info.source, caret_info.offset, SEEK_SET);
}
/* Advance to the line's position, keeping track of the offset. */
{
int i;
for (i = caret_info.line; i < loc.start.line; caret_info.offset++)
if (fgetc (caret_info.source) == '\n')
++i;
}
caret_info.line = loc.start.line;
/* Read the actual line. Don't update the offset, so that we keep a pointer
to the start of the line. */
{
ssize_t len = 0;
char *buf = NULL;
if ((len = getline (&buf, (size_t*) &len, caret_info.source)) != -1)
{
/* The caret of a multiline location ends with the first line. */
int end = loc.start.line != loc.end.line ? len : loc.end.column;
if (len)
{
int i = loc.start.column;
/* Quote the file, indent by a single column. */
fputc (' ', out);
fwrite (buf, 1, len, out);
/* Print the caret, with the same indent as above. */
fputc (' ', out);
fprintf (out, "%*s", loc.start.column - 1, "");
do {
fputc ('^', out);
} while (++i < end);
}
fputc ('\n', out);
free (buf);
}
}
}
void
boundary_set_from_string (boundary *bound, char *loc_str)
{

View File

@@ -102,6 +102,13 @@ void location_compute (location *loc,
characters. */
unsigned location_print (FILE *out, location loc);
/* Free any allocated ressources and close any open file handles that are
left-over by the usage of location_caret. */
void cleanup_caret (void);
/* Output to OUT the line and caret corresponding to location LOC. */
void location_caret (FILE *out, location loc);
/* Return -1, 0, 1, depending whether a is before, equal, or
after b. */
static inline int

View File

@@ -215,5 +215,7 @@ main (int argc, char *argv[])
timevar_stop (TV_TOTAL);
timevar_print (stderr);
cleanup_caret ();
return complaint_status ? EXIT_FAILURE : EXIT_SUCCESS;
}

View File

@@ -1329,6 +1329,21 @@ input.y:33.3-23: warning: unset value: $$ [-Wother]
input.y:30.3-35.37: warning: unused value: $3 [-Wother]
]])
AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
%printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
^^^
input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
%printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
^^^
input.y:33.3-23: warning: unset value: $$ [-Wother]
{ @$ = 4; } // Only used.
^^^^^^^^^^^^^^^^^^^^^
input.y:30.3-35.37: warning: unused value: $3 [-Wother]
{ @$ = 1; } // Not set or used.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]])
AT_COMPILE([input])
AT_PARSER_CHECK([./input], 1,,
[[Starting parse

View File

@@ -40,6 +40,12 @@ AT_BISON_CHECK([-o input.c input.y], 0, [],
[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother]
]])
AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
[[input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
e: 'e' | /* Nothing. */;
^
]])
AT_CLEANUP

View File

@@ -229,27 +229,30 @@ AT_TEST([x8], [%define api.pure %define api.push-pull both])
# C++ output relies on namespaces and still uses yy a lot.
#
# Check there is no 'YY' left.
# Ignore comments, YYPUSH_MORE(_DEFINED)? (constant definition),
# Ignore comments, YYChar (template parameter), YYPARSE_PARAM
# (obsolete), YYPUSH_MORE(_DEFINED)? (constant definition),
# YY_\w+_INCLUDED (header guards).
#
# YYDEBUG (not renamed) can be read, but not changed.
AT_CHECK([[$PERL -n -0777 -e '
s{/\*.*?\*/}{}gs;
s{//.*}{}g;
s{\b(YYPUSH_MORE(_DEFINED)?
s{\b(YYChar
|YYPARSE_PARAM
|YYPUSH_MORE(_DEFINED)?
|YY_\w+_INCLUDED
|YY_NULL
|(defined|if)\ YYDEBUG
)\b}{}gx;
while (/^(.*YY.*)$/gm)
{
print "$ARGV: $1\n";
print "$ARGV: invalid exported YY: $1\n";
}
if ($ARGV =~ /\.h$/)
{
while (/^(.*yy.*)$/gm)
{
print "$ARGV: $1\n";
print "$ARGV: invalid exported yy: $1\n";
}
}
' -- *.hh *.h]])

View File

@@ -925,6 +925,25 @@ input.y:19.13-20.0: error: missing '}' at end of file
input.y:20.1: error: syntax error, unexpected end of file
]])
AT_BISON_CHECK([-fcaret -o input.c input.y], 1, [],
[[input.y:1.10-2.0: error: missing '"' at end of line
%token A "a
^^
input.y:4.10-5.0: error: missing "'" at end of line
%token C '1
^^
input.y:14.11-15.0: error: missing "'" at end of line
%type <f> 'a
^^
input.y:16.11-17.0: error: missing '"' at end of line
%type <f> "a
^^
input.y:19.13-20.0: error: missing '}' at end of file
%destructor { free ($$)
^^^^^^^^^^^
input.y:20.1: error: syntax error, unexpected end of file
]])
AT_CLEANUP
@@ -1157,6 +1176,18 @@ AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
<command line>:1: previous definition
]])
AT_DATA([[input-dg.y]],
[[%define var "gram"
%%
start: ;
]])
AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
[[input-dg.y:1.9-11: error: %define variable 'var' redefined
%define var "gram"
^^^
<command line>:2: previous definition
]])
AT_DATA([[input-unused.y]],
[[%%
start: ;

View File

@@ -393,6 +393,127 @@ 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
]])
AT_BISON_CHECK([-fcaret -o test.c test.y], 1, [],
[[test.y:24.36-41: error: invalid reference: '$cond1'
{ $if_stmt1 = new IfStmt($cond1, $then.f1, $else); };
^^^^^^
test.y:23.11-24.62: symbol not found in production: cond1
if_stmt1: IF expr[cond] THEN stmt[then] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:26.43-53: error: invalid reference: '$stmt.field'
{ $if_stmt2 = new IfStmt($cond, $stmt.field, 0); };
^^^^^^^^^^^
test.y:25.11-26.60: symbol not found in production: stmt
if_stmt2: IF expr[cond] THEN stmt[then] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:25.35-38: possibly meant: $then.field, hiding $stmt.field at $4
if_stmt2: IF expr[cond] THEN stmt[then] FI
^^^^
test.y:28.43-52: error: invalid reference: '$stmt.list'
{ $if_stmt3 = new IfStmt($cond, $stmt.list, 0); };
^^^^^^^^^^
test.y:27.11-28.59: symbol not found in production: stmt
if_stmt3: IF expr[cond] THEN stmt.list FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:27.30-38: possibly meant: $[stmt.list] at $4
if_stmt3: IF expr[cond] THEN stmt.list FI
^^^^^^^^^
test.y:30.43-46: error: ambiguous reference: '$xyz'
{ $if_stmt4 = new IfStmt($cond, $xyz, $cond); };
^^^^
test.y:29.35-37: refers to: $xyz at $4
if_stmt4: IF expr[cond] THEN stmt[xyz] ELSE stmt[xyz] FI
^^^
test.y:29.50-52: refers to: $xyz at $6
if_stmt4: IF expr[cond] THEN stmt[xyz] ELSE stmt[xyz] FI
^^^
test.y:32.43-52: error: invalid reference: '$stmt.list'
{ $if_stmt5 = new IfStmt($cond, $stmt.list, $else); };
^^^^^^^^^^
test.y:31.11-32.63: symbol not found in production: stmt
if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:31.40-43: possibly meant: $then, hiding $[stmt.list] at $4
if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^
test.y:31.61-64: possibly meant: $else, hiding $[stmt.list] at $6
if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^
test.y:34.43-58: error: invalid reference: '$stmt.list.field'
{ $if_stmt6 = new IfStmt($cond, $stmt.list.field, $else); };
^^^^^^^^^^^^^^^^
test.y:33.11-34.69: symbol not found in production: stmt
if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:33.40-43: possibly meant: $then.field, hiding $[stmt.list].field at $4
if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^
test.y:33.61-64: possibly meant: $else.field, hiding $[stmt.list].field at $6
if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^
test.y:36.43-54: error: invalid reference: '$[stmt.list]'
{ $if_stmt7 = new IfStmt($cond, $[stmt.list].field, $else); };
^^^^^^^^^^^^
test.y:35.11-36.71: symbol not found in production: stmt.list
if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:35.40-43: possibly meant: $then, hiding $[stmt.list] at $4
if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^
test.y:35.61-64: possibly meant: $else, hiding $[stmt.list] at $6
if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^
test.y:38.43-49: error: invalid reference: '$then.1'
{ $if_stmt8 = new IfStmt($cond, $then.1, $else); };
^^^^^^^
test.y:37.11-38.60: symbol not found in production: then
if_stmt8: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:37.40-45: possibly meant: $[then.1] at $4
if_stmt8: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
^^^^^^
test.y:40.43-55: error: invalid reference: '$then.1.field'
{ $if_stmt9 = new IfStmt($cond, $then.1.field, $else); };
^^^^^^^^^^^^^
test.y:39.11-40.66: symbol not found in production: then
if_stmt9: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:39.40-45: possibly meant: $[then.1].field at $4
if_stmt9: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
^^^^^^
test.y:42.44-50: error: invalid reference: '$stmt.x'
{ $if_stmt10 = new IfStmt($cond, $stmt.x, 0); };
^^^^^^^
test.y:41.12-42.57: symbol not found in production: stmt
if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:41.36-41: possibly meant: $[stmt.x].x, hiding $stmt.x at $4
if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
^^^^^^
test.y:41.36-41: possibly meant: $[stmt.x] at $4
if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
^^^^^^
test.y:44.13-22: error: invalid reference: '$if-stmt-a'
{ $if-stmt-a = new IfStmt($cond, $then, $else); };
^^^^^^^^^^
test.y:43.12-44.59: symbol not found in production: if
if-stmt-a: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:43.1-9: possibly meant: $[if-stmt-a] at $$
if-stmt-a: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
^^^^^^^^^
test.y:46.46-54: error: invalid reference: '$then-a.f'
{ $[if-stmt-b] = new IfStmt($cond, $then-a.f, $else); };
^^^^^^^^^
test.y:45.12-46.65: symbol not found in production: then
if-stmt-b: IF expr[cond] THEN if-stmt-a[then-a] ELSE stmt.list[else] FI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
test.y:45.41-46: possibly meant: $[then-a].f at $4
if-stmt-b: IF expr[cond] THEN if-stmt-a[then-a] ELSE stmt.list[else] FI
^^^^^^
]])
AT_CLEANUP
#######################################################################

View File

@@ -142,6 +142,65 @@ useless8: '8';
useless9: '9';
]])
AT_BISON_CHECK([[-fcaret input.y]], 0, [],
[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
input.y: warning: 9 rules useless in grammar [-Wother]
input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
useless1: '1';
^^^^^^^^
input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
useless2: '2';
^^^^^^^^
input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
useless3: '3';
^^^^^^^^
input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
useless4: '4';
^^^^^^^^
input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
useless5: '5';
^^^^^^^^
input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
useless6: '6';
^^^^^^^^
input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
useless7: '7';
^^^^^^^^
input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
useless8: '8';
^^^^^^^^
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
useless9: '9';
^^^^^^^^
input.y:6.11-13: warning: rule useless in grammar [-Wother]
useless1: '1';
^^^
input.y:7.11-13: warning: rule useless in grammar [-Wother]
useless2: '2';
^^^
input.y:8.11-13: warning: rule useless in grammar [-Wother]
useless3: '3';
^^^
input.y:9.11-13: warning: rule useless in grammar [-Wother]
useless4: '4';
^^^
input.y:10.11-13: warning: rule useless in grammar [-Wother]
useless5: '5';
^^^
input.y:11.11-13: warning: rule useless in grammar [-Wother]
useless6: '6';
^^^
input.y:12.11-13: warning: rule useless in grammar [-Wother]
useless7: '7';
^^^
input.y:13.11-13: warning: rule useless in grammar [-Wother]
useless8: '8';
^^^
input.y:14.11-13: warning: rule useless in grammar [-Wother]
useless9: '9';
^^^
]])
AT_BISON_CHECK([[input.y]], 0, [],
[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
input.y: warning: 9 rules useless in grammar [-Wother]
@@ -238,6 +297,26 @@ non_productive: non_productive useless_token
%%
]])
AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
not-reduced.y: warning: 3 rules useless in grammar [-Wother]
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
not_reachable: useful { /* A not reachable action. */ }
^^^^^^^^^^^^^
not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
| non_productive { /* A non productive action. */ }
^^^^^^^^^^^^^^
not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
| non_productive { /* A non productive action. */ }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
not_reachable: useful { /* A not reachable action. */ }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
non_productive: non_productive useless_token
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]])
AT_BISON_CHECK([[not-reduced.y]], 0, [],
[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
not-reduced.y: warning: 3 rules useless in grammar [-Wother]

View File

@@ -481,6 +481,14 @@ AT_BISON_CHECK([-o input.c input.y], [[0]], [[]],
[[input.y:22.8-14: warning: symbol SPECIAL redeclared [-Wother]
input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string [-Wother]
]])
AT_BISON_CHECK([-fcaret -o input.c input.y], [[0]], [[]],
[[input.y:22.8-14: warning: symbol SPECIAL redeclared [-Wother]
%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
^^^^^^^
input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string [-Wother]
%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]])
AT_COMPILE([input])
# Checking the error message here guarantees that yytname, which does contain