summaryrefslogtreecommitdiffhomepage
path: root/minicc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'minicc.cpp')
-rw-r--r--minicc.cpp86
1 files changed, 60 insertions, 26 deletions
diff --git a/minicc.cpp b/minicc.cpp
index e9bc918..b609477 100644
--- a/minicc.cpp
+++ b/minicc.cpp
@@ -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;
}