From 39716aa1907e975f6e37adafe42d72d643223a98 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 17 Jan 2020 23:05:21 +0100 Subject: Separated out CheckCandidates --- minicc.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 26 deletions(-) (limited to 'minicc.cpp') diff --git a/minicc.cpp b/minicc.cpp index e9bc918..b609477 100644 --- a/minicc.cpp +++ b/minicc.cpp @@ -21,7 +21,7 @@ std::vector split(std::string s) std::vector result; boost::algorithm::split(result, s, boost::algorithm::is_any_of(s), boost::algorithm::token_compress_on); while (result.size() > 0 && result.back() == ""s) - result.pop_back(); + result.pop_back(); return result; } @@ -43,12 +43,43 @@ struct TreeNode { std::string name; }; -using Tree = std::map; +struct Tree { + std::map nodes; // index 0 = non existing; index starting at 1 + index_t node_num{}; + index_t root{}; + index_t last{}; -bool ValidTree(const Tree& tree) { - // Start symbol? - // All terminal symbols? - return true; // TODO + bool Valid() const { + // Start symbol? + // All terminal symbols? + return true; // TODO + } + + bool Add(char c) { + // TODO + //node_num ++; + //nodes.emplace(node_num, {}); + return false; + } + +}; + +void CheckCandidates(std::deque& candidates, std::string& token, std::vector& result) +{ + bool valid{false}; + for (const auto& ct : candidates) { + if (ct.Valid()) { + if (valid) + throw std::runtime_error("Found ambiguous token "s + token); + result.push_back(token); + token.clear(); + valid = true; + } + } + if (!valid) + throw std::runtime_error("Invalid token: "s + token); + + candidates.clear(); } std::vector Lex(std::string s, std::string Top, BNF bnf) @@ -68,38 +99,41 @@ std::vector Lex(std::string s, std::string Top, BNF bnf) if (!token.empty()) throw std::runtime_error("Expected empty token, got "s + token); } else { // check candidates - bool valid{false}; - for (const auto& ct : candidates) { - if (ValidTree(ct)) { - if (valid) - throw std::runtime_error("Found ambigous token"); - result.push_back(token); - token.clear(); - valid = true; - } - } - if (!valid) - throw std::runtime_error("Invalid token: "s + token); - - candidates.clear(); + CheckCandidates(candidates, token, result); } } else { // no whitespace: try to add to tree - for (auto& ct : candidates) { - EraseList; - if (!Add(ct, c)) { - EraseList.add(ct); // no candidate anymore + std::deque EraseList; + int i = 0; + for (auto ct = candidates.begin(); ct != candidates.end(); ct++, i++) { + if (!ct->Add(c)) { + EraseList.push_front(i); // no candidate anymore } } + // new candidate: starting with c + auto element {ReverseBNF.find(std::string(1, c))}; + if (element != ReverseBNF.end()) { + candidates.emplace_back(); + candidates.back().Add(c); + } if (candidates.size() - EraseList.size() > 0) { // Added to some candidates: Continue growing token token.push_back(c); - candidates.erase(EraseList); + for (const auto& i : EraseList) + candidates.erase(candidates.begin() + i); } else { // no candidates left: new tree - // TODO: same as above "check candidates" + CheckCandidates(candidates, token, result); } } } + // Final evaluation + if (candidates.empty()) { // skip + if (!token.empty()) + throw std::runtime_error("Expected empty token at end of input, got "s + token); + } else { // check candidates + CheckCandidates(candidates, token, result); + } + return result; } -- cgit v1.2.3