diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-01-17 23:05:21 +0100 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-01-17 23:05:21 +0100 | 
| commit | 39716aa1907e975f6e37adafe42d72d643223a98 (patch) | |
| tree | 98222599ce7d605872ff5f047703c4e8c06668f0 | |
| parent | 5e00d651f172f43917f381edef95c001ed97c904 (diff) | |
Separated out CheckCandidates
| -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;  } | 
