diff options
author | Roland Reichwein <mail@reichwein.it> | 2020-02-09 15:34:46 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2020-02-09 15:34:46 +0100 |
commit | ff0c8036659ea31f60b6b3523b8e4e044a70ecf4 (patch) | |
tree | 602a97a7ad52964eec478e3dcc4919b38330fcf8 | |
parent | 047a1ae14c75ce08ca04e67452eaebf89a1076d9 (diff) |
Bugfixing
-rw-r--r-- | grammer.cpp | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/grammer.cpp b/grammer.cpp index 4118733..186a4bd 100644 --- a/grammer.cpp +++ b/grammer.cpp @@ -264,12 +264,13 @@ void Compiler::TrackBack() ChangeNodeType(); } -// return shortest path with variants +// GetPath() + traverse(): return shortest path with variants // via first-entry-in-bnf-rule // excluding lower (already exists) // including upper (already determined to be included) // breadth-first search +// return: node, child std::map<std::string, std::string> Compiler::traverse(lower, upper) { std::map<std::string, std::string> visited; // node, child @@ -279,7 +280,8 @@ std::map<std::string, std::string> Compiler::traverse(lower, upper) auto& [current_node, current_child] = todo.front(); todo.pop_front(); - if (!visited[current_node]) { + auto it {visited.find(current_node)}; + if (it == visited.end()) { // not visited, yet: visit now auto parents_it {reverseBNF.find(current_node)}; if (parents_it != reverseBNF.end()) { @@ -295,7 +297,7 @@ std::map<std::string, std::string> Compiler::traverse(lower, upper) return visited; } -// returns list from lower (excluding) to upper (including) +// returns list from upper (including) to lower (excluding) // returns empty list on fail std::vector<std::string> Compiler::GetPath(std::string upper, std::string lower) { @@ -306,16 +308,20 @@ std::vector<std::string> Compiler::GetPath(std::string upper, std::string lower) auto current {upper}; while (current != lower) { - auto& child = visited[current]; + auto it {visited.find(current)}; + if (it != visited.end()) { + auto& child{it->second}; - result.push_back(current); + result.push_back(current); - current = child; + current = child; + } else + return {}; } return result; } -index_t Compiler::AddNode(const std::string& name, const std::string& child_type, index_t parent_index) +index_t Compiler::AddNode(const std::string& child_type, index_t parent_index) { TreeNode& parent {nodes[parent_index]}; index_t index = nodes.size(); @@ -325,9 +331,16 @@ index_t Compiler::AddNode(const std::string& name, const std::string& child_type std::deque<std::string> alternatives; const auto& lists { bnf[parent.type] }; + bool found{false}; for (int i = 0; i < lists.size(); i++) { // variants - if (lists[i].size() > 0 && lists[i][0] == child_type) - variant = i; + if (lists[i].size() > 0 && lists[i][0] == child_type) { + if (!found) { // use first match + variant = i; + found = true; + } else { // defer all others + alternatives.emplace_back(child_type, i); + } + } } nodes.emplace_back({parent_index, index, child_type, variant, alternatives, {}}); @@ -338,9 +351,8 @@ index_t Compiler::AddNode(const std::string& name, const std::string& child_type void Compiler::AddPath(const std::vector<std::string>& path, index_t current_index) { - for (int i = path.size() - 1; i > 0; i--) { - std::string child_name = path[i - 1]; - current_index = AddNode(path[i], child_name, current_index); + for (const std::string& child_type: path) { + current_index = AddNode(child_type, current_index); } nodes.back().child_ids.emplace_back(ChildIdFromTokenId(tokens_used)); @@ -352,18 +364,18 @@ bool Compiler::FillTree() if (nodes.size() == 0) // ignore empty tree, successfully return true; - index_t to_fill; + index_t to_fill{}; while (!subTreeIsComplete(root_node_id, to_fill)) { 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; } else { return false; } } + return true; } Compiler::Compiler(const BNF& bnf, const std::string& Top): bnf(bnf), Top(Top), ReverseBNF{Reverse(bnf)} |