diff options
Diffstat (limited to 'grammer.cpp')
-rw-r--r-- | grammer.cpp | 32 |
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()) { |