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)} | 
