From 2ef1ff5ec53767a8f54fcb957f0cda3059d406b5 Mon Sep 17 00:00:00 2001
From: "Sven M. Hallberg" <pesco@khjk.org>
Date: Fri, 21 Feb 2020 11:28:57 +0100
Subject: [PATCH] remove tainted memo entries at the end of h_follow

doh! fixes issue 92 again.
---
 src/cfgrammar.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/src/cfgrammar.c b/src/cfgrammar.c
index 2244237..1e43b79 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;
 }
 
-- 
GitLab