diff --git a/src/backends/llk.c b/src/backends/llk.c
index 2bc39daf92b371b3b22b783623442eee36053bc0..89151e6f7fb3cc605ca6cbb7e498cdb1490776ea 100644
--- a/src/backends/llk.c
+++ b/src/backends/llk.c
@@ -81,13 +81,12 @@ static void *combine_entries(HHashSet *workset, void *dst, const void *src)
 
 // add the mappings of src to dst, marking conflicts and adding the conflicting
 // values to workset.
-// note: reuses parts of src to build dst!
 static void stringmap_merge(HHashSet *workset, HStringMap *dst, HStringMap *src)
 {
   if(src->epsilon_branch) {
     if(dst->epsilon_branch)
       dst->epsilon_branch =
-	combine_entries(workset, dst->epsilon_branch, src->epsilon_branch);
+        combine_entries(workset, dst->epsilon_branch, src->epsilon_branch);
     else
       dst->epsilon_branch = src->epsilon_branch;
   } else {
@@ -101,7 +100,7 @@ static void stringmap_merge(HHashSet *workset, HStringMap *dst, HStringMap *src)
   if(src->end_branch) {
     if(dst->end_branch)
       dst->end_branch =
-	combine_entries(workset, dst->end_branch, src->end_branch);
+        combine_entries(workset, dst->end_branch, src->end_branch);
     else
       dst->end_branch = src->end_branch;
   }
@@ -118,10 +117,13 @@ static void stringmap_merge(HHashSet *workset, HStringMap *dst, HStringMap *src)
 
       if(src_) {
         HStringMap *dst_ = h_hashtable_get(dst->char_branches, (void *)c);
-        if(dst_)
+        if(dst_) {
           stringmap_merge(workset, dst_, src_);
-        else
+        } else {
+          if(src_->arena != dst->arena)
+            src_ = h_stringmap_copy(dst->arena, src_);
           h_hashtable_put(dst->char_branches, (void *)c, src_);
+        }
       }
     }
   }
diff --git a/src/cfgrammar.c b/src/cfgrammar.c
index 196d9d3c8b6ee9cb77b24a98ff365b8b4634ac45..b33ad86220321db0410b914daab81c00648b5613 100644
--- a/src/cfgrammar.c
+++ b/src/cfgrammar.c
@@ -281,6 +281,13 @@ void h_stringmap_update(HStringMap *m, const HStringMap *n)
   h_hashtable_merge(combine_stringmap, m->char_branches, n->char_branches);
 }
 
+HStringMap *h_stringmap_copy(HArena *a, const HStringMap *m)
+{
+  HStringMap *res = h_stringmap_new(a);
+  h_stringmap_update(res, m);
+  return res;
+}
+
 /* Replace all occurances of old in m with new.
  * If old is NULL, replace all values in m with new.
  * If new is NULL, remove the respective values.
diff --git a/src/cfgrammar.h b/src/cfgrammar.h
index 193f8ca327d2f9c0b74518b9942b5fe3f37c407b..9cefc62e83f07048dc2a24f0cda1bde28ca72066 100644
--- a/src/cfgrammar.h
+++ b/src/cfgrammar.h
@@ -40,6 +40,7 @@ typedef struct HStringMap_ {
 } HStringMap;
 
 HStringMap *h_stringmap_new(HArena *a);
+HStringMap *h_stringmap_copy(HArena *a, const HStringMap *m);
 void h_stringmap_put_end(HStringMap *m, void *v);
 void h_stringmap_put_epsilon(HStringMap *m, void *v);
 void h_stringmap_put_after(HStringMap *m, uint8_t c, HStringMap *ends);