finished reducer and wrote shifter. Actually kinda recognizes now! Errors too, but comes up with correct result.

This commit is contained in:
Nathan Braswell
2015-08-08 02:50:36 -04:00
parent 674e7e6538
commit 216cf0252f
5 changed files with 119 additions and 14 deletions

View File

@@ -76,6 +76,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
NodeTree<ASTData>* builtin_trans_unit; // the top scope for language level stuff
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelReservedWords;
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelOperators;
std::map<NodeTree<ASTData>*, NodeTree<ASTData>*> this_map; // used to map implicit "this" variables to their type
NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated
int lambdaID = 0;
};

View File

@@ -1371,14 +1371,18 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
}
NodeTree<ASTData>* ASTTransformation::generateThis(NodeTree<ASTData>* scope) {
NodeTree<ASTData>* identifier = languageLevelReservedWords["this"][0];
identifier = new NodeTree<ASTData>("identifier", identifier->getData());
// if we're looking for this, traverse up until we find the declaration of this object and assign it's type to this
NodeTree<ASTData>* trans;
for (trans = scope; trans->getDataRef()->type != type_def; trans = trans->getDataRef()->scope["~enclosing_scope"][0]);
auto possible_this = this_map.find(trans); // check to see if we've generated this this before
if (possible_this != this_map.end())
return possible_this->second;
NodeTree<ASTData>* identifier = languageLevelReservedWords["this"][0];
identifier = new NodeTree<ASTData>("identifier", identifier->getData());
identifier->getDataRef()->valueType = trans->getDataRef()->valueType->clone();
identifier->getDataRef()->valueType->increaseIndirection();
identifier->getDataRef()->scope = trans->getDataRef()->scope;
this_map[trans] = identifier;
return identifier;
}

View File

@@ -452,6 +452,18 @@ obj action {
fun operator==(other: action): bool {
return act == other.act && state_or_rule == other.state_or_rule
}
fun print() {
if (act == push)
io::print("push ")
else if (act == reduce)
io::print("reduce ")
else if (act == accept)
io::print("accept ")
else if (act == reject)
io::print("reject ")
io::print(state_or_rule)
io::println()
}
}
obj table (Object) {
@@ -514,8 +526,15 @@ obj table (Object) {
if (actions[i].act == push)
return actions[i]
io::println("tried to get a shift when none existed")
io::print("for state ")
io::print(state)
io::print(" and symbol ")
io::println(on_symbol.to_string())
return action(-1,-1)
}
fun get_reduces(state: int, on_symbol: symbol::symbol): vector::vector<action> {
return get(state, on_symbol).filter(fun(act: action):bool { return act.act == reduce; })
}
fun print_string() {
/*return string::string("woo a table of size: ") + items.size*/
io::print("woo a table of size: ")
@@ -528,16 +547,7 @@ obj table (Object) {
io::print("\ton symbol: ")
io::print(sym.to_string())
io::print(" do action: ")
if (action.act == push)
io::print("push ")
else if (action.act == reduce)
io::print("reduce ")
else if (action.act == accept)
io::print("accept ")
else if (action.act == reject)
io::print("reject ")
io::print(action.state_or_rule)
io::println()
action.print()
})
})
}

View File

@@ -77,6 +77,7 @@ obj parser (Object) {
/*println(current_symbol.to_string())*/
input.addEnd(current_symbol)
}
input.addEnd(current_symbol)
if (current_symbol == invalid_symbol()) {
println("lexing failed for ")
println(name)
@@ -91,7 +92,8 @@ obj parser (Object) {
/*println("looking up")*/
/*println(input[0].to_string())*/
gram.parse_table.get(0, input[0]).for_each(fun(act: action) {
/*println("for each action")*/
println("for each action")
act.print()
if (act.act == push)
to_shift.push(make_pair(v0, act.state_or_rule))
else if (act.act == reduce && fully_reduces_to_null(gram.rules[act.state_or_rule]))
@@ -102,7 +104,7 @@ obj parser (Object) {
for (var i = 0; i < input.size; i++;) {
if (gss.frontier_is_empty(i)) {
print(i)
print(" frontier is empty in file '")
print("th frontier is empty in file '")
print(name)
print("' with txt ")
print(input[i].to_string())
@@ -110,6 +112,10 @@ obj parser (Object) {
return null<tree<symbol>>()
}
SPPFStepNodes.clear()
print("to_reduce size: ")
println(to_reduce.size())
print("to_shift size: ")
println(to_shift.size())
while (to_reduce.size())
reducer(i)
shifter(i)
@@ -130,11 +136,14 @@ obj parser (Object) {
var curr_reduction = to_reduce.pop()
gss.get_reachable_paths(curr_reduction.from, max(0, curr_reduction.length-1)).
for_each(fun(path: ref vector<*tree<int>>) {
println("in get_reachable_paths for_each loop")
var path_edges = range(path.size-1).map(fun(indx: int): *tree<symbol> { return gss.get_edge(path[indx], path[indx+1]);}).reverse()
println("got path edges")
if (curr_reduction.length != 0)
path_edges.addEnd(curr_reduction.label)
var curr_reached = path.last()
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>>()
if (curr_reduction.length == 0) {
new_label = curr_reduction.nullable_parts
@@ -172,10 +181,86 @@ obj parser (Object) {
shift_to_node = gss.new_node(shift_to)
gss.add_to_frontier(i, shift_to_node)
gss.add_edge(shift_to_node, curr_reached, new_label)
gram.parse_table.get(shift_to, input[i]).for_each(fun(act: action) {
if (act.act == push) {
to_shift.push(make_pair(shift_to_node, act.state_or_rule))
} else {
var action_rule = gram.rules[act.state_or_rule]
if (fully_reduces_to_null(action_rule)) {
to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0,
new<tree<symbol>>()->construct(null_symbol()),
null<tree<symbol>>() ))
} else if (curr_reduction.length == 0) {
to_reduce.push(reduction(curr_reached, action_rule.lhs, action_rule.position,
new<tree<symbol>>()->construct(null_symbol()),
new_label ))
}
}
})
}
if (curr_reduction.length)
add_children(new_label, path_edges, curr_reduction.nullable_parts)
})
}
fun shifter(i: int) {
println("shifting")
if (i == input.size)
return; // darn ambiguity
print("shifting on ")
println(input[i].to_string())
var next_shifts = stack< pair<*tree<int>, int> >()
var new_label = new<tree<symbol>>()->construct(input[i])
while (!to_shift.empty()) {
println("to_shift not empty")
var shift = to_shift.pop()
println("post pop")
var shift_to_node = gss.in_frontier(i+1, shift.second)
println("post in_frontier")
if (shift_to_node) {
print("already in frontier ")
println(i+1)
gram.parse_table.get_reduces(shift.second, input[i+1]).for_each(fun(action: action) {
var reduce_rule = gram.rules[action.state_or_rule]
if (!fully_reduces_to_null(reduce_rule)) {
to_reduce.push(reduction(shift.first, reduce_rule.lhs, reduce_rule.position,
new<tree<symbol>>()->construct(null_symbol()),
new_label ))
}
})
} else {
print("adding to frontier ")
println(i+1)
shift_to_node = gss.new_node(shift.second)
gss.add_to_frontier(i+1, shift_to_node)
println("post add to frontier")
gss.add_edge(shift_to_node, shift.first, new_label)
println("post add edger")
gram.parse_table.get(shift.second, input[i+1]).for_each(fun(action: action) {
println("looking at an action")
if (action.act == push) {
println("is push")
next_shifts.push(make_pair(shift_to_node, action.state_or_rule))
} else {
println("is reduce")
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,
new<tree<symbol>>()->construct(null_symbol()),
new_label ))
} else {
println("does reduce to null")
to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0,
new<tree<symbol>>()->construct(null_symbol()),
null<tree<symbol>>() ))
}
}
})
}
}
to_shift = next_shifts
}
fun add_children(parent: *tree<symbol>, children: vector<*tree<symbol>>, nullable_parts: *tree<symbol>) {
}
fun fully_reduces_to_null(r: ref rule): bool {
@@ -219,6 +304,8 @@ obj gss (Object) {
return in_frontier(frontier, 1)
}
fun in_frontier(frontier: int, state: int): *tree<int> {
if (frontier >= data.size)
return null<tree<int>>()
for (var i = 0; i < data[frontier].size; i++;)
if (data[frontier][i]->data == state)
return data[frontier][i]

View File

@@ -43,4 +43,7 @@ obj stack<T> (Object) {
fun size(): int {
return data.size
}
fun empty():bool {
return data.size == 0
}
}