From f1b23e34bee172e0c0ed8e65bcd7904baef9e857 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 5 Feb 2020 21:18:31 +0100 Subject: Fix GetPath --- grammer.cpp | 51 ++++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/grammer.cpp b/grammer.cpp index f7a370f..4bdf8f4 100644 --- a/grammer.cpp +++ b/grammer.cpp @@ -268,22 +268,26 @@ std::map Compiler::traverse(lower, upper) std::deque> todo{{lower, ""}}; // node, child while (!todo.empty()) { - current = todo.front(); + auto& [current_node, current_child] = todo.front(); todo.pop_front(); - if (!visited[current.first]) { - parents = reverseBNF[current.first]; - - visited[current.first] = current.second; - - std::for_each(parents.begin(), parents.end(), [&](const auto&x) {todo.emplace_back(x, current.first);}); + if (!visited[current_node]) { + auto parents_it {reverseBNF.find(current_node)}; + + if (parents_it != reverseBNF.end()) { + auto& parents {parents_it->second}; + + visited[current_node] = current_child; + + std::for_each(parents.begin(), parents.end(), [&](const auto&x) {todo.emplace_back(x, current_node);}); + } } } return visited; } -// returns list from lower (including) to upper (excluding) +// returns list from lower (excluding) to upper (including) // returns empty list on fail std::vector Compiler::GetPath(std::string upper, std::string lower) { std::vector result; @@ -291,29 +295,13 @@ std::vector Compiler::GetPath(std::string upper, std::string lower) // traverse bnf from lower to upper std::map visited {traverse(lower, upper)}; - while (lower != upper) { - auto parents {ReverseBNF.find(lower)}; - if (parents == ReverseBNF.end()) - return {}; - - std::string new_lower; - bool hit{false}; - for (const auto& parent : parents->second) { - for (const auto& list : bnf.at(parent)) { - if (list.size() > 0 && list[0] == lower) { - if (!hit) { - result.push_back(lower); - new_lower = parent; - hit = true; - } else - throw std::runtime_error("Double match for "s + lower + ": "s + parent + ", "s + new_lower); // TODO: also get alternatives at each step - } - } - } + auto current {upper}; + while (current != lower) { + auto& child = visited[current]; + + result.push_back(current); - if (!hit) - throw std::runtime_error("GetPath error!"); // ICE - lower = new_lower; + current = child; } return result; } @@ -357,7 +345,8 @@ bool Compiler::FillTree() index_t to_fill; while (!subTreeIsComplete(root_node_id, to_fill)) { - auto list = GetPath(nodes[to_fill].type, tokens[tokens_used]); + auto& node {nodes[to_fill]}; + auto list = GetPath(bnf[node.type][node.variant][node.child_ids.size()], tokens[tokens_used]); if (list.size() > 0) { AddPath(list, to_fill); return true; -- cgit v1.2.3