diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-01-19 18:52:23 +0100 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-01-19 18:52:23 +0100 | 
| commit | 4e6fe47af1964c3efe50d0e244331d0dd4df51fc (patch) | |
| tree | 0677caab24b06ff015185d3820afc2d34e8f184c | |
| parent | 5d3d2130e2c1c3793d17b12dc7bcc0ee06795b9e (diff) | |
Remove candidate handling
| -rw-r--r-- | minicc.cpp | 71 | 
1 files changed, 21 insertions, 50 deletions
| @@ -62,6 +62,13 @@ private:   index_t last{};  public: + void clear() { +  nodes.clear(); +  root = 0; +  last = 0; +  node_num = 0; + } +   bool Valid(const std::string& Top) const {    // A token is non empty    if (node_num == 0) @@ -298,38 +305,14 @@ private:   std::map<std::string, std::set<std::string>> ReverseBNF;   // to be called on token end - void FinalizeCandidates(std::deque<Tree>& candidates, std::string& token, std::vector<std::string>& result) + void FinalizeTree(Tree& tree, std::string& token, std::vector<std::string>& result)   { -  if (candidates.empty()) { // skip -   if (!token.empty()) -    throw std::runtime_error("Expected empty token, got "s + token); -  } else { // check candidates -   bool valid{false}; -   for (auto& ct : candidates) { -    ct.Resolve(bnf, ReverseBNF); -    if (ct.Valid(Top)) { -     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(); -  } - } - - void AddCandidate(char c, std::deque<Tree>& candidates) { -  // new candidate: starting with c -  auto element {ReverseBNF.find(std::string(1, c))}; -  if (element != ReverseBNF.end()) { -   Tree newTree; -   if (newTree.Add(c, bnf, ReverseBNF)) -    candidates.push_back(newTree); +  tree.Resolve(bnf, ReverseBNF); +  if (tree.Valid(Top)) { +   result.push_back(token); +   token.clear();    } +  tree.clear();   }  public: @@ -343,39 +326,27 @@ public:    std::string token;    std::string Whitespace{"\t \n\r"}; -  std::deque<Tree> candidates; +  Tree tree;    for (size_t pos{0}; pos < s.size(); pos++) {     char c{s[pos]};     std::cout << "Char: |" << c << "|" << std::endl;     if (Whitespace.find(c) != std::string::npos) { // found whitespace character      // evaluate token up to now and skip whitespace -    FinalizeCandidates(candidates, token, result); +    FinalizeTree(tree, token, result);     } else { // no whitespace: try to add to tree -    std::deque<index_t> EraseList; -    int i = 0; -    for (auto ct = candidates.begin(); ct != candidates.end(); ct++, i++) { -     if (!ct->Add(c, bnf, ReverseBNF)) { // either add char or delete candidate -      // push to front to get reversed order -      EraseList.push_front(i); // no candidate anymore -     } -    } -     -    if (token.empty()) { -     AddCandidate(c, candidates); -    } else if (candidates.size() - EraseList.size() > 0) { // added to some candidates: Erase invalidated ones -     for (const auto& i : EraseList) -      candidates.erase(candidates.begin() + i); -    } else { // no candidates left: new tree -     FinalizeCandidates(candidates, token, result); -     AddCandidate(c, candidates); +    if (!tree.Add(c, bnf, ReverseBNF)) { +     FinalizeTree(tree, token, result); +     if (!tree.Add(c, bnf, ReverseBNF)) +      throw std::runtime_error("Parse error");      } +      token.push_back(c);     }    }    // Final evaluation of last token -  FinalizeCandidates(candidates, token, result); +  FinalizeTree(tree, token, result);    return result;   } | 
