I have begun writing a polymorphic recursive descent parser in C++. However I am running an issue. The classes are set up like this:
class Node {
public:
std::vector<Node*> children;
};
class NodeBinary : public Node {
public:
Node* left;
Node* right;
};
class NodeUnary : public Node {
public:
Node* operand;
};
class NodeVar : public Node {
public:
std::string string;
NodeVar(std::string str) : string(str) {};
};
class NodeNumber : public Node {
public:
signed long number;
NodeNumber(signed long n) : number(n) {};
};
// etc.
And then classes like NodeDeclaration
, NodeCall
, NodeNot
, NodeAssignment
, NodePlus
, NodeMinus
, NodeIf
etc. will inherit either from Node
or something less generic like NodeBinary
or NodeUnary
.
However, some of them take more specific operands. NodeAssignment
always takes a var and a number/expression. So I will have to override Node* left to NodeVar* left and NodeExpr* right. The problem comes in with things like NodePlus
. Left can be a NodeVar
or a NodeExpr
! And the root node has a similar problem: while parsing at the top level to add children nodes to root, how is it possible to tell if a child is a NodeExpr
, a NodePlus
, a NodeIf
etc...?
I could have all Nodes have a enum "type" that says what type it is, but then whats the point of having a nice polymorphic inheritance tree?
How is is this problem normally solved??