Reputation: 309
I'm writing a basic lexer for my language and I want to traverse a tree of Node
objects in an AST
object. Each Node
object in the AST has a member Children
of type vector<Node>
. This is to allow for nodes to have child nodes (for example, an expression node coul store two nodes operand_a, and operand_b).
The problem is, I don't know how to make a for loop iterate through an AST of Nodes, whose child nodes can have an indefinite number of their own child nodes and so on.
Here is the header for my AST/Node classes.
enum NodeType {
...
TOKEN_SIGN_PLUS,
TOKEN_SIGN_MINUS,
...
};
class Node;
struct AST
{
vector<Node> Nodes;
void addNode(Node node);
void deleteNode(size_t nodeID);
//void deleteNodeRange(size_t from, size_t to);
void popEndNode();
size_t NodeCount() { return Nodes.size(); }
AST() {}
~AST() {}
};
struct Node
{
friend AST;
AST* ParentAST;
NodeType NodeType;
size_t NodeID();
string Data;
vector<Node> Children;
size_t ChildCount() { return Children.size(); }
Node() {}
~Node() {}
private:
size_t _nodeID;
};
So my question is, how can I iterate through every single child node and its children, on a per parent basis so I could, say, print something like this:
NODE: "EXPR"
NODE: "INT_LITERAL"
NODE: "OP_PLUS"
NODE: "INT_LITERAL"
OR, more to the point (multiple nested children):
NODE: "DECL_AND_INIT_VARIABLE"
NODE: "KEYWORD_INT"
NODE: "IDENTIFIER"
NODE: "OP_EQ"
NODE: "EXPR"
NODE: "INT_LITERAL"
NODE: "OP_PLUS"
NODE: "INT_LITERAL"
Upvotes: 0
Views: 351
Reputation: 2181
This is a quick/crude example, but probably something vaguely like this:
struct AST
{
...
void print() const;
};
...
struct Node
{
...
void print(int indent) const;
};
void AST::print() const
{
for(const auto& node:Nodes)
node.print(0);
}
void Node::print(int indent) const
{
auto thisindent = strlen("NODE: ") + Data.length();
cout << string(indent + thisindent, ' ');
cout << "NODE: " << Data << endl;
if(Children.size() > 0)
for(const auto& child:Children)
child.print(indent + thisindent);
}
Upvotes: 1