import vec:* import vec_literals:* import map:* import set:* import util:* import str:* // 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 to_string(): str { return str() + nonterminal + " " + rule_idx + " " + idx_into_rule + " " + left + " " + pivot + " " + right } } 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, vec>(), set(), set()) } fun descend(grammer: ref Grammer, symbol: int, l: int): set { /*grammer.get_nonterminal_rules(symbol).map(fun(rhs): descriptor { })*/ return grammer.get_nonterminal_rules(symbol).map(fun(rhs: int): Descriptor { return descriptor(symbol, rhs, 0, l, l); }) } fun loop(grammer: ref Grammer, input: ref str, R: set, U: set, G: map, vec>, P: map, set>, 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 it = process(grammer, input, d, G, P) var Rp = it.first.first var Yp = it.first.second var Gp = it.second var Pp = it.third 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: map, vec>, P: map, set>): triple, set>, map, Pending>, map, set>> { /*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: ref map, vec>, P: ref map, set>): triple, set>, map, Pending>, map, set>> { 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(make_pair(X,l)) /*var = ascend(l,K,k)*/ var it = ascend(l,K,k) var R = it.first var Y = it.second /*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 make_triple(make_pair(R,Y), map, Pending>(), map(make_pair(X,l), 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: ref map, vec>, P: ref map, set>): triple, set>, map, Pending>, map, set>> { 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(make_pair(s,k)) /*G' = {<, >}*/ var Gp = map(make_pair(s,k), pending(descript.nonterminal, descript.rule_idx, descript.idx_into_rule, descript.left)) if grammer.is_terminal(s) { /*return ),set(),set()>*/ /*return make_triple(match(input,descript), map, vec>(), map, set>())*/ return make_triple(matc(input,descript), map, vec>(), map, set>()) } else if R.size() == 0 { // s in N /*return <, G', set()>*/ return make_triple(make_pair(descend(grammer,s,k), set()), Gp, map, set>()) } else { // s in N and R != set() /*return R), G', set()>*/ return make_triple(skip(k,pending(descript.nonterminal, descript.rule_idx, descript.idx_into_rule, descript.left), R), Gp, map, set>()) } } /*fun match(input: ref str, ): > {*/ fun matc(input: ref str, descript: Descriptor): pair, set> { /*if input[k] == grammer.get_terminal(s) {*/ if input[descript.piviot] == grammer.get_terminal(s) { /*return ), set(*/ return make_pair(set(descriptor(descript.nonterminal, descript.rule_idx, descript.idx_into_rule+1, descript.left, descript.pivot+1)), set(bs(descript.nonterminal, descript.rule_idx, descript.idx_into_rule+1, descript.left, descript.pivot, descript.pivot+1))) } else { return make_pair(set(), set()) } } fun skip(k: int, c: Pending, R: ref set): pair, set> { return nmatch(k, set(c), R); } fun ascend(k:int, K: ref set, r: int): pair, set> { return nmatch(k, K, set(r)); } fun nmatch(k:int, K: ref set, R: ref set): pair, set> { /*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 (var i = 0; i < K.data.size; i++;) { var pending = K.data[i] /*for r in R {*/ for (var j = 0; j < R.data.size; j++;) { var r = R.data[j] 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 make_pair(R,Y) } fun main(argc: int, argv: **char): int { var grammer.construct(): Grammer /*add_new_nonterminal(rule: ref vec): int {*/ /*add_to_nonterminal(nonterminal: int, rule: ref vec) {*/ /*add_terminal(c: char): int {*/ /*fungll(grammer: ref Grammer, input: ref str): set {*/ var one = grammer.add_terminal('1') var E = grammer.add_new_nonterminal(vec()) grammer.add_to_nonterminal(E, vec(one)) grammer.add_to_nonterminal(E, vec(E,E,E)) var BSR = fungll(grammer, str("1")) for (var i = 0; i < BSR.data.size; i++;) { var BS = BSR.data[i] println(str() + i + ": " + BSR.data[i].to_string()) } return 0 }