summaryrefslogtreecommitdiff
path: root/src/gll.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gll.c')
-rw-r--r--src/gll.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/gll.c b/src/gll.c
new file mode 100644
index 0000000..38e3f77
--- /dev/null
+++ b/src/gll.c
@@ -0,0 +1,68 @@
+#include "list.h"
+#include "ht.h"
+#include "slr_table.h"
+
+struct rule_s{
+ NUM nt_num;
+ NUM rule_num;
+};
+
+struct item_s {
+ rule r;
+ NUM pos;
+};
+
+struct item_set_s {
+ /* a list of items */
+ List *nonkernels;
+ /* a list of nonterminal symbols: a kernel item for a nonterminal
+ consists of all rules for that nonterminal, so we only need to
+ store the nonterminal, which are represented as NUM's. */
+ List *kernels;
+};
+
+typedef enum SLR_ACTION_e {
+ SHIFT,
+ REDUCE,
+ ACCEPT,
+ REJECT
+} SLR_ACTION;
+
+struct action_s {
+ SLR_ACTION type;
+ NUM arg1;
+ NUM arg2;
+};
+
+struct slr_table_s {
+ /* a list of states/rows
+
+ Each row contains a hash table mapping non-terminals, terminals,
+ and predicate terminals to an action set. */
+ List *rows;
+ /* a list of item sets; these are the states */
+ List *states;
+};
+
+BOOL
+closure(item_set *is, Grammar *g)
+{
+ NUM nonlen = list_length(is->nonkernels);
+
+ for (NUM i = 0; i < nonlen; i++) {
+ item it = *((item *)list_nth(is->nonkernels, i));
+ List *tnts = grammar_rule(g, it.r.nt_num, it.r.rule_num);
+ if (list_length(tnts) == 0) continue;
+
+ NUM *temp = MYALLOC(NUM, 1);
+ *temp = *((NUM *) list_nth(tnts, it.pos));
+
+ if (add_to_list(is->kernels, temp)) {
+ free(temp);
+ fleprintf("Fail to add to list at i = %ld\n", i);
+ return 1;
+ }
+ }
+
+ return 0;
+}