summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--grammer.cpp32
1 files changed, 23 insertions, 9 deletions
diff --git a/grammer.cpp b/grammer.cpp
index 896a928..dc65876 100644
--- a/grammer.cpp
+++ b/grammer.cpp
@@ -193,7 +193,6 @@ void Compiler::AddFirstNode()
bool Compiler::AddRootNode()
{
- std::cout << "AddRootNode()" << std::endl;
if (nodes.size() == 0) {
AddFirstNode();
} else {
@@ -237,16 +236,18 @@ bool Compiler::AddRootNode()
// keep tokens_used as is
}
+ DumpTree();
return true;
}
+// Go back one step: Remove Node or Token
void Compiler::RemoveLastNode()
{
TreeNode& node {nodes.back()};
index_t node_id = node.node_id;
if (node_id == root_node_id) { // No parent -> remove root
- if (node.child_ids.empty()) { // No children -> now empty
+ if (node.child_ids.empty()) { // No children -> now tree is empty
clear();
} else if (node.child_ids.size() == 1) { // One child: removing possible
if (!ChildIdIsToken(node.child_ids[0])) {
@@ -254,6 +255,7 @@ void Compiler::RemoveLastNode()
root_node_id = node.child_ids[0];
}
nodes.pop_back();
+ std::cout << "Removing " << nodes.back().type << "(" << nodes.back().node_id << ")" << std::endl;
} else {
DumpTree();
throw std::runtime_error("Backtrack not possible: Root not empty"); // ICE
@@ -265,9 +267,16 @@ void Compiler::RemoveLastNode()
throw std::runtime_error("Backtrack: Bad child nodes"); // ICE
parent.child_ids.pop_back();
nodes.pop_back();
+ } else if (ChildIdIsToken(node.child_ids.back())) {
+ node.child_ids.pop_back();
+ if (tokens_used > 0)
+ tokens_used--;
+ else
+ throw std::runtime_error("Parse error at "s + std::to_string(node_id) + " ("s + node.type + ")"s);
} else { // In the middle
- throw std::runtime_error("Backtrack in the middle of the tree."); // ICE
+ throw std::runtime_error("Backtrack in the middle of the tree: "s + std::to_string(node_id) + " ("s + node.type + ")"s); // ICE
}
+ DumpTree();
}
// Change type of last node according to alternatives
@@ -406,11 +415,17 @@ bool Compiler::FillTree()
while (!subTreeIsComplete(root_node_id, to_fill)) {
auto& node {nodes[to_fill]};
- auto list = GetPath(bnf[node.type][node.variant][node.child_ids.size()], tokens[tokens_used].type);
- if (list.size() > 0) {
- AddPath(list, to_fill);
- } else {
- return false;
+ std::string next_child {bnf[node.type][node.variant][node.child_ids.size()]};
+ if (next_child == tokens[tokens_used].type) { // add token directly
+ node.child_ids.push_back(ChildIdFromTokenId(tokens_used));
+ tokens_used++;
+ } else { // add inner nodes
+ auto list = GetPath(next_child, tokens[tokens_used].type);
+ if (list.size() > 0) {
+ AddPath(list, to_fill);
+ } else {
+ return false;
+ }
}
}
return true;
@@ -429,7 +444,6 @@ std::pair<index_t, std::vector<TreeNode>> Compiler::compile(std::vector<Token> T
throw std::runtime_error("No tokens!");
while (!treeIsComplete()) {
- DumpTree();
if (!FillTree()) {
TrackBack();
} else if (!AddRootNode()) {