// 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 }