[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
fixits: report duplicate %yacc directives
From: |
Akim Demaille |
Subject: |
fixits: report duplicate %yacc directives |
Date: |
Wed, 16 Jan 2019 08:46:16 +0100 |
commit b6b397b7f0a764f29f8b60f7d9eb7696473aa556
Author: Akim Demaille <address@hidden>
Date: Wed Jan 16 07:45:54 2019 +0100
fixits: report duplicate %yacc directives
We should use -ffixit and --update to clean files with duplicate
directives. And we should complain only once about duplicate
obsolete
directives: keep only the "duplicate" warning. Let's start with
%yacc.
For instance on:
%fixed-output_files
%fixed-output-files
%yacc
%%
exp:
This run of bison:
$ bison /tmp/foo.y -u
foo.y:1.1-19: warning: deprecated directive, use
'%fixed-output-files' [-Wdeprecated]
%fixed-output_files
^~~~~~~~~~~~~~~~~~~
foo.y:2.1-19: warning: duplicate directive [-Wother]
%fixed-output-files
^~~~~~~~~~~~~~~~~~~
foo.y:1.1-19: previous declaration
%fixed-output_files
^~~~~~~~~~~~~~~~~~~
foo.y:3.1-5: warning: duplicate directive [-Wother]
%yacc
^~~~~
foo.y:1.1-19: previous declaration
%fixed-output_files
^~~~~~~~~~~~~~~~~~~
bison: file 'foo.y' was updated (backup: 'foo.y~')
gives:
%fixed-output-files
%%
exp:
* src/location.h, src/location.c (location_empty): New.
* src/complain.h, src/complain.c (duplicate_directive): New.
* src/getargs.h, src/getargs.c (yacc_flag): Instead of a Boolean, be
the location of the definition.
Update dependencies.
* src/scan-gram.l (%yacc, %fixed-output-files): Move the handling of
its warnings to...
* src/parse-gram.y (do_yacc): This new function.
* tests/input.at (Deprecated Directives): Adjust expectations.
diff --git a/src/complain.c b/src/complain.c
index 3f8c5118..6b6b2c0b 100644
--- a/src/complain.c
+++ b/src/complain.c
@@ -399,6 +399,19 @@ deprecated_directive (location const *loc, char
const *old, char const *upd)
fixits_register (loc, upd);
}
+void
+duplicate_directive (char const *directive,
+ location first, location second)
+{
+ if (feature_flag & feature_caret)
+ complain (&second, Wother, _("duplicate directive"));
+ else
+ complain (&second, Wother, _("duplicate directive: %s"),
directive);
+ unsigned i = SUB_INDENT;
+ complain_indent (&first, complaint, &i, _("previous declaration"));
+ fixits_register (&second, "");
+}
+
void
duplicate_rule_directive (char const *directive,
location first, location second)
diff --git a/src/complain.h b/src/complain.h
index e5f6d7e6..266992f6 100644
--- a/src/complain.h
+++ b/src/complain.h
@@ -126,6 +126,10 @@ void bison_directive (location const *loc, char
const *directive);
void deprecated_directive (location const *loc,
char const *obsolete, char const *updated);
+/** Report a repeated directive. */
+void duplicate_directive (char const *directive,
+ location first, location second);
+
/** Report a repeated directive for a rule. */
void duplicate_rule_directive (char const *directive,
location first, location second);
diff --git a/src/files.c b/src/files.c
index 7c33b23d..f805524c 100644
--- a/src/files.c
+++ b/src/files.c
@@ -285,7 +285,7 @@ compute_file_name_parts (void)
last_component (spec_file_prefix) -
spec_file_prefix);
all_but_tab_ext = xstrdup (spec_file_prefix);
}
- else if (yacc_flag)
+ else if (! location_empty (yacc_loc))
{
/* If --yacc, then the output is 'y.tab.c'. */
dir_prefix = xstrdup ("");
@@ -306,7 +306,7 @@ compute_file_name_parts (void)
all_but_ext = xstrdup (all_but_tab_ext);
/* Compute the extensions from the grammar file name. */
- if (ext && !yacc_flag)
+ if (ext && location_empty (yacc_loc))
compute_exts_from_gf (ext);
}
}
diff --git a/src/getargs.c b/src/getargs.c
index 83ebcb09..a66e4c66 100644
--- a/src/getargs.c
+++ b/src/getargs.c
@@ -41,7 +41,7 @@ bool graph_flag = false;
bool xml_flag = false;
bool no_lines_flag = false;
bool token_table_flag = false;
-bool yacc_flag = false; /* for -y */
+location yacc_loc = EMPTY_LOCATION_INIT;
bool update_flag = false; /* for -u */
bool nondeterministic_parser = false;
@@ -709,7 +709,7 @@ getargs (int argc, char *argv[])
case 'y':
warning_argmatch ("error=yacc", 0, 6);
- yacc_flag = true;
+ yacc_loc = command_line_location ();
break;
case LOCATIONS_OPTION:
diff --git a/src/getargs.h b/src/getargs.h
index f44f2183..c5adb848 100644
--- a/src/getargs.h
+++ b/src/getargs.h
@@ -39,7 +39,7 @@ extern bool graph_flag; /* for -g */
extern bool xml_flag; /* for -x */
extern bool no_lines_flag; /* for -l */
extern bool token_table_flag; /* for -k */
-extern bool yacc_flag; /* for -y */
+extern location yacc_loc; /* for -y */
extern bool update_flag; /* for -u */
/* GLR_PARSER is true if the input file says to use the GLR
diff --git a/src/location.c b/src/location.c
index 4ec12a70..6876890c 100644
--- a/src/location.c
+++ b/src/location.c
@@ -216,6 +216,13 @@ location_caret (location loc, FILE *out)
}
}
+bool
+location_empty (location loc)
+{
+ return !loc.start.file && !loc.start.line && !loc.start.column
+ && !loc.end.file && !loc.end.line && !loc.end.column;
+}
+
void
boundary_set_from_string (boundary *bound, char *loc_str)
{
diff --git a/src/location.h b/src/location.h
index 26d6af61..39e0507d 100644
--- a/src/location.h
+++ b/src/location.h
@@ -126,6 +126,9 @@ location_cmp (location a, location b)
return res;
}
+/* Whether this is the empty location. */
+bool location_empty (location loc);
+
/* LOC_STR must be formatted as 'file:line.column', it will be
modified. */
void boundary_set_from_string (boundary *bound, char *loc_str);
diff --git a/src/output.c b/src/output.c
index 6a9553c5..da600ae5 100644
--- a/src/output.c
+++ b/src/output.c
@@ -665,7 +665,7 @@ prepare (void)
MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
MUSCLE_INSERT_BOOL ("token_table_flag", token_table_flag);
MUSCLE_INSERT_BOOL ("use_push_for_pull_flag",
use_push_for_pull_flag);
- MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
+ MUSCLE_INSERT_BOOL ("yacc_flag", !location_empty (yacc_loc));
/* File names. */
if (spec_name_prefix)
diff --git a/src/parse-gram.y b/src/parse-gram.y
index e0496d5a..aa1a450f 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -95,6 +95,9 @@
/* Handle a %skeleton directive. */
static void do_skeleton (location const *loc, char const *skel);
+ /* Handle a %yacc directive. */
+ static void do_yacc (location const *loc, char const *directive);
+
static void gram_error (location const *, char const *);
/* A string that describes a char (e.g., 'a' -> "'a'"). */
@@ -201,8 +204,9 @@
%type <uniqstr>
BRACKETED_ID ID ID_COLON
- PERCENT_ERROR_VERBOSE PERCENT_FLAG PERCENT_NAME_PREFIX TAG
- tag tag.opt variable
+ PERCENT_ERROR_VERBOSE PERCENT_FLAG PERCENT_NAME_PREFIX
+ PERCENT_YACC
+ TAG tag tag.opt variable
%printer { fputs ($$, yyo); } <uniqstr>
%printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
%printer { fprintf (yyo, "%s:", $$); } ID_COLON
@@ -329,7 +333,7 @@ prologue_declaration:
| "%skeleton" STRING { do_skeleton (&@2, $2); }
| "%token-table" { token_table_flag = true; }
| "%verbose" { report_flag |= report_states; }
-| "%yacc" { yacc_flag = true; }
+| "%yacc" { do_yacc (&@$, $1); }
| error ";" { current_class = unknown_sym; yyerrok;
}
| /*FIXME: Err? What is this horror doing here? */ ";"
;
@@ -956,6 +960,25 @@ do_skeleton (location const *loc, char const
*skel)
skeleton_arg (skeleton_user, grammar_prio, *loc);
}
+static void
+do_yacc (location const *loc, char const *directive)
+{
+ bison_directive (loc, directive);
+ bool warned = false;
+
+ if (location_empty (yacc_loc))
+ yacc_loc = *loc;
+ else
+ {
+ duplicate_directive (directive, yacc_loc, *loc);
+ warned = true;
+ }
+
+ if (!warned
+ && STRNEQ (directive, "%fixed-output-files")
+ && STRNEQ (directive, "%yacc"))
+ deprecated_directive (loc, directive, "%fixed-output-files");
+}
static void
gram_error (location const *loc, char const *msg)
diff --git a/src/scan-gram.l b/src/scan-gram.l
index 2eaa1606..e1536f5c 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -229,7 +229,7 @@ eqopt ({sp}=)?
"%expect" return BISON_DIRECTIVE (EXPECT);
"%expect-rr" return BISON_DIRECTIVE (EXPECT_RR);
"%file-prefix" return BISON_DIRECTIVE
(FILE_PREFIX);
- "%fixed-output-files" return BISON_DIRECTIVE (YACC);
+ "%fixed-output-files" RETURN_VALUE (PERCENT_YACC,
uniqstr_new (yytext));
"%initial-action" return BISON_DIRECTIVE
(INITIAL_ACTION);
"%glr-parser" return BISON_DIRECTIVE
(GLR_PARSER);
"%language" return BISON_DIRECTIVE (LANGUAGE);
@@ -259,7 +259,7 @@ eqopt ({sp}=)?
"%type" return PERCENT_TYPE;
"%union" return PERCENT_UNION;
"%verbose" return BISON_DIRECTIVE (VERBOSE);
- "%yacc" return BISON_DIRECTIVE (YACC);
+ "%yacc" RETURN_VALUE (PERCENT_YACC,
uniqstr_new (yytext));
/* Deprecated since Bison 3.0 (2013-07-25), but the warning is
issued only since Bison 3.3. */
@@ -274,7 +274,7 @@ eqopt ({sp}=)?
"%error"[-_]"verbose" RETURN_VALUE
(PERCENT_ERROR_VERBOSE, uniqstr_new (yytext));
"%expect"[-_]"rr" DEPRECATED ("%expect-rr");
"%file-prefix"{eqopt} DEPRECATED ("%file-prefix");
- "%fixed"[-_]"output"[-_]"files" DEPRECATED
("%fixed-output-files");
+ "%fixed"[-_]"output"[-_]"files" RETURN_VALUE (PERCENT_YACC,
uniqstr_new (yytext));
"%no"[-_]"default"[-_]"prec" DEPRECATED ("%no-default-prec");
"%no"[-_]"lines" DEPRECATED ("%no-lines");
"%output"{eqopt} DEPRECATED ("%output");
diff --git a/tests/input.at b/tests/input.at
index f4a2cbbb..3314d680 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -2526,8 +2526,12 @@ input.y:14.1-15.2: warning: deprecated
directive: '%file-prefix\n =', use '%file
fix-it:"input.y":{14:1-15:3}:"%file-prefix"
input.y:17.1-19: warning: deprecated directive: '%fixed-output_files',
use '%fixed-output-files' [-Wdeprecated]
fix-it:"input.y":{17:1-17:20}:"%fixed-output-files"
-input.y:18.1-19: warning: deprecated directive: '%fixed_output-files',
use '%fixed-output-files' [-Wdeprecated]
-fix-it:"input.y":{18:1-18:20}:"%fixed-output-files"
+input.y:18.1-19: warning: duplicate directive: %fixed_output-files
[-Wother]
+input.y:17.1-19: previous declaration
+fix-it:"input.y":{18:1-18:20}:""
+input.y:19.1-19: warning: duplicate directive: %fixed-output-files
[-Wother]
+input.y:17.1-19: previous declaration
+fix-it:"input.y":{19:1-19:20}:""
input.y:20.1-19: warning: deprecated directive: '%name-prefix= "foo"',
use '%define api.prefix {foo}' [-Wdeprecated]
fix-it:"input.y":{20:1-20:20}:"%define api.prefix {foo}"
input.y:21.1-16: warning: deprecated directive: '%no-default_prec', use
'%no-default-prec' [-Wdeprecated]
@@ -2550,12 +2554,12 @@ fix-it:"input.y":{29:1-29:19}:"%define
api.prefix {bar}"
input.y: warning: fix-its can be applied. Rerun with option
'--update'. [-Wother]
]])
-AT_CHECK([[sed -e '/^fix-it:/d' errors-all >experr]])
-AT_BISON_CHECK([[input.y]], [[1]], [[]], [experr])
-
AT_CHECK([cp errors-all experr])
AT_BISON_CHECK([[-ffixit input.y]], [[1]], [[]], [experr])
+AT_CHECK([[sed -e '/^fix-it:/d' errors-all >experr]])
+AT_BISON_CHECK([[input.y]], [[1]], [[]], [experr])
+
# Update the input file.
AT_CHECK([cp input.y input.y.orig])
AT_CHECK([sed -e '/fix-it/d' <errors-all >experr])
@@ -2583,8 +2587,6 @@ AT_CHECK([cat input.y], [],
%file-prefix
"bar"
%fixed-output-files
-%fixed-output-files
-%fixed-output-files
%define api.prefix {foo}
%no-default-prec
%no-default-prec
@@ -2599,10 +2601,10 @@ exp : '0'
]])
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [],
-[[input.y:27.1-24: error: %define variable 'api.prefix' redefined
+[[input.y:25.1-24: error: %define variable 'api.prefix' redefined
%define api.prefix {bar}
^~~~~~~~~~~~~~~~~~~~~~~~
-input.y:19.1-24: previous definition
+input.y:17.1-24: previous definition
%define api.prefix {foo}
^~~~~~~~~~~~~~~~~~~~~~~~
input.y: warning: fix-its can be applied. Rerun with option
'--update'. [-Wother]
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- fixits: report duplicate %yacc directives,
Akim Demaille <=