diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-02-04 21:35:26 +0100 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-02-04 21:35:26 +0100 | 
| commit | 867f5c29ca2bb1c61797634942fa9f6023a79afe (patch) | |
| tree | 1533e5f799a5356ef80357e1c38408c7c2e2691c | |
| parent | 7b3c48e4b0fed9369f8d62854eb6e2453888fe75 (diff) | |
Add traversing
| -rw-r--r-- | grammer.cpp | 33 | 
1 files changed, 33 insertions, 0 deletions
| diff --git a/grammer.cpp b/grammer.cpp index 07e527f..f7a370f 100644 --- a/grammer.cpp +++ b/grammer.cpp @@ -256,11 +256,41 @@ void Compiler::TrackBack()   ChangeNodeType();  } +// 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 +std::map<std::string, std::string> Compiler::traverse(lower, upper) +{ + std::map<std::string, std::string> visited; // node, child + std::deque<std::pair<std::string, std::string>> todo{{lower, ""}}; // node, child +  + while (!todo.empty()) { +  current = 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);}); +  } + } +  + return visited; +} +  // returns list from lower (including) to upper (excluding)  // returns empty list on fail  std::vector<std::string> Compiler::GetPath(std::string upper, std::string lower) {   std::vector<std::string> result; + // 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()) @@ -280,6 +310,9 @@ std::vector<std::string> Compiler::GetPath(std::string upper, std::string lower)      }     }    } + +  if (!hit) +   throw std::runtime_error("GetPath error!"); // ICE    lower = new_lower;   }   return result; | 
