From 216cf0252fba55299b3e7f060c2c288b0be9ac03 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 8 Aug 2015 02:50:36 -0400 Subject: [PATCH] finished reducer and wrote shifter. Actually kinda recognizes now! Errors too, but comes up with correct result. --- include/ASTTransformation.h | 1 + src/ASTTransformation.cpp | 8 +++- stdlib/grammer.krak | 30 ++++++++---- stdlib/parser.krak | 91 ++++++++++++++++++++++++++++++++++++- stdlib/stack.krak | 3 ++ 5 files changed, 119 insertions(+), 14 deletions(-) diff --git a/include/ASTTransformation.h b/include/ASTTransformation.h index 1a6d70f..bda6ad0 100644 --- a/include/ASTTransformation.h +++ b/include/ASTTransformation.h @@ -76,6 +76,7 @@ class ASTTransformation: public NodeTransformation { NodeTree* builtin_trans_unit; // the top scope for language level stuff std::map*>> languageLevelReservedWords; std::map*>> languageLevelOperators; + std::map*, NodeTree*> this_map; // used to map implicit "this" variables to their type NodeTree* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated int lambdaID = 0; }; diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 55f7b3d..f0cd0bf 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -1371,14 +1371,18 @@ std::vector*> ASTTransformation::scopeLookup(NodeTree } NodeTree* ASTTransformation::generateThis(NodeTree* scope) { - NodeTree* identifier = languageLevelReservedWords["this"][0]; - identifier = new NodeTree("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* 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* identifier = languageLevelReservedWords["this"][0]; + identifier = new NodeTree("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; } diff --git a/stdlib/grammer.krak b/stdlib/grammer.krak index 0137ce4..161ad55 100644 --- a/stdlib/grammer.krak +++ b/stdlib/grammer.krak @@ -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 { + 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() }) }) } diff --git a/stdlib/parser.krak b/stdlib/parser.krak index 9d13d0d..e506c8f 100644 --- a/stdlib/parser.krak +++ b/stdlib/parser.krak @@ -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>() } 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>) { + println("in get_reachable_paths for_each loop") var path_edges = range(path.size-1).map(fun(indx: int): *tree { 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>() 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>()->construct(null_symbol()), + null>() )) + } else if (curr_reduction.length == 0) { + to_reduce.push(reduction(curr_reached, action_rule.lhs, action_rule.position, + new>()->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> >() + var new_label = new>()->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>()->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>()->construct(null_symbol()), + new_label )) + } else { + println("does reduce to null") + to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0, + new>()->construct(null_symbol()), + null>() )) + } + } + }) + } + } + to_shift = next_shifts + } + fun add_children(parent: *tree, children: vector<*tree>, nullable_parts: *tree) { } 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 { + if (frontier >= data.size) + return null>() for (var i = 0; i < data[frontier].size; i++;) if (data[frontier][i]->data == state) return data[frontier][i] diff --git a/stdlib/stack.krak b/stdlib/stack.krak index e4660f6..c3b7aff 100644 --- a/stdlib/stack.krak +++ b/stdlib/stack.krak @@ -43,4 +43,7 @@ obj stack (Object) { fun size(): int { return data.size } + fun empty():bool { + return data.size == 0 + } }