Tree 复制一棵树
我使用ANTLR构建一个树(CommonTree),如下所示(语言:JAVA): 现在,我需要将“t”作为参数传递,并在不影响原始树的情况下进行一些更改。但是,使用Java的指针,这无法完成,因此我需要复制树 我一直在互联网上搜索,我能找到的最有趣的东西是ASTFactory类的dupTree()方法 任何关于如何实现这一目标的建议都将不胜感激 编辑 @巴特·基尔斯,谢谢你的回答,它绝对有效 我看到您正在对树进行深度优先遍历,并为访问的每个节点创建一个CommonTree对象 我现在的问题是,CommonToken和CommonTree之间的关系是什么,这些属性的作用是什么:Tree 复制一棵树,tree,duplicates,antlr,Tree,Duplicates,Antlr,我使用ANTLR构建一个树(CommonTree),如下所示(语言:JAVA): 现在,我需要将“t”作为参数传递,并在不影响原始树的情况下进行一些更改。但是,使用Java的指针,这无法完成,因此我需要复制树 我一直在互联网上搜索,我能找到的最有趣的东西是ASTFactory类的dupTree()方法 任何关于如何实现这一目标的建议都将不胜感激 编辑 @巴特·基尔斯,谢谢你的回答,它绝对有效 我看到您正在对树进行深度优先遍历,并为访问的每个节点创建一个CommonTree对象 我现在的问题是,C
cTok.setCharPositionInLine(oTok.getCharPositionInLine());
cTok.setChannel(oTok.getChannel());
cTok.setStartIndex(oTok.getStartIndex());
cTok.setStopIndex(oTok.getStopIndex());
cTok.setTokenIndex(oTok.getTokenIndex());
试着这样做:
公共静态CommonTree复制树(CommonTree原件){
CommonTree copy=新的CommonTree(original.getToken());
复印件草书(复印件,原件);
返回副本;
}
私有静态void copytree草书(CommonTree副本,CommonTree原件){
if(original.getChildren()!=null){
对于(对象o:original.getChildren()){
CommonTree originalChild=(CommonTree)o;
//从原始子节点获取令牌
CommonToken oTok=(CommonToken)originalChild.getToken();
//创建与“oTok”类型和文本相同的新令牌
CommonToken cTok=新的CommonToken(oTok.getType(),oTok.getText());
//将所有属性从“oTok”复制到“cTok”
cTok.setLine(oTok.getLine());
cTok.setCharPositionInLine(oTok.getCharPositionInLine());
cTok.setChannel(oTok.getChannel());
cTok.setStartIndex(oTok.getStartIndex());
cTok.setStopIndex(oTok.getStopIndex());
setTokenIndex(oTok.getTokenIndex());
//使用“cTok”作为令牌创建新的树节点
CommonTree copyChild=新CommonTree(cTok);
//设置子节点的父节点
copyChild.setParent(复制);
//将子节点添加到父节点
copy.addChild(copyChild);
//进行递归调用以复制到更深的位置
CopyTreeCursive(copyChild、originalChild);
}
}
}
...
//获取原始树
CommonTree=(CommonTree)parser.parse().getTree();
//创建树的副本
CommonTree副本=复制树(树);
//更改根的右节点的右节点的内容
((CommonTree)tree.getChild(1.getChild(1)).getToken().setText(“X”);
System.out.println(tree.toStringTree());
System.out.println(copy.toStringTree());
这将产生:
(&& a (|| b X))
(&& a (|| b c))
(&&a(| b X))
(&&a(| b c))
对于输入“a&&(b|c)”
。即,树
具有X
,但是副本
将具有原始内容:c
注意,我选择了CommonTree
和CommonToken
对象,因为它们是默认的Token
和Tree
实现。如果您选择创建自己的Token
和/或Tree
,那么很可能您将对CommonTree
和CommonToken
类进行子类化,在这种情况下,我的建议不会中断
CommonTree
只不过是CommonToken
的包装器,包含一些额外的信息:父节点和子节点。这就是为什么我还复制了CommonToken
对象中的所有信息。我在dupTree()
上遇到了同样的问题,这似乎是不推荐的,然后是Bart的帖子,它将我引向了正确的方向。我最终得出以下结论:使用CommonTree
的构造函数接受CommonTree
——将其从复制单个字段的需要中抽象出来
私有静态CommonTree copyTreeRecursive(CommonTree原件){
CommonTree副本=新CommonTree(原始);//利用构造函数
if(original.getChildren()!=null){
对于(对象o:original.getChildren()){
CommonTree childCopy=CopyTree手写体((CommonTree)o);
childCopy.setParent(复制);
copy.addChild(childCopy);
}
};
返回副本;
}
注:我坚持巴特的命名惯例。Chen,注意我忘了添加
copyChild.setParent(复制)代码>到代码。
(&& a (|| b X))
(&& a (|| b c))