diff --git a/src/cfgrammar.c b/src/cfgrammar.c index 22442376c6df18a7b83e4da9158271e684887435..1e43b797a9794807b8e8cb28e629e05d5316345f 100644 --- a/src/cfgrammar.c +++ b/src/cfgrammar.c @@ -397,6 +397,32 @@ bool h_stringmap_empty(const HStringMap *m) && h_hashtable_empty(m->char_branches)); } +// helper: remove all tainted stringmap entries from a hashtable +void remove_tainted(HHashTable *ht) +{ + HHashTableEntry *hte; + HStringMap *s; + + for (size_t i=0; i < ht->capacity; i++) { + for (hte = &ht->contents[i]; hte; hte = hte->next) { + if (hte->key == NULL) + continue; + s = hte->value; + assert(s != NULL); + + if (s->taint) { + // remove the entry + if (hte->next != NULL) + *hte = *hte->next; + else { + hte->key = hte->value = NULL; + hte->hashval = 0; + } + } + } + } +} + const HStringMap *h_first(size_t k, HCFGrammar *g, const HCFChoice *x) { HStringMap *ret; @@ -659,6 +685,10 @@ const HStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x) follow_work(k, g, x, ret); ret->taint = false; + // finished - clear the temporaries (tainted entries) + for (size_t i=0; i <= g->kmax; i++) + remove_tainted(g->follow[i]); + return ret; }