diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2019-09-27 18:28:19 +0200 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2019-10-06 09:54:25 +0200 |
commit | be3cf406afcd68bbf1c113607f3362722f4418d1 (patch) | |
tree | ba19fa11dedeb8ba306533fa6c4c441ebc5f2de9 /src | |
parent | 126c4622de27197bbe4c6a713f28d114839e636f (diff) | |
download | bison-be3cf406afcd68bbf1c113607f3362722f4418d1.tar.gz |
diagnostics: suggest fixes for undeclared symbols
From
input.y:1.17-19: warning: symbol baz is used, but is not defined as a token and has no rules [-Wother]
1 | %printer {} foo baz
| ^~~
to
input.y:1.17-19: warning: symbol 'baz' is used, but is not defined as a token and has no rules; did you mean 'bar'? [-Wother]
1 | %printer {} foo baz
| ^~~
| bar
* bootstrap.conf: We need fstrcmp.
* src/symtab.c (symbol_from_uniqstr_fuzzy): New.
(complain_symbol_undeclared): Use it.
* tests/diagnostics.at (Suggestions): New.
* data/bison-default.css (insertion): Rename as...
(fixit-insert): this, as this is what GCC uses.
Diffstat (limited to 'src')
-rw-r--r-- | src/location.c | 2 | ||||
-rw-r--r-- | src/symtab.c | 56 |
2 files changed, 49 insertions, 9 deletions
diff --git a/src/location.c b/src/location.c index b36f49d3..e6406bd6 100644 --- a/src/location.c +++ b/src/location.c @@ -473,7 +473,7 @@ location_caret (location loc, const char *style, FILE *out) void location_caret_suggestion (location loc, const char *s, FILE *out) { - const char *style = "insertion"; + const char *style = "fixit-insert"; fprintf (out, " | %*s", loc.start.column - 1 - caret_info.skip + (caret_info.skip ? 3 : 0), ""); diff --git a/src/symtab.c b/src/symtab.c index c7d308ac..b3642e67 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -24,6 +24,7 @@ #include "system.h" #include <assure.h> +#include <fstrcmp.h> #include <hash.h> #include "complain.h" @@ -32,6 +33,8 @@ #include "quote.h" +static struct hash_table *symbol_table = NULL; +static struct hash_table *semantic_type_table = NULL; /*----------------------------------------------------------------. | Symbols sorted by tag. Allocated by table_sort, after which no | @@ -41,6 +44,7 @@ static symbol **symbols_sorted = NULL; static semantic_type **semantic_types_sorted = NULL; + /*------------------------. | Distinguished symbols. | `------------------------*/ @@ -321,15 +325,54 @@ complain_class_redeclared (symbol *sym, symbol_class class, location second) } } +static const symbol * +symbol_from_uniqstr_fuzzy (const uniqstr key) +{ + aver (symbols_sorted); +#define FSTRCMP_THRESHOLD 0.6 + double best_similarity = FSTRCMP_THRESHOLD; + const symbol *res = NULL; + size_t count = hash_get_n_entries (symbol_table); + for (int i = 0; i < count; ++i) + { + symbol *sym = symbols_sorted[i]; + if (STRNEQ (key, sym->tag) + && (sym->content->status == declared + || sym->content->status == undeclared)) + { + double similarity = fstrcmp_bounded (key, sym->tag, best_similarity); + if (best_similarity < similarity) + { + res = sym; + best_similarity = similarity; + } + } + } + return res; +} + static void complain_symbol_undeclared (symbol *sym) { assert (sym->content->status != declared); - complain (&sym->location, - sym->content->status == needed ? complaint : Wother, - _("symbol %s is used, but is not defined as a token" - " and has no rules"), - quote (sym->tag)); + const symbol *best = symbol_from_uniqstr_fuzzy (sym->tag); + if (best) + { + complain (&sym->location, + sym->content->status == needed ? complaint : Wother, + _("symbol %s is used, but is not defined as a token" + " and has no rules; did you mean %s?"), + quote_n (0, sym->tag), + quote_n (1, best->tag)); + if (feature_flag & feature_caret) + location_caret_suggestion (sym->location, best->tag, stderr); + } + else + complain (&sym->location, + sym->content->status == needed ? complaint : Wother, + _("symbol %s is used, but is not defined as a token" + " and has no rules"), + quote (sym->tag)); } void @@ -694,9 +737,6 @@ symbol_translation (symbol *this) /* Initial capacity of symbol and semantic type hash table. */ #define HT_INITIAL_CAPACITY 257 -static struct hash_table *symbol_table = NULL; -static struct hash_table *semantic_type_table = NULL; - static inline bool hash_compare_symbol (const symbol *m1, const symbol *m2) { |