私はC++で多態的な再帰的下降パーサーを書くことに始めました。しかし、私は問題を実行しています。クラスは、このように設定されています多態抽象構文木(再帰的降下構文解析器):不可能か?
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.
そしてNodeDeclaration
、NodeCall
、NodeNot
、NodeAssignment
、NodePlus
、NodeMinus
、NodeIf
などのようなクラスがNode
からかNodeBinary
またはNodeUnary
のようにそれほど一般的な何かのいずれかを継承します。
しかし、その中にはさらに特定のオペランドがあります。 NodeAssignment
は常にvarと数値/式をとります。だから私はNode * leftをNodeVar * leftとNodeExpr * rightにオーバーライドする必要があります。問題はNodePlus
のようなもので起こります。左はNodeVar
またはNodeExpr
です。ルートノードにも同様の問題があります。ルートノードに子ノードを追加するために最上位レベルで解析するとき、子供がNodeExpr
、NodePlus
、NodeIf
などであるかどうかをどのようにして知ることができますか?
すべてのノードにはどのタイプの列挙型の「型」があるかもしれませんが、いい多形の継承ツリーを持つ点は何でしょうか?
この問題は通常どのように解決されていますか?
私の問題の一部は、その差は、たとえNodeValueであっても、使用されている数値や変数の場合は、プラスとなります(たとえば、左と右は値または変数になります)。 – Accumulator
@accumulator:オブジェクト指向設計の本質は、すべてのオブジェクトが何をすべきかを実行することです。オブジェクトのために何かをするためにオブジェクトを要求する必要がある場合、オブジェクトに正しく動作をカプセル化していません。 – rici
次に、varまたはvalになる可能性があるものに対して、適切なカプセル化は何ですか? – Accumulator