From: Akim Demaille Date: Wed, 26 Sep 2012 12:35:47 +0000 (+0200) Subject: Merge branch 'maint' X-Git-Tag: v2.7.90~323 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/11b192127cac086338bfaa43f3bab3acda8e3a20?ds=inline;hp=-c Merge branch 'maint' * maint: warnings: introduce -Wdeprecated in the usage info errors: prefix the output with "error: " errors: indent "invalid value for %define" context errors: indent "%define var" redefinition context errors: indent "symbol redeclaration" context errors: indent "result type clash" error context Conflicts: src/complain.c src/muscle-tab.c src/reader.c src/symtab.c tests/conflicts.at tests/input.at tests/named-refs.at tests/output.at tests/skeletons.at --- 11b192127cac086338bfaa43f3bab3acda8e3a20 diff --combined NEWS index 7f0fe8b2,772a2d51..a70c23db --- a/NEWS +++ b/NEWS @@@ -2,203 -2,6 +2,203 @@@ GNU Bison NEW * Noteworthy changes in release ?.? (????-??-??) [?] +** Incompatible changes + +*** Obsolete features + + Support for YYFAIL is removed (deprecated in Bison 2.4.2). + Support for yystype and yyltype (instead of YYSTYPE and YYLTYPE) + is removed (deprecated in Bison 1.875). + Support for YYPARSE_PARAM is removed (deprecated in Bison 1.875). + +** Warnings + +*** Deprecated constructs + + The new 'deprecated' warning category flags obsolete constructs whose + support will be discontinued. It is enabled by default. These warnings + used to be reported as 'other' warnings. + +*** Warning categories are now displayed + + For instance: + + foo.y:4.6: warning: type clash on default action: != [-Wother] + +*** Useless semantic types + + Bison now warns about useless (uninhabited) semantic types. Since + semantic types are not declared to Bison (they are defined in the opaque + %union structure), it is %printer/%destructor directives about useless + types that trigger the warning: + + %token term + %type nterm + %printer {} + %destructor {} + %% + nterm: term { $$ = $1; }; + + 3.28-34: warning: type is used, but is not associated to any symbol + 4.28-34: warning: type is used, but is not associated to any symbol + +*** Undefined but unused symbols + + Bison used to raise an error for undefined symbols that are not used in + the grammar. This is now only a warning. + + %printer {} symbol1 + %destructor {} symbol2 + %type symbol3 + %% + exp: "a"; + +*** Useless destructors or printers + + Bison now warns about useless destructors or printers. In the following + example, the printer for , and the destructor for are + useless: all symbols of (token1) already have a printer, and all + symbols of type (token2) already have a destructor. + + %token token1 + token2 + token3 + token4 + %printer {} token1 + %destructor {} token2 + +*** Conflicts + + The warnings and error messages about shift/reduce and reduce/reduce + conflicts have been normalized. For instance on the following foo.y file: + + %glr-parser + %% + exp: exp '+' exp | '0' | '0'; + + compare the previous version of bison: + + $ bison foo.y + foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce + $ bison -Werror foo.y + bison: warnings being treated as errors + foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce + + with the new behavior: + + $ bison foo.y + foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] + foo.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr] + $ bison -Werror foo.y + bison: warnings being treated as errors + foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] + foo.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr] + + When %expect or %expect-rr is used, such as with bar.y: + + %expect 0 + %glr-parser + %% + exp: exp '+' exp | '0' | '0'; + + Former behavior: + + $ bison bar.y + bar.y: conflicts: 1 shift/reduce, 2 reduce/reduce + bar.y: expected 0 shift/reduce conflicts + bar.y: expected 0 reduce/reduce conflicts + + New one: + + $ bison bar.y + bar.y: shift/reduce conflicts: 1 found, 0 expected + bar.y: reduce/reduce conflicts: 2 found, 0 expected + +** Additional yylex/yyparse arguments + + The new directive %param declares additional arguments to both yylex and + yyparse. The %lex-param, %parse-param, and %param directives support one + or more arguments. Instead of + + %lex-param {arg1_type *arg1} + %lex-param {arg2_type *arg2} + %parse-param {arg1_type *arg1} + %parse-param {arg2_type *arg2} + + one may now declare + + %param {arg1_type *arg1} {arg2_type *arg2} + +** Java skeleton improvements + + The constants for token names were moved to the Lexer interface. Also, it + is possible to add code to the parser's constructors using "%code init" + and "%define init_throws". + +** C++ skeletons improvements + +*** The parser header is no longer mandatory (lalr1.cc, glr.cc) + + Using %defines is now optional. Without it, the needed support classes + are defined in the generated parser, instead of additional files (such as + location.hh, position.hh and stack.hh). + +*** Locations are no longer mandatory (lalr1.cc, glr.cc) + + Both lalr1.cc and glr.cc no longer require %location. + +*** syntax_error exception (lalr1.cc) + + The C++ parser features a syntax_error exception, which can be + thrown from the scanner or from user rules to raise syntax errors. + This facilitates reporting errors caught in sub-functions (e.g., + rejecting too large integral literals from a conversion function + used by the scanner, or rejecting invalid combinations from a + factory invoked by the user actions). + +** Variable api.tokens.prefix + + The variable api.tokens.prefix changes the way tokens are identified in + the generated files. This is especially useful to avoid collisions + with identifiers in the target language. For instance + + %token FILE for ERROR + %define api.tokens.prefix "TOK_" + %% + start: FILE for ERROR; + + will generate the definition of the symbols TOK_FILE, TOK_for, and + TOK_ERROR in the generated sources. In particular, the scanner must + use these prefixed token names, although the grammar itself still + uses the short names (as in the sample rule given above). + +** Variable api.namespace + + The 'namespace' variable is renamed 'api.namespace'. Backward + compatibility is ensured, but upgrading is recommended. + +** Variable parse.error + + This variable controls the verbosity of error messages. The use of the + %error-verbose directive is deprecated in favor of "%define parse.error + verbose". + +** Semantic predicates + + The new, experimental, semantic-predicate feature allows actions of the + form "%?{ BOOLEAN-EXPRESSION }", which cause syntax errors (as for + YYERROR) if the expression evaluates to 0, and are evaluated immediately + in GLR parsers, rather than being deferred. The result is that they allow + the programmer to prune possible parses based on the values of run-time + expressions. + +** The directive %expect-rr is now an error in non GLR mode + + It used to be an error only if used in non GLR mode, _and_ if there are + reduce/reduce conflicts. + +* Noteworthy changes in release ?.? (????-??-??) [?] + ** Bug fixes Bugs in the test suite have been fixed. @@@ -211,6 -14,18 +211,18 @@@ Incorrect definitions of YY_, issued by yacc.c when no parser header is generated, are removed. + ** Changes in the format of errors and exceptions output + + This used to be the format of many error reports: + + foo.y:5.10-24: result type clash on merge function 'merge': != + foo.y:4.13-27: previous declaration + + It is now: + + foo.y:5.10-25: result type clash on merge function 'merge': != + foo.y:4.13-27: previous declaration + * Noteworthy changes in release 2.6.2 (2012-08-03) [stable] ** Bug fixes @@@ -229,7 -44,7 +241,7 @@@ * Noteworthy changes in release 2.6.1 (2012-07-30) [stable] - Bison no longer executes user-specified M4 code when processing a grammar. + Bison no longer executes user-specified M4 code when processing a grammar. ** Future Changes @@@ -267,7 -82,7 +279,7 @@@ * Noteworthy changes in release 2.6 (2012-07-19) [stable] -** Future Changes +** Future changes: The next major release of Bison will drop support for the following deprecated features. Please report disagreements to bug-bison@gnu.org. @@@ -2068,8 -1883,7 +2080,8 @@@ along with this program. If not, see < LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf - LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp + LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init + LocalWords: TOK Local Variables: mode: outline diff --combined THANKS index 4ed4256d,8af0abbe..19ec28a9 --- a/THANKS +++ b/THANKS @@@ -71,7 -71,6 +71,7 @@@ Matt Kraai kraai@alumni. Matt Rosing rosing@peakfive.com Michael Hayes m.hayes@elec.canterbury.ac.nz Michael Raskin 7c6f434c@mail.ru +Michiel De Wilde mdewilde.agilent@gmail.com Mickael Labau labau_m@epita.fr Mike Castle dalgoda@ix.netcom.com Neil Booth NeilB@earthling.net @@@ -89,7 -88,6 +89,7 @@@ Per Allansson per@appgate.c Peter Fales psfales@lucent.com Peter Hamorsky hamo@upjs.sk Piotr Gackiewicz gacek@intertel.com.pl +Quentin Hocquet hocquet@gostai.com Quoc Peyrot chojin@lrde.epita.fr R Blake blakers@mac.com Raja R Harinath harinath@cs.umn.edu @@@ -104,6 -102,7 +104,7 @@@ Shura debil_urod@ng Stefano Lattarini stefano.lattarini@gmail.com Steve Murphy murf@parsetree.com Sum Wu sum@geekhouse.org + Théophile Ranquet theophile.ranquet@gmail.com Thiru Ramakrishnan thiru.ramakrishnan@gmail.com Tim Josling tej@melbpc.org.au Tim Landscheidt tim@tim-landscheidt.de @@@ -127,6 -126,7 +128,7 @@@ thank them! Please, help us keeping th Local Variables: mode: text + coding: utf-8 End: ----- diff --combined src/complain.c index d79a2502,b063c6b6..1834120d --- a/src/complain.c +++ b/src/complain.c @@@ -29,45 -29,15 +29,45 @@@ #include "files.h" #include "getargs.h" +warnings warnings_flag = + Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother; + bool complaint_issued; static unsigned *indent_ptr = 0; - +void +warnings_print_categories (warnings warn_flags) +{ + if (! (warn_flags & silent)) + { + char const *warn_names[] = + { + "midrule-values", + "yacc", + "conflicts-sr", + "conflicts-rr", + "deprecated", + "other" + }; + + bool any = false; + int i; + for (i = 0; i < ARRAY_CARDINALITY (warn_names); ++i) + if (warn_flags & 1 << i) + { + fprintf (stderr, "%s-W%s", any ? ", " : " [", warn_names[i]); + any = true; + } + if (any) + fprintf (stderr, "]"); + } +} /** Report an error message. * * \param loc the location, defaulting to the current file, * or the program name. + * \param flags the category for this message. * \param prefix put before the message (e.g., "warning"). * \param message the error message, a printf format string. Iff it * ends with ": ", then no trailing newline is printed, @@@ -77,10 -47,10 +77,10 @@@ */ static void -error_message (location *loc, - const char *prefix, - const char *message, va_list args) +error_message (const location *loc, warnings flags, const char *prefix, + const char *message, va_list args) { + (void) flags; unsigned pos = 0; if (loc) @@@ -102,95 -72,142 +102,102 @@@ fprintf (stderr, "%s: ", prefix); vfprintf (stderr, message, args); + warnings_print_categories (flags); { size_t l = strlen (message); - if (l < 2 || message[l-2] != ':' || message[l-1] != ' ') { - putc ('\n', stderr); - fflush (stderr); - } + if (l < 2 || message[l-2] != ':' || message[l-1] != ' ') + { + putc ('\n', stderr); + fflush (stderr); + } } } -/** Wrap error_message() with varargs handling. */ -#define ERROR_MESSAGE(Loc, Prefix, Message) \ -{ \ - va_list args; \ - va_start (args, Message); \ - error_message (Loc, Prefix, Message, args); \ - va_end (args); \ -} - - -/*--------------------------------. -| Report a warning, and proceed. | -`--------------------------------*/ +/** Raise a complaint. That can be a fatal error, a complaint or just a + warning. */ -void -set_warning_issued (void) +static inline void +complains (const location *loc, warnings flags, const char *message, + va_list args) { - static bool warning_issued = false; - if (!warning_issued && (warnings_flag & warnings_error)) + if (flags & complaint) { - error_message (loc, complaint, NULL, message, args); - fprintf (stderr, "%s: warnings being treated as errors\n", program_name); ++ error_message (loc, complaint, ++ indent_ptr && *indent_ptr ? NULL : _("error"), ++ message, args); complaint_issued = true; } - warning_issued = true; -} - -void -warn_at (location loc, const char *message, ...) -{ - if (!(warnings_flag & warnings_other)) - return; - set_warning_issued (); - ERROR_MESSAGE (&loc, _("warning"), message); -} - -void -warn_at_indent (location loc, unsigned *indent, - const char *message, ...) -{ - if (!(warnings_flag & warnings_other)) - return; - set_warning_issued (); - indent_ptr = indent; - ERROR_MESSAGE (&loc, *indent ? NULL : _("warning"), message); + else if (flags & fatal) + { + error_message (loc, fatal, _("fatal error"), message, args); + exit (EXIT_FAILURE); + } + else if (flags & Wyacc) + { + if (yacc_flag) + { + error_message (loc, flags, NULL, message, args); + complaint_issued = true; + } + else if (warnings_flag & Wyacc) + { + set_warning_issued (); - error_message (loc, flags, _("warning"), message, args); ++ error_message (loc, flags, ++ indent_ptr && *indent_ptr ? NULL : _("warning"), ++ message, args); + } + } + else if (warnings_flag & flags) + { + set_warning_issued (); - error_message (loc, flags, _("warning"), message, args); ++ error_message (loc, flags, ++ indent_ptr && *indent_ptr ? NULL : _("warning"), ++ message, args); + } } void -warn (const char *message, ...) +complain (warnings flags, const char *message, ...) { - if (!(warnings_flag & warnings_other)) - return; - set_warning_issued (); - ERROR_MESSAGE (NULL, _("warning"), message); + va_list args; + va_start (args, message); + complains (NULL, flags, message, args); + va_end (args); } - -/*-----------------------------------------------------------. -| An error has occurred, but we can proceed, and die later. | -`-----------------------------------------------------------*/ - void -complain_at (location loc, const char *message, ...) +complain_at (location loc, warnings flags, const char *message, ...) { - ERROR_MESSAGE (&loc, _("error"), message); - complaint_issued = true; + va_list args; + va_start (args, message); + complains (&loc, flags, message, args); + va_end (args); } -void -complain_at_indent (location loc, unsigned *indent, - const char *message, ...) +void complain_at_indent (location loc, warnings flags, unsigned *indent, + const char *message, ...) { indent_ptr = indent; - ERROR_MESSAGE (&loc, *indent ? NULL : _("error"), message); - complaint_issued = true; -} -void -complain (const char *message, ...) -{ - ERROR_MESSAGE (NULL, _("error"), message); - complaint_issued = true; + va_list args; + va_start (args, message); + complains (&loc, flags, message, args); + va_end (args); } + -/*--------------------------------------------------------------. -| An incompatibility with POSIX Yacc: mapped either to warn* or | -| complain* depending on yacc_flag. | -`--------------------------------------------------------------*/ +/*--------------------------------. +| Report a warning, and proceed. | +`--------------------------------*/ void -yacc_at (location loc, const char *message, ...) +set_warning_issued (void) { - if (yacc_flag) + static bool warning_issued = false; + if (!warning_issued && (warnings_flag & Werror)) { - ERROR_MESSAGE (&loc, NULL, message); + fprintf (stderr, "%s: warnings being treated as errors\n", program_name); complaint_issued = true; } - else if (warnings_flag & warnings_yacc) - { - set_warning_issued (); - ERROR_MESSAGE (&loc, _("warning"), message); - } -} - -void -midrule_value_at (location loc, const char *message, ...) -{ - if (!(warnings_flag & warnings_midrule_values)) - return; - set_warning_issued (); - ERROR_MESSAGE (&loc, _("warning"), message); -} - -/*-------------------------------------------------. -| A severe error has occurred, we cannot proceed. | -`-------------------------------------------------*/ - -void -fatal_at (location loc, const char *message, ...) -{ - ERROR_MESSAGE (&loc, _("fatal error"), message); - exit (EXIT_FAILURE); -} - -void -fatal (const char *message, ...) -{ - ERROR_MESSAGE (NULL, _("fatal error"), message); - exit (EXIT_FAILURE); + warning_issued = true; } diff --combined src/complain.h index 44be293d,997d577b..452508ef --- a/src/complain.h +++ b/src/complain.h @@@ -21,54 -21,76 +21,57 @@@ # include "location.h" -# ifdef __cplusplus -extern "C" { -# endif +/*-------------. +| --warnings. | +`-------------*/ + +typedef enum + { + Wnone = 0, /**< Issue no warnings. */ + Wmidrule_values = 1 << 0, /**< Unset or unused midrule values. */ + Wyacc = 1 << 1, /**< POSIXME. */ + Wconflicts_sr = 1 << 2, /**< S/R conflicts. */ + Wconflicts_rr = 1 << 3, /**< R/R conflicts. */ + Wdeprecated = 1 << 4, /**< Obsolete constructs. */ + Wother = 1 << 5, /**< All other warnings. */ + + Werror = 1 << 10, /**< Warnings are treated as errors. */ + complaint = 1 << 11, /**< All complaints. */ + fatal = 1 << 12, /**< All fatal errors. */ + silent = 1 << 13, /**< Do not display the warning type. */ + Wall = ~Werror /**< All above warnings. */ + } warnings; + +/** What warnings are issued. */ +extern warnings warnings_flag; + +/** Display a "[-Wyacc]" like message on stderr. */ +void warnings_print_categories (warnings warn_flags); + /* Sub-messages indent. */ + #define SUB_INDENT (4) + /** Record that a warning is about to be issued, and treat it as an - error if warnings_flag & warnings_error. This is exported + error if warnings_flag & Werror. This is exported only for the sake of Yacc-compatible conflict reports in conflicts.c. All other warnings should be implemented in complain.c and should use the normal warning format. */ void set_warning_issued (void); -/** Informative messages, but we proceed. Report iff - warnings_flag & warnings_other. */ - -void warn (char const *format, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); - -void warn_at (location loc, char const *format, ...) +/** Make a complaint, but don't specify any location. */ +void complain (warnings flags, char const *message, ...) __attribute__ ((__format__ (__printf__, 2, 3))); -/* Generate a message aligned by an indent. - When *indent == 0, assign message's indent to *indent, - When *indent > 0, align the message by *indent value. */ -void warn_at_indent (location loc, unsigned *indent, - char const *format, ...) +/** Make a complaint with location. */ +void complain_at (location loc, warnings flags, char const *message, ...) __attribute__ ((__format__ (__printf__, 3, 4))); -/** An error, but we continue and die later. */ - -void complain (char const *format, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); - -void complain_at (location loc, char const *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -/* Generate a message aligned by an indent. - When *indent == 0, assign message's indent to *indent, - When *indent > 0, align the message by *indent value. */ -void complain_at_indent (location loc, unsigned *indent, - char const *format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -/** An incompatibility with POSIX Yacc: mapped either to warn* or - complain* depending on yacc_flag. */ - -void yacc_at (location loc, char const *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -/** A midrule-value warning. Report iff - warnings_flag & warnings_midrule_values. */ - -void midrule_value_at (location loc, char const *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -/** A fatal error, causing immediate exit. */ - -void fatal (char const *format, ...) - __attribute__ ((__noreturn__, __format__ (__printf__, 1, 2))); - -void fatal_at (location loc, char const *format, ...) - __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))); +/** Make a complaint with location and some indentation. */ +void complain_at_indent (location loc, warnings flags, unsigned *indent, + char const *message, ...) + __attribute__ ((__format__ (__printf__, 4, 5))); /** Whether an error was reported. */ extern bool complaint_issued; -# ifdef __cplusplus -} -# endif - #endif /* !COMPLAIN_H_ */ diff --combined src/getargs.c index 74be4101,56d9724d..97f061f8 --- a/src/getargs.c +++ b/src/getargs.c @@@ -26,7 -26,20 +26,7 @@@ #include #include #include - -/* Hack to get to declare getopt with a prototype. */ -#if lint && ! defined __GNU_LIBRARY__ -# define __GNU_LIBRARY__ -# define HACK_FOR___GNU_LIBRARY___PROTOTYPE 1 -#endif - #include - -#ifdef HACK_FOR___GNU_LIBRARY___PROTOTYPE -# undef __GNU_LIBRARY__ -# undef HACK_FOR___GNU_LIBRARY___PROTOTYPE -#endif - #include #include "complain.h" @@@ -36,18 -49,24 +36,18 @@@ #include "quote.h" #include "uniqstr.h" -bool debug_flag; bool defines_flag; bool graph_flag; bool xml_flag; -bool locations_flag; bool no_lines_flag; bool token_table_flag; -bool yacc_flag; /* for -y */ - -bool error_verbose = false; +bool yacc_flag; /* for -y */ bool nondeterministic_parser = false; bool glr_parser = false; int report_flag = report_none; int trace_flag = trace_none; -int warnings_flag = warnings_conflicts_sr | warnings_conflicts_rr - | warnings_other; static struct bison_language const valid_languages[] = { { "c", "c-skel.m4", ".c", ".h", true }, @@@ -79,32 -98,32 +79,32 @@@ const char *include = NULL */ static void flags_argmatch (const char *option, - const char * const keys[], const int values[], - int all, int *flags, char *args) + const char * const keys[], const int values[], + int all, int *flags, char *args) { if (args) { args = strtok (args, ","); while (args) - { - int no = strncmp (args, "no-", 3) == 0 ? 3 : 0; - int value = XARGMATCH (option, args + no, keys, values); - if (value == 0) - { - if (no) - *flags |= all; - else - *flags &= ~all; - } - else - { - if (no) - *flags &= ~value; - else - *flags |= value; - } - args = strtok (NULL, ","); - } + { + int no = STRPREFIX_LIT ("no-", args) ? 3 : 0; + int value = XARGMATCH (option, args + no, keys, values); + if (value == 0) + { + if (no) + *flags |= all; + else + *flags &= ~all; + } + else + { + if (no) + *flags &= ~value; + else + *flags |= value; + } + args = strtok (NULL, ","); + } } else *flags |= all; @@@ -114,15 -133,15 +114,15 @@@ * * \param FlagName the flag familly to update. * \param Args the effective sub arguments to decode. + * \param All the "all" value. * * \arg FlagName_args the list of keys. * \arg FlagName_types the list of values. - * \arg FlagName_all the all value. * \arg FlagName_flag the flag to update. */ -#define FLAGS_ARGMATCH(FlagName, Args) \ +#define FLAGS_ARGMATCH(FlagName, Args, All) \ flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \ - FlagName ## _all, &FlagName ## _flag, Args) + All, &FlagName ## _flag, Args) /*----------------------. @@@ -218,7 -237,6 +218,7 @@@ static const char * const warnings_args "yacc - incompatibilities with POSIX Yacc", "conflicts-sr - S/R conflicts", "conflicts-rr - R/R conflicts", + "deprecated - obsolete constructs", "other - all other warnings", "all - all of the above", "error - warnings are errors", @@@ -227,19 -245,19 +227,19 @@@ static const int warnings_types[] = { - warnings_none, - warnings_midrule_values, - warnings_yacc, - warnings_conflicts_sr, - warnings_conflicts_rr, - warnings_other, - warnings_all, - warnings_error + Wnone, + Wmidrule_values, + Wyacc, + Wconflicts_sr, + Wconflicts_rr, + Wdeprecated, + Wother, + Wall, + Werror }; ARGMATCH_VERIFY (warnings_args, warnings_types); - /*-------------------------------------------. | Display the help message and exit STATUS. | `-------------------------------------------*/ @@@ -251,13 -269,13 +251,13 @@@ usage (int status { if (status != 0) fprintf (stderr, _("Try `%s --help' for more information.\n"), - program_name); + program_name); else { /* For ../build-aux/cross-options.pl to work, use the format: - ^ -S, --long[=ARGS] (whitespace) - A --long option is required. - Otherwise, add exceptions to ../build-aux/cross-options.pl. */ + ^ -S, --long[=ARGS] (whitespace) + A --long option is required. + Otherwise, add exceptions to ../build-aux/cross-options.pl. */ printf (_("Usage: %s [OPTION]... FILE\n"), program_name); fputs (_("\ @@@ -291,8 -309,7 +291,8 @@@ Parser:\n -L, --language=LANGUAGE specify the output programming language\n\ (this is an experimental feature)\n\ -S, --skeleton=FILE specify the skeleton to use\n\ - -t, --debug instrument the parser for debugging\n\ + -t, --debug instrument the parser for tracing\n\ + same as `-Dparse.trace'\n\ --locations enable location support\n\ -D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\ -F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\ @@@ -326,13 -343,14 +326,14 @@@ Warning categories include:\n `yacc' incompatibilities with POSIX Yacc\n\ `conflicts-sr' S/R conflicts (enabled by default)\n\ `conflicts-rr' R/R conflicts (enabled by default)\n\ + `deprecated' obsolete constructs\n\ `other' all other warnings (enabled by default)\n\ `all' all the warnings\n\ `no-CATEGORY' turn off warnings in CATEGORY\n\ `none' turn off all the warnings\n\ `error' treat warnings as errors\n\ - \n\ "), stdout); + putc ('\n', stdout); fputs (_("\ THINGS is a list of comma separated words that can include:\n\ @@@ -354,7 -372,7 +355,7 @@@ Note we still output for 'C' so that it gets included in the man page. */ const char *lc_messages = setlocale (LC_MESSAGES, NULL); - if (lc_messages && strcmp (lc_messages, "en_")) + if (lc_messages && !STREQ (lc_messages, "en_")) /* TRANSLATORS: Replace LANG_CODE in this URL with your language code to form one of the URLs at http://translationproject.org/team/. @@@ -384,14 -402,14 +385,14 @@@ version (void putc ('\n', stdout); fprintf (stdout, - _("Copyright (C) %d Free Software Foundation, Inc.\n"), - PACKAGE_COPYRIGHT_YEAR); + _("Copyright (C) %d Free Software Foundation, Inc.\n"), + PACKAGE_COPYRIGHT_YEAR); fputs (_("\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ "), - stdout); + stdout); } @@@ -408,8 -426,7 +409,8 @@@ skeleton_arg (char const *arg, int prio skeleton = arg; } else if (prio == skeleton_prio) - complain_at (loc, _("multiple skeleton declarations are invalid")); + complain_at (loc, complaint, + _("multiple skeleton declarations are invalid")); } void @@@ -434,7 -451,7 +435,7 @@@ language_argmatch (char const *arg, in else return; - complain_at (loc, msg, quotearg_colon (arg)); + complain_at (loc, complaint, msg, quotearg_colon (arg)); } /*----------------------. @@@ -480,25 -497,25 +481,25 @@@ enu static struct option const long_options[] = { /* Operation modes. */ - { "help", no_argument, 0, 'h' }, - { "version", no_argument, 0, 'V' }, - { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION }, - { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION }, + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'V' }, + { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION }, + { "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION }, { "warnings", optional_argument, 0, 'W' }, /* Parser. */ - { "name-prefix", required_argument, 0, 'p' }, + { "name-prefix", required_argument, 0, 'p' }, { "include", required_argument, 0, 'I' }, /* Output. */ - { "file-prefix", required_argument, 0, 'b' }, - { "output", required_argument, 0, 'o' }, - { "output-file", required_argument, 0, 'o' }, - { "graph", optional_argument, 0, 'g' }, + { "file-prefix", required_argument, 0, 'b' }, + { "output", required_argument, 0, 'o' }, + { "output-file", required_argument, 0, 'o' }, + { "graph", optional_argument, 0, 'g' }, { "xml", optional_argument, 0, 'x' }, - { "report", required_argument, 0, 'r' }, + { "report", required_argument, 0, 'r' }, { "report-file", required_argument, 0, REPORT_FILE_OPTION }, - { "verbose", no_argument, 0, 'v' }, + { "verbose", no_argument, 0, 'v' }, /* Hidden. */ { "trace", optional_argument, 0, 'T' }, @@@ -508,13 -525,13 +509,13 @@@ /* Operation modes. */ { "fixed-output-files", no_argument, 0, 'y' }, - { "yacc", no_argument, 0, 'y' }, + { "yacc", no_argument, 0, 'y' }, /* Parser. */ - { "debug", no_argument, 0, 't' }, - { "define", required_argument, 0, 'D' }, + { "debug", no_argument, 0, 't' }, + { "define", required_argument, 0, 'D' }, { "force-define", required_argument, 0, 'F' }, - { "locations", no_argument, 0, LOCATIONS_OPTION }, + { "locations", no_argument, 0, LOCATIONS_OPTION }, { "no-lines", no_argument, 0, 'l' }, { "raw", no_argument, 0, 0 }, { "skeleton", required_argument, 0, 'S' }, @@@ -551,21 -568,21 +552,21 @@@ getargs (int argc, char *argv[] int c; while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) - != -1) + != -1) switch (c) { /* ASCII Sorting for short options (i.e., upper case then lower case), and then long-only options. */ case 0: - /* Certain long options cause getopt_long to return 0. */ - break; + /* Certain long options cause getopt_long to return 0. */ + break; case 'D': /* -DNAME[=VALUE]. */ case 'F': /* -FNAME[=VALUE]. */ { char* name = optarg; - char* value = mbschr (optarg, '='); + char* value = strchr (optarg, '='); if (value) *value++ = 0; muscle_percent_define_insert (name, command_line_location (), @@@ -573,37 -590,37 +574,37 @@@ c == 'D' ? MUSCLE_PERCENT_DEFINE_D : MUSCLE_PERCENT_DEFINE_F); } - break; + break; case 'I': - include = AS_FILE_NAME (optarg); - break; + include = AS_FILE_NAME (optarg); + break; case 'L': - language_argmatch (optarg, command_line_prio, - command_line_location ()); - break; + language_argmatch (optarg, command_line_prio, + command_line_location ()); + break; case 'S': - skeleton_arg (AS_FILE_NAME (optarg), command_line_prio, - command_line_location ()); - break; + skeleton_arg (AS_FILE_NAME (optarg), command_line_prio, + command_line_location ()); + break; case 'T': - FLAGS_ARGMATCH (trace, optarg); - break; + FLAGS_ARGMATCH (trace, optarg, trace_all); + break; case 'V': - version (); - exit (EXIT_SUCCESS); + version (); + exit (EXIT_SUCCESS); case 'W': - FLAGS_ARGMATCH (warnings, optarg); - break; + FLAGS_ARGMATCH (warnings, optarg, Wall); + break; case 'b': - spec_file_prefix = AS_FILE_NAME (optarg); - break; + spec_file_prefix = AS_FILE_NAME (optarg); + break; case 'd': /* Here, the -d and --defines options are differentiated. */ @@@ -616,80 -633,77 +617,80 @@@ break; case 'g': - graph_flag = true; - if (optarg) + graph_flag = true; + if (optarg) { free (spec_graph_file); spec_graph_file = xstrdup (AS_FILE_NAME (optarg)); } - break; + break; case 'h': - usage (EXIT_SUCCESS); + usage (EXIT_SUCCESS); case 'k': - token_table_flag = true; - break; + token_table_flag = true; + break; case 'l': - no_lines_flag = true; - break; + no_lines_flag = true; + break; case 'o': - spec_outfile = AS_FILE_NAME (optarg); - break; + spec_outfile = AS_FILE_NAME (optarg); + break; case 'p': - spec_name_prefix = optarg; - break; + spec_name_prefix = optarg; + break; case 'r': - FLAGS_ARGMATCH (report, optarg); - break; + FLAGS_ARGMATCH (report, optarg, report_all); + break; case 't': - debug_flag = true; - break; + muscle_percent_define_insert ("parse.trace", + command_line_location (), "", + MUSCLE_PERCENT_DEFINE_D); + break; case 'v': - report_flag |= report_states; - break; + report_flag |= report_states; + break; case 'x': - xml_flag = true; - if (optarg) + xml_flag = true; + if (optarg) { free (spec_xml_file); spec_xml_file = xstrdup (AS_FILE_NAME (optarg)); } - break; + break; case 'y': - yacc_flag = true; - break; + yacc_flag = true; + break; case LOCATIONS_OPTION: - locations_flag = true; - break; + muscle_percent_define_ensure ("locations", + command_line_location (), true); + break; case PRINT_LOCALEDIR_OPTION: - printf ("%s\n", LOCALEDIR); - exit (EXIT_SUCCESS); + printf ("%s\n", LOCALEDIR); + exit (EXIT_SUCCESS); case PRINT_DATADIR_OPTION: - printf ("%s\n", compute_pkgdatadir ()); - exit (EXIT_SUCCESS); + printf ("%s\n", pkgdatadir ()); + exit (EXIT_SUCCESS); case REPORT_FILE_OPTION: free (spec_verbose_file); - spec_verbose_file = xstrdup (AS_FILE_NAME (optarg)); - break; + spec_verbose_file = xstrdup (AS_FILE_NAME (optarg)); + break; default: - usage (EXIT_FAILURE); + usage (EXIT_FAILURE); } if (argc - optind != 1) diff --combined src/muscle-tab.c index 8e569812,37a0f0e8..4738fdfd --- a/src/muscle-tab.c +++ b/src/muscle-tab.c @@@ -50,7 -50,7 +50,7 @@@ hash_compare_muscles (void const *x, vo { muscle_entry const *m1 = x; muscle_entry const *m2 = y; - return strcmp (m1->key, m2->key) == 0; + return STREQ (m1->key, m2->key); } static size_t @@@ -80,7 -80,7 +80,7 @@@ muscle_init (void obstack_init (&muscle_obstack); muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle, - hash_compare_muscles, muscle_entry_free); + hash_compare_muscles, muscle_entry_free); /* Version and input file. */ MUSCLE_INSERT_STRING ("version", VERSION); @@@ -157,9 -157,12 +157,9 @@@ muscle_grow (const char *key, const cha { /* Grow the current value. */ char *new_val; - obstack_sgrow (&muscle_obstack, entry->value); + obstack_printf (&muscle_obstack, "%s%s%s", entry->value, separator, val); free (entry->storage); - obstack_sgrow (&muscle_obstack, separator); - obstack_sgrow (&muscle_obstack, val); - obstack_1grow (&muscle_obstack, 0); - new_val = obstack_finish (&muscle_obstack); + new_val = obstack_finish0 (&muscle_obstack); entry->value = entry->storage = xstrdup (new_val); obstack_free (&muscle_obstack, new_val); } @@@ -178,7 -181,8 +178,7 @@@ muscle_syncline_grow (char const *key, obstack_quote (&muscle_obstack, quotearg_style (c_quoting_style, loc.start.file)); obstack_sgrow (&muscle_obstack, ")["); - obstack_1grow (&muscle_obstack, 0); - extension = obstack_finish (&muscle_obstack); + extension = obstack_finish0 (&muscle_obstack); muscle_grow (key, extension, ""); obstack_free (&muscle_obstack, extension); } @@@ -198,7 -202,7 +198,7 @@@ muscle_code_grow (const char *key, cons void muscle_pair_list_grow (const char *muscle, - const char *a1, const char *a2) + const char *a1, const char *a2) { char *pair; obstack_sgrow (&muscle_obstack, "["); @@@ -206,7 -210,8 +206,7 @@@ obstack_sgrow (&muscle_obstack, ", "); obstack_quote (&muscle_obstack, a2); obstack_sgrow (&muscle_obstack, "]"); - obstack_1grow (&muscle_obstack, 0); - pair = obstack_finish (&muscle_obstack); + pair = obstack_finish0 (&muscle_obstack); muscle_grow (muscle, pair, ",\n"); obstack_free (&muscle_obstack, pair); } @@@ -263,8 -268,13 +263,8 @@@ muscle_boundary_grow (char const *key, char *extension; obstack_sgrow (&muscle_obstack, "[["); obstack_escape (&muscle_obstack, bound.file); - obstack_1grow (&muscle_obstack, ':'); - obstack_printf (&muscle_obstack, "%d", bound.line); - obstack_1grow (&muscle_obstack, '.'); - obstack_printf (&muscle_obstack, "%d", bound.column); - obstack_sgrow (&muscle_obstack, "]]"); - obstack_1grow (&muscle_obstack, '\0'); - extension = obstack_finish (&muscle_obstack); + obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column); + extension = obstack_finish0 (&muscle_obstack); muscle_grow (key, extension, ""); obstack_free (&muscle_obstack, extension); } @@@ -305,10 -315,11 +305,10 @@@ muscle_location_grow (char const *key, static char * string_decode (char const *key) { - char const *value; + char const *value = muscle_find_const (key); char *value_decoded; char *result; - value = muscle_find_const (key); if (!value) return NULL; do { @@@ -347,7 -358,8 +347,7 @@@ location_decode (char const *key { char *boundary_str; aver (*++value == ']'); - obstack_1grow (&muscle_obstack, '\0'); - boundary_str = obstack_finish (&muscle_obstack); + boundary_str = obstack_finish0 (&muscle_obstack); switch (*++value) { case ',': @@@ -384,49 -396,25 +384,49 @@@ muscle_user_name_list_grow (char const muscle_grow (key, "]]", ""); } +/** If the \a variable name is obsolete, return the name to use, + * otherwise \a variable. */ +static +char const * +muscle_percent_variable_update (char const *variable, location variable_loc) +{ + typedef struct + { + const char *obsolete; + const char *updated; + } conversion_type; + const conversion_type conversion[] = + { + { "api.push_pull", "api.push-pull", }, + { "lr.keep_unreachable_states", "lr.keep-unreachable-states", }, + { "namespace", "api.namespace", }, + }; + char const *res = variable; + int i; + for (i = 0; i < ARRAY_CARDINALITY (conversion); ++i) + if (STREQ (conversion[i].obsolete, variable)) + { + res = conversion[i].updated; + complain_at (variable_loc, Wdeprecated, + _("deprecated %%define variable name: %s, use %s"), + quote (variable), quote_n (1, res)); + break; + } + return res; +} + void muscle_percent_define_insert (char const *variable, location variable_loc, char const *value, muscle_percent_define_how how) { - char *variable_tr = NULL; char const *name; char const *loc_name; char const *syncline_name; char const *how_name; /* Permit certain names with underscores for backward compatibility. */ - if (0 == strcmp (variable, "api.push_pull") - || 0 == strcmp (variable, "lr.keep_unreachable_states")) - { - variable_tr = strdup (variable); - tr (variable_tr, '_', '-'); - variable = variable_tr; - } + variable = muscle_percent_variable_update (variable, variable_loc); name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); @@@ -438,13 -426,19 +438,17 @@@ if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE && muscle_find_const (name)) { + muscle_percent_define_how how_old = atoi (muscle_find_const (how_name)); + unsigned i = 0; - muscle_percent_define_how how_old = - atoi (muscle_find_const (how_name)); if (how_old == MUSCLE_PERCENT_DEFINE_F) - { - free (variable_tr); - return; - } - complain_at_indent (variable_loc, &i, - _("%%define variable %s redefined"), quote (variable)); + return; - complain_at (variable_loc, complaint, _("%%define variable %s redefined"), - quote (variable)); - location loc = muscle_percent_define_get_loc (variable); - complain_at (loc, complaint, _("previous definition")); ++ complain_at_indent (variable_loc, complaint, &i, ++ _("%%define variable %s redefined"), ++ quote (variable)); + i += SUB_INDENT; - complain_at_indent (muscle_percent_define_get_loc (variable), &i, ++ complain_at_indent (muscle_percent_define_get_loc (variable), ++ complaint, &i, + _("previous definition")); } MUSCLE_INSERT_STRING (name, value); @@@ -455,74 -449,65 +459,74 @@@ muscle_user_name_list_grow ("percent_define_user_variables", variable, variable_loc); MUSCLE_INSERT_INT (how_name, how); +} + +/* This is used for backward compatibility, e.g., "%define api.pure" + supersedes "%pure-parser". */ +void +muscle_percent_define_ensure (char const *variable, location loc, + bool value) +{ + char const *val = value ? "" : "false"; + char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); - free (variable_tr); + /* %pure-parser is deprecated in favor of `%define api.pure', so use + `%define api.pure' in a backward-compatible manner here. First, + don't complain if %pure-parser is specified multiple times. */ + if (!muscle_find_const (name)) + muscle_percent_define_insert (variable, loc, val, + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); + /* In all cases, use api.pure now so that the backend doesn't complain if + the skeleton ignores api.pure, but do warn now if there's a previous + conflicting definition from an actual %define. */ + if (muscle_percent_define_flag_if (variable) != value) + muscle_percent_define_insert (variable, loc, val, + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); } char * muscle_percent_define_get (char const *variable) { - char const *name; - char const *usage_name; - char *value; - - name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); - usage_name = UNIQSTR_CONCAT ("percent_define_bison_variables(", - variable, ")"); - - muscle_insert (usage_name, ""); - value = string_decode (name); + char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); + char const *usage_name = + UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")"); + char *value = string_decode (name); if (!value) value = xstrdup (""); + + muscle_insert (usage_name, ""); return value; } location muscle_percent_define_get_loc (char const *variable) { - char const *loc_name; - loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); + char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); if (!muscle_find_const (loc_name)) - fatal(_("%s: undefined %%define variable %s"), - "muscle_percent_define_get_loc", quote (variable)); + complain (fatal, _("%s: undefined %%define variable %s"), + "muscle_percent_define_get_loc", quote (variable)); return location_decode (loc_name); } char const * muscle_percent_define_get_syncline (char const *variable) { - char const *syncline_name; - char const *syncline; - syncline_name = + char const *syncline_name = UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); - syncline = muscle_find_const (syncline_name); + char const *syncline = muscle_find_const (syncline_name); if (!syncline) - fatal(_("%s: undefined %%define variable %s"), - "muscle_percent_define_get_syncline", quote (variable)); + complain (fatal, _("%s: undefined %%define variable %s"), + "muscle_percent_define_get_syncline", quote (variable)); return syncline; } bool muscle_percent_define_ifdef (char const *variable) { - char const *name; - char const *usage_name; - char const *value; - - name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); - usage_name = + char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); + char const *usage_name = UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")"); - - value = muscle_find_const (name); + char const *value = muscle_find_const (name); if (value) { muscle_insert (usage_name, ""); @@@ -535,30 -520,31 +539,30 @@@ bool muscle_percent_define_flag_if (char const *variable) { - char const *invalid_boolean_name; - bool result = false; - - invalid_boolean_name = + char const *invalid_boolean_name = UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")"); + bool result = false; if (muscle_percent_define_ifdef (variable)) { char *value = muscle_percent_define_get (variable); - if (value[0] == '\0' || 0 == strcmp (value, "true")) + if (value[0] == '\0' || STREQ (value, "true")) result = true; - else if (0 == strcmp (value, "false")) + else if (STREQ (value, "false")) result = false; else if (!muscle_find_const (invalid_boolean_name)) { muscle_insert (invalid_boolean_name, ""); - complain_at(muscle_percent_define_get_loc (variable), - _("invalid value for %%define Boolean variable %s"), - quote (variable)); + location loc = muscle_percent_define_get_loc (variable); + complain_at (loc, complaint, + _("invalid value for %%define Boolean variable %s"), + quote (variable)); } free (value); } else - fatal(_("%s: undefined %%define variable %s"), - "muscle_percent_define_flag", quote (variable)); + complain (fatal, _("%s: undefined %%define variable %s"), + "muscle_percent_define_flag", quote (variable)); return result; } @@@ -566,9 -552,12 +570,9 @@@ void muscle_percent_define_default (char const *variable, char const *value) { - char const *name; - char const *loc_name; - char const *syncline_name; - name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); - loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); - syncline_name = + char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); + char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); + char const *syncline_name = UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); if (!muscle_find_const (name)) { @@@ -589,24 -578,30 +593,27 @@@ muscle_percent_define_check_values (cha for (; *values; ++values) { char const * const *variablep = values; - char const *name; - char *value; - - name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")"); - - value = string_decode (name); + char const *name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")"); + char *value = string_decode (name); if (value) { for (++values; *values; ++values) { - if (0 == strcmp (value, *values)) + if (STREQ (value, *values)) break; } if (!*values) { + unsigned i = 0; location loc = muscle_percent_define_get_loc (*variablep); - complain_at (loc, complaint, - _("invalid value for %%define variable %s: %s"), - quote (*variablep), quote_n (1, value)); - complain_at_indent (loc, &i, - _("invalid value for %%define variable %s: %s"), - quote (*variablep), quote_n (1, value)); ++ complain_at_indent ++ (loc, complaint, &i, ++ _("invalid value for %%define variable %s: %s"), ++ quote (*variablep), quote_n (1, value)); + i += SUB_INDENT; for (values = variablep + 1; *values; ++values) - complain_at (loc, complaint, _("accepted value: %s"), - quote (*values)); - complain_at_indent (loc, &i, _("accepted value: %s"), ++ complain_at_indent (loc, complaint, &i, _("accepted value: %s"), + quote (*values)); } else { @@@ -616,8 -611,8 +623,8 @@@ free (value); } else - fatal (_("%s: undefined %%define variable %s"), - "muscle_percent_define_check_values", quote (*variablep)); + complain (fatal, _("%s: undefined %%define variable %s"), + "muscle_percent_define_check_values", quote (*variablep)); } } @@@ -625,7 -620,8 +632,7 @@@ voi muscle_percent_code_grow (char const *qualifier, location qualifier_loc, char const *code, location code_loc) { - char const *name; - name = UNIQSTR_CONCAT ("percent_code(", qualifier, ")"); + char const *name = UNIQSTR_CONCAT ("percent_code(", qualifier, ")"); muscle_code_grow (name, code, code_loc); muscle_user_name_list_grow ("percent_code_user_qualifiers", qualifier, qualifier_loc); @@@ -639,9 -635,8 +646,9 @@@ static inline bool muscle_m4_output (muscle_entry *entry, FILE *out) { - fprintf (out, "m4_define([b4_%s],\n", entry->key); - fprintf (out, "[[%s]])\n\n\n", entry->value); + fprintf (out, + "m4_define([b4_%s],\n" + "[[%s]])\n\n\n", entry->key, entry->value); return true; } diff --combined src/reader.c index 52c0b139,86fde7b2..f658e64e --- a/src/reader.c +++ b/src/reader.c @@@ -59,7 -59,7 +59,7 @@@ voi grammar_start_symbol_set (symbol *sym, location loc) { if (start_flag) - complain_at (loc, _("multiple %s declarations"), "%start"); + complain_at (loc, complaint, _("multiple %s declarations"), "%start"); else { start_flag = true; @@@ -94,7 -94,7 +94,7 @@@ get_merge_function (uniqstr name syms->next = xmalloc (sizeof syms->next[0]); syms->next->name = uniqstr_new (name); /* After all symbol type declarations have been parsed, packgram invokes - record_merge_function_type to set the type. */ + record_merge_function_type to set the type. */ syms->next->type = NULL; syms->next->next = NULL; merge_functions = head.next; @@@ -128,18 -128,22 +128,23 @@@ record_merge_function_type (int merger aver (merge_function != NULL && merger_find == merger); if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type)) { - complain_at (declaration_loc, complaint, - _("result type clash on merge function %s: <%s> != <%s>"), - quote (merge_function->name), type, merge_function->type); - complain_at (merge_function->type_declaration_location, complaint, - _("previous declaration")); + unsigned indent = 0; - complain_at_indent (declaration_loc, &indent, ++ complain_at_indent (declaration_loc, complaint, &indent, + _("result type clash on merge function %s: " + "<%s> != <%s>"), + quote (merge_function->name), type, + merge_function->type); + indent += SUB_INDENT; - complain_at_indent (merge_function->type_declaration_location, &indent, ++ complain_at_indent (merge_function->type_declaration_location, complaint, ++ &indent, + _("previous declaration")); - } + } merge_function->type = uniqstr_new (type); merge_function->type_declaration_location = declaration_loc; } /*--------------------------------------. -| Free all merge-function definitions. | +| Free all merge-function definitions. | `--------------------------------------*/ void @@@ -197,9 -201,9 +202,9 @@@ assign_named_ref (symbol_list *p, named if (name->id == sym->tag) { - warn_at (name->loc, - _("duplicated symbol name for %s ignored"), - quote (sym->tag)); + complain_at (name->loc, Wother, + _("duplicated symbol name for %s ignored"), + quote (sym->tag)); named_ref_free (name); } else @@@ -220,7 -224,7 +225,7 @@@ static symbol_list *previous_rule_end void grammar_current_rule_begin (symbol *lhs, location loc, - named_ref *lhs_name) + named_ref *lhs_name) { symbol_list* p; @@@ -242,8 -246,7 +247,8 @@@ ++nvars; } else if (lhs->class == token_sym) - complain_at (loc, _("rule given for %s, which is a token"), lhs->tag); + complain_at (loc, complaint, _("rule given for %s, which is a token"), + lhs->tag); } @@@ -258,7 -261,7 +263,7 @@@ static bool symbol_should_be_used (symbol_list const *s, bool *midrule_warning) { - if (symbol_destructor_get (s->content.sym)->code) + if (symbol_code_props_get (s->content.sym, destructor)->code) return true; if ((s->midrule && s->midrule->action_props.is_value_used) || (s->midrule_parent_rule @@@ -292,19 -295,19 +297,19 @@@ grammar_rule_check (const symbol_list * symbol *first_rhs = r->next->content.sym; /* If $$ is being set in default way, report if any type mismatch. */ if (first_rhs) - { - char const *lhs_type = r->content.sym->type_name; - const char *rhs_type = - first_rhs->type_name ? first_rhs->type_name : ""; - if (!UNIQSTR_EQ (lhs_type, rhs_type)) - warn_at (r->location, - _("type clash on default action: <%s> != <%s>"), - lhs_type, rhs_type); - } + { + char const *lhs_type = r->content.sym->type_name; + const char *rhs_type = + first_rhs->type_name ? first_rhs->type_name : ""; + if (!UNIQSTR_EQ (lhs_type, rhs_type)) + complain_at (r->location, Wother, + _("type clash on default action: <%s> != <%s>"), + lhs_type, rhs_type); + } /* Warn if there is no default for $$ but we need one. */ else - warn_at (r->location, - _("empty rule for typed nonterminal, and no action")); + complain_at (r->location, Wother, + _("empty rule for typed nonterminal, and no action")); } /* Check that symbol values that should be used are in fact used. */ @@@ -319,11 -322,12 +324,11 @@@ /* The default action, $$ = $1, `uses' both. */ && (r->action_props.code || (n != 0 && n != 1))) { - void (*warn_at_ptr)(location, char const*, ...) = - midrule_warning ? midrule_value_at : warn_at; + warnings warn_flag = midrule_warning ? Wmidrule_values : Wother; if (n) - warn_at_ptr (r->location, _("unused value: $%d"), n); + complain_at (r->location, warn_flag, _("unused value: $%d"), n); else - warn_at_ptr (r->location, _("unset value: $$")); + complain_at (r->location, warn_flag, _("unset value: $$")); } } } @@@ -333,9 -337,9 +338,9 @@@ it for char literals and strings, which are always tokens. */ if (r->ruleprec && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"' - && !r->ruleprec->declared && !r->ruleprec->prec) - warn_at (r->location, _("token for %%prec is not defined: %s"), - r->ruleprec->tag); + && r->ruleprec->status != declared && !r->ruleprec->prec) + complain_at (r->location, Wother, + _("token for %%prec is not defined: %s"), r->ruleprec->tag); } @@@ -384,8 -388,7 +389,8 @@@ grammar_midrule_action (void code_props_rule_action_init (&midrule->action_props, current_rule->action_props.code, current_rule->action_props.location, - midrule, 0); + midrule, 0, + current_rule->action_props.is_predicate); code_props_none_init (¤t_rule->action_props); if (previous_rule_end) @@@ -425,7 -428,7 +430,7 @@@ grammar_current_rule_prec_set (symbol * token. */ symbol_class_set (precsym, token_sym, loc, false); if (current_rule->ruleprec) - complain_at (loc, _("only one %s allowed per rule"), "%prec"); + complain_at (loc, complaint, _("only one %s allowed per rule"), "%prec"); current_rule->ruleprec = precsym; } @@@ -435,13 -438,11 +440,13 @@@ voi grammar_current_rule_dprec_set (int dprec, location loc) { if (! glr_parser) - warn_at (loc, _("%s affects only GLR parsers"), "%dprec"); + complain_at (loc, Wother, _("%s affects only GLR parsers"), + "%dprec"); if (dprec <= 0) - complain_at (loc, _("%s must be followed by positive number"), "%dprec"); + complain_at (loc, complaint, _("%s must be followed by positive number"), + "%dprec"); else if (current_rule->dprec != 0) - complain_at (loc, _("only one %s allowed per rule"), "%dprec"); + complain_at (loc, complaint, _("only one %s allowed per rule"), "%dprec"); current_rule->dprec = dprec; } @@@ -452,10 -453,9 +457,10 @@@ voi grammar_current_rule_merge_set (uniqstr name, location loc) { if (! glr_parser) - warn_at (loc, _("%s affects only GLR parsers"), "%merge"); + complain_at (loc, Wother, _("%s affects only GLR parsers"), + "%merge"); if (current_rule->merger != 0) - complain_at (loc, _("only one %s allowed per rule"), "%merge"); + complain_at (loc, complaint, _("only one %s allowed per rule"), "%merge"); current_rule->merger = get_merge_function (name); current_rule->merger_declaration_location = loc; } @@@ -465,7 -465,7 +470,7 @@@ void grammar_current_rule_symbol_append (symbol *sym, location loc, - named_ref *name) + named_ref *name) { symbol_list *p; if (current_rule->action_props.code) @@@ -473,22 -473,20 +478,22 @@@ p = grammar_symbol_append (sym, loc); if (name) assign_named_ref(p, name); + if (sym->status == undeclared || sym->status == used) + sym->status = needed; } /* Attach an ACTION to the current rule. */ void grammar_current_rule_action_append (const char *action, location loc, - named_ref *name) + named_ref *name, bool is_predicate) { if (current_rule->action_props.code) grammar_midrule_action (); /* After all symbol declarations have been parsed, packgram invokes code_props_translate_code. */ code_props_rule_action_init (¤t_rule->action_props, action, loc, - current_rule, name); + current_rule, name, is_predicate); } @@@ -516,7 -514,7 +521,7 @@@ packgram (void int rule_length = 0; symbol *ruleprec = p->ruleprec; record_merge_function_type (p->merger, p->content.sym->type_name, - p->merger_declaration_location); + p->merger_declaration_location); rules[ruleno].user_number = ruleno; rules[ruleno].number = ruleno; rules[ruleno].lhs = p->content.sym; @@@ -529,50 -527,49 +534,50 @@@ rules[ruleno].useful = true; rules[ruleno].action = p->action_props.code; rules[ruleno].action_location = p->action_props.location; + rules[ruleno].is_predicate = p->action_props.is_predicate; /* If the midrule's $$ is set or its $n is used, remove the `$' from the - symbol name so that it's a user-defined symbol so that the default - %destructor and %printer apply. */ + symbol name so that it's a user-defined symbol so that the default + %destructor and %printer apply. */ if (p->midrule_parent_rule && (p->action_props.is_value_used - || symbol_list_n_get (p->midrule_parent_rule, - p->midrule_parent_rhs_index) + || symbol_list_n_get (p->midrule_parent_rule, + p->midrule_parent_rhs_index) ->action_props.is_value_used)) - p->content.sym->tag += 1; + p->content.sym->tag += 1; /* Don't check the generated rule 0. It has no action, so some rhs - symbols may appear unused, but the parsing algorithm ensures that - %destructor's are invoked appropriately. */ + symbols may appear unused, but the parsing algorithm ensures that + %destructor's are invoked appropriately. */ if (p != grammar) - grammar_rule_check (p); + grammar_rule_check (p); for (p = p->next; p && p->content.sym; p = p->next) - { - ++rule_length; + { + ++rule_length; - /* Don't allow rule_length == INT_MAX, since that might - cause confusion with strtol if INT_MAX == LONG_MAX. */ - if (rule_length == INT_MAX) - fatal_at (rules[ruleno].location, _("rule is too long")); + /* Don't allow rule_length == INT_MAX, since that might + cause confusion with strtol if INT_MAX == LONG_MAX. */ + if (rule_length == INT_MAX) + complain_at (rules[ruleno].location, fatal, _("rule is too long")); - /* item_number = symbol_number. - But the former needs to contain more: negative rule numbers. */ - ritem[itemno++] = + /* item_number = symbol_number. + But the former needs to contain more: negative rule numbers. */ + ritem[itemno++] = symbol_number_as_item_number (p->content.sym->number); - /* A rule gets by default the precedence and associativity - of its last token. */ - if (p->content.sym->class == token_sym && default_prec) - rules[ruleno].prec = p->content.sym; - } + /* A rule gets by default the precedence and associativity + of its last token. */ + if (p->content.sym->class == token_sym && default_prec) + rules[ruleno].prec = p->content.sym; + } /* If this rule has a %prec, the specified symbol's precedence replaces the default. */ if (ruleprec) - { - rules[ruleno].precsym = ruleprec; - rules[ruleno].prec = ruleprec; - } + { + rules[ruleno].precsym = ruleprec; + rules[ruleno].prec = ruleprec; + } /* An item ends by the rule number (negated). */ ritem[itemno++] = rule_number_as_item_number (ruleno); aver (itemno < ITEM_NUMBER_MAX); @@@ -580,7 -577,7 +585,7 @@@ aver (ruleno < RULE_NUMBER_MAX); if (p) - p = p->next; + p = p->next; } aver (itemno == nritems); @@@ -643,7 -640,7 +648,7 @@@ prepare_percent_define_front_end_variab default. */ muscle_percent_define_default ("lr.type", "lalr"); lr_type = muscle_percent_define_get ("lr.type"); - if (0 != strcmp (lr_type, "canonical-lr")) + if (STRNEQ (lr_type, "canonical-lr")) muscle_percent_define_default ("lr.default-reductions", "most"); else muscle_percent_define_default ("lr.default-reductions", "accepting"); @@@ -664,7 -661,7 +669,7 @@@ /*-------------------------------------------------------------. | Check the grammar that has just been read, and convert it to | -| internal form. | +| internal form. | `-------------------------------------------------------------*/ static void @@@ -672,7 -669,7 +677,7 @@@ check_and_convert_grammar (void { /* Grammar has been read. Do some checking. */ if (nrules == 0) - fatal (_("no rules in the input grammar")); + complain (fatal, _("no rules in the input grammar")); /* If the user did not define her ENDTOKEN, do it now. */ if (!endtoken) diff --combined src/symtab.c index 21c61255,2e0b9201..916536ae --- a/src/symtab.c +++ b/src/symtab.c @@@ -33,7 -33,6 +33,7 @@@ `-------------------------------------------------------------------*/ static symbol **symbols_sorted = NULL; +static symbol **semantic_types_sorted = NULL; /*------------------------. | Distinguished symbols. | @@@ -46,6 -45,14 +46,6 @@@ symbol *accept = NULL symbol *startsymbol = NULL; location startsymbol_location; -/*---------------------------------------. -| Default %destructor's and %printer's. | -`---------------------------------------*/ - -static code_props default_tagged_destructor = CODE_PROPS_NONE_INIT; -static code_props default_tagless_destructor = CODE_PROPS_NONE_INIT; -static code_props default_tagged_printer = CODE_PROPS_NONE_INIT; -static code_props default_tagless_printer = CODE_PROPS_NONE_INIT; /*---------------------------------. | Create a new symbol, named TAG. | @@@ -60,16 -67,16 +60,16 @@@ symbol_new (uniqstr tag, location loc /* If the tag is not a string (starts with a double quote), check that it is valid for Yacc. */ - if (tag[0] != '\"' && tag[0] != '\'' && mbschr (tag, '-')) - yacc_at (loc, _("POSIX Yacc forbids dashes in symbol names: %s"), - tag); + if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-')) + complain_at (loc, Wyacc, + _("POSIX Yacc forbids dashes in symbol names: %s"), tag); res->tag = tag; res->location = loc; res->type_name = NULL; - code_props_none_init (&res->destructor); - code_props_none_init (&res->printer); + for (int i = 0; i < CODE_PROPS_SIZE; ++i) + code_props_none_init (&res->props[i]); res->number = NUMBER_UNDEFINED; res->prec = 0; @@@ -78,43 -85,28 +78,43 @@@ res->alias = NULL; res->class = unknown_sym; - res->declared = false; + res->status = undeclared; if (nsyms == SYMBOL_NUMBER_MAXIMUM) - fatal (_("too many symbols in input grammar (limit is %d)"), - SYMBOL_NUMBER_MAXIMUM); + complain (fatal, _("too many symbols in input grammar (limit is %d)"), + SYMBOL_NUMBER_MAXIMUM); nsyms++; return res; } +char const * +code_props_type_string (code_props_type kind) +{ + switch (kind) + { + case destructor: + return "%destructor"; + case printer: + return "%printer"; + } + assert (0); +} + /*----------------------------------------. | Create a new semantic type, named TAG. | `----------------------------------------*/ static semantic_type * -semantic_type_new (uniqstr tag) +semantic_type_new (uniqstr tag, const location *loc) { semantic_type *res = xmalloc (sizeof *res); uniqstr_assert (tag); res->tag = tag; - code_props_none_init (&res->destructor); - code_props_none_init (&res->printer); + if (loc) + res->location = *loc; + for (int i = 0; i < CODE_PROPS_SIZE; ++i) + code_props_none_init (&res->props[i]); return res; } @@@ -124,16 -116,16 +124,16 @@@ | Print a symbol. | `-----------------*/ -#define SYMBOL_ATTR_PRINT(Attr) \ - if (s->Attr) \ +#define SYMBOL_ATTR_PRINT(Attr) \ + if (s->Attr) \ fprintf (f, " %s { %s }", #Attr, s->Attr) -#define SYMBOL_CODE_PRINT(Attr) \ - if (s->Attr.code) \ - fprintf (f, " %s { %s }", #Attr, s->Attr.code) +#define SYMBOL_CODE_PRINT(Attr) \ + if (s->props[Attr].code) \ + fprintf (f, " %s { %s }", #Attr, s->props[Attr].code) void -symbol_print (symbol *s, FILE *f) +symbol_print (symbol const *s, FILE *f) { if (s) { @@@ -149,41 -141,6 +149,41 @@@ #undef SYMBOL_ATTR_PRINT #undef SYMBOL_CODE_PRINT + +/*----------------------------------. +| Whether S is a valid identifier. | +`----------------------------------*/ + +static bool +is_identifier (uniqstr s) +{ + static char const alphanum[26 + 26 + 1 + 10] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "_" + "0123456789"; + if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10)) + return false; + for (++s; *s; ++s) + if (! memchr (alphanum, *s, sizeof alphanum)) + return false; + return true; +} + + +/*-----------------------------------------------. +| Get the identifier associated to this symbol. | +`-----------------------------------------------*/ +uniqstr +symbol_id_get (symbol const *sym) +{ + aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS); + if (sym->alias) + sym = sym->alias; + return is_identifier (sym->tag) ? sym->tag : 0; +} + + /*------------------------------------------------------------------. | Complain that S's WHAT is redeclared at SECOND, and was first set | | at FIRST. | @@@ -193,16 -150,20 +193,24 @@@ static voi symbol_redeclaration (symbol *s, const char *what, location first, location second) { - complain_at (second, complaint, _("%s redeclaration for %s"), what, s->tag); - complain_at (first, complaint, _("previous declaration")); + unsigned i = 0; - complain_at_indent (second, &i, _("%s redeclaration for %s"), what, s->tag); ++ complain_at_indent (second, complaint, &i, ++ _("%s redeclaration for %s"), what, s->tag); + i += SUB_INDENT; - complain_at_indent (first, &i, _("previous declaration")); ++ complain_at_indent (first, complaint, &i, ++ _("previous declaration")); } static void semantic_type_redeclaration (semantic_type *s, const char *what, location first, location second) { - complain_at (second, complaint, _("%s redeclaration for <%s>"), what, s->tag); - complain_at (first, complaint, _("previous declaration")); + unsigned i = 0; - complain_at_indent (second, &i, _("%s redeclaration for <%s>"), what, s->tag); ++ complain_at_indent (second, complaint, &i, ++ _("%s redeclaration for <%s>"), what, s->tag); + i += SUB_INDENT; - complain_at_indent (first, &i, _("previous declaration")); ++ complain_at_indent (first, complaint, &i, ++ _("previous declaration")); } @@@ -218,73 -179,122 +226,73 @@@ symbol_type_set (symbol *sym, uniqstr t if (type_name) { if (sym->type_name) - symbol_redeclaration (sym, "%type", sym->type_location, loc); + symbol_redeclaration (sym, "%type", sym->type_location, loc); uniqstr_assert (type_name); sym->type_name = type_name; sym->type_location = loc; } } -/*-----------------------------------------. -| Set the DESTRUCTOR associated with SYM. | -`-----------------------------------------*/ +/*--------------------------------------------------------. +| Set the DESTRUCTOR or PRINTER associated with the SYM. | +`--------------------------------------------------------*/ void -symbol_destructor_set (symbol *sym, code_props const *destructor) +symbol_code_props_set (symbol *sym, code_props_type kind, + code_props const *code) { - if (sym->destructor.code) - symbol_redeclaration (sym, "%destructor", sym->destructor.location, - destructor->location); - sym->destructor = *destructor; + if (sym->props[kind].code) + symbol_redeclaration (sym, code_props_type_string (kind), + sym->props[kind].location, + code->location); + sym->props[kind] = *code; } -/*------------------------------------------. -| Set the DESTRUCTOR associated with TYPE. | -`------------------------------------------*/ +/*-----------------------------------------------------. +| Set the DESTRUCTOR or PRINTER associated with TYPE. | +`-----------------------------------------------------*/ void -semantic_type_destructor_set (semantic_type *type, - code_props const *destructor) +semantic_type_code_props_set (semantic_type *type, + code_props_type kind, + code_props const *code) { - if (type->destructor.code) - semantic_type_redeclaration (type, "%destructor", - type->destructor.location, - destructor->location); - type->destructor = *destructor; + if (type->props[kind].code) + semantic_type_redeclaration (type, code_props_type_string (kind), + type->props[kind].location, + code->location); + type->props[kind] = *code; } -/*---------------------------------------. -| Get the computed %destructor for SYM. | -`---------------------------------------*/ +/*---------------------------------------------------. +| Get the computed %destructor or %printer for SYM. | +`---------------------------------------------------*/ -code_props const * -symbol_destructor_get (symbol const *sym) +code_props * +symbol_code_props_get (symbol *sym, code_props_type kind) { - /* Per-symbol %destructor. */ - if (sym->destructor.code) - return &sym->destructor; + /* Per-symbol code props. */ + if (sym->props[kind].code) + return &sym->props[kind]; - /* Per-type %destructor. */ + /* Per-type code props. */ if (sym->type_name) { - code_props const *destructor = - &semantic_type_get (sym->type_name)->destructor; - if (destructor->code) - return destructor; + code_props *code = + &semantic_type_get (sym->type_name, NULL)->props[kind]; + if (code->code) + return code; } - /* Apply default %destructor's only to user-defined symbols. */ - if (sym->tag[0] == '$' || sym == errtoken) - return &code_props_none; - - if (sym->type_name) - return &default_tagged_destructor; - return &default_tagless_destructor; -} - -/*--------------------------------------. -| Set the PRINTER associated with SYM. | -`--------------------------------------*/ - -void -symbol_printer_set (symbol *sym, code_props const *printer) -{ - if (sym->printer.code) - symbol_redeclaration (sym, "%printer", - sym->printer.location, printer->location); - sym->printer = *printer; -} - -/*---------------------------------------. -| Set the PRINTER associated with TYPE. | -`---------------------------------------*/ - -void -semantic_type_printer_set (semantic_type *type, code_props const *printer) -{ - if (type->printer.code) - semantic_type_redeclaration (type, "%printer", - type->printer.location, printer->location); - type->printer = *printer; -} - -/*------------------------------------. -| Get the computed %printer for SYM. | -`------------------------------------*/ - -code_props const * -symbol_printer_get (symbol const *sym) -{ - /* Per-symbol %printer. */ - if (sym->printer.code) - return &sym->printer; - - /* Per-type %printer. */ - if (sym->type_name) + /* Apply default code props's only to user-defined symbols. */ + if (sym->tag[0] != '$' && sym != errtoken) { - code_props const *printer = &semantic_type_get (sym->type_name)->printer; - if (printer->code) - return printer; + code_props *code = + &semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind]; + if (code->code) + return code; } - - /* Apply the default %printer only to user-defined symbols. */ - if (sym->tag[0] == '$' || sym == errtoken) - return &code_props_none; - - if (sym->type_name) - return &default_tagged_printer; - return &default_tagless_printer; + return &code_props_none; } /*-----------------------------------------------------------------. @@@ -298,7 -308,7 +306,7 @@@ symbol_precedence_set (symbol *sym, in if (a != undef_assoc) { if (sym->prec != 0) - symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, + symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, loc); sym->prec = prec; sym->assoc = a; @@@ -317,12 -327,10 +325,12 @@@ void symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) { + bool warned = false; if (sym->class != unknown_sym && sym->class != class) { - complain_at (loc, _("symbol %s redefined"), sym->tag); - sym->declared = false; + complain_at (loc, complaint, _("symbol %s redefined"), sym->tag); + // Don't report both "redefined" and "redeclared". + warned = true; } if (class == nterm_sym && sym->class != nterm_sym) @@@ -334,9 -342,9 +342,9 @@@ if (declaring) { - if (sym->declared) - warn_at (loc, _("symbol %s redeclared"), sym->tag); - sym->declared = true; + if (sym->status == declared && !warned) + complain_at (loc, Wother, _("symbol %s redeclared"), sym->tag); + sym->status = declared; } } @@@ -356,8 -364,7 +364,8 @@@ symbol_user_token_number_set (symbol *s user_token_numberp = &sym->alias->user_token_number; if (*user_token_numberp != USER_NUMBER_UNDEFINED && *user_token_numberp != user_token_number) - complain_at (loc, _("redefining user token number of %s"), sym->tag); + complain_at (loc, complaint, _("redefining user token number of %s"), + sym->tag); *user_token_numberp = user_token_number; /* User defined $end token? */ @@@ -365,7 -372,7 +373,7 @@@ { endtoken = sym; /* It is always mapped to 0, so it was already counted in - NTOKENS. */ + NTOKENS. */ if (endtoken->number != NUMBER_UNDEFINED) --ntokens; endtoken->number = 0; @@@ -383,51 -390,14 +391,51 @@@ symbol_check_defined (symbol *sym { if (sym->class == unknown_sym) { - complain_at - (sym->location, - _("symbol %s is used, but is not defined as a token and has no rules"), - sym->tag); + assert (sym->status != declared); + complain_at (sym->location, + sym->status == needed ? complaint : Wother, + _("symbol %s is used, but is not defined as a token" + " and has no rules"), + sym->tag); sym->class = nterm_sym; sym->number = nvars++; } + for (int i = 0; i < 2; ++i) + symbol_code_props_get (sym, i)->is_used = true; + + /* Set the semantic type status associated to the current symbol to + 'declared' so that we could check semantic types unnecessary uses. */ + if (sym->type_name) + { + semantic_type *sem_type = semantic_type_get (sym->type_name, NULL); + if (sem_type) + sem_type->status = declared; + } + + return true; +} + +static inline bool +semantic_type_check_defined (semantic_type *sem_type) +{ + // <*> and <> do not have to be "declared". + if (sem_type->status == declared + || !*sem_type->tag + || STREQ(sem_type->tag, "*")) + { + for (int i = 0; i < 2; ++i) + if (sem_type->props[i].kind != CODE_PROPS_NONE + && ! sem_type->props[i].is_used) + complain_at (sem_type->location, Wother, + _("useless %s for type <%s>"), + code_props_type_string (i), sem_type->tag); + } + else + complain_at (sem_type->location, Wother, + _("type <%s> is used, but is not associated to any symbol"), + sem_type->tag); + return true; } @@@ -437,23 -407,16 +445,23 @@@ symbol_check_defined_processor (void *s return symbol_check_defined (sym); } +static bool +semantic_type_check_defined_processor (void *sem_type, + void *null ATTRIBUTE_UNUSED) +{ + return semantic_type_check_defined (sem_type); +} + void symbol_make_alias (symbol *sym, symbol *str, location loc) { if (str->alias) - warn_at (loc, _("symbol %s used more than once as a literal string"), - str->tag); + complain_at (loc, Wother, + _("symbol %s used more than once as a literal string"), str->tag); else if (sym->alias) - warn_at (loc, _("symbol %s given more than one literal string"), - sym->tag); + complain_at (loc, Wother, + _("symbol %s given more than one literal string"), sym->tag); else { str->class = token_sym; @@@ -486,32 -449,42 +494,32 @@@ symbol_check_alias_consistency (symbol if (str->type_name != sym->type_name) { if (str->type_name) - symbol_type_set (sym, str->type_name, str->type_location); + symbol_type_set (sym, str->type_name, str->type_location); else - symbol_type_set (str, sym->type_name, sym->type_location); + symbol_type_set (str, sym->type_name, sym->type_location); } - if (str->destructor.code || sym->destructor.code) - { - if (str->destructor.code) - symbol_destructor_set (sym, &str->destructor); - else - symbol_destructor_set (str, &sym->destructor); - } - - if (str->printer.code || sym->printer.code) - { - if (str->printer.code) - symbol_printer_set (sym, &str->printer); - else - symbol_printer_set (str, &sym->printer); - } + for (int i = 0; i < CODE_PROPS_SIZE; ++i) + if (str->props[i].code) + symbol_code_props_set (sym, i, &str->props[i]); + else if (sym->props[i].code) + symbol_code_props_set (str, i, &sym->props[i]); if (sym->prec || str->prec) { if (str->prec) - symbol_precedence_set (sym, str->prec, str->assoc, - str->prec_location); + symbol_precedence_set (sym, str->prec, str->assoc, + str->prec_location); else - symbol_precedence_set (str, sym->prec, sym->assoc, - sym->prec_location); + symbol_precedence_set (str, sym->prec, sym->assoc, + sym->prec_location); } } static bool symbol_check_alias_consistency_processor (void *this, - void *null ATTRIBUTE_UNUSED) + void *null ATTRIBUTE_UNUSED) { symbol_check_alias_consistency (this); return true; @@@ -546,6 -519,7 +554,7 @@@ symbol_pack_processor (void *this, voi static void user_token_number_redeclaration (int num, symbol *first, symbol *second) { + unsigned i = 0; /* User token numbers are not assigned during the parsing, but in a second step, via a traversal of the symbol table sorted on tag. @@@ -557,11 -531,12 +566,12 @@@ first = second; second = tmp; } - complain_at (second->location, complaint, - _("user token number %d redeclaration for %s"), - num, second->tag); - complain_at (first->location, complaint, _("previous declaration for %s"), - first->tag); - complain_at_indent (second->location, &i, ++ complain_at_indent (second->location, complaint, &i, + _("user token number %d redeclaration for %s"), + num, second->tag); - complain_at_indent (first->location, &i, ++ complain_at_indent (first->location, complaint, &i, + _("previous declaration for %s"), + first->tag); } /*--------------------------------------------------. @@@ -577,7 -552,7 +587,7 @@@ symbol_translation (symbol *this { /* A token which translation has already been set? */ if (token_translations[this->user_token_number] != undeftoken->number) - user_token_number_redeclaration + user_token_number_redeclaration (this->user_token_number, symbols[token_translations[this->user_token_number]], this); @@@ -665,15 -640,15 +675,15 @@@ voi symbols_new (void) { symbol_table = hash_initialize (HT_INITIAL_CAPACITY, - NULL, - hash_symbol_hasher, - hash_symbol_comparator, - free); + NULL, + hash_symbol_hasher, + hash_symbol_comparator, + free); semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY, - NULL, - hash_semantic_type_hasher, - hash_semantic_type_comparator, - free); + NULL, + hash_semantic_type_hasher, + hash_semantic_type_comparator, + free); } @@@ -709,7 -684,7 +719,7 @@@ symbol_from_uniqstr (const uniqstr key `-----------------------------------------------------------------------*/ semantic_type * -semantic_type_from_uniqstr (const uniqstr key) +semantic_type_from_uniqstr (const uniqstr key, const location *loc) { semantic_type probe; semantic_type *entry; @@@ -720,7 -695,7 +730,7 @@@ if (!entry) { /* First insertion in the hash. */ - entry = semantic_type_new (key); + entry = semantic_type_new (key, loc); if (!hash_insert (semantic_type_table, entry)) xalloc_die (); } @@@ -746,9 -721,9 +756,9 @@@ symbol_get (const char *key, location l `-----------------------------------------------------------------------*/ semantic_type * -semantic_type_get (const char *key) +semantic_type_get (const char *key, const location *loc) { - return semantic_type_from_uniqstr (uniqstr_new (key)); + return semantic_type_from_uniqstr (uniqstr_new (key), loc); } @@@ -811,20 -786,20 +821,20 @@@ symbols_cmp_qsort (void const *a, void } static void -symbols_do (Hash_processor processor, void *processor_data) +symbols_do (Hash_processor processor, void *processor_data, + struct hash_table *table, symbol **sorted) { - size_t count = hash_get_n_entries (symbol_table); - if (!symbols_sorted) + size_t count = hash_get_n_entries (table); + if (!sorted) { - symbols_sorted = xnmalloc (count, sizeof *symbols_sorted); - hash_get_entries (symbol_table, (void**)symbols_sorted, count); - qsort (symbols_sorted, count, sizeof *symbols_sorted, - symbols_cmp_qsort); + sorted = xnmalloc (count, sizeof *sorted); + hash_get_entries (table, (void**)sorted, count); + qsort (sorted, count, sizeof *sorted, symbols_cmp_qsort); } { size_t i; for (i = 0; i < count; ++i) - processor (symbols_sorted[i], processor_data); + processor (sorted[i], processor_data); } } @@@ -836,10 -811,7 +846,10 @@@ void symbols_check_defined (void) { - symbols_do (symbol_check_defined_processor, NULL); + symbols_do (symbol_check_defined_processor, NULL, + symbol_table, symbols_sorted); + symbols_do (semantic_type_check_defined_processor, NULL, + semantic_type_table, semantic_types_sorted); } /*------------------------------------------------------------------. @@@ -860,12 -832,12 +870,12 @@@ symbols_token_translations_init (void { symbol *this = symbols[i]; if (this->user_token_number != USER_NUMBER_UNDEFINED) - { - if (this->user_token_number > max_user_token_number) - max_user_token_number = this->user_token_number; - if (this->user_token_number == 256) - num_256_available_p = false; - } + { + if (this->user_token_number > max_user_token_number) + max_user_token_number = this->user_token_number; + if (this->user_token_number == 256) + num_256_available_p = false; + } } /* If 256 is not used, assign it to error, to follow POSIX. */ @@@ -881,20 -853,20 +891,20 @@@ { symbol *this = symbols[i]; if (this->user_token_number == USER_NUMBER_UNDEFINED) - this->user_token_number = ++max_user_token_number; + this->user_token_number = ++max_user_token_number; if (this->user_token_number > max_user_token_number) - max_user_token_number = this->user_token_number; + max_user_token_number = this->user_token_number; } token_translations = xnmalloc (max_user_token_number + 1, - sizeof *token_translations); + sizeof *token_translations); - /* Initialize all entries for literal tokens to 2, the internal - token number for $undefined, which represents all invalid inputs. - */ + /* Initialize all entries for literal tokens to the internal token + number for $undefined, which represents all invalid inputs. */ for (i = 0; i < max_user_token_number + 1; i++) token_translations[i] = undeftoken->number; - symbols_do (symbol_translation_processor, NULL); + symbols_do (symbol_translation_processor, NULL, + symbol_table, symbols_sorted); } @@@ -906,11 -878,10 +916,11 @@@ void symbols_pack (void) { - symbols_do (symbol_check_alias_consistency_processor, NULL); + symbols_do (symbol_check_alias_consistency_processor, NULL, + symbol_table, symbols_sorted); symbols = xcalloc (nsyms, sizeof *symbols); - symbols_do (symbol_pack_processor, NULL); + symbols_do (symbol_pack_processor, NULL, symbol_table, symbols_sorted); /* Aliases leave empty slots in symbols, so remove them. */ { @@@ -939,11 -910,76 +949,11 @@@ symbols_token_translations_init (); if (startsymbol->class == unknown_sym) - fatal_at (startsymbol_location, - _("the start symbol %s is undefined"), - startsymbol->tag); + complain_at (startsymbol_location, fatal, + _("the start symbol %s is undefined"), + startsymbol->tag); else if (startsymbol->class == token_sym) - fatal_at (startsymbol_location, - _("the start symbol %s is a token"), - startsymbol->tag); -} - - -/*--------------------------------------------------. -| Set default tagged/tagless %destructor/%printer. | -`--------------------------------------------------*/ - -void -default_tagged_destructor_set (code_props const *destructor) -{ - if (default_tagged_destructor.code) - { - unsigned i = 0; - complain_at_indent (destructor->location, &i, - _("redeclaration for default tagged %%destructor")); - i += SUB_INDENT; - complain_at_indent (default_tagged_destructor.location, &i, - _("previous declaration")); - } - default_tagged_destructor = *destructor; -} - -void -default_tagless_destructor_set (code_props const *destructor) -{ - if (default_tagless_destructor.code) - { - unsigned i = 0; - complain_at_indent (destructor->location, &i, - _("redeclaration for default tagless %%destructor")); - i += SUB_INDENT; - complain_at_indent (default_tagless_destructor.location, &i, - _("previous declaration")); - } - default_tagless_destructor = *destructor; -} - -void -default_tagged_printer_set (code_props const *printer) -{ - if (default_tagged_printer.code) - { - unsigned i = 0; - complain_at_indent (printer->location, &i, - _("redeclaration for default tagged %%printer")); - i += SUB_INDENT; - complain_at_indent (default_tagged_printer.location, &i, - _("previous declaration")); - } - default_tagged_printer = *printer; -} - -void -default_tagless_printer_set (code_props const *printer) -{ - if (default_tagless_printer.code) - { - unsigned i = 0; - complain_at_indent (printer->location, &i, - _("redeclaration for default tagless %%printer")); - i += SUB_INDENT; - complain_at_indent (default_tagless_printer.location, &i, - _("previous declaration")); - } - default_tagless_printer = *printer; + complain_at (startsymbol_location, fatal, + _("the start symbol %s is a token"), + startsymbol->tag); } diff --combined tests/conflicts.at index 83ef1286,3934a6cf..b3f67098 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@@ -1,6 -1,7 +1,6 @@@ # Exercising Bison on conflicts. -*- Autotest -*- -# Copyright (C) 2002-2005, 2007, 2009-2012 Free Software Foundation, -# Inc. +# Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@@ -37,7 -38,7 +37,7 @@@ e: 'e' | /* Nothing. */ ]]) AT_BISON_CHECK([-o input.c input.y], 0, [], -[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ +[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother] ]]) AT_CLEANUP @@@ -141,11 -142,11 +141,11 @@@ AT_CLEANU -## -------------------------------------- ## -## %error-verbose and consistent errors. ## -## -------------------------------------- ## +## ------------------------------------------- ## +## parse.error=verbose and consistent errors. ## +## ------------------------------------------- ## -AT_SETUP([[%error-verbose and consistent errors]]) +AT_SETUP([[parse.error=verbose and consistent errors]]) m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [ @@@ -163,6 -164,7 +163,6 @@@ AT_SKEL_JAVA_IF([AT_DATA], [AT_DATA_GRA }]], [[ %code {]AT_SKEL_CC_IF([[ - #include #include ]], [[ #include #include @@@ -175,7 -177,7 +175,7 @@@ ]$1[ -%error-verbose +%define parse.error verbose %% @@@ -370,7 -372,7 +370,7 @@@ error-reduce ; consistent-reduction: /*empty*/ { - assert (yychar == ]AT_SKEL_CC_IF([[yyempty_]], [[YYEMPTY]])[); + assert (yychar == YYEMPTY); yylval = 0; yychar = 'b'; } ; @@@ -394,7 -396,11 +394,7 @@@ AT_CONSISTENT_ERRORS_CHECK([[%glr-parse [AT_USER_ACTION_GRAMMAR], [AT_USER_ACTION_INPUT], [['b']], [[none]]) -AT_CONSISTENT_ERRORS_CHECK([[%language "c++"]], - [AT_USER_ACTION_GRAMMAR], - [AT_USER_ACTION_INPUT], - [['b']], [[none]]) -# No Java test because yychar cannot be manipulated by users. +# No C++ or Java test because yychar cannot be manipulated by users. AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reductions consistent]], [AT_USER_ACTION_GRAMMAR], @@@ -498,7 -504,7 +498,7 @@@ AT_BISON_OPTION_POPDEF # Show canonical LR's failure. AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]], [[0]], [[]], -[[input.y: conflicts: 2 shift/reduce +[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr] ]]) AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]], [[1]], [[]], @@@ -508,7 -514,7 +508,7 @@@ # It's corrected by LAC. AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \ -o input.c input.y]], [[0]], [[]], -[[input.y: conflicts: 2 shift/reduce +[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr] ]]) AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]], [[1]], [[]], @@@ -518,7 -524,7 +518,7 @@@ # IELR is sufficient when LAC is used. AT_BISON_CHECK([[-Dlr.type=ielr -Dparse.lac=full -o input.c input.y]], [[0]], [[]], -[[input.y: conflicts: 2 shift/reduce +[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr] ]]) AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]], [[1]], [[]], @@@ -542,8 -548,8 +542,8 @@@ exp: exp OP exp | NUM ]]) AT_BISON_CHECK([-o input.c --report=all input.y], 0, [], -[input.y: conflicts: 1 shift/reduce -]) +[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] +]]) # Check the contents of the report. AT_CHECK([cat input.output], [], @@@ -735,62 -741,6 +735,62 @@@ state AT_CLEANUP +## ---------------------- ## +## %precedence suffices. ## +## ---------------------- ## + +AT_SETUP([%precedence suffices]) + +AT_DATA([input.y], +[[%precedence "then" +%precedence "else" +%% +stmt: + "if" cond "then" stmt +| "if" cond "then" stmt "else" stmt +| "stmt" +; + +cond: + "exp" +; +]]) + +AT_BISON_CHECK([-o input.c input.y]) + +AT_CLEANUP + + +## ------------------------------ ## +## %precedence does not suffice. ## +## ------------------------------ ## + +AT_SETUP([%precedence does not suffice]) + +AT_DATA([input.y], +[[%precedence "then" +%precedence "else" +%% +stmt: + "if" cond "then" stmt +| "if" cond "then" stmt "else" stmt +| "stmt" +; + +cond: + "exp" +| cond "then" cond +; +]]) + +AT_BISON_CHECK([-o input.c input.y], 0, [], +[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] +input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond [-Wother] +]]) + +AT_CLEANUP + + ## -------------------------------- ## ## Defaulted Conflicted Reduction. ## ## -------------------------------- ## @@@ -828,8 -778,8 +828,8 @@@ id : '0' ]]) AT_BISON_CHECK([-o input.c --report=all input.y], 0, [], -[[input.y: conflicts: 1 reduce/reduce -input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' +[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' [-Wother] ]]) # Check the contents of the report. @@@ -945,8 -895,9 +945,8 @@@ exp: exp OP exp | NUM ]]) AT_BISON_CHECK([-o input.c input.y], 1, [], - [[input.y: shift/reduce conflicts: 1 found, 0 expected -[input.y: conflicts: 1 shift/reduce -input.y: error: expected 0 shift/reduce conflicts -]) ++[[input.y: error: shift/reduce conflicts: 1 found, 0 expected +]]) AT_CLEANUP @@@ -981,8 -932,9 +981,8 @@@ exp: exp OP exp | NUM ]]) AT_BISON_CHECK([-o input.c input.y], 1, [], - [[input.y: shift/reduce conflicts: 1 found, 2 expected -[input.y: conflicts: 1 shift/reduce -input.y: error: expected 2 shift/reduce conflicts -]) ++[[input.y: error: shift/reduce conflicts: 1 found, 2 expected +]]) AT_CLEANUP @@@ -1000,8 -952,9 +1000,8 @@@ a: 'a' ]]) AT_BISON_CHECK([-o input.c input.y], 1, [], - [[input.y: reduce/reduce conflicts: 1 found, 0 expected -[input.y: conflicts: 1 reduce/reduce -input.y: error: expected 0 reduce/reduce conflicts -]) ++[[input.y: error: reduce/reduce conflicts: 1 found, 0 expected +]]) AT_CLEANUP @@@ -1043,7 -996,7 +1043,7 @@@ e: e '+' ]]) AT_BISON_CHECK([-o input.c input.y], 0, [], -[[input.y: conflicts: 4 shift/reduce +[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr] ]]) AT_CLEANUP @@@ -1145,15 -1098,14 +1145,15 @@@ reported_conflicts ]]) AT_BISON_CHECK([[--report=all input.y]], 0, [], -[[input.y: conflicts: 1 shift/reduce, 1 reduce/reduce -input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1 -input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2 -input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ -input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ -input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ -input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' -input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ +[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] +input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1 [-Wother] +input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2 [-Wother] +input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother] +input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother] +input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother] +input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother] +input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother] ]]) AT_CHECK([[cat input.output]], 0, @@@ -1298,12 -1250,11 +1298,12 @@@ AT_DATA([[input-keep.y]] AT_CHECK([[cat input.y >> input-keep.y]]) AT_BISON_CHECK([[input-keep.y]], 0, [], -[[input-keep.y: conflicts: 2 shift/reduce, 2 reduce/reduce -input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ -input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ -input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' -input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ +[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr] +input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr] +input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother] +input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother] +input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother] +input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother] ]]) AT_CLEANUP @@@ -1458,40 -1409,9 +1458,40 @@@ state AT_CLEANUP -## --------------------------------- ## -## -W versus %expect and %expect-rr ## -## --------------------------------- ## +## -------------------- ## +## %expect-rr non GLR. ## +## -------------------- ## + +AT_SETUP([[%expect-rr non GLR]]) + +AT_DATA([[1.y]], +[[%expect-rr 0 +%% +exp: 'a' +]]) + +AT_BISON_CHECK([[1.y]], [[0]], [], +[[1.y: warning: %expect-rr applies only to GLR parsers [-Wother] +]]) + +AT_DATA([[2.y]], +[[%expect-rr 1 +%% +exp: 'a' | 'a'; +]]) + +AT_BISON_CHECK([[2.y]], [[0]], [], +[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother] +2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +2.y:3.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother] +]]) + +AT_CLEANUP + + +## ---------------------------------- ## +## -W versus %expect and %expect-rr. ## +## ---------------------------------- ## AT_SETUP([[-W versus %expect and %expect-rr]]) @@@ -1517,27 -1437,17 +1517,27 @@@ B: ]]) AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]], -[[sr-rr.y: conflicts: 1 shift/reduce, 1 reduce/reduce +[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] +sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] ]]) AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]], -[[sr-rr.y: conflicts: 1 reduce/reduce +[[sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] ]]) AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]], -[[sr-rr.y: conflicts: 1 shift/reduce +[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] ]]) -[for gram in sr-rr sr rr; do +[ +# This is piece of code is rather complex for a simple task: try every +# combinaison of (0 or 1 real SR) x (0 or 1 real RR) x (don't %expect +# or %expect 0, 1, or 2 SR) x (don't %expect-rr or %expect-rr 0, 1, or 2 +# RR). + +# Number and types of genuine conflicts in the grammar. +for gram in sr-rr sr rr; do + # Number of expected s/r conflicts. for sr_exp_i in '' 0 1 2; do + # Number of expected r/r conflicts. for rr_exp_i in '' 0 1 2; do test -z "$sr_exp_i" && test -z "$rr_exp_i" && continue @@@ -1560,38 -1470,36 +1560,38 @@@ echo "$directives" > $file cat $gram.y >> $file - # Count actual conflicts. - conflicts= - sr_count=0 - rr_count=0 - if test $gram = sr || test $gram = sr-rr; then - conflicts="1 shift/reduce" - sr_count=1 - fi - if test $gram = rr || test $gram = sr-rr; then - if test -n "$conflicts"; then - conflicts="$conflicts, " - fi - conflicts="${conflicts}1 reduce/reduce" - rr_count=1 - fi + # Number of found conflicts. + case $gram in + (sr) sr_count=1; rr_count=0;; + (rr) sr_count=0; rr_count=1;; + (sr-rr) sr_count=1; rr_count=1;; + esac + + # Update number of expected conflicts: if %expect is given then + # %expect-rr defaults to 0, and vice-versa. Leave empty if + # nothing expected. + case $sr_exp_i:$rr_exp_i in + ?:) rr_exp_i=0;; + :?) sr_exp_i=0;; + esac # Run tests. if test $sr_count -eq $sr_exp && test $rr_count -eq $rr_exp; then ]AT_BISON_CHECK([[-Wnone $file]])[ ]AT_BISON_CHECK([[-Werror $file]])[ else - echo "$file: conflicts: $conflicts" > experr - if test $sr_count -ne $sr_exp; then - if test $sr_exp -ne 1; then s=s; else s= ; fi - echo "$file: error: expected $sr_exp shift/reduce conflict$s" >> experr - fi - if test $rr_count -ne $rr_exp; then - if test $rr_exp -ne 1; then s=s; else s= ; fi - echo "$file: error: expected $rr_exp reduce/reduce conflict$s" >> experr - fi + { + if test -z "$sr_exp_i" && test "$sr_count" -ne 0; then + echo "warning: $sr_count shift/reduce conflicts" + elif test "$sr_exp_i" -ne "$sr_count"; then - echo "shift/reduce conflicts: $sr_count found, $sr_exp_i expected" ++ echo "error: shift/reduce conflicts: $sr_count found, $sr_exp_i expected" + fi + if test -z "$rr_exp_i" && test "$rr_count" -ne 0; then + echo "warning: $rr_count reduce/reduce conflicts" + elif test "$rr_exp_i" -ne "$rr_count"; then - echo "reduce/reduce conflicts: $rr_count found, $rr_exp_i expected" ++ echo "error: reduce/reduce conflicts: $rr_count found, $rr_exp_i expected" + fi + } | sed -e "s/^/$file: /" > experr ]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[ ]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[ fi diff --combined tests/glr-regression.at index 98ebdfa6,aacc57c8..b376c1c0 --- a/tests/glr-regression.at +++ b/tests/glr-regression.at @@@ -93,8 -93,8 +93,8 @@@ yylex (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr1.c glr-regr1.y]], 0, [], -[glr-regr1.y: conflicts: 1 shift/reduce -]) +[[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] +]]) AT_COMPILE([glr-regr1]) AT_PARSER_CHECK([[echo BPBPB | ./glr-regr1]], 0, [[E -> 'B' @@@ -208,8 -208,8 +208,8 @@@ main (int argc, char **argv AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr2a.c glr-regr2a.y]], 0, [], -[glr-regr2a.y: conflicts: 2 shift/reduce -]) +[[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr] +]]) AT_COMPILE([glr-regr2a]) AT_PARSER_CHECK([[echo s VARIABLE_1 t v x q | ./glr-regr2a]], 0, @@@ -325,9 -325,8 +325,9 @@@ main(int argc, char* argv[] AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr3.c glr-regr3.y]], 0, [], -[glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce -]) +[[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] +glr-regr3.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr3]) AT_PARSER_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]], @@@ -418,8 -417,8 +418,8 @@@ merge (YYSTYPE s1, YYSTYPE s2 AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr4.c glr-regr4.y]], 0, [], -[glr-regr4.y: conflicts: 1 reduce/reduce -]) +[[glr-regr4.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr4]) AT_PARSER_CHECK([[./glr-regr4]], 0, @@@ -478,8 -477,8 +478,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr5.c glr-regr5.y]], 0, [], -[glr-regr5.y: conflicts: 1 reduce/reduce -]) +[[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr5]) AT_PARSER_CHECK([[./glr-regr5]], 0, [], @@@ -530,8 -529,8 +530,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr6.c glr-regr6.y]], 0, [], -[glr-regr6.y: conflicts: 1 reduce/reduce -]) +[[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr6]) AT_PARSER_CHECK([[./glr-regr6]], 0, @@@ -619,8 -618,8 +619,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr7.c glr-regr7.y]], 0, [], -[glr-regr7.y: conflicts: 2 reduce/reduce -]) +[[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr7]) AT_PARSER_CHECK([[./glr-regr7]], 2, [], @@@ -713,8 -712,8 +713,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr8.c glr-regr8.y]], 0, [], -[glr-regr8.y: conflicts: 1 reduce/reduce -]) +[[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr8]) AT_PARSER_CHECK([[./glr-regr8]], 0, @@@ -793,8 -792,8 +793,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr9.c glr-regr9.y]], 0, [], -[glr-regr9.y: conflicts: 1 reduce/reduce -]) +[[glr-regr9.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr9]) AT_PARSER_CHECK([[./glr-regr9]], 0, [], @@@ -849,8 -848,8 +849,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr10.c glr-regr10.y]], 0, [], -[glr-regr10.y: conflicts: 1 reduce/reduce -]) +[[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr10]) AT_PARSER_CHECK([[./glr-regr10]], 0, [], []) @@@ -907,8 -906,8 +907,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr11.c glr-regr11.y]], 0, [], -[glr-regr11.y: conflicts: 1 reduce/reduce -]) +[[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr11]) AT_PARSER_CHECK([[./glr-regr11]], 0, [], []) @@@ -1028,9 -1027,8 +1028,9 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr12.c glr-regr12.y]], 0, [], -[glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce -]) +[[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] +glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr12]) AT_PARSER_CHECK([[./glr-regr12]], 0, [], []) @@@ -1359,8 -1357,8 +1359,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr14.c glr-regr14.y]], 0, [], -[glr-regr14.y: conflicts: 3 reduce/reduce -]) +[[glr-regr14.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr14]) AT_PARSER_CHECK([[./glr-regr14]], 0, @@@ -1452,8 -1450,8 +1452,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr15.c glr-regr15.y]], 0, [], -[glr-regr15.y: conflicts: 2 reduce/reduce -]) +[[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr15]) AT_PARSER_CHECK([[./glr-regr15]], 0, [], @@@ -1512,8 -1510,8 +1512,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr16.c glr-regr16.y]], 0, [], -[glr-regr16.y: conflicts: 1 reduce/reduce -]) +[[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr16]) AT_PARSER_CHECK([[./glr-regr16]], 0, [], @@@ -1597,8 -1595,8 +1597,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr17.c glr-regr17.y]], 0, [], -[glr-regr17.y: conflicts: 3 reduce/reduce -]) +[[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr] +]]) AT_COMPILE([glr-regr17]) AT_PARSER_CHECK([[./glr-regr17]], 0, [], @@@ -1652,11 -1650,11 +1652,11 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o glr-regr18.c glr-regr18.y]], 1, [], - [glr-regr18.y:26.18-24: result type clash on merge function 'merge': != - glr-regr18.y:25.18-24: previous declaration - glr-regr18.y:27.13-19: result type clash on merge function 'merge': != - glr-regr18.y:26.18-24: previous declaration - ]) -[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': != ++[[glr-regr18.y:26.18-24: error: result type clash on merge function 'merge': != + glr-regr18.y:25.18-24: previous declaration + glr-regr18.y:27.13-19: error: result type clash on merge function 'merge': != + glr-regr18.y:26.18-24: previous declaration -]) ++]]) AT_CLEANUP @@@ -1700,8 -1698,8 +1700,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]], 0, [], -[input.y: conflicts: 1 reduce/reduce -]) +[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] +]]) AT_COMPILE([input]) AT_PARSER_CHECK([[./input]], 1, [], diff --combined tests/input.at index 056e5785,50c10506..5bb707e7 --- a/tests/input.at +++ b/tests/input.at @@@ -33,8 -33,8 +33,8 @@@ exp: { @$ = @1 ; } ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:2.13-14: integer out of range: '$1' - input.y:3.13-14: integer out of range: '@1' + [[input.y:2.13-14: error: integer out of range: '$1' + input.y:3.13-14: error: integer out of range: '@1' ]]) AT_CLEANUP @@@ -58,11 -58,11 +58,11 @@@ exp: foo { $$; } foo { $2; } fo ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:5.12-13: $$ for the midrule at $2 of 'exp' has no declared type - input.y:5.24-25: $2 of 'exp' has no declared type + [[input.y:5.12-13: error: $$ for the midrule at $2 of 'exp' has no declared type + input.y:5.24-25: error: $2 of 'exp' has no declared type -input.y:5.6-32: warning: type clash on default action: != <> -input.y:6.6-8: warning: type clash on default action: != <> -input.y:7.5: warning: empty rule for typed nonterminal, and no action +input.y:5.6-32: warning: type clash on default action: != <> [-Wother] +input.y:6.6-8: warning: type clash on default action: != <> [-Wother] +input.y:7.5: warning: empty rule for typed nonterminal, and no action [-Wother] ]]) AT_CLEANUP @@@ -72,6 -72,7 +72,6 @@@ # -------------------------------- # Generate the token, type, and destructor # declarations for the unused values tests. - m4_define([_AT_UNUSED_VALUES_DECLARATIONS], [[[%token INT; %type a b c d e f g h i j k l; @@@ -79,11 -80,15 +79,11 @@@ # AT_CHECK_UNUSED_VALUES(DECLARATIONS_AFTER, CHECK_MIDRULE_VALUES) -# ------------------------------------------------------------------ -# Generate a grammar to test unused values, -# compile it, run it. If DECLARATIONS_AFTER -# is set, then the token, type, and destructor -# declarations are generated after the rules -# rather than before. If CHECK_MIDRULE_VALUES -# is set, then --warnings=midrule-values is -# set. - +# ---------------------------------------------------------------- +# Generate a grammar to test unused values, compile it, run it. If +# DECLARATIONS_AFTER is set, then the token, type, and destructor +# declarations are generated after the rules rather than before. If +# CHECK_MIDRULE_VALUES is set, then --warnings=midrule-values is set. m4_define([AT_CHECK_UNUSED_VALUES], [AT_DATA([input.y], m4_ifval($1, [ @@@ -113,39 -118,39 +113,39 @@@ _AT_UNUSED_VALUES_DECLARATIONS] ) AT_BISON_CHECK(m4_ifval($2, [ --warnings=midrule-values ])[ input.y], [0], [], -[[input.y:11.10-32: warning: unset value: $]$[ -input.y:11.10-32: warning: unused value: $]1[ -input.y:11.10-32: warning: unused value: $]3[ -input.y:11.10-32: warning: unused value: $]5[ -input.y:12.9: warning: empty rule for typed nonterminal, and no action -]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $$ -input.y:13.26-41: warning: unset value: $$ -]]])[[input.y:13.10-62: warning: unset value: $]$[ -input.y:13.10-62: warning: unused value: $]3[ -input.y:13.10-62: warning: unused value: $]5[ -]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $$ -]]])[[input.y:14.10-49: warning: unset value: $]$[ -input.y:14.10-49: warning: unused value: $]3[ -input.y:14.10-49: warning: unused value: $]5[ -input.y:15.10-37: warning: unset value: $]$[ -input.y:15.10-37: warning: unused value: $]3[ -input.y:15.10-37: warning: unused value: $]5[ -input.y:17.10-58: warning: unset value: $]$[ -input.y:17.10-58: warning: unused value: $]1[ -]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]2[ -]]])[[input.y:17.10-58: warning: unused value: $]3[ -]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]4[ -]]])[[input.y:17.10-58: warning: unused value: $]5[ -input.y:18.10-72: warning: unset value: $]$[ -input.y:18.10-72: warning: unused value: $]1[ -input.y:18.10-72: warning: unused value: $]3[ -]]m4_ifval($2, [[[input.y:18.10-72: warning: unused value: $]4[ -]]])[[input.y:18.10-72: warning: unused value: $]5[ -]]m4_ifval($2, [[[input.y:20.10-55: warning: unused value: $]3[ -]]])[[input.y:21.10-68: warning: unset value: $]$[ -input.y:21.10-68: warning: unused value: $]1[ -input.y:21.10-68: warning: unused value: $]2[ -]]m4_ifval($2, [[[input.y:21.10-68: warning: unused value: $]4[ +[[input.y:11.10-32: warning: unset value: $]$[ [-Wother] +input.y:11.10-32: warning: unused value: $]1[ [-Wother] +input.y:11.10-32: warning: unused value: $]3[ [-Wother] +input.y:11.10-32: warning: unused value: $]5[ [-Wother] +input.y:12.9: warning: empty rule for typed nonterminal, and no action [-Wother] +]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $$ [-Wmidrule-values] +input.y:13.26-41: warning: unset value: $$ [-Wmidrule-values] +]]])[[input.y:13.10-62: warning: unset value: $]$[ [-Wother] +input.y:13.10-62: warning: unused value: $]3[ [-Wother] +input.y:13.10-62: warning: unused value: $]5[ [-Wother] +]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $$ [-Wmidrule-values] +]]])[[input.y:14.10-49: warning: unset value: $]$[ [-Wother] +input.y:14.10-49: warning: unused value: $]3[ [-Wother] +input.y:14.10-49: warning: unused value: $]5[ [-Wother] +input.y:15.10-37: warning: unset value: $]$[ [-Wother] +input.y:15.10-37: warning: unused value: $]3[ [-Wother] +input.y:15.10-37: warning: unused value: $]5[ [-Wother] +input.y:17.10-58: warning: unset value: $]$[ [-Wother] +input.y:17.10-58: warning: unused value: $]1[ [-Wother] +]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]2[ [-Wmidrule-values] +]]])[[input.y:17.10-58: warning: unused value: $]3[ [-Wother] +]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]4[ [-Wmidrule-values] +]]])[[input.y:17.10-58: warning: unused value: $]5[ [-Wother] +input.y:18.10-72: warning: unset value: $]$[ [-Wother] +input.y:18.10-72: warning: unused value: $]1[ [-Wother] +input.y:18.10-72: warning: unused value: $]3[ [-Wother] +]]m4_ifval($2, [[[input.y:18.10-72: warning: unused value: $]4[ [-Wmidrule-values] +]]])[[input.y:18.10-72: warning: unused value: $]5[ [-Wother] +]]m4_ifval($2, [[[input.y:20.10-55: warning: unused value: $]3[ [-Wmidrule-values] +]]])[[input.y:21.10-68: warning: unset value: $]$[ [-Wother] +input.y:21.10-68: warning: unused value: $]1[ [-Wother] +input.y:21.10-68: warning: unused value: $]2[ [-Wother] +]]m4_ifval($2, [[[input.y:21.10-68: warning: unused value: $]4[ [-Wmidrule-values] ]]]))]) @@@ -200,30 -205,30 +200,30 @@@ start: ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:1.13-29: %destructor redeclaration for <*> - input.y:1.13-29: previous declaration - input.y:2.10-24: %printer redeclaration for <*> - input.y:2.10-24: previous declaration - input.y:4.13-29: %destructor redeclaration for <*> - input.y:1.13-29: previous declaration - input.y:5.10-24: %printer redeclaration for <*> - input.y:2.10-24: previous declaration - input.y:7.13-29: %destructor redeclaration for <> - input.y:7.13-29: previous declaration - input.y:8.10-24: %printer redeclaration for <> - input.y:8.10-24: previous declaration - input.y:10.13-29: %destructor redeclaration for <> - input.y:7.13-29: previous declaration - input.y:11.10-24: %printer redeclaration for <> - input.y:8.10-24: previous declaration - input.y:17.13-29: %destructor redeclaration for <*> - input.y:4.13-29: previous declaration - input.y:18.10-24: %printer redeclaration for <*> - input.y:5.10-24: previous declaration - input.y:20.13-29: %destructor redeclaration for <> - input.y:10.13-29: previous declaration - input.y:21.10-24: %printer redeclaration for <> - input.y:11.10-24: previous declaration -[[input.y:1.13-29: error: redeclaration for default tagged %destructor ++[[input.y:1.13-29: error: %destructor redeclaration for <*> + input.y:1.13-29: previous declaration -input.y:2.10-24: error: redeclaration for default tagged %printer ++input.y:2.10-24: error: %printer redeclaration for <*> + input.y:2.10-24: previous declaration -input.y:4.13-29: error: redeclaration for default tagged %destructor ++input.y:4.13-29: error: %destructor redeclaration for <*> + input.y:1.13-29: previous declaration -input.y:5.10-24: error: redeclaration for default tagged %printer ++input.y:5.10-24: error: %printer redeclaration for <*> + input.y:2.10-24: previous declaration -input.y:7.13-29: error: redeclaration for default tagless %destructor ++input.y:7.13-29: error: %destructor redeclaration for <> + input.y:7.13-29: previous declaration -input.y:8.10-24: error: redeclaration for default tagless %printer ++input.y:8.10-24: error: %printer redeclaration for <> + input.y:8.10-24: previous declaration -input.y:10.13-29: error: redeclaration for default tagless %destructor ++input.y:10.13-29: error: %destructor redeclaration for <> + input.y:7.13-29: previous declaration -input.y:11.10-24: error: redeclaration for default tagless %printer ++input.y:11.10-24: error: %printer redeclaration for <> + input.y:8.10-24: previous declaration -input.y:17.13-29: error: redeclaration for default tagged %destructor ++input.y:17.13-29: error: %destructor redeclaration for <*> + input.y:4.13-29: previous declaration -input.y:18.10-24: error: redeclaration for default tagged %printer ++input.y:18.10-24: error: %printer redeclaration for <*> + input.y:5.10-24: previous declaration -input.y:20.13-29: error: redeclaration for default tagless %destructor ++input.y:20.13-29: error: %destructor redeclaration for <> + input.y:10.13-29: previous declaration -input.y:21.10-24: error: redeclaration for default tagless %printer ++input.y:21.10-24: error: %printer redeclaration for <> + input.y:11.10-24: previous declaration ]]) AT_CLEANUP @@@ -251,143 -256,26 +251,143 @@@ start: ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:4.13-29: %destructor redeclaration for - input.y:1.13-29: previous declaration - input.y:4.13-29: %destructor redeclaration for - input.y:4.13-29: previous declaration - input.y:5.10-24: %printer redeclaration for - input.y:2.10-24: previous declaration - input.y:5.10-24: %printer redeclaration for - input.y:5.10-24: previous declaration - input.y:11.13-29: %destructor redeclaration for - input.y:4.13-29: previous declaration - input.y:11.13-29: %destructor redeclaration for - input.y:1.13-29: previous declaration - input.y:12.10-24: %printer redeclaration for - input.y:2.10-24: previous declaration - input.y:12.10-24: %printer redeclaration for - input.y:5.10-24: previous declaration + [[input.y:4.13-29: error: %destructor redeclaration for + input.y:1.13-29: previous declaration + input.y:4.13-29: error: %destructor redeclaration for + input.y:4.13-29: previous declaration + input.y:5.10-24: error: %printer redeclaration for + input.y:2.10-24: previous declaration + input.y:5.10-24: error: %printer redeclaration for + input.y:5.10-24: previous declaration + input.y:11.13-29: error: %destructor redeclaration for + input.y:4.13-29: previous declaration + input.y:11.13-29: error: %destructor redeclaration for + input.y:1.13-29: previous declaration + input.y:12.10-24: error: %printer redeclaration for + input.y:2.10-24: previous declaration + input.y:12.10-24: error: %printer redeclaration for + input.y:5.10-24: previous declaration ]]) AT_CLEANUP +## ------------------- ## +## Undefined symbols. ## +## ------------------- ## + +AT_SETUP([Undefined symbols]) + +AT_DATA([[input.y]], +[[%printer {} foo baz +%destructor {} bar +%type qux +%% +exp: bar; +]]) + +AT_BISON_CHECK([input.y], [1], [], - [[input.y:2.16-18: symbol bar is used, but is not defined as a token and has no rules ++[[input.y:2.16-18: error: symbol bar is used, but is not defined as a token and has no rules +input.y:1.17-19: warning: symbol baz is used, but is not defined as a token and has no rules [-Wother] +input.y:1.13-15: warning: symbol foo is used, but is not defined as a token and has no rules [-Wother] +input.y:3.13-15: warning: symbol qux is used, but is not defined as a token and has no rules [-Wother] +]]) + +AT_CLEANUP + + +## ----------------------------------------------------- ## +## Unassociated types used for a printer or destructor. ## +## ----------------------------------------------------- ## + +AT_SETUP([Unassociated types used for a printer or destructor]) + +AT_DATA([[input.y]], +[[%token tag1 +%type tag2 + +%printer { } +%destructor { } + +%% + +exp: tag1 { $1; } + | tag2 { $1; } + +tag2: "a" { $$; } +]]) + +AT_BISON_CHECK([input.y], [0], [], +[[input.y:4.22-28: warning: type is used, but is not associated to any symbol [-Wother] +input.y:5.25-31: warning: type is used, but is not associated to any symbol [-Wother] +]]) + +AT_CLEANUP + + +## --------------------------------- ## +## Useless printers or destructors. ## +## --------------------------------- ## + +AT_SETUP([Useless printers or destructors]) + +# AT_TEST([INPUT], [STDERR]) +# -------------------------- +m4_pushdef([AT_TEST], +[AT_DATA([[input.y]], +[$1 +]) +AT_BISON_CHECK([input.y], [0], [], [$2 +])]) + +AT_TEST([[%token token1 +%token token2 +%token token3 +%token token4 +%token token51 token52 +%token token61 token62 +%token token7 + +%printer {} token1 +%destructor {} token2 +%printer {} token51 +%destructor {} token61 + +%printer {} token7 + +%printer {} +%destructor {} +%printer {} +%destructor {} + +%printer {} +%destructor {} + +%destructor {} + +%% +exp: "a";]], +[[input.y:16.13-19: warning: useless %printer for type [-Wother] +input.y:17.16-22: warning: useless %destructor for type [-Wother]]]) + +# If everybody is typed, <> is useless. +AT_TEST([[%type exp +%token a +%printer {} <> <*> +%% +exp: a;]], +[[input.y:3.13-14: warning: useless %printer for type <> [-Wother]]]) + +# If nobody is typed, <*> is useless. +AT_TEST([[%token a +%printer {} <> <*> +%% +exp: a;]], +[[input.y:2.16-18: warning: useless %printer for type <*> [-Wother]]]) + +m4_popdef([AT_TEST]) + +AT_CLEANUP + ## ---------------------------------------- ## ## Unused values with default %destructor. ## @@@ -407,9 -295,9 +407,9 @@@ tagged: { } ]]) AT_BISON_CHECK([input.y], [0], [], -[[input.y:6.8-45: warning: unset value: $$ -input.y:6.8-45: warning: unused value: $2 -input.y:7.6-8: warning: unset value: $$ +[[input.y:6.8-45: warning: unset value: $$ [-Wother] +input.y:6.8-45: warning: unused value: $2 [-Wother] +input.y:7.6-8: warning: unset value: $$ [-Wother] ]]) AT_DATA([[input.y]], @@@ -424,8 -312,8 +424,8 @@@ tagged: { } ]]) AT_BISON_CHECK([input.y], [0], [], -[[input.y:6.8-45: warning: unused value: $4 -input.y:8.9-11: warning: unset value: $$ +[[input.y:6.8-45: warning: unused value: $4 [-Wother] +input.y:8.9-11: warning: unset value: $$ [-Wother] ]]) AT_CLEANUP @@@ -448,9 -336,9 +448,9 @@@ end: { } ]]) AT_BISON_CHECK([input.y], [0], [], -[[input.y:6.8-22: warning: unset value: $$ -input.y:6.8-22: warning: unused value: $2 -input.y:7.6-8: warning: unset value: $$ +[[input.y:6.8-22: warning: unset value: $$ [-Wother] +input.y:6.8-22: warning: unused value: $2 [-Wother] +input.y:7.6-8: warning: unset value: $$ [-Wother] ]]) AT_CLEANUP @@@ -480,14 -368,14 +480,14 @@@ exp: foo ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:8.7-11: %type redeclaration for foo - input.y:3.7-11: previous declaration - input.y:10.13-17: %destructor redeclaration for foo - input.y:5.13-17: previous declaration - input.y:9.10-14: %printer redeclaration for foo - input.y:4.10-14: previous declaration - input.y:11.1-5: %left redeclaration for foo - input.y:6.1-5: previous declaration + [[input.y:8.7-11: error: %type redeclaration for foo + input.y:3.7-11: previous declaration + input.y:10.13-17: error: %destructor redeclaration for foo + input.y:5.13-17: previous declaration + input.y:9.10-14: error: %printer redeclaration for foo + input.y:4.10-14: previous declaration + input.y:11.1-5: error: %left redeclaration for foo + input.y:6.1-5: previous declaration ]]) AT_CLEANUP @@@ -506,7 -394,7 +506,7 @@@ AT_SETUP([Torturing the Scanner] AT_BISON_OPTION_PUSHDEFS AT_DATA([input.y], []) AT_BISON_CHECK([input.y], [1], [], - [[input.y:1.1: syntax error, unexpected end of file + [[input.y:1.1: error: syntax error, unexpected end of file ]]) @@@ -514,7 -402,7 +514,7 @@@ AT_DATA([input.y] [{} ]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:1.1-2: syntax error, unexpected {...} + [[input.y:1.1-2: error: syntax error, unexpected {...} ]]) @@@ -628,7 -516,7 +628,7 @@@ yylex (void } ]]) -# Pacify Emacs' font-lock-mode: " +# Pacify Emacs'font-lock-mode: " AT_DATA([main.c], [[typedef int value; @@@ -707,8 -595,8 +707,8 @@@ AT_CHECK_REQUIRE(100.0, 63 AT_SETUP([String aliases for character tokens]) -# Bison once thought a character token and its alias were different symbols -# with the same user token number. +# Bison once thought a character token and its alias were different +# symbols with the same user token number. AT_DATA_GRAMMAR([input.y], [[%token 'a' "a" @@@ -752,14 -640,14 +752,14 @@@ AT_BISON_OPTION_POPDEF # POSIX Yacc accept periods, but not dashes. AT_BISON_CHECK([--yacc input.y], [1], [], -[[input.y:9.8-16: POSIX Yacc forbids dashes in symbol names: WITH-DASH -input.y:18.8-16: POSIX Yacc forbids dashes in symbol names: with-dash +[[input.y:9.8-16: POSIX Yacc forbids dashes in symbol names: WITH-DASH [-Wyacc] +input.y:18.8-16: 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 -input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash +[[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] ]]) # Dashes are fine for GNU Bison. @@@ -780,9 -668,9 +780,9 @@@ AT_DATA_GRAMMAR([input.y] start: .GOOD GOOD ]]) AT_BISON_CHECK([-o input.c input.y], [1], [], - [[input.y:10.10: invalid character: '-' - input.y:11.10-16: invalid identifier: '1NV4L1D' - input.y:12.10: invalid character: '-' + [[input.y:10.10: error: invalid character: '-' + input.y:11.10-16: error: invalid identifier: '1NV4L1D' + input.y:12.10: error: invalid character: '-' ]]) AT_CLEANUP @@@ -804,9 -692,9 +804,9 @@@ start: DECIMAL_1 HEXADECIMAL_2 ]]) AT_BISON_CHECK([redecl.y], [1], [], - [[redecl.y:10.10-22: user token number 11259375 redeclaration for HEXADECIMAL_1 - redecl.y:9.8-16: previous declaration for DECIMAL_1 - redecl.y:12.10-18: user token number 16702650 redeclaration for DECIMAL_2 + [[redecl.y:10.10-22: error: user token number 11259375 redeclaration for HEXADECIMAL_1 + redecl.y:9.8-16: previous declaration for DECIMAL_1 + redecl.y:12.10-18: error: user token number 16702650 redeclaration for DECIMAL_2 redecl.y:11.10-22: previous declaration for HEXADECIMAL_2 ]]) @@@ -819,8 -707,8 +819,8 @@@ start: TOO_LARGE_DEC TOO_LARGE_HE ]]) AT_BISON_CHECK([too-large.y], [1], [], - [[too-large.y:9.22-42: integer out of range: '999999999999999999999' - too-large.y:10.24-44: integer out of range: '0xFFFFFFFFFFFFFFFFFFF' + [[too-large.y:9.22-42: error: integer out of range: '999999999999999999999' + too-large.y:10.24-44: error: integer out of range: '0xFFFFFFFFFFFFFFFFFFF' ]]) AT_CLEANUP @@@ -832,10 -720,10 +832,10 @@@ AT_SETUP([Unclosed constructs]) -# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed constructs, so -# they were prepended to whatever it STRING_GROW'ed next. It also threw them -# away rather than returning them to the parser. The effect was confusing -# subsequent error messages. +# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed +# constructs, so they were prepended to whatever it STRING_GROW'ed +# next. It also threw them away rather than returning them to the +# parser. The effect was confusing subsequent error messages. AT_DATA([input.y], [[%token A "a @@@ -860,12 -748,12 +860,12 @@@ start: ]]) AT_BISON_CHECK([-o input.c input.y], 1, [], - [[input.y:1.10-2.0: missing '"' at end of line - input.y:4.10-5.0: missing "'" at end of line - input.y:14.11-15.0: missing "'" at end of line - input.y:16.11-17.0: missing '"' at end of line - input.y:19.13-20.0: missing '}' at end of file - input.y:20.1: syntax error, unexpected end of file + [[input.y:1.10-2.0: error: missing '"' at end of line + input.y:4.10-5.0: error: missing "'" at end of line + input.y:14.11-15.0: error: missing "'" at end of line + input.y:16.11-17.0: error: missing '"' at end of line + input.y:19.13-20.0: error: missing '}' at end of file + input.y:20.1: error: syntax error, unexpected end of file ]]) AT_CLEANUP @@@ -877,8 -765,8 +877,8 @@@ AT_SETUP([%start after first rule]) -# Bison once complained that a %start after the first rule was a redeclaration -# of the start symbol. +# Bison once complained that a %start after the first rule was a +# redeclaration of the start symbol. AT_DATA([input.y], [[%% @@@ -907,7 -795,7 +907,7 @@@ PREC: ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:3.1-4: rule given for PREC, which is a token + [[input.y:3.1-4: error: rule given for PREC, which is a token ]]) AT_CLEANUP @@@ -927,7 -815,7 +927,7 @@@ start: %prec PREC ]]) AT_BISON_CHECK([[input.y]], [[0]], [], -[[input.y:2.8-17: warning: token for %prec is not defined: PREC +[[input.y:2.8-17: warning: token for %prec is not defined: PREC [-Wother] ]]) AT_CLEANUP @@@ -948,10 -836,10 +948,10 @@@ AT_DATA([input-c.y] start: ; ]]) AT_BISON_CHECK([[input-c.y]], [[1]], [], - [[input-c.y:1.7: %code qualifier 'q' is not used - input-c.y:2.7-9: %code qualifier 'bad' is not used - input-c.y:3.7-9: %code qualifier 'bad' is not used - input-c.y:4.7-12: %code qualifier 'format' is not used + [[input-c.y:1.7: error: %code qualifier 'q' is not used + input-c.y:2.7-9: error: %code qualifier 'bad' is not used + input-c.y:3.7-9: error: %code qualifier 'bad' is not used + input-c.y:4.7-12: error: %code qualifier 'format' is not used ]]) AT_DATA([input-c-glr.y], @@@ -962,9 -850,9 +962,9 @@@ start: ; ]]) AT_BISON_CHECK([[input-c-glr.y]], [[1]], [], - [[input-c-glr.y:1.7: %code qualifier 'q' is not used - input-c-glr.y:2.7-9: %code qualifier 'bad' is not used - input-c-glr.y:3.8-10: %code qualifier 'bad' is not used + [[input-c-glr.y:1.7: error: %code qualifier 'q' is not used + input-c-glr.y:2.7-9: error: %code qualifier 'bad' is not used + input-c-glr.y:3.8-10: error: %code qualifier 'bad' is not used ]]) AT_DATA([input-c++.y], @@@ -975,9 -863,9 +975,9 @@@ start: ; ]]) AT_BISON_CHECK([[input-c++.y]], [[1]], [], - [[input-c++.y:1.7: %code qualifier 'q' is not used - input-c++.y:2.7-9: %code qualifier 'bad' is not used - input-c++.y:3.8: %code qualifier 'q' is not used + [[input-c++.y:1.7: error: %code qualifier 'q' is not used + input-c++.y:2.7-9: error: %code qualifier 'bad' is not used + input-c++.y:3.8: error: %code qualifier 'q' is not used ]]) AT_DATA([input-c++-glr.y], @@@ -988,9 -876,9 +988,9 @@@ start: ; ]]) AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [], - [[input-c++-glr.y:1.7-9: %code qualifier 'bad' is not used - input-c++-glr.y:2.7: %code qualifier 'q' is not used - input-c++-glr.y:3.7: %code qualifier 'q' is not used + [[input-c++-glr.y:1.7-9: error: %code qualifier 'bad' is not used + input-c++-glr.y:2.7: error: %code qualifier 'q' is not used + input-c++-glr.y:3.7: error: %code qualifier 'q' is not used ]]) AT_DATA([special-char-@@.y], @@@ -1001,9 -889,9 +1001,9 @@@ start: ; ]]) AT_BISON_CHECK([[special-char-@@.y]], [[1]], [], - [[special-char-@@.y:1.7-9: %code qualifier 'bad' is not used - special-char-@@.y:2.7: %code qualifier 'q' is not used - special-char-@@.y:3.7: %code qualifier 'q' is not used + [[special-char-@@.y:1.7-9: error: %code qualifier 'bad' is not used + special-char-@@.y:2.7: error: %code qualifier 'q' is not used + special-char-@@.y:3.7: error: %code qualifier 'q' is not used ]]) AT_DATA([special-char-@:>@.y], @@@ -1014,9 -902,9 +1014,9 @@@ start: ; ]]) AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [], - [[special-char-@:>@.y:1.7-9: %code qualifier 'bad' is not used - special-char-@:>@.y:2.7: %code qualifier 'q' is not used - special-char-@:>@.y:3.7: %code qualifier 'q' is not used + [[special-char-@:>@.y:1.7-9: error: %code qualifier 'bad' is not used + special-char-@:>@.y:2.7: error: %code qualifier 'q' is not used + special-char-@:>@.y:3.7: error: %code qualifier 'q' is not used ]]) AT_CLEANUP @@@ -1039,10 -927,10 +1039,10 @@@ start: ]]) AT_BISON_CHECK([[input-redefined.y]], [[1]], [], - [[input-redefined.y:2.9-11: %define variable 'var' redefined - input-redefined.y:1.9-11: previous definition - input-redefined.y:3.10-12: %define variable 'var' redefined - input-redefined.y:2.9-11: previous definition + [[input-redefined.y:2.9-11: error: %define variable 'var' redefined + input-redefined.y:1.9-11: previous definition + input-redefined.y:3.10-12: error: %define variable 'var' redefined + input-redefined.y:2.9-11: previous definition ]]) AT_DATA([input-unused.y], @@@ -1052,7 -940,7 +1052,7 @@@ start: ]]) AT_BISON_CHECK([[input-unused.y]], [[1]], [], - [[input-unused.y:1.9-11: %define variable 'var' is not used + [[input-unused.y:1.9-11: error: %define variable 'var' is not used ]]) AT_CLEANUP @@@ -1096,8 -984,8 +1096,8 @@@ AT_DATA([[input-dg.y]] start: ; ]]) AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [], - [[input-dg.y:1.9-11: %define variable 'var' redefined - :2: previous definition + [[input-dg.y:1.9-11: error: %define variable 'var' redefined + :2: previous definition ]]) AT_DATA([[input-unused.y]], @@@ -1105,8 -993,8 +1105,8 @@@ start: ; ]]) AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [], - [[:2: %define variable 'unused-d' is not used - :3: %define variable 'unused-f' is not used + [[:2: error: %define variable 'unused-d' is not used + :3: error: %define variable 'unused-f' is not used ]]) AT_CLEANUP @@@ -1126,7 -1014,7 +1126,7 @@@ start: ]]) AT_BISON_CHECK([[Input.y]], [1], [], - [[Input.y:2.9-14: invalid value for %define Boolean variable 'public' + [[Input.y:2.9-14: error: invalid value for %define Boolean variable 'public' ]]) AT_CLEANUP @@@ -1144,23 -1032,24 +1144,24 @@@ AT_DATA([[input.y]] start: ; ]]) AT_BISON_CHECK([[input.y]], [[1]], [[]], - [[input.y:1.9-29: invalid value for %define variable 'lr.default-reductions': 'bogus' - input.y:1.9-29: accepted value: 'most' - input.y:1.9-29: accepted value: 'consistent' - input.y:1.9-29: accepted value: 'accepting' + [[input.y:1.9-29: error: invalid value for %define variable 'lr.default-reductions': 'bogus' + input.y:1.9-29: accepted value: 'most' + input.y:1.9-29: accepted value: 'consistent' + input.y:1.9-29: accepted value: 'accepting' ]]) # Back-end. + # FIXME: these should be indented, but we shouldn't mess with the m4 yet AT_DATA([[input.y]], [[%define api.push-pull neither %% start: ; ]]) AT_BISON_CHECK([[input.y]], [1], [], - [[input.y:1.9-21: invalid value for %define variable 'api.push-pull': 'neither' - input.y:1.9-21: accepted value: 'pull' - input.y:1.9-21: accepted value: 'push' - input.y:1.9-21: accepted value: 'both' + [[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither' + input.y:1.9-21: error: accepted value: 'pull' + input.y:1.9-21: error: accepted value: 'push' + input.y:1.9-21: error: accepted value: 'both' ]]) AT_CLEANUP @@@ -1180,11 -1069,10 +1181,11 @@@ AT_DATA([[input.y]] start: ; ]]) AT_BISON_CHECK([[input.y]], [1], [], -[[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither' +[[input.y:1.9-21: warning: deprecated %define variable name: 'api.push_pull', use 'api.push-pull' [-Wdeprecated] - input.y:1.9-21: invalid value for %define variable 'api.push-pull': 'neither' - input.y:1.9-21: accepted value: 'pull' - input.y:1.9-21: accepted value: 'push' - input.y:1.9-21: accepted value: 'both' ++input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither' + input.y:1.9-21: error: accepted value: 'pull' + input.y:1.9-21: error: accepted value: 'push' + input.y:1.9-21: error: accepted value: 'both' ]]) AT_DATA([[input.y]], @@@ -1193,20 -1081,7 +1194,20 @@@ start: ; ]]) AT_BISON_CHECK([[input.y]], [1], [], -[[input.y:1.9-34: error: invalid value for %define Boolean variable 'lr.keep-unreachable-states' +[[input.y:1.9-34: warning: deprecated %define variable name: 'lr.keep_unreachable_states', use 'lr.keep-unreachable-states' [-Wdeprecated] - input.y:1.9-34: invalid value for %define Boolean variable 'lr.keep-unreachable-states' ++input.y:1.9-34: error: invalid value for %define Boolean variable 'lr.keep-unreachable-states' +]]) + +AT_DATA([[input.y]], +[[%define namespace "foo" +%define api.namespace "foo" +%% +start: ; +]]) +AT_BISON_CHECK([[input.y]], [1], [], +[[input.y:1.9-17: warning: deprecated %define variable name: 'namespace', use 'api.namespace' [-Wdeprecated] - input.y:2.9-21: %define variable 'api.namespace' redefined - input.y:1.9-17: previous definition ++input.y:2.9-21: error: %define variable 'api.namespace' redefined ++input.y:1.9-17: previous definition ]]) AT_DATA([[input.y]], @@@ -1215,7 -1090,7 +1216,7 @@@ start: ; ]]) AT_BISON_CHECK([[input.y]], [[1]], [], - [[input.y:1.9-15: %define variable 'foo_bar' is not used + [[input.y:1.9-15: error: %define variable 'foo_bar' is not used ]]) AT_CLEANUP @@@ -1240,7 -1115,7 +1241,7 @@@ start: ]]) AT_BISON_CHECK([[input.y]], [[1]], [], - [[input.y:1.9-16: %define variable 'api.pure' is not used + [[input.y:1.9-16: error: %define variable 'api.pure' is not used ]]) ]) @@@ -1267,14 -1142,14 +1268,14 @@@ m4_define([AT_CHECK_NAMESPACE_ERROR] AT_DATA([[input.y]], [[%language "C++" %defines -%define namespace "]$1[" +%define api.namespace "]$1[" %% start: ; ]]) AT_BISON_CHECK([[input.y]], [1], [], [m4_foreach([b4_arg], m4_dquote(m4_shift($@)), - [[input.y:3.9-21: ]b4_arg[ -[[input.y:3.9-17: error: ]b4_arg[ ++[[input.y:3.9-21: error: ]b4_arg[ ]])]) ]) @@@ -1323,11 -1198,11 +1324,11 @@@ start: AT_CHECK([[perl -e "print 'start: \'';" >> empty.y || exit 77]]) AT_BISON_CHECK([empty.y], [1], [], -[[empty.y:2.8-9: warning: empty character literal -empty.y:3.8-4.0: warning: empty character literal +[[empty.y:2.8-9: warning: empty character literal [-Wother] +empty.y:3.8-4.0: warning: empty character literal [-Wother] - empty.y:3.8-4.0: missing "'" at end of line + empty.y:3.8-4.0: error: missing "'" at end of line -empty.y:4.8: warning: empty character literal +empty.y:4.8: warning: empty character literal [-Wother] - empty.y:4.8: missing "'" at end of file + empty.y:4.8: error: missing "'" at end of file ]]) AT_DATA([two.y], @@@ -1338,11 -1213,11 +1339,11 @@@ start: 'a AT_CHECK([[perl -e "print 'start: \'ab';" >> two.y || exit 77]]) AT_BISON_CHECK([two.y], [1], [], -[[two.y:2.8-11: warning: extra characters in character literal -two.y:3.8-4.0: warning: extra characters in character literal +[[two.y:2.8-11: warning: extra characters in character literal [-Wother] +two.y:3.8-4.0: warning: extra characters in character literal [-Wother] - two.y:3.8-4.0: missing "'" at end of line + two.y:3.8-4.0: error: missing "'" at end of line -two.y:4.8-10: warning: extra characters in character literal +two.y:4.8-10: warning: extra characters in character literal [-Wother] - two.y:4.8-10: missing "'" at end of file + two.y:4.8-10: error: missing "'" at end of file ]]) AT_DATA([three.y], @@@ -1353,11 -1228,11 +1354,11 @@@ start: 'ab AT_CHECK([[perl -e "print 'start: \'abc';" >> three.y || exit 77]]) AT_BISON_CHECK([three.y], [1], [], -[[three.y:2.8-12: warning: extra characters in character literal -three.y:3.8-4.0: warning: extra characters in character literal +[[three.y:2.8-12: warning: extra characters in character literal [-Wother] +three.y:3.8-4.0: warning: extra characters in character literal [-Wother] - three.y:3.8-4.0: missing "'" at end of line + three.y:3.8-4.0: error: missing "'" at end of line -three.y:4.8-11: warning: extra characters in character literal +three.y:4.8-11: warning: extra characters in character literal [-Wother] - three.y:4.8-11: missing "'" at end of file + three.y:4.8-11: error: missing "'" at end of file ]]) AT_CLEANUP @@@ -1383,30 -1258,30 +1384,30 @@@ AT_CHECK([[perl -e 'print "start: \"\\\ || exit 77]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:2.9-12: invalid number after \-escape: 777 + [[input.y:2.9-12: error: invalid number after \-escape: 777 -input.y:2.8-13: warning: empty character literal +input.y:2.8-13: warning: empty character literal [-Wother] - input.y:2.16-17: invalid number after \-escape: 0 + input.y:2.16-17: error: invalid number after \-escape: 0 -input.y:2.15-18: warning: empty character literal +input.y:2.15-18: warning: empty character literal [-Wother] - input.y:2.21-25: invalid number after \-escape: xfff + input.y:2.21-25: error: invalid number after \-escape: xfff -input.y:2.20-26: warning: empty character literal +input.y:2.20-26: warning: empty character literal [-Wother] - input.y:2.29-31: invalid number after \-escape: x0 + input.y:2.29-31: error: invalid number after \-escape: x0 -input.y:2.28-32: warning: empty character literal +input.y:2.28-32: warning: empty character literal [-Wother] - input.y:3.9-14: invalid number after \-escape: uffff + input.y:3.9-14: error: invalid number after \-escape: uffff -input.y:3.8-15: warning: empty character literal +input.y:3.8-15: warning: empty character literal [-Wother] - input.y:3.18-23: invalid number after \-escape: u0000 + input.y:3.18-23: error: invalid number after \-escape: u0000 -input.y:3.17-24: warning: empty character literal +input.y:3.17-24: warning: empty character literal [-Wother] - input.y:3.27-36: invalid number after \-escape: Uffffffff + input.y:3.27-36: error: invalid number after \-escape: Uffffffff -input.y:3.26-37: warning: empty character literal +input.y:3.26-37: warning: empty character literal [-Wother] - input.y:3.40-49: invalid number after \-escape: U00000000 + input.y:3.40-49: error: invalid number after \-escape: U00000000 -input.y:3.39-50: warning: empty character literal +input.y:3.39-50: warning: empty character literal [-Wother] - input.y:4.9-10: invalid character after \-escape: ' ' + input.y:4.9-10: error: invalid character after \-escape: ' ' -input.y:4.8-11: warning: empty character literal +input.y:4.8-11: warning: empty character literal [-Wother] - input.y:4.14-15: invalid character after \-escape: A + input.y:4.14-15: error: invalid character after \-escape: A -input.y:4.13-16: warning: empty character literal +input.y:4.13-16: warning: empty character literal [-Wother] - input.y:5.9-16: invalid character after \-escape: \t - input.y:5.17: invalid character after \-escape: \f - input.y:5.18: invalid character after \-escape: \0 - input.y:5.19: invalid character after \-escape: \001 + input.y:5.9-16: error: invalid character after \-escape: \t + input.y:5.17: error: invalid character after \-escape: \f + input.y:5.18: error: invalid character after \-escape: \0 + input.y:5.19: error: invalid character after \-escape: \001 ]]) AT_CLEANUP @@@ -1425,11 -1300,11 +1426,11 @@@ start: # parse.lac.* options are useless if LAC isn't actually activated. AT_BISON_CHECK([[-Dparse.lac.es-capacity-initial=1 input.y]], [[1]], [], - [[:2: %define variable 'parse.lac.es-capacity-initial' is not used + [[:2: error: %define variable 'parse.lac.es-capacity-initial' is not used ]]) AT_BISON_CHECK([[-Dparse.lac.memory-trace=full input.y]], [[1]], [], - [[:2: %define variable 'parse.lac.memory-trace' is not used + [[:2: error: %define variable 'parse.lac.memory-trace' is not used ]]) AT_CLEANUP @@@ -1447,20 -1322,20 +1448,20 @@@ foo-bar: # -Werror is not enabled by -Wall or equivalent. AT_BISON_CHECK([[-Wall input.y]], [[0]], [[]], -[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar +[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc] ]]) AT_BISON_CHECK([[-W input.y]], [[0]], [[]], -[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar +[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc] ]]) AT_BISON_CHECK([[-Wno-none input.y]], [[0]], [[]], -[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar +[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc] ]]) # -Werror is not disabled by -Wnone or equivalent. AT_BISON_CHECK([[-Werror,none,yacc input.y]], [[1]], [[]], [[stderr]]) AT_CHECK([[sed 's/^.*bison:/bison:/' stderr]], [[0]], [[bison: warnings being treated as errors -input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar +input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc] ]]) [mv stderr experr] AT_BISON_CHECK([[-Werror,no-all,yacc input.y]], [[1]], [[]], [[experr]]) @@@ -1483,7 -1358,7 +1484,7 @@@ m4_pushdef([AT_TEST] exp:; ]]) AT_BISON_CHECK([[$2 input.y]], [[1]], [[]], - [[$3: '%name-prefix' and '%define api.prefix' cannot be used together + [[$3: error: '%name-prefix' and '%define api.prefix' cannot be used together ]]) ]) @@@ -1507,8 -1382,7 +1508,8 @@@ AT_SETUP([[Stray $ or @]] # check that the warnings are reported once, not three times. AT_DATA_GRAMMAR([[input.y]], -[[%token TOK +[[%type exp +%token TOK TOK2 %destructor { $%; @%; } <*> exp TOK; %initial-action { $%; @%; }; %printer { $%; @%; } <*> exp TOK; @@@ -1517,14 -1391,14 +1518,14 @@@ exp: TOK { $%; @%; $$ = $1; } ]]) AT_BISON_CHECK([[input.y]], 0, [], -[[input.y:10.19: warning: stray '$' -input.y:10.23: warning: stray '@' -input.y:11.19: warning: stray '$' -input.y:11.23: warning: stray '@' -input.y:12.19: warning: stray '$' -input.y:12.23: warning: stray '@' -input.y:14.19: warning: stray '$' -input.y:14.23: warning: stray '@' +[[input.y:11.19: warning: stray '$' [-Wother] +input.y:11.23: warning: stray '@' [-Wother] +input.y:12.19: warning: stray '$' [-Wother] +input.y:12.23: warning: stray '@' [-Wother] +input.y:13.19: warning: stray '$' [-Wother] +input.y:13.23: warning: stray '@' [-Wother] +input.y:15.19: warning: stray '$' [-Wother] +input.y:15.23: warning: stray '@' [-Wother] ]]) AT_CLEANUP @@@ -1547,7 -1421,6 +1548,7 @@@ m4_pushdef([AT_TEST] [AT_DATA([[input.y]], [[%type <$1(DEAD %type)> exp %token <$1(DEAD %token)> a +%token b %initial-action { $$; @@@ -1568,13 -1441,13 +1569,13 @@@ }; %% exp: - a a[last] + a a[name] b { $$; $][1; $<$1(DEAD action 1)>$ $<$1(DEAD action 2)>1 - $<$1(DEAD action 3)>last + $<$1(DEAD action 3)>name $<$1(DEAD action 4)>0 ; }; diff --combined tests/named-refs.at index f9e48a57,d76e75f3..1cd55b31 --- a/tests/named-refs.at +++ b/tests/named-refs.at @@@ -46,10 -46,10 +46,10 @@@ static int power (int base, int exponen %token NUM "number" %type exp -%nonassoc '=' /* comparison */ +%nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' -%left NEG /* negation--unary minus */ +%precedence NEG /* negation--unary minus */ %right '^' /* exponentiation */ %% @@@ -211,10 -211,10 +211,10 @@@ static int power (int base, int exponen %token NUM "number" %type exp -%nonassoc '=' /* comparison */ +%nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' -%left NEG /* negation--unary minus */ +%precedence NEG /* negation--unary minus */ %right '^' /* exponentiation */ %% @@@ -251,16 -251,16 +251,16 @@@ exp ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:50.51-60: invalid reference: '$lo9' + [[test.y:50.51-60: error: invalid reference: '$lo9' test.y:50.3-68: symbol not found in production: lo9 -test.y:51.51-60: warning: misleading reference: '$exp' -test.y:42.1-3: refers to: $exp at $$ -test.y:51.7: possibly meant: $x, hiding $exp at $1 -test.y:51.41: possibly meant: $r, hiding $exp at $4 +test.y:51.51-60: warning: misleading reference: '$exp' [-Wother] - test.y:42.1-3: warning: refers to: $exp at $$ [-Wother] - test.y:51.7: warning: possibly meant: $x, hiding $exp at $1 [-Wother] - test.y:51.41: warning: possibly meant: $r, hiding $exp at $4 [-Wother] - test.y:52.51-52: $l of 'exp' has no declared type - test.y:55.46-49: invalid reference: '$r12' ++test.y:42.1-3: refers to: $exp at $$ [-Wother] ++test.y:51.7: possibly meant: $x, hiding $exp at $1 [-Wother] ++test.y:51.41: possibly meant: $r, hiding $exp at $4 [-Wother] + test.y:52.51-52: error: $l of 'exp' has no declared type + test.y:55.46-49: error: invalid reference: '$r12' test.y:55.3-53: symbol not found in production: r12 - test.y:56.29-33: invalid reference: '$expo' + test.y:56.29-33: error: invalid reference: '$expo' test.y:56.3-46: symbol not found in production: expo ]]) AT_BISON_OPTION_POPDEFS @@@ -277,9 -277,9 +277,9 @@@ foo: '1 foo.bar: '2' ]]) AT_BISON_CHECK([-o test.c test.y], 0, [], -[[test.y:11.22-29: warning: misleading reference: '$foo.bar' -test.y:11.8-10: refers to: $foo at $1 -test.y:11.12-18: possibly meant: $[foo.bar] at $2 +[[test.y:11.22-29: warning: misleading reference: '$foo.bar' [-Wother] - test.y:11.8-10: warning: refers to: $foo at $1 [-Wother] - test.y:11.12-18: warning: possibly meant: $[foo.bar] at $2 [-Wother] ++test.y:11.8-10: refers to: $foo at $1 [-Wother] ++test.y:11.12-18: possibly meant: $[foo.bar] at $2 [-Wother] ]]) AT_CLEANUP @@@ -353,43 -353,43 +353,43 @@@ factor: '(' expr ')' { $$ = $2; ; ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:24.36-41: invalid reference: '$cond1' + [[test.y:24.36-41: error: invalid reference: '$cond1' test.y:23.11-24.62: symbol not found in production: cond1 - test.y:26.43-53: invalid reference: '$stmt.field' + test.y:26.43-53: error: invalid reference: '$stmt.field' test.y:25.11-26.60: symbol not found in production: stmt test.y:25.35-38: possibly meant: $then.field, hiding $stmt.field at $4 - test.y:28.43-52: invalid reference: '$stmt.list' + test.y:28.43-52: error: invalid reference: '$stmt.list' test.y:27.11-28.59: symbol not found in production: stmt test.y:27.30-38: possibly meant: $[stmt.list] at $4 - test.y:30.43-46: ambiguous reference: '$xyz' + test.y:30.43-46: error: ambiguous reference: '$xyz' test.y:29.35-37: refers to: $xyz at $4 test.y:29.50-52: refers to: $xyz at $6 - test.y:32.43-52: invalid reference: '$stmt.list' + test.y:32.43-52: error: invalid reference: '$stmt.list' test.y:31.11-32.63: symbol not found in production: stmt test.y:31.40-43: possibly meant: $then, hiding $[stmt.list] at $4 test.y:31.61-64: possibly meant: $else, hiding $[stmt.list] at $6 - test.y:34.43-58: invalid reference: '$stmt.list.field' + test.y:34.43-58: error: invalid reference: '$stmt.list.field' test.y:33.11-34.69: symbol not found in production: stmt test.y:33.40-43: possibly meant: $then.field, hiding $[stmt.list].field at $4 test.y:33.61-64: possibly meant: $else.field, hiding $[stmt.list].field at $6 - test.y:36.43-54: invalid reference: '$[stmt.list]' + test.y:36.43-54: error: invalid reference: '$[stmt.list]' test.y:35.11-36.71: symbol not found in production: stmt.list test.y:35.40-43: possibly meant: $then, hiding $[stmt.list] at $4 test.y:35.61-64: possibly meant: $else, hiding $[stmt.list] at $6 - test.y:38.43-49: invalid reference: '$then.1' + test.y:38.43-49: error: invalid reference: '$then.1' test.y:37.11-38.60: symbol not found in production: then test.y:37.40-45: possibly meant: $[then.1] at $4 - test.y:40.43-55: invalid reference: '$then.1.field' + test.y:40.43-55: error: invalid reference: '$then.1.field' test.y:39.11-40.66: symbol not found in production: then test.y:39.40-45: possibly meant: $[then.1].field at $4 - test.y:42.44-50: invalid reference: '$stmt.x' + test.y:42.44-50: error: invalid reference: '$stmt.x' test.y:41.12-42.57: symbol not found in production: stmt test.y:41.36-41: possibly meant: $[stmt.x].x, hiding $stmt.x at $4 test.y:41.36-41: possibly meant: $[stmt.x] at $4 - test.y:44.13-22: invalid reference: '$if-stmt-a' + test.y:44.13-22: error: invalid reference: '$if-stmt-a' test.y:43.12-44.59: symbol not found in production: if test.y:43.1-9: possibly meant: $[if-stmt-a] at $$ - test.y:46.46-54: invalid reference: '$then-a.f' + test.y:46.46-54: error: invalid reference: '$then-a.f' test.y:45.12-46.65: symbol not found in production: then test.y:45.41-46: possibly meant: $[then-a].f at $4 ]]) @@@ -405,7 -405,7 +405,7 @@@ start: foo[] ba { s = $foo; } ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:11.12: an identifier expected + [[test.y:11.12: error: an identifier expected ]]) AT_CLEANUP @@@ -419,7 -419,7 +419,7 @@@ start: foo[ a d ] ba { s = $foo; } ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:11.15: unexpected identifier in bracketed name: 'd' + [[test.y:11.15: error: unexpected identifier in bracketed name: 'd' ]]) AT_CLEANUP @@@ -433,7 -433,7 +433,7 @@@ start: foo[/* comment */] ba { s = $foo; } ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:11.25: an identifier expected + [[test.y:11.25: error: an identifier expected ]]) AT_CLEANUP @@@ -447,10 -447,10 +447,10 @@@ start: foo[ /* aaa */ *&-.+ ] ba { s = $foo; } ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:11.23: invalid character in bracketed name: '*' - test.y:11.24: invalid character in bracketed name: '&' - test.y:11.25: invalid character in bracketed name: '-' - test.y:11.27: invalid character in bracketed name: '+' + [[test.y:11.23: error: invalid character in bracketed name: '*' + test.y:11.24: error: invalid character in bracketed name: '&' + test.y:11.25: error: invalid character in bracketed name: '-' + test.y:11.27: error: invalid character in bracketed name: '+' ]]) AT_CLEANUP @@@ -463,7 -463,7 +463,7 @@@ AT_DATA_GRAMMAR([test.y] start[a s]: foo; ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:11.9: unexpected identifier in bracketed name: 's' + [[test.y:11.9: error: unexpected identifier in bracketed name: 's' ]]) AT_CLEANUP @@@ -510,37 -510,37 +510,37 @@@ sym_a: 'a' sym_b: 'b'; ]]) AT_BISON_CHECK([-o test.c test.y], 1, [], - [[test.y:12.22-31: invalid reference: '$sym.field' + [[test.y:12.22-31: error: invalid reference: '$sym.field' test.y:12.3-35: symbol not found in production: sym - test.y:13.22-35: invalid reference: '$sym.field' + test.y:13.22-35: error: invalid reference: '$sym.field' test.y:13.3-39: symbol not found in production: sym - test.y:14.22-33: invalid reference: '$[sym.field]' + test.y:14.22-33: error: invalid reference: '$[sym.field]' test.y:14.3-37: symbol not found in production: sym.field - test.y:15.22-37: invalid reference: '$[sym.field]' + test.y:15.22-37: error: invalid reference: '$[sym.field]' test.y:15.3-41: symbol not found in production: sym.field - test.y:16.22-25: invalid reference: '$sym' + test.y:16.22-25: error: invalid reference: '$sym' test.y:16.3-29: symbol not found in production: sym - test.y:17.22-29: invalid reference: '$sym' + test.y:17.22-29: error: invalid reference: '$sym' test.y:17.3-33: symbol not found in production: sym - test.y:18.22-27: invalid reference: '$[sym]' + test.y:18.22-27: error: invalid reference: '$[sym]' test.y:18.3-65: symbol not found in production before $3: sym - test.y:18.52-61: invalid reference: '$[sym]' + test.y:18.52-61: error: invalid reference: '$[sym]' test.y:18.3-65: symbol not found in production: sym - test.y:22.22-31: invalid reference: '$sym-field' + test.y:22.22-31: error: invalid reference: '$sym-field' test.y:22.3-35: symbol not found in production: sym - test.y:23.22-35: invalid reference: '$sym-field' + test.y:23.22-35: error: invalid reference: '$sym-field' test.y:23.3-39: symbol not found in production: sym - test.y:24.22-33: invalid reference: '$[sym-field]' + test.y:24.22-33: error: invalid reference: '$[sym-field]' test.y:24.3-37: symbol not found in production: sym-field - test.y:25.22-37: invalid reference: '$[sym-field]' + test.y:25.22-37: error: invalid reference: '$[sym-field]' test.y:25.3-41: symbol not found in production: sym-field - test.y:26.22-25: invalid reference: '$sym' + test.y:26.22-25: error: invalid reference: '$sym' test.y:26.3-29: symbol not found in production: sym - test.y:27.22-29: invalid reference: '$sym' + test.y:27.22-29: error: invalid reference: '$sym' test.y:27.3-33: symbol not found in production: sym - test.y:28.22-27: invalid reference: '$[sym]' + test.y:28.22-27: error: invalid reference: '$[sym]' test.y:28.3-65: symbol not found in production before $3: sym - test.y:28.52-61: invalid reference: '$[sym]' + test.y:28.52-61: error: invalid reference: '$[sym]' test.y:28.3-65: symbol not found in production: sym ]]) AT_CLEANUP @@@ -558,10 -558,10 +558,10 @@@ start .field: ; ]]) AT_BISON_CHECK([[test.y]], [[1]], [], - [[test.y:4.12-18: invalid reference: '$.field' + [[test.y:4.12-18: error: invalid reference: '$.field' test.y:4.13: syntax error after '$', expecting integer, letter, '_', '@<:@', or '$' test.y:4.3-8: possibly meant: $[.field] at $1 - test.y:5.12-18: invalid reference: '@.field' + test.y:5.12-18: error: invalid reference: '@.field' test.y:5.13: syntax error after '@', expecting integer, letter, '_', '@<:@', or '$' ]]) AT_DATA([[test.y]], @@@ -573,7 -573,7 +573,7 @@@ start ; ]]) AT_BISON_CHECK([[test.y]], [[0]], [], -[[test.y:4.9: warning: stray '$' -test.y:5.9: warning: stray '@' +[[test.y:4.9: warning: stray '$' [-Wother] +test.y:5.9: warning: stray '@' [-Wother] ]]) AT_CLEANUP diff --combined tests/output.at index cce330e8,9f1bd115..3a13fd3e --- a/tests/output.at +++ b/tests/output.at @@@ -22,91 -22,85 +22,91 @@@ AT_BANNER([[Output file names.]] # [ADDITIONAL-TESTS], [PRE-TESTS]) # ----------------------------------------------------------------------------- m4_define([AT_CHECK_OUTPUT], -[AT_SETUP([[Output files: $2 $3 $5]]) -$7 -for file in $1 $4; do - case "$file" in - */*) mkdir -p `echo "$file" | sed 's,/.*,,'`;; +[AT_SETUP([[Output files: ]$2 $3 $5])[ +]$7[ +for file in ]$1 $4[; do + case $file in + */*) mkdir -p `echo "$file" | sed 's,/[^/]*,,'`;; esac done -AT_DATA([$1], -[[$2 +]AT_DATA([$1], +[$2[ %% foo: {}; +]])[ + +]AT_BISON_CHECK([$3 $1 $5], 0)[ +# Ignore the files non-generated files +]AT_CHECK([find . -type f -and -not -path './$1' -and -not -path './testsuite.log' | + sed 's,\./,,' | + sort | + xargs echo], + [], [$4 +])[ +]$6[ +]AT_CLEANUP[ ]]) -AT_BISON_CHECK([$3 $1 $5], 0) -AT_CHECK([ls $4], [], [ignore]) -$6 -AT_CLEANUP -]) - AT_CHECK_OUTPUT([foo.y], [], [-dv], - [foo.output foo.tab.c foo.tab.h]) + [foo.output foo.tab.c foo.tab.h]) # Some versions of Valgrind (at least valgrind-3.6.0.SVN-Debian) report # "fgrep: write error: Bad file descriptor" when stdout is closed, so we # skip this test group during maintainer-check-valgrind. AT_CHECK_OUTPUT([foo.y], [], [-dv], - [foo.output foo.tab.c foo.tab.h], - [>&-], [], - [AT_CHECK([[case "$PREBISON" in *valgrind*) exit 77;; esac]])]) + [foo.output foo.tab.c foo.tab.h], + [>&-], [], + [AT_CHECK([[case "$PREBISON" in *valgrind*) exit 77;; esac]])]) AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c], - [foo.c foo.h foo.output]) + [foo.c foo.h foo.output]) AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c], - [foo.output foo.tab.c foo.tab.h]) + [foo.output foo.tab.c foo.tab.h]) AT_CHECK_OUTPUT([foo.y], [], [-dv -y], - [y.output y.tab.c y.tab.h]) + [y.output y.tab.c y.tab.h]) AT_CHECK_OUTPUT([foo.y], [], [-dv -b bar], - [bar.output bar.tab.c bar.tab.h]) + [bar.output bar.tab.c bar.tab.h]) AT_CHECK_OUTPUT([foo.y], [], [-dv -g -o foo.c], - [foo.c foo.dot foo.h foo.output]) + [foo.c foo.dot foo.h foo.output]) AT_CHECK_OUTPUT([foo.y], [%defines %verbose], [], - [foo.output foo.tab.c foo.tab.h]) + [foo.output foo.tab.c foo.tab.h]) AT_CHECK_OUTPUT([foo.y], [%defines %verbose %yacc],[], - [y.output y.tab.c y.tab.h]) + [y.output y.tab.c y.tab.h]) AT_CHECK_OUTPUT([foo.yy], [%defines %verbose %yacc],[], - [y.output y.tab.c y.tab.h]) + [y.output y.tab.c y.tab.h]) # Exercise %output and %file-prefix including deprecated '=' AT_CHECK_OUTPUT([foo.y], [%file-prefix "bar" %defines %verbose], [], - [bar.output bar.tab.c bar.tab.h]) + [bar.output bar.tab.c bar.tab.h]) AT_CHECK_OUTPUT([foo.y], [%output="bar.c" %defines %verbose %yacc],[], - [bar.output bar.c bar.h]) + [bar.c bar.h bar.output]) AT_CHECK_OUTPUT([foo.y], - [%file-prefix="baz" %output "bar.c" %defines %verbose %yacc], - [], - [bar.output bar.c bar.h]) + [%file-prefix="baz" %output "bar.c" %defines %verbose %yacc], + [], + [bar.c bar.h bar.output]) # Check priorities of extension control. AT_CHECK_OUTPUT([foo.yy], [%defines %verbose], [], - [foo.output foo.tab.cc foo.tab.hh]) + [foo.output foo.tab.cc foo.tab.hh]) AT_CHECK_OUTPUT([foo.yy], [%defines %verbose ], [-o foo.c], - [foo.c foo.h foo.output]) + [foo.c foo.h foo.output]) AT_CHECK_OUTPUT([foo.yy], [], - [--defines=foo.hpp -o foo.c++], - [foo.c++ foo.hpp]) + [--defines=foo.hpp -o foo.c++], + [foo.c++ foo.hpp]) AT_CHECK_OUTPUT([foo.yy], [%defines "foo.hpp"], - [-o foo.c++], - [foo.c++ foo.hpp]) + [-o foo.c++], + [foo.c++ foo.hpp]) AT_CHECK_OUTPUT([foo.yy], [], - [-o foo.c++ --graph=foo.gph], - [foo.c++ foo.gph]) + [-o foo.c++ --graph=foo.gph], + [foo.c++ foo.gph]) ## ------------ ## @@@ -119,36 -113,22 +119,36 @@@ AT_CHECK([grep 'include .subdir/' $1.cc AT_CHECK([grep 'include .subdir/' $1.hh], 1, []) ]) +AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc" %verbose], [], + [foo.output foo.tab.cc]) + AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc" %defines %verbose], [], - [foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh]) + [foo.output foo.tab.cc foo.tab.hh stack.hh]) + +AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc" %verbose %locations], [], + [foo.output foo.tab.cc]) + +AT_CHECK_OUTPUT([foo.yy], [%skeleton "lalr1.cc" %defines %verbose %locations], [], + [foo.output foo.tab.cc foo.tab.hh location.hh position.hh stack.hh]) AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose], [], - [foo.tab.cc foo.tab.hh foo.output location.hh stack.hh position.hh], - [], [AT_CHECK_NO_SUBDIR_PART([foo.tab])]) + [foo.output foo.tab.cc foo.tab.hh stack.hh], + [], [AT_CHECK_NO_SUBDIR_PART([foo.tab])]) -AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose], - [-o subdir/foo.cc], - [subdir/foo.cc subdir/foo.hh subdir/foo.output subdir/location.hh subdir/stack.hh subdir/position.hh], - [], [AT_CHECK_NO_SUBDIR_PART([subdir/foo])]) +AT_CHECK_OUTPUT([subdir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose %locations], + [-o subdir/foo.cc], + [subdir/foo.cc subdir/foo.hh subdir/foo.output subdir/location.hh subdir/position.hh subdir/stack.hh], + [], [AT_CHECK_NO_SUBDIR_PART([subdir/foo])]) AT_CHECK_OUTPUT([gram_dir/foo.yy], [%skeleton "lalr1.cc" %defines %verbose %file-prefix "output_dir/foo"], [], - [output_dir/foo.tab.cc output_dir/foo.tab.hh output_dir/foo.output output_dir/location.hh output_dir/stack.hh output_dir/position.hh]) + [output_dir/foo.output output_dir/foo.tab.cc output_dir/foo.tab.hh output_dir/stack.hh]) + +AT_CHECK_OUTPUT([gram_dir/foo.yy], + [%skeleton "lalr1.cc" %defines %locations %verbose %file-prefix "output_dir/foo"], + [], + [output_dir/foo.output output_dir/foo.tab.cc output_dir/foo.tab.hh output_dir/location.hh output_dir/position.hh output_dir/stack.hh]) # AT_CHECK_CONFLICTING_OUTPUT(INPUT-FILE, DIRECTIVES, FLAGS, STDERR, @@@ -177,22 -157,22 +177,22 @@@ AT_CLEANU AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [--graph="foo.tab.c"], -[foo.y: warning: conflicting outputs to file 'foo.tab.c' -]) +[[foo.y: warning: conflicting outputs to file 'foo.tab.c' [-Wother] +]]) AT_CHECK_CONFLICTING_OUTPUT([foo.y], [%defines "foo.output"], [-v], -[foo.y: warning: conflicting outputs to file 'foo.output' -]) +[[foo.y: warning: conflicting outputs to file 'foo.output' [-Wother] +]]) AT_CHECK_CONFLICTING_OUTPUT([foo.y], -[%skeleton "lalr1.cc" %defines], [--graph="location.hh"], -[foo.y: warning: conflicting outputs to file 'location.hh' -]) +[%skeleton "lalr1.cc" %defines %locations], [--graph="location.hh"], +[[foo.y: warning: conflicting outputs to file 'location.hh' [-Wother] +]]) AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [-o foo.y], - [[foo.y: refusing to overwrite the input file 'foo.y' -[foo.y: error: refusing to overwrite the input file 'foo.y' -], 1) ++[[foo.y: error: refusing to overwrite the input file 'foo.y' +]], 1) # AT_CHECK_OUTPUT_FILE_NAME(FILE-NAME-PREFIX, [ADDITIONAL-TESTS]) diff --combined tests/regression.at index 5911c537,617a6752..2fb180e9 --- a/tests/regression.at +++ b/tests/regression.at @@@ -209,7 -209,7 +209,7 @@@ exp: '(' exp ')' | NUM AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-v -o input.c input.y], 0, [], -[[input.y:6.8-14: warning: symbol "<=" used more than once as a literal string +[[input.y:6.8-14: warning: symbol "<=" used more than once as a literal string [-Wother] ]]) AT_CLEANUP @@@ -401,15 -401,15 +401,15 @@@ default: 'a' ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:2.1: invalid character: '?' - input.y:3.14: invalid character: '}' - input.y:4.1: invalid character: '%' - input.y:4.2: invalid character: '&' - input.y:5.1-17: invalid directive: '%a-does-not-exist' - input.y:6.1: invalid character: '%' - input.y:6.2: invalid character: '-' - input.y:7.1-8.0: missing '%}' at end of file - input.y:7.1-8.0: syntax error, unexpected %{...%} + [[input.y:2.1: error: invalid character: '?' + input.y:3.14: error: invalid character: '}' + input.y:4.1: error: invalid character: '%' + input.y:4.2: error: invalid character: '&' + input.y:5.1-17: error: invalid directive: '%a-does-not-exist' + input.y:6.1: error: invalid character: '%' + input.y:6.2: error: invalid character: '-' + input.y:7.1-8.0: error: missing '%}' at end of file + input.y:7.1-8.0: error: syntax error, unexpected %{...%} ]]) AT_CLEANUP @@@ -428,7 -428,7 +428,7 @@@ AT_DATA([input.y] ]]) AT_BISON_CHECK([input.y], [1], [], - [[input.y:3.1-15: syntax error, unexpected %initial-action, expecting {...} + [[input.y:3.1-15: error: syntax error, unexpected %initial-action, expecting {...} ]]) AT_CLEANUP @@@ -478,8 -478,8 +478,8 @@@ AT_BISON_OPTION_POPDEF # C-string literal. Also notice that unnecessary escaping, such as "\?", from # the user specification is eliminated. AT_BISON_CHECK([-o input.c input.y], [[0]], [[]], -[[input.y:22.8-14: warning: symbol SPECIAL redeclared -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 +[[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_COMPILE([input]) @@@ -538,7 -538,7 +538,7 @@@ AT_SETUP([Web2c Report] AT_KEYWORDS([report]) AT_DATA([input.y], -[[%token undef_id_tok const_id_tok +[[%token undef_id_tok const_id_tok %start CONST_DEC_PART @@@ -548,12 -548,12 +548,12 @@@ CONST_DEC_PART ; CONST_DEC_LIST: - CONST_DEC + CONST_DEC | CONST_DEC_LIST CONST_DEC ; CONST_DEC: - { } undef_id_tok '=' const_id_tok ';' + { } undef_id_tok '=' const_id_tok ';' ; %% ]]) @@@ -759,6 -759,15 +759,6 @@@ AT_CHECK([[cat tables.c]], 0 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6 }; -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 6, 9, 14 -}; -static const yytype_int8 yyrhs[] = -{ - 8, 0, -1, 9, -1, -1, 10, 11, -1, 3, - 4, 5, 8, -1, 6, 8, -1 -}; static const yytype_uint8 yyrline[] = { 0, 2, 2, 3, 3, 4, 5 @@@ -772,24 -781,32 +772,24 @@@ static const yytype_uint16 yytoknum[] { 0, 256, 257, 258, 259, 260, 261 }; -static const yytype_uint8 yyr1[] = -{ - 0, 7, 8, 9, 9, 10, 11 -}; -static const yytype_uint8 yyr2[] = +static const yytype_int8 yypact[] = { - 0, 2, 1, 0, 2, 4, 2 + -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, + -8, -8 }; static const yytype_uint8 yydefact[] = { 3, 0, 0, 2, 0, 0, 1, 3, 4, 3, 6, 5 }; -static const yytype_int8 yydefgoto[] = -{ - -1, 2, 3, 4, 8 -}; -static const yytype_int8 yypact[] = -{ - -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, - -8, -8 -}; static const yytype_int8 yypgoto[] = { -8, -7, -8, -8, -8 }; +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 3, 4, 8 +}; static const yytype_uint8 yytable[] = { 10, 1, 11, 5, 6, 0, 7, 9 @@@ -803,14 -820,6 +803,14 @@@ static const yytype_uint8 yystos[] 0, 3, 8, 9, 10, 4, 0, 6, 11, 5, 8, 8 }; +static const yytype_uint8 yyr1[] = +{ + 0, 7, 8, 9, 9, 10, 11 +}; +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 0, 2, 4, 2 +}; ]]) AT_CLEANUP @@@ -930,11 -939,11 +930,11 @@@ AT_CHECK_DANCER([%skeleton "lalr1.cc"] # -------------------------------- m4_define([_AT_DATA_EXPECT2_Y], [AT_DATA_GRAMMAR([expect2.y], -[[%{ -static int yylex (]AT_LALR1_CC_IF([int *], [void])); -AT_LALR1_CC_IF([], -[[#include -#include +[%{ +static int yylex (AT_LALR1_CC_IF([int *], [void])); +AT_LALR1_CC_IF([[#include ]], +[[#include +#include ]AT_YYERROR_DECLARE])[ %} $1 @@@ -1029,7 -1038,7 +1029,7 @@@ AT_DATA_GRAMMAR([input.y] start: { printf ("Bison would once convert this action to a midrule because of the" - " subsequent braced code.\n"); + " subsequent braced code.\n"); } ; @@@ -1182,8 -1191,8 +1182,8 @@@ main (void 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 -input.y:27.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" +[[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] ]]) AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]]) @@@ -1201,9 -1210,8 +1201,9 @@@ AT_CLEANU AT_SETUP([[parse-gram.y: LALR = IELR]]) -# Avoid differences in synclines by telling bison that the output files -# have the same name. +# Avoid tests/bison's dark magic by processing a local copy of the +# grammar. Avoid differences in synclines by telling bison that the +# output files have the same name. [cp $abs_top_srcdir/src/parse-gram.y input.y] AT_BISON_CHECK([[-o input.c -Dlr.type=lalr input.y]]) [mv input.c lalr.c] @@@ -1217,11 -1225,11 +1217,11 @@@ AT_CLEANU -## --------------------------------------- ## -## %error-verbose and YYSTACK_USE_ALLOCA. ## -## --------------------------------------- ## +## -------------------------------------------- ## +## parse.error=verbose and YYSTACK_USE_ALLOCA. ## +## -------------------------------------------- ## -AT_SETUP([[%error-verbose and YYSTACK_USE_ALLOCA]]) +AT_SETUP([[parse.error=verbose and YYSTACK_USE_ALLOCA]]) AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], @@@ -1232,7 -1240,7 +1232,7 @@@ #define YYSTACK_USE_ALLOCA 1 } -%error-verbose +%define parse.error verbose %% @@@ -1265,9 -1273,9 +1265,9 @@@ syntax_error %% ]AT_YYERROR_DEFINE[ -/* Induce two syntax error messages (which requires full error - recovery by shifting 3 tokens) in order to detect any loss of the - reallocated buffer. */ + /* Induce two syntax error messages (which requires full error + recovery by shifting 3 tokens) in order to detect any loss of the + reallocated buffer. */ ]AT_YYLEX_DEFINE(["abc"])[ int main (void) @@@ -1288,9 -1296,9 +1288,9 @@@ AT_CLEANU -## ------------------------- ## -## %error-verbose overflow. ## -## ------------------------- ## +## ------------------------------ ## +## parse.error=verbose overflow. ## +## ------------------------------ ## # Imagine the case where YYSTACK_ALLOC_MAXIMUM = YYSIZE_MAXIMUM and an # invocation of yysyntax_error has caused yymsg_alloc to grow to exactly @@@ -1300,8 -1308,7 +1300,8 @@@ # size calculation would return YYSIZE_MAXIMUM to yyparse. Then, # yyparse would invoke yyerror using the old contents of yymsg. -AT_SETUP([[%error-verbose overflow]]) +AT_SETUP([[parse.error=verbose overflow]]) + AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%code { @@@ -1326,7 -1333,7 +1326,7 @@@ #define YYMAXDEPTH 100 } -%error-verbose +%define parse.error verbose %% @@@ -1374,8 -1381,8 +1374,8 @@@ syntax_error2 %% ]AT_YYERROR_DEFINE[ -/* Induce two syntax error messages (which requires full error - recovery by shifting 3 tokens). */ + /* Induce two syntax error messages (which requires full error + recovery by shifting 3 tokens). */ ]AT_YYLEX_DEFINE(["abc"])[ int main (void) @@@ -1425,7 -1432,7 +1425,7 @@@ AT_DATA_GRAMMAR([input.y] } ]$1[ -%error-verbose +%define parse.error verbose %token 'c' %% @@@ -1461,7 -1468,7 +1461,7 @@@ main (void AT_BISON_CHECK([[-Dparse.lac=full -Dparse.lac.es-capacity-initial=1 \ -Dparse.lac.memory-trace=full \ -t -o input.c input.y]], [[0]], [], -[[input.y: conflicts: 21 shift/reduce +[[input.y: warning: 21 shift/reduce conflicts [-Wconflicts-sr] ]]) AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input > stdout.txt 2> stderr.txt]], [[1]]) @@@ -1537,7 -1544,7 +1537,7 @@@ main (void AT_BISON_CHECK([[-Dparse.lac=full -Dparse.lac.es-capacity-initial=1 \ -t -o input.c input.y]], [[0]], [], -[[input.y: conflicts: 8 shift/reduce +[[input.y: warning: 8 shift/reduce conflicts [-Wconflicts-sr] ]]) AT_COMPILE([[input]]) AT_BISON_OPTION_POPDEFS diff --combined tests/skeletons.at index ce32e88b,ec8170ca..ce079d62 --- a/tests/skeletons.at +++ b/tests/skeletons.at @@@ -157,7 -157,7 +157,7 @@@ start: ]]) AT_BISON_CHECK([[input.y]], [[1]], [[]], - [[: invalid value for %define Boolean variable 'foo' + [[: error: invalid value for %define Boolean variable 'foo' ]]) AT_CLEANUP @@@ -191,10 -191,10 +191,10 @@@ start: ]]) AT_BISON_CHECK([[input1.y]], [[1]], [[]], -[[input1.y: warning: foow fubar -foow.y:2.3-5.3: warning: foowat fubar +[[input1.y: warning: foow fubar [-Wother] +foow.y:2.3-5.3: warning: foowat fubar [-Wother] - input1.y: fooc fubar - fooc.y:1.1-10.5: foocat fubar + input1.y: error: fooc fubar + fooc.y:1.1-10.5: error: foocat fubar input1.y: fatal error: foof fubar ]]) @@@ -264,7 -264,7 +264,7 @@@ start: ]]) AT_BISON_CHECK([[input1.y]], [[1]], [[]], - [[input1.y: non-fatal error + [[input1.y: error: non-fatal error input1.y: fatal error: M4 should exit immediately here ]]) @@@ -281,7 -281,7 +281,7 @@@ start: ]]) AT_BISON_CHECK([[input2.y]], [[1]], [[]], -[[input2.y: warning: morning +[[input2.y: warning: morning [-Wother] foo.y:1.5-6: fatal error: M4 should exit immediately here ]])