antlr4中的ParseTree遍历
ParseTree traversal in antlr4
我正在使用 antlr4 c++。
我有一个 ParseTree
并且正在尝试重新创建树结构。
为此,我使用了访问者 my_Visitor
和我自己的节点对象。
我的问题是visitChildren(tree::RuleNode*)
调用了所有子树的访问函数,所以我在遍历一个子树和访问下一个子树时丢失了信息。
假设一棵树是这样的:
A
/ \
B C
当我调用visitChildren(A)
时(对B和C使用重载的visitExpression(ExpressionContext*)
函数),我可以提取出访问顺序是A,B,C的信息。
这个序列也可能来自:
A
|
B
|
C
要重新创建树,我想我需要类似
的东西
antlrcpp::Any my_Visitor::my_visitChildren(tree::RuleNode* A){
for(int i=0;i<A->children.size();i++){
//create a new node in my own tree representation as child of A
visit(A->children[i]);
}
}
并在我重载的 visitExpression
函数中调用 my_visitChildren
。
这里的问题是 A->children[i]
是一个 Tree
而 visit(.)
需要一个 ParseTree
.
我能以某种方式从 children[i]
创建一个 ParseTree
还是有更好的方法来做到这一点?
我也在考虑使用从 tree->parent
到我的对象的映射,然后将我的新节点附加到那里,但是如果我想省略一些节点(例如 AST),这不是最佳选择。
ParseTree
和 Tree
之间的区别纯粹是人为的,实际上没有实际用处。树节点的子节点实际上都是 ParseTree
个实例。除了构建 ParseTree
的基础 classes 之外,有一些树 classes 从未在运行时使用过。因此后来我删除了 Tree
、SyntaxTree
和 RuleNode
并将所有这些放在一起到 ParseTree class.
回答您的问题:您可以安全地将子节点投射到 ParseTree
以进行树遍历。
我正在使用 antlr4 c++。
我有一个 ParseTree
并且正在尝试重新创建树结构。
为此,我使用了访问者 my_Visitor
和我自己的节点对象。
我的问题是visitChildren(tree::RuleNode*)
调用了所有子树的访问函数,所以我在遍历一个子树和访问下一个子树时丢失了信息。
假设一棵树是这样的:
A
/ \
B C
当我调用visitChildren(A)
时(对B和C使用重载的visitExpression(ExpressionContext*)
函数),我可以提取出访问顺序是A,B,C的信息。
这个序列也可能来自:
A
|
B
|
C
要重新创建树,我想我需要类似
的东西antlrcpp::Any my_Visitor::my_visitChildren(tree::RuleNode* A){
for(int i=0;i<A->children.size();i++){
//create a new node in my own tree representation as child of A
visit(A->children[i]);
}
}
并在我重载的 visitExpression
函数中调用 my_visitChildren
。
这里的问题是 A->children[i]
是一个 Tree
而 visit(.)
需要一个 ParseTree
.
我能以某种方式从 children[i]
创建一个 ParseTree
还是有更好的方法来做到这一点?
我也在考虑使用从 tree->parent
到我的对象的映射,然后将我的新节点附加到那里,但是如果我想省略一些节点(例如 AST),这不是最佳选择。
ParseTree
和 Tree
之间的区别纯粹是人为的,实际上没有实际用处。树节点的子节点实际上都是 ParseTree
个实例。除了构建 ParseTree
的基础 classes 之外,有一些树 classes 从未在运行时使用过。因此后来我删除了 Tree
、SyntaxTree
和 RuleNode
并将所有这些放在一起到 ParseTree class.
回答您的问题:您可以安全地将子节点投射到 ParseTree
以进行树遍历。