diff options
-rw-r--r-- | minicc.cpp | 86 |
1 files changed, 60 insertions, 26 deletions
@@ -21,7 +21,7 @@ std::vector<std::string> split(std::string s) std::vector<std::string> 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<index_t, TreeNode>; +struct Tree { + std::map<index_t, TreeNode> 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<Tree>& candidates, std::string& token, std::vector<std::string>& 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<std::string> Lex(std::string s, std::string Top, BNF bnf) @@ -68,38 +99,41 @@ std::vector<std::string> 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<index_t> 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; } |