From ebcfa8691191d2306546900d1867ef78cebdabf0 Mon Sep 17 00:00:00 2001
From: "Sven M. Hallberg" <pesco@khjk.org>
Date: Wed, 8 May 2013 18:49:05 +0200
Subject: [PATCH] finish (untested) LL(1) table generation

---
 src/backends/ll.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/src/backends/ll.c b/src/backends/ll.c
index 8ed4d604..3f1ee5ad 100644
--- a/src/backends/ll.c
+++ b/src/backends/ll.c
@@ -68,12 +68,64 @@ HHashSet *h_predict(HCFGrammar *g, const HCFChoice *A, const HCFSequence *rhs)
   }
 }
 
+/* Generate entries for the production "A -> rhs" in the given table row. */
+static
+int fill_table_row(HCFGrammar *g, HHashTable *row,
+                   const HCFChoice *A, HCFSequence *rhs)
+{
+  // iterate over predict(A -> rhs)
+  HHashSet *pred = h_predict(g, A, rhs);
+
+  size_t i;
+  HHashTableEntry *hte;
+  for(i=0; i < pred->capacity; i++) {
+    for(hte = &pred->contents[i]; hte; hte = hte->next) {
+      if(hte->key == NULL)
+        continue;
+      HCFToken x = (uintptr_t)hte->key;
+
+      if(h_hashtable_present(row, (void *)x))
+        return -1;  // table would be ambiguous
+
+      h_hashtable_put(row, (void *)x, rhs);
+    }
+  }
+
+  return 0;
+}
+
 /* Generate the LL parse table from the given grammar.
  * Returns -1 on error, 0 on success.
  */
 static int fill_table(HCFGrammar *g, HLLTable *table)
 {
-  return -1; // XXX
+  // iterate over g->nts
+  size_t i;
+  HHashTableEntry *hte;
+  for(i=0; i < g->nts->capacity; i++) {
+    for(hte = &g->nts->contents[i]; hte; hte = hte->next) {
+      if(hte->key == NULL)
+        continue;
+      const HCFChoice *a = hte->key;        // production's left-hand symbol
+
+      // create table row for this nonterminal
+      HHashTable *row = h_hashtable_new(table->arena, h_eq_ptr, h_hash_ptr);
+      h_hashtable_put(table->rows, a, row);
+
+      // iterate over a's productions
+      HCFSequence **s;
+      for(s = a->seq; *s; s++) {
+        // record this production in row as appropriate
+        // this can signal an ambiguity conflict.
+        // NB we don't worry about deallocating anything, h_ll_compile will
+        //    delete the whole arena for us.
+        if(fill_table_row(g, row, a, *s) < 0)
+          return -1;
+      }
+    }
+  }
+  
+  return 0;
 }
 
 int h_ll_compile(HAllocator* mm__, HParser* parser, const void* params)
-- 
GitLab