summaryrefslogtreecommitdiffhomepage
path: root/grammer.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-02-05 21:18:31 +0100
committerRoland Reichwein <mail@reichwein.it>2020-02-05 21:18:31 +0100
commitf1b23e34bee172e0c0ed8e65bcd7904baef9e857 (patch)
tree36eaccf3ac66c50bad7e583a098f0a931409ae4d /grammer.cpp
parent867f5c29ca2bb1c61797634942fa9f6023a79afe (diff)
Fix GetPath
Diffstat (limited to 'grammer.cpp')
-rw-r--r--grammer.cpp51
1 files 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<std::string, std::string> Compiler::traverse(lower, upper)
std::deque<std::pair<std::string, std::string>> 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<std::string> Compiler::GetPath(std::string upper, std::string lower) {
std::vector<std::string> result;
@@ -291,29 +295,13 @@ std::vector<std::string> Compiler::GetPath(std::string upper, std::string lower)
// traverse bnf from lower to upper
std::map<std::string, std::string> 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;