diff --git a/fungll.krak b/fungll.krak new file mode 100644 index 0000000..9f9926e --- /dev/null +++ b/fungll.krak @@ -0,0 +1,240 @@ +// nonterminals are negative, terminals are positive +obj Grammer (Object) { + var nonterminals: vec> + var terminals: vec + fun construct(): *Grammer { + nonterminals.construct() + terminals.construct() + return this + } + fun copy_construct(old: *Grammer): void { + nonterminals.copy_construct(&old->nonterminals) + terminals.copy_construct(&old->terminals) + } + fun destruct(): void { + nonterminals.destruct() + terminals.destruct() + } + fun operator=(other:ref Grammer):void { + destruct() + copy_construct(&other) + } + fun add_new_nonterminal(rule: ref vec): int { + nonterminals.add(vec(rule)) + return -1*nonterminal.size + } + fun add_to_nonterminal(nonterminal: int, rule: ref vec) { + nonterminals[(-1*nonterminal)-1].add(rule) + } + fun add_terminal(c: char): int { + terminals.add(rule) + return terminals.size + } + fun get_nonterminal_rules(nonterminal: int): ref vec { + return nonterminals[(-1*nonterminal)-1] + } + fun get_terminal(terminal: int): char { + return terminals[terminal-1] + } +} +obj Pending (Object) { + var nonterminal: int + var rule_idx: int + var idx_into_rule: int + var left: int + fun construct(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int): *Pending { + this->nonterminal = nonterminal; + this->rule_idx = rule_idx; + this->idx_into_rule = idx_into_rule; + this->left = left; + return this + } + fun copy_construct(old: *Pending): void { + this->nonterminal = old->nonterminal; + this->rule_idx = old->rule_idx; + this->idx_into_rule = old->idx_into_rule; + this->left = old->left; + } + fun destruct(): void { } + fun operator=(other:ref Pending):void { + destruct() + copy_construct(&other) + } +} +fun pending(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int): Pending { + var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left): Pending + return to_ret +} +obj Descriptor (Object) { + var nonterminal: int + var rule_idx: int + var idx_into_rule: int + var left: int + var pivot: int + fun construct(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: int): *Descriptor { + this->nonterminal = nonterminal; + this->rule_idx = rule_idx; + this->idx_into_rule = idx_into_rule; + this->left = left; + this->pivot = pivot; + return this + } + fun copy_construct(old: *Descriptor): void { + this->nonterminal = old->nonterminal; + this->rule_idx = old->rule_idx; + this->idx_into_rule = old->idx_into_rule; + this->left = old->left; + this->pivot = old->pivot; + } + fun destruct(): void { } + fun operator=(other:ref Descriptor):void { + destruct() + copy_construct(&other) + } +} +fun descriptor(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: int): Descriptor { + var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left, pivot): Descriptor + return to_ret +} +obj BS (Object) { + var nonterminal: int + var rule_idx: int + var idx_into_rule: int + var left: int + var pivot: int + var right: int + fun construct(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: int, right: int): *BS { + this->nonterminal = nonterminal; + this->rule_idx = rule_idx; + this->idx_into_rule = idx_into_rule; + this->left = left; + this->pivot = pivot; + this->right = right; + return this + } + fun copy_construct(old: *BS): void { + this->nonterminal = old->nonterminal; + this->rule_idx = old->rule_idx; + this->idx_into_rule = old->idx_into_rule; + this->left = old->left; + this->pivot = old->pivot; + this->right = old->right; + } + fun destruct(): void { } + fun operator=(other:ref BS):void { + destruct() + copy_construct(&other) + } +} +fun bs(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: int, right: int): BS { + var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left, pivot, right): BS + return to_ret +} +/*fun complete_parser_for(grammer: ref Grammer, start_symbol, input: ref str): set {*/ + /*return fungll(grammer, input, start_symbol).second*/ +/*}*/ +/*fun fungll(grammer: ref Grammer, input: ref str, start_symbol: int): set {*/ +/*fun fungll(grammer: ref Grammer, input: ref str): <, set> {*/ +fun fungll(grammer: ref Grammer, input: ref str): set { + /*loop(grammer, input, decend(grammer, 0 [>start_symbol<], 0), set(), set(), set(), set())*/ + loop(grammer, input, decend(grammer, 0 /*start_symbol*/, 0), set(), map(), set(), set()) +} +fun descend(grammer: ref Grammer, symbol: int, l: int): set { + /*grammer.get_nonterminal_rules(symbol).map(fun(rhs): descriptor { })*/ + grammer.get_nonterminal_rules(symbol).map(fun(rhs): Descriptor { return descriptor(symbol, rhs, 0, l, l); }) +} +fun loop(grammer: ref Grammer, input: ref str, R: set, U: set, G, P, Y: set): set { + /*if R.size() == 0 {*/ + /*return */ + /*} else {*/ + /*var d = R.pop()*/ + /*var <,G',P'> = process(grammer, input, d, G, P)*/ + /*var U_with_d = U.union(set(d));*/ + /*var R'' = (R.union(R') - U_with_d*/ + /*return loop(grammer, input, R'', U_with_d, G.union(G'), P.union(P'), Y.union(Y'))*/ + /*}*/ + while R.size() != 0 { + var d = R.pop() + var <,Gp,Pp> = process(grammer, input, d, G, P) + var U_with_d = U.union(set(d)); + var nextR = (R.union(Rp) - U_with_d + R = nextR + U = U_with_d + G += Gp + P += Pp + Y += Yp + } + return Y +} +/*fun process(grammer: ref Grammer, input: ref str, , G, P): {*/ +fun process(grammer: ref Grammer, input: ref str, discript: Descriptor, G, P): { + /*if is_e(b) {*/ + if descript.idx_into_rule == grammer.get_nonterminal_rules(discript.nonterminal)[descript.rule_idx].size { + /*return process_e(, G, P)*/ + return process_e(descript, G, P) + } else { + /*return process_symbol(grammer, input, , G, P) // b=sb'*/ + return process_symbol(grammer, input, descript, G, P) + } +} +/*fun process_e(, G, P) {*/ +fun process_e(descript: Descriptor, G, P) { + var nonterminal: int + var rule_idx: int + var left: int + var pivot: int + var X = descript.nonterminal + var l = descript.left; + /*var K = { | <,> in G }*/ + var K = G.get() + var = ascend(l,K,k) + /*var Y' = { | is_e(a) }*/ + if grammer.get_nonterminal_rules(X)[descript.rule_idx].size == 0 { + Y.add(bs(X,descript.rule_idx, 0, l, l, l)) + } + /*return <,set(),set(<,k>)>*/ + return <,set(),set(<,k>)> +} +/*fun process_symbol(grammer: ref Grammer, input: ref str, , G, P) {*/ +fun process_symbol(grammer: ref Grammer, input: ref str, descript: Descriptor, G, P) { + var s = grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx][descript.idx_into_rule] + var k = descript.pivot + /*R = { r | <,r> in P }*/ + R = P.get() + /*G' = {<, >}*/ + Gp = map(, pending(descript.nonterminal, descript.rule_idx, descript.idx_into_rule, descript.left) + if grammer.is_terminal(s) { + /*return ),set(),set()>*/ + return + } else if R.size() == 0 { // s in N + /*return <, G', set()>*/ + return <, Gp, set()> + } else { // s in N and R != set() + /*return R), G', set()>*/ + return + } +} +/*fun match(input: ref str, ): > {*/ +fun match(input: ref str, descript: Descriptor): > { + if input[k] == grammer.get_terminal(s) { + /*return ), set(*/ + return + } else { + return + } +} +fun skip(k:int,c,R) { return nmatch(k, set(c), R); } +fun ascend(k:int, K, r) { return nmatch(k,K,set(r)); } +fun nmatch(k:int, K, R) { + /*var R = { | in K, r in R }*/ + /*var Y = { | in K, r in R }*/ + var R = set() + var Y = set() + for pending in K { + for r in R { + R.push(descriptor(pending.nonterminal, pending.rule_idx, pending.idx_into_rule, pending.left, r) + Y.push(bs(pending.nonterminal, pending.rule_idx, pending.idx_into_rule, pending.left, k, r) + } + } + return +}