From 867f5c29ca2bb1c61797634942fa9f6023a79afe Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Tue, 4 Feb 2020 21:35:26 +0100 Subject: Add traversing --- grammer.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'grammer.cpp') 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 Compiler::traverse(lower, upper) +{ + std::map visited; // node, child + std::deque> 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 Compiler::GetPath(std::string upper, std::string lower) { std::vector result; + // traverse bnf from lower to upper + std::map visited {traverse(lower, upper)}; + while (lower != upper) { auto parents {ReverseBNF.find(lower)}; if (parents == ReverseBNF.end()) @@ -280,6 +310,9 @@ std::vector Compiler::GetPath(std::string upper, std::string lower) } } } + + if (!hit) + throw std::runtime_error("GetPath error!"); // ICE lower = new_lower; } return result; -- cgit v1.2.3