Fixed add_children to actually add children correctly and only do the ambiguity at the right time. Still have the looking in map with non-existant key problem, but it is actually parsing nicely.

This commit is contained in:
Nathan Braswell
2015-08-12 23:15:41 -04:00
parent 8321b35a03
commit 4b6693ac1c
8 changed files with 84 additions and 36 deletions

View File

@@ -47,7 +47,13 @@ obj map<T,U> (Object) {
return keys.contains(key)
}
fun get(key: T): ref U {
return values.get(keys.find(key))
/*return values.get(keys.find(key))*/
var key_loc = keys.find(key)
if (key_loc == -1) {
io::println("trying to access nonexistant key-value!")
/*while (true) {}*/
}
return values.get(key_loc)
}
fun remove(key: T) {
var idx = keys.find(key)

View File

@@ -158,8 +158,10 @@ obj parser (Object) {
// the shift lookup will fail, and likely other things, and this is our accept
// criteria anyway
/*if (curr_reached->data == 0 && curr_reduction.sym == gram.rules[0].lhs)*/
if (curr_reduction.sym == gram.rules[0].lhs)
if (curr_reduction.sym == gram.rules[0].lhs) {
println("would accept here")
return;
}
var shift_to = gram.parse_table.get_shift(curr_reached->data, curr_reduction.sym).state_or_rule
println("got shift to")
var new_label = null<tree<symbol>>()
@@ -264,12 +266,12 @@ obj parser (Object) {
var action_rule = gram.rules[action.state_or_rule]
if (!fully_reduces_to_null(action_rule)) {
println("does not reduce to null")
to_reduce.push(reduction(shift.first, action_rule.lhs, action.rule_position,
to_reduce.push(reduction(shift.first, action_rule.lhs, action.rule_position,
get_nullable_parts(action_rule),
new_label ))
} else {
println("does reduce to null")
to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0,
to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0,
get_nullable_parts(action_rule),
null<tree<symbol>>() ))
}
@@ -283,30 +285,39 @@ obj parser (Object) {
if (nullable_parts)
children.add(nullable_parts)
if (!belongs_to_family(parent, children)) {
parent->children.add_all(children)
} else {
if (!are_packed(parent->children)) {
// ambiguity inner
var sub_parent = new<tree<symbol>>()->construct(symbol("AmbiguityInner", true))
set_packed(sub_parent, true)
sub_parent->children.add_all(parent->children)
parent->children.clear()
parent->children.add(sub_parent)
if (parent->children.size == 0) {
parent->children.add_all(children)
} else {
if (!are_packed(parent->children)) {
// ambiguity inner
var sub_parent = new<tree<symbol>>()->construct(symbol("AmbiguityInner", true))
set_packed(sub_parent, true)
sub_parent->children.add_all(parent->children)
parent->children.clear()
parent->children.add(sub_parent)
}
// ambiguity outer
var next_sub_parent = new<tree<symbol>>()->construct(symbol("AmbiguityOuter", true))
set_packed(next_sub_parent, true)
parent->children.add(next_sub_parent)
next_sub_parent->children.add_all(children)
}
// ambiguity outer
var next_sub_parent = new<tree<symbol>>()->construct(symbol("AmbiguityOuter", true))
set_packed(next_sub_parent, true)
parent->children.add(next_sub_parent)
next_sub_parent->children.add_all(children)
}
}
fun belongs_to_family(node: *tree<symbol>, nodes: vector<*tree<symbol>>): bool {
var family_count = 0
node->children.for_each(fun(child: *tree<symbol>) {
if (nodes.contains(child))
family_count++
})
return family_count == nodes.size
for (var i = 0; i < nodes.size; i++;) {
var contains_one = false
for (var j = 0; j < node->children.size; j++;) {
var child = node->children[j]
if (nodes[i] == child || (nodes[i] && child && *nodes[i] == *child)) {
contains_one = true
break
}
}
if (!contains_one)
return false
}
return true
}
fun are_packed(nodes: vector<*tree<symbol>>): bool {
return nodes.any_true(fun(it: *tree<symbol>):bool { return packed_map.contains_key(it) && packed_map[it]; })
@@ -439,19 +450,27 @@ obj reduction (Object) {
fun syntax_tree_to_dot(root: *tree<symbol>): string {
var ret = string("digraph Kaken {\n")
var counter = 0
var node_name_map = map<*tree<symbol>, string>()
var get_name = fun(node: *tree<symbol>): string {
if (node_name_map.contains_key(node))
return node_name_map[node]
var escaped = string("")
node->data.to_string().data.for_each(fun(c: char) {
if (c != '"')
escaped += c
else
escaped += "\\\""
})
escaped += to_string(counter++)
node_name_map.set(node, escaped)
return escaped
}
var helper: fun(*tree<symbol>):void = fun(node: *tree<symbol>) {
/*ret += node->data.to_string() + ";;;;\n";*/
node->children.for_each(fun(child: *tree<symbol>) {
if (!child)
return; // where on earth does the null come from
var escaped_child = string("")
child->data.to_string().data.for_each(fun(c: char) {
if (c != '"')
escaped_child += c
else
escaped_child += "\\\""
})
ret += string("\"") + node->data.to_string() + "\" -> \"" + escaped_child + "\"\n";
ret += string("\"") + get_name(node) + "\" -> \"" + get_name(child) + "\"\n";
helper(child)
})
}

View File

@@ -2,6 +2,18 @@ import vector
import util
import mem
fun to_string(in: int): string {
var dest = mem::new<char>(mem::sizeof<int>() * 8)
defer mem::delete(dest)
__if_comp__ __C__ {
simple_passthrough(dest = dest, in = in::) """
sprintf(dest, "%d", in);
"""
}
var ret = string(dest)
return ret
}
fun string(in:*char):string {
var out.construct(in):string
return out

View File

@@ -20,6 +20,9 @@ obj tree<T> (Object) {
destruct()
copy_construct(&other)
}
fun operator==<U>(other: ref tree<U>):bool {
return data == other.data
}
fun destruct() {
mem::maybe_destruct(&data)
children.destruct()

View File

@@ -121,6 +121,7 @@ obj vector<T> (Object) {
println(index);
print("Max Index of vector: ");
println(size-1);
/*while(true) {}*/
return data[0];
}
return data[index];

View File

@@ -1,11 +1,12 @@
# comment
Goal = a ;
a = b | rec ;
a = b | rec "end" ;
b = "c":named_c ;
b = c "d":dname ;
c = "a" | d ;
d = e post_null post_non_null inherit_null ;
inherit_null = e | post_non_null ;
e = ;
e = f | ;
f = ;
post_null = "hi" ;

View File

@@ -52,11 +52,12 @@ fun main():int {
println(a.to_string())
a.calculate_state_automaton()
var parse.construct(a): parser
var result = parse.parse_input(string("inport a;"), string("fun name"))
var result = parse.parse_input(read_file(string("to_parse.krak")), string("fun name"))
/*var result = parse.parse_input(string("inport a;"), string("fun name"))*/
/*var result = parse.parse_input(string("fun main():int { return 0; }"), string("fun name"))*/
/*var result = parse.parse_input(string("ad"), string("fun name"))*/
/*var result = parse.parse_input(string("hibyed"), string("fun name"))*/
/*var result = parse.parse_input(string("hmmhmm"), string("fun name"))*/
/*var result = parse.parse_input(string("hmmhmmend"), string("fun name"))*/
/*var result = parse.parse_input(string("hid"), string("fun name"))*/
println("the tree")
println(syntax_tree_to_dot(result))

5
tests/to_parse.krak Normal file
View File

@@ -0,0 +1,5 @@
fun main(): int {
return 0
}