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

Polymorphic Abstract Syntax Tree (recursive descent parser): impossible?

本文关键字:不可能 语法树 抽象 递归 多态性      更新时间:2023-10-16

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

然后类似NodeDeclarationNodeCallNodeNotNodeAssignment,CC_4,NodePlusNodeMinusNodeIf等类,CC_7等。

但是,其中一些采用更具体的操作数。NodeAssignment始终采用VAR和数字/表达式。因此,我将不得不覆盖节点*向左*向左*右nodeexpr*右。问题带有NodePlus之类的东西。左可以是NodeVarNodeExpr!根节点也有类似的问题:在顶层解析以将孩子节点添加到root时,如何确定孩子是否是NodeExprNodePlusNodeIf,CC_17等...?

我可以让所有节点都有一个枚举的"类型",说什么类型是什么类型,但是拥有一个不错的多态性继承树有什么意义?

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

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

因此,例如,NodeAssignment(大概是NodeStatement的专业化)需要包含NodeLValue(其中NodeVariable是专业化)和NodeValue。像往常一样,lvalues(即您可以分配给的东西)是值的子集,因此NodeLValue将是NodeValue的专业化。等等。您的二进制操作员节点将包含leftright成员,这两个成员都是NodeValue基本对象(我希望NodeValue是纯虚拟的,具有大量特定的特定专业。)

如果您坚持使用递归下降解析器,则每个解析功能都需要返回适当的Node子类,以便解析分配的左侧的功能在逻辑上返回NodeLValue*NodeAssignment构造函数。(坦率地说,我会在所有这些类名称中抛弃 Node一词。将它们全部放入命名空间node::并节省一些打字。)