Tree 复制一棵树

Tree 复制一棵树,tree,duplicates,antlr,Tree,Duplicates,Antlr,我使用ANTLR构建一个树(CommonTree),如下所示(语言:JAVA): 现在,我需要将“t”作为参数传递,并在不影响原始树的情况下进行一些更改。但是,使用Java的指针,这无法完成,因此我需要复制树 我一直在互联网上搜索,我能找到的最有趣的东西是ASTFactory类的dupTree()方法 任何关于如何实现这一目标的建议都将不胜感激 编辑 @巴特·基尔斯,谢谢你的回答,它绝对有效 我看到您正在对树进行深度优先遍历,并为访问的每个节点创建一个CommonTree对象 我现在的问题是,C

我使用ANTLR构建一个树(CommonTree),如下所示(语言:JAVA):

现在,我需要将“t”作为参数传递,并在不影响原始树的情况下进行一些更改。但是,使用Java的指针,这无法完成,因此我需要复制树

我一直在互联网上搜索,我能找到的最有趣的东西是ASTFactory类的dupTree()方法

任何关于如何实现这一目标的建议都将不胜感激

编辑 @巴特·基尔斯,谢谢你的回答,它绝对有效

我看到您正在对树进行深度优先遍历,并为访问的每个节点创建一个CommonTree对象

我现在的问题是,CommonToken和CommonTree之间的关系是什么,这些属性的作用是什么:

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))