diff options
Diffstat (limited to 'src/gll.c')
-rw-r--r-- | src/gll.c | 68 |
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; +} |