mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
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:
13
NEWS
13
NEWS
@@ -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
1
THANKS
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
14
lib/.gitignore
vendored
@@ -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
6
m4/.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
13
src/gram.c
13
src/gram.c
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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]])
|
||||
|
||||
@@ -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: ;
|
||||
|
||||
@@ -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
|
||||
|
||||
#######################################################################
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user