mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
grammar: warn about unused precedence for symbols
Symbols with precedence but no associativity, and whose precedence is never used, can be declared with %token instead. The used precedence relationships are recorded and a warning about useless ones is issued. * src/conflicts.c (resolve_sr_conflict): Record precedence relation. * src/symtab.c, src/symtab.h (prec_nodes, init_prec_nodes) (symgraphlink_new, register_precedence_second_symbol) (print_precedence_warnings): New. Record relationships in a graph and warn about useless ones. * src/main.c (main): Print precedence warnings. * tests/conflicts.at: New.
This commit is contained in:
committed by
Akim Demaille
parent
fbecd2ab59
commit
284bc49c83
@@ -276,11 +276,13 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
The precedence of shifting is that of token i. */
|
||||
if (symbols[i]->prec < redprec)
|
||||
{
|
||||
register_precedence (redrule->prec->number, i);
|
||||
log_resolution (redrule, i, reduce_resolution);
|
||||
flush_shift (s, i);
|
||||
}
|
||||
else if (symbols[i]->prec > redprec)
|
||||
{
|
||||
register_precedence (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, shift_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
}
|
||||
|
||||
@@ -144,6 +144,8 @@ main (int argc, char *argv[])
|
||||
|
||||
grammar_rules_useless_report (_("rule useless in parser due to conflicts"));
|
||||
|
||||
print_precedence_warnings ();
|
||||
|
||||
/* Output file names. */
|
||||
compute_output_file_names ();
|
||||
|
||||
|
||||
102
src/symtab.c
102
src/symtab.c
@@ -46,6 +46,11 @@ symbol *accept = NULL;
|
||||
symbol *startsymbol = NULL;
|
||||
location startsymbol_location;
|
||||
|
||||
/*---------------------------.
|
||||
| Precedence relation graph. |
|
||||
`---------------------------*/
|
||||
|
||||
static symgraph **prec_nodes;
|
||||
|
||||
/*---------------------------------.
|
||||
| Create a new symbol, named TAG. |
|
||||
@@ -971,3 +976,100 @@ symbols_pack (void)
|
||||
_("the start symbol %s is a token"),
|
||||
startsymbol->tag);
|
||||
}
|
||||
|
||||
/*---------------------------------.
|
||||
| Initialize relation graph nodes. |
|
||||
`---------------------------------*/
|
||||
|
||||
static void
|
||||
init_prec_nodes (void)
|
||||
{
|
||||
int i;
|
||||
prec_nodes = xcalloc (nsyms, sizeof *prec_nodes);
|
||||
for (i = 0; i < nsyms; ++i)
|
||||
{
|
||||
prec_nodes[i] = xmalloc (sizeof *prec_nodes[i]);
|
||||
symgraph *s = prec_nodes[i];
|
||||
s->id = i;
|
||||
s->succ = 0;
|
||||
s->pred = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------.
|
||||
| Create a link. |
|
||||
`----------------*/
|
||||
|
||||
static symgraphlink *
|
||||
symgraphlink_new (graphid id, symgraphlink *next)
|
||||
{
|
||||
symgraphlink *l = xmalloc (sizeof *l);
|
||||
l->id = id;
|
||||
l->next = next;
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Register the second symbol of the precedence relation, and return |
|
||||
| whether this relation is new. Use only in register_precedence. |
|
||||
`------------------------------------------------------------------*/
|
||||
|
||||
static bool
|
||||
register_precedence_second_symbol (symgraphlink **first, graphid sym)
|
||||
{
|
||||
if (!*first || sym < (*first)->id)
|
||||
*first = symgraphlink_new (sym, *first);
|
||||
else
|
||||
{
|
||||
symgraphlink *slist = *first;
|
||||
|
||||
while (slist->next && slist->next->id <= sym)
|
||||
slist = slist->next;
|
||||
|
||||
if (slist->id == sym)
|
||||
/* Relation already present. */
|
||||
return false;
|
||||
|
||||
slist->next = symgraphlink_new (sym, slist->next);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Register a new relation between symbols as used. The first symbol |
|
||||
| has a greater precedence than the second one. |
|
||||
`------------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
register_precedence (graphid first, graphid snd)
|
||||
{
|
||||
if (!prec_nodes)
|
||||
init_prec_nodes ();
|
||||
register_precedence_second_symbol (&(prec_nodes[first]->succ), snd);
|
||||
register_precedence_second_symbol (&(prec_nodes[snd]->pred), first);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------.
|
||||
| Print a warning for unused precedence relations. |
|
||||
`--------------------------------------------------*/
|
||||
|
||||
void
|
||||
print_precedence_warnings (void)
|
||||
{
|
||||
int i;
|
||||
if (!prec_nodes)
|
||||
init_prec_nodes ();
|
||||
for (i = 0; i < nsyms; ++i)
|
||||
{
|
||||
symbol *s = symbols[i];
|
||||
if (s
|
||||
&& s->prec != 0
|
||||
&& !prec_nodes[i]->pred
|
||||
&& !prec_nodes[i]->succ
|
||||
&& s->assoc == precedence_assoc)
|
||||
complain (&s->location, Wother,
|
||||
_("useless precedence for %s"), s->tag);
|
||||
}
|
||||
}
|
||||
|
||||
46
src/symtab.h
46
src/symtab.h
@@ -224,6 +224,52 @@ extern symbol *startsymbol;
|
||||
extern location startsymbol_location;
|
||||
|
||||
|
||||
|
||||
/*-------------------.
|
||||
| Symbol Relations. |
|
||||
`-------------------*/
|
||||
|
||||
/* The symbol relations are represented by a directed graph. */
|
||||
|
||||
/* The id of a node */
|
||||
typedef int graphid;
|
||||
|
||||
typedef struct symgraphlink symgraphlink;
|
||||
|
||||
struct symgraphlink
|
||||
{
|
||||
/** The second \c symbol or group of a precedence relation.
|
||||
* See \c symgraph. */
|
||||
graphid id;
|
||||
|
||||
symgraphlink *next;
|
||||
};
|
||||
|
||||
/* Symbol precedence graph, to store the used precedence relations between
|
||||
* symbols. */
|
||||
|
||||
typedef struct symgraph symgraph;
|
||||
|
||||
struct symgraph
|
||||
{
|
||||
/** Identifier for the node: equal to the number of the symbol. */
|
||||
graphid id;
|
||||
|
||||
/** The list of related symbols that have a smaller precedence. */
|
||||
symgraphlink *succ;
|
||||
|
||||
/** The list of related symbols that have a greater precedence. */
|
||||
symgraphlink *pred;
|
||||
};
|
||||
|
||||
/** Register a new precedence relation as used. */
|
||||
|
||||
void register_precedence (graphid first, graphid snd);
|
||||
|
||||
/** Print a warning for each symbol whose precedence is useless. */
|
||||
|
||||
void print_precedence_warnings (void);
|
||||
|
||||
/*-----------------.
|
||||
| Semantic types. |
|
||||
`-----------------*/
|
||||
|
||||
Reference in New Issue
Block a user