多态抽象语法树(递归下降解析器):不可能? 我已经开始在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. 类节点{ 公众: 性病媒儿童; }; 类NodeBinary:公共节点{ 公众: 节点*左; 节点*右; }; 类nodenuary:公共节点{ 公众: 节点*操作数; }; 类NodeVar:公共节点{ 公众: std::字符串; NodeVar(std::string str):string(str){}; }; 类节点枚举器:公共节点{ 公众: 签名长数; NodeNumber(有符号长n):数(n){}; }; //等等。

多态抽象语法树(递归下降解析器):不可能? 我已经开始在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. 类节点{ 公众: 性病媒儿童; }; 类NodeBinary:公共节点{ 公众: 节点*左; 节点*右; }; 类nodenuary:公共节点{ 公众: 节点*操作数; }; 类NodeVar:公共节点{ 公众: std::字符串; NodeVar(std::string str):string(str){}; }; 类节点枚举器:公共节点{ 公众: 签名长数; NodeNumber(有符号长n):数(n){}; }; //等等。,c++,parsing,polymorphism,abstract-syntax-tree,recursive-descent,C++,Parsing,Polymorphism,Abstract Syntax Tree,Recursive Descent,然后像nodeclaration,NodeCall,NodeNot,NodeAssignment,NodePlus,NodeMinus,NodeIf等类将继承自Node,或者继承自NodeBinary或NodeUnary>等非通用类 但是,其中一些采用更具体的操作数NodeAssignment始终采用一个var和一个数字/表达式。所以我必须将Node*left覆盖到NodeVar*left和NodeExpr*right。问题出现在NodePlus之类的东西上。左侧可以是NodeVar或NodeE

然后像
nodeclaration
NodeCall
NodeNot
NodeAssignment
NodePlus
NodeMinus
NodeIf
等类将继承自
Node
,或者继承自
NodeBinary
NodeUnary>等非通用类

但是,其中一些采用更具体的操作数
NodeAssignment
始终采用一个var和一个数字/表达式。所以我必须将Node*left覆盖到NodeVar*left和NodeExpr*right。问题出现在
NodePlus
之类的东西上。左侧可以是
NodeVar
NodeExpr
!根节点也有一个类似的问题:在顶层解析以将子节点添加到根节点时,如何判断子节点是
NodeExpr
、是
NodePlus
、是
NodeIf

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


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

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

因此,例如,
NodeAssignment
(可能是
NodeStatement
的专门化)需要包含
NodeLValue
(其中
NodeVariable
是专门化)和
NodeValue
。通常,左值(即您可以指定的对象)是值的子集,因此
NodeLValue
将是
NodeValue
的特化。等等您的二进制运算符节点将包含
left
right
成员,这两个成员都是
NodeValue
基本对象(我希望
NodeValue
是纯虚拟的,具有大量特定的专门化)


如果坚持使用递归下降解析器,则每个解析函数都需要返回
节点
的适当子类,以便解析赋值左侧的函数在逻辑上返回一个
NodeLValue*
,准备插入
NodeAssignment
构造函数。(坦白地说,我会在所有这些类名中去掉
节点
这个词。把它们都放在名称空间
节点:
中,省得自己打字。)

我明白你的意思,但我的部分问题是,即使在NodeValue中(例如,在加号中,左和右可以是值或变量),人们如何区分它们之间的差异如果使用的是一个数字还是一个变量?@acculator:面向对象设计的本质是每个对象都做它被要求做的事情。如果您需要询问对象它是什么以便为它做些什么,那么您没有正确地将行为封装到对象中。那么对于可以是var或val的对象,正确的封装是什么?@acculator:如果对象可以是var或val,那么它必须是val,因为它可以做val所能做的一切,在这种情况下,你不能要求做任何其他事情。这就是为什么我说var必须从val派生:var是一个val,它还可以做其他事情(比如被赋值)