multistart: check duplicates

* src/symlist.h, src/symlist.c (symbol_list_find_symbol)
(symbol_list_last): New.
(symbol_list_append): Use symbol_list_last.
* src/reader.c (grammar_start_symbols_add): Check and discard duplicates.
* tests/input.at (Duplicate %start symbol): New.
* tests/reduce.at (Bad start symbols): Add the multistart keyword.
This commit is contained in:
Akim Demaille
2020-11-22 11:19:48 +01:00
parent 7fe9205b9f
commit 5b19f91ccf
6 changed files with 137 additions and 15 deletions

View File

@@ -55,7 +55,37 @@ bool default_prec = true;
void
grammar_start_symbols_add (symbol_list *syms)
{
start_symbols = symbol_list_append (start_symbols, syms);
/* Report and ignore duplicates. Append the others to START_SYMBOLS. */
symbol_list *last = symbol_list_last (start_symbols);
for (symbol_list *l = syms; l && l->content.sym; /* nothing */)
{
/* Is there a previous definition? */
symbol_list *first = symbol_list_find_symbol (start_symbols, l->content.sym);
if (first)
{
duplicate_directive ("%start", first->sym_loc, l->sym_loc);
symbol_list *dup = l;
l = l->next;
dup->next = NULL;
symbol_list_free (dup);
}
else
{
if (last)
{
last->next = l;
last = l;
}
else
{
last = l;
start_symbols = last;
}
symbol_list *next = l->next;
l->next = NULL;
l = next;
}
}
}