Use the new parser (now with reduction functions) for mal
This commit is contained in:
123
fungll.krak
123
fungll.krak
@@ -7,46 +7,57 @@ import str:*
|
||||
import regex:*
|
||||
|
||||
// nonterminals are negative, terminals are positive
|
||||
obj Grammer (Object) {
|
||||
obj Grammer<T> (Object) {
|
||||
var nonterminals: vec<vec<vec<int>>>
|
||||
var nonterminal_names: vec<str>
|
||||
var nonterminal_funs: vec<vec<fun(ref vec<T>): T>>
|
||||
var terminals: vec<regex>
|
||||
var terminal_funs: vec<fun(ref str,int,int): T>
|
||||
var start_symbol: int
|
||||
fun construct(): *Grammer {
|
||||
nonterminals.construct()
|
||||
nonterminal_names.construct()
|
||||
nonterminal_funs.construct()
|
||||
terminals.construct()
|
||||
terminal_funs.construct()
|
||||
start_symbol = 0
|
||||
return this
|
||||
}
|
||||
fun copy_construct(old: *Grammer): void {
|
||||
nonterminals.copy_construct(&old->nonterminals)
|
||||
nonterminal_names.copy_construct(&old->nonterminal_names)
|
||||
nonterminal_funs.copy_construct(&old->nonterminal_funs)
|
||||
terminals.copy_construct(&old->terminals)
|
||||
terminal_funs.copy_construct(&old->terminal_funs)
|
||||
start_symbol = old->start_symbol
|
||||
}
|
||||
fun destruct(): void {
|
||||
nonterminals.destruct()
|
||||
nonterminal_names.destruct()
|
||||
nonterminal_funs.destruct()
|
||||
terminals.destruct()
|
||||
terminal_funs.destruct()
|
||||
}
|
||||
fun operator=(other:ref Grammer):void {
|
||||
destruct()
|
||||
copy_construct(&other)
|
||||
}
|
||||
fun add_new_nonterminal(name: *char, rule: ref vec<int>): int {
|
||||
return add_new_nonterminal(str(name), rule)
|
||||
fun add_new_nonterminal(name: *char, rule: ref vec<int>, f: fun(ref vec<T>): T): int {
|
||||
return add_new_nonterminal(str(name), rule, f)
|
||||
}
|
||||
fun add_new_nonterminal(name: ref str, rule: ref vec<int>): int {
|
||||
fun add_new_nonterminal(name: ref str, rule: ref vec<int>, f: fun(ref vec<T>): T): int {
|
||||
nonterminals.add(vec(rule))
|
||||
nonterminal_names.add(name)
|
||||
nonterminal_funs.add(vec(f))
|
||||
return -1*nonterminals.size
|
||||
}
|
||||
fun add_to_nonterminal(nonterminal: int, rule: ref vec<int>) {
|
||||
fun add_to_nonterminal(nonterminal: int, rule: ref vec<int>, f: fun(ref vec<T>): T) {
|
||||
nonterminals[(-1*nonterminal)-1].add(rule)
|
||||
nonterminal_funs[(-1*nonterminal)-1].add(f)
|
||||
}
|
||||
fun add_terminal(c: *char): int {
|
||||
fun add_terminal(c: *char, f: fun(ref str,int,int): T): int {
|
||||
terminals.add(regex(c))
|
||||
terminal_funs.add(f)
|
||||
return terminals.size
|
||||
}
|
||||
fun get_nonterminal_rules(nonterminal: int): ref vec<vec<int>> {
|
||||
@@ -69,6 +80,9 @@ obj Grammer (Object) {
|
||||
}
|
||||
var erminal = nonterminals[(-1*it.nonterminal)-1][it.rule_idx][i]
|
||||
rule_str += to_string(erminal)
|
||||
if i < nonterminals[(-1*it.nonterminal)-1][it.rule_idx].size-1 {
|
||||
rule_str += " "
|
||||
}
|
||||
}
|
||||
if it.idx_into_rule == nonterminals[(-1*it.nonterminal)-1][it.rule_idx].size {
|
||||
rule_str += "*"
|
||||
@@ -82,6 +96,60 @@ obj Grammer (Object) {
|
||||
return terminals[erminal-1].regexString
|
||||
}
|
||||
}
|
||||
fun eval_BSR(input: ref str, BSR: ref set<BS>): T {
|
||||
var top = -1
|
||||
for (var i = 0; i < BSR.data.size; i++;) {
|
||||
if BSR.data[i].nonterminal == start_symbol && BSR.data[i].idx_into_rule == nonterminals[(-1*BSR.data[i].nonterminal)-1][BSR.data[i].rule_idx].size && BSR.data[i].left == 0 && BSR.data[i].right == input.length() {
|
||||
top = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if top == -1 {
|
||||
error("Could not find top")
|
||||
}
|
||||
return eval_BSR(input, BSR, top)
|
||||
}
|
||||
fun eval_BSR(input: ref str, BSR: ref set<BS>, c: int): T {
|
||||
var bs = BSR.data[c]
|
||||
var nonterminal = (-1*bs.nonterminal)-1
|
||||
if bs.idx_into_rule != nonterminals[nonterminal][bs.rule_idx].size {
|
||||
error("Evaluating BSR from not the end!")
|
||||
}
|
||||
var params = vec<T>()
|
||||
for (var i = bs.idx_into_rule-1; i >= 0; i--;) {
|
||||
var erminal = nonterminals[nonterminal][bs.rule_idx][i]
|
||||
if is_terminal(erminal) {
|
||||
var right_value = terminal_funs[erminal-1](input, bs.pivot, bs.right)
|
||||
params.add(right_value)
|
||||
} else {
|
||||
/*var right = find_comp(erminal, bs.pivot, bs.right)*/
|
||||
var right = -1
|
||||
var sub_nonterminal_idx = (-1*erminal)-1
|
||||
for (var j = 0; j < BSR.data.size; j++;) {
|
||||
if BSR.data[j].nonterminal == erminal && BSR.data[j].idx_into_rule == nonterminals[sub_nonterminal_idx][BSR.data[j].rule_idx].size && BSR.data[j].left == bs.pivot && BSR.data[j].right == bs.right {
|
||||
right = j
|
||||
break
|
||||
}
|
||||
}
|
||||
var right_value = eval_BSR(input, BSR, right)
|
||||
params.add(right_value)
|
||||
}
|
||||
// get the new left bs
|
||||
if i != 0 {
|
||||
/*var new_bs_idx = find_mid(bs.nonterminal, bs.rule_idx, i, bs.left, bs.pivot)*/
|
||||
var new_bs_idx = -1
|
||||
for (var j = 0; j < BSR.data.size; j++;) {
|
||||
if BSR.data[j].nonterminal == bs.nonterminal && BSR.data[j].rule_idx == bs.rule_idx && BSR.data[j].idx_into_rule == i && BSR.data[j].left == bs.left && BSR.data[j].right == bs.pivot {
|
||||
new_bs_idx = j
|
||||
break
|
||||
}
|
||||
}
|
||||
bs = BSR.data[new_bs_idx]
|
||||
}
|
||||
}
|
||||
var to_ret = nonterminal_funs[nonterminal][bs.rule_idx](params.reverse())
|
||||
return to_ret
|
||||
}
|
||||
}
|
||||
obj Pending (Object) {
|
||||
var nonterminal: int
|
||||
@@ -197,7 +265,7 @@ fun bs(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: in
|
||||
var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left, pivot, right): BS
|
||||
return to_ret
|
||||
}
|
||||
fun fungll(grammer: ref Grammer, input: ref str): set<BS> {
|
||||
fun fungll<T>(grammer: ref Grammer<T>, input: ref str): set<BS> {
|
||||
var R = descend(grammer, grammer.start_symbol, 0)
|
||||
var U = set<Descriptor>()
|
||||
var G = map<pair<int, int>, set<Pending>>()
|
||||
@@ -211,10 +279,10 @@ fun fungll(grammer: ref Grammer, input: ref str): set<BS> {
|
||||
var Gp = it.second
|
||||
var Pp = it.third
|
||||
|
||||
var U_with_d = U.union(set(d));
|
||||
var nextR = R.union(Rp) - U_with_d
|
||||
U.add(d)
|
||||
var nextR = R.union(Rp) - U
|
||||
R = nextR
|
||||
U = U_with_d
|
||||
|
||||
for (var i = 0; i < Gp.keys.size; i++;) {
|
||||
if G.contains_key(Gp.keys[i]) {
|
||||
G[Gp.keys[i]].add(Gp.values[i])
|
||||
@@ -233,13 +301,13 @@ fun fungll(grammer: ref Grammer, input: ref str): set<BS> {
|
||||
}
|
||||
return Y
|
||||
}
|
||||
fun descend(grammer: ref Grammer, symbol: int, l: int): set<Descriptor> {
|
||||
fun descend<T>(grammer: ref Grammer<T>, symbol: int, l: int): set<Descriptor> {
|
||||
var to_ret = set<Descriptor>()
|
||||
for (var rhs = 0; rhs < grammer.get_nonterminal_rules(symbol).size; rhs++;)
|
||||
to_ret.add(descriptor(symbol, rhs, 0, l, l))
|
||||
return to_ret
|
||||
}
|
||||
fun process(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
|
||||
fun process<T>(grammer: ref Grammer<T>, input: ref str, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
|
||||
// if at end / end is emptystr
|
||||
if descript.idx_into_rule == grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx].size {
|
||||
return process_e(grammer, descript, G, P)
|
||||
@@ -247,7 +315,7 @@ fun process(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref m
|
||||
return process_symbol(grammer, input, descript, G, P)
|
||||
}
|
||||
}
|
||||
fun process_e(grammer: ref Grammer, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
|
||||
fun process_e<T>(grammer: ref Grammer<T>, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
|
||||
var nonterminal: int
|
||||
var rule_idx: int
|
||||
var left: int
|
||||
@@ -264,7 +332,7 @@ fun process_e(grammer: ref Grammer, descript: Descriptor, G: ref map<pair<int, i
|
||||
}
|
||||
return make_triple(make_pair(R,Y), map<pair<int, int>, set<Pending>>(), map(make_pair(X,l), set(k)))
|
||||
}
|
||||
fun process_symbol(grammer: ref Grammer, input: ref str, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
|
||||
fun process_symbol<T>(grammer: ref Grammer<T>, input: ref str, descript: Descriptor, G: ref map<pair<int, int>, set<Pending>>, P: ref map<pair<int,int>, set<int>>): triple<pair<set<Descriptor>, set<BS>>, map<pair<int, int>, set<Pending>>, map<pair<int,int>, set<int>>> {
|
||||
var s = grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx][descript.idx_into_rule]
|
||||
var k = descript.pivot
|
||||
var R = P.get_with_default(make_pair(s,k), set<int>())
|
||||
@@ -277,7 +345,7 @@ fun process_symbol(grammer: ref Grammer, input: ref str, descript: Descriptor, G
|
||||
return make_triple(skip(k,pending(descript.nonterminal, descript.rule_idx, descript.idx_into_rule+1, descript.left), R), Gp, map<pair<int,int>, set<int>>())
|
||||
}
|
||||
}
|
||||
fun matc(grammer: ref Grammer, input: ref str, descript: Descriptor): pair<set<Descriptor>, set<BS>> {
|
||||
fun matc<T>(grammer: ref Grammer<T>, input: ref str, descript: Descriptor): pair<set<Descriptor>, set<BS>> {
|
||||
/*println("trying to match " + grammer.to_string(grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx][descript.idx_into_rule]))*/
|
||||
var match_length = grammer.match_terminal(grammer.get_nonterminal_rules(descript.nonterminal)[descript.rule_idx][descript.idx_into_rule], input, descript.pivot)
|
||||
if match_length > 0 {
|
||||
@@ -303,18 +371,31 @@ fun nmatch(k:int, K: ref set<Pending>, R: ref set<int>): pair<set<Descriptor>, s
|
||||
return make_pair(Rp,Y)
|
||||
}
|
||||
/*fun main(argc: int, argv: **char): int {*/
|
||||
/*var grammer.construct(): Grammer*/
|
||||
/*var one = grammer.add_terminal("12")*/
|
||||
/*var E = grammer.add_new_nonterminal("E", vec<int>())*/
|
||||
/*grammer.add_to_nonterminal(E, vec(one))*/
|
||||
/*grammer.add_to_nonterminal(E, vec(E,E,E))*/
|
||||
/*var grammer.construct(): Grammer<int>*/
|
||||
/*var Number = grammer.add_new_nonterminal("Number", vec(grammer.add_terminal("[0-9]+", fun(input: ref str, l: int, r: int): int { return string_to_num<int>(input.slice(l,r)); })), fun(i: ref vec<int>): int { return i[0]; })*/
|
||||
|
||||
/*var mult = grammer.add_terminal("\\*", fun(input: ref str, l: int, r: int): int { return 1; })*/
|
||||
/*var Factor = grammer.add_new_nonterminal("Factor", vec(Number), fun(i: ref vec<int>): int { return i[0]; })*/
|
||||
/*grammer.add_to_nonterminal(Factor, vec(Factor, mult, Number), fun(i: ref vec<int>): int { return i[0]*i[2]; })*/
|
||||
|
||||
/*var add = grammer.add_terminal("\\+", fun(input: ref str, l: int, r: int): int { return 1; })*/
|
||||
/*var Term = grammer.add_new_nonterminal("Term", vec(Factor), fun(i: ref vec<int>): int { return i[0]; })*/
|
||||
/*grammer.add_to_nonterminal(Term, vec(Term, add, Factor), fun(i: ref vec<int>): int { return i[0]+i[2]; })*/
|
||||
|
||||
/*grammer.set_start_symbol(Term)*/
|
||||
|
||||
/*var input = str("1+23*44")*/
|
||||
/*var BSR = fungll(grammer, input)*/
|
||||
|
||||
|
||||
/*var BSR = fungll(grammer, str("1212"))*/
|
||||
/*println(str("length of BSR is: ") + BSR.size())*/
|
||||
/*for (var i = 0; i < BSR.data.size; i++;) {*/
|
||||
/*var BS = BSR.data[i]*/
|
||||
/*println(str() + i + ": " + grammer.to_string(BSR.data[i]))*/
|
||||
/*}*/
|
||||
|
||||
/*var res = grammer.eval_BSR(input, BSR)*/
|
||||
/*println(str("result of grammer.eval_BSR(fungll(grammer, ") + input + ")) = " + res)*/
|
||||
|
||||
/*return 0*/
|
||||
/*}*/
|
||||
|
||||
Reference in New Issue
Block a user