多态抽象语法树(递归下降解析器):不可能?

时间:2017-03-06 20:46:34

标签: c++ parsing polymorphism abstract-syntax-tree recursive-descent

我已经开始在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.

然后是NodeDeclarationNodeCallNodeNotNodeAssignmentNodePlusNodeMinusNodeIf等类。将继承Node或不太通用的内容,例如NodeBinaryNodeUnary

但是,其中一些需要更具体的操作数。 NodeAssignment始终采用var和数字/表达式。因此,我必须将Node *左侧覆盖到NodeVar * left和NodeExpr *右侧。问题出现在NodePlus之类的问题上。左边可以是NodeVarNodeExpr!并且根节点也有类似的问题:在顶层解析以将子节点添加到root时,如何判断子节点是NodeExprNodePlus还是{{1}等等......?

我可以让所有节点都有一个枚举“类型”,说明它是什么类型,但那么有一个很好的多态继承树的意义呢?

这个问题通常是如何解决的?

1 个答案:

答案 0 :(得分:0)

如果您正在为AST节点使用类继承,则需要创建适当的继承层次结构,就像任何面向对象的设计一样。

因此,例如,NodeAssignment(可能是NodeStatement的特化)需要包含NodeLValue(其中NodeVariable是专业化)和NodeValue。像往常一样,LValues(即您可以分配的内容)是值的子集,因此NodeLValue将是NodeValue的特化。等等。您的二元运算符节点将包含leftright个成员,这两个成员都是NodeValue个基础对象(我希望NodeValue是纯虚拟的,具有大量特定的特。)

如果你坚持使用递归下降解析器,每个解析函数都需要返回Node的适当子类,以便解析赋值左侧的函数在逻辑上返回{{1准备插入NodeLValue*构造函数。 (坦率地说,我在所有这些类名中抛弃了NodeAssignment这个词。将它们全部放入命名空间Node并节省一些打字。)