summaryrefslogtreecommitdiffhomepage
path: root/grammer.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-02-09 15:34:46 +0100
committerRoland Reichwein <mail@reichwein.it>2020-02-09 15:34:46 +0100
commitff0c8036659ea31f60b6b3523b8e4e044a70ecf4 (patch)
tree602a97a7ad52964eec478e3dcc4919b38330fcf8 /grammer.cpp
parent047a1ae14c75ce08ca04e67452eaebf89a1076d9 (diff)
Bugfixing
Diffstat (limited to 'grammer.cpp')
-rw-r--r--grammer.cpp40
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)}