ANTLR复制树 [英] ANTLR duplicate a tree

查看:138
本文介绍了ANTLR复制树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I use ANTLR to build a tree (CommonTree) like follwing (language: JAVA):

  Parser.prog_return r = parser.prog();
  CommonTree t = (CommonTree) r.getTree();

现在,我需要传递t作为参数,并进行一些更改,而不会影响原始树。然而,使用Java的指针,这是无法做到的,所以我需要复制树。

Now, I need to pass "t" as a parameter, and make some changes without affecting the original tree. However, with Java's pointer, this could not been done, so I need to duplicate the tree.

我已经在互联网上搜索,可以找到的东西是ASTFactory类的 dupTree()方法。

I have been search on the internet, the cloested thing I could find is the dupTree() method of ASTFactory class.

任何建议或建议如何获取这将不胜感激!

Any suggestion or advises on how to achive this would be appreciated!

@Bart Kiers,谢谢你的回答,绝对有效!

@Bart Kiers, Thanks for your answer, it absolutely works!

我看到你正在树上深入第一步,并为访问的每个节点创建一个CommonTree对象。

I see you are doing a depth first walk over the tree, and create a CommonTree object for each node that was visited.

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

My question is now, what is the relation between CommonToken and CommonTree, and what are these attributes do:

cTok.setCharPositionInLine(oTok.getCharPositionInLine());
cTok.setChannel(oTok.getChannel());
cTok.setStartIndex(oTok.getStartIndex());
cTok.setStopIndex(oTok.getStopIndex());
cTok.setTokenIndex(oTok.getTokenIndex());


推荐答案

尝试这样:

public static CommonTree copyTree(CommonTree original) {
  CommonTree copy = new CommonTree(original.getToken());
  copyTreeRecursive(copy, original);
  return copy;
}

private static void copyTreeRecursive(CommonTree copy, CommonTree original) {
  if(original.getChildren() != null) {
    for(Object o : original.getChildren()) {

      CommonTree originalChild = (CommonTree)o;

      // get the token from the original child node
      CommonToken oTok = (CommonToken)originalChild.getToken();

      // create a new token with the same type & text as 'oTok' 
      CommonToken cTok = new CommonToken(oTok.getType(), oTok.getText());

      // copy all attributes from 'oTok' to 'cTok'  
      cTok.setLine(oTok.getLine());
      cTok.setCharPositionInLine(oTok.getCharPositionInLine());
      cTok.setChannel(oTok.getChannel());
      cTok.setStartIndex(oTok.getStartIndex());
      cTok.setStopIndex(oTok.getStopIndex());
      cTok.setTokenIndex(oTok.getTokenIndex());

      // create a new tree node with the 'cTok' as token
      CommonTree copyChild = new CommonTree(cTok);

      // set the parent node of the child node
      copyChild.setParent(copy);

      // add the child to the parent node
      copy.addChild(copyChild);

      // make a recursive call to copy deeper
      copyTreeRecursive(copyChild, originalChild);
    }
  }
}

...

// get the original tree
CommonTree tree = (CommonTree)parser.parse().getTree();

// create a copy of the tree
CommonTree copy = copyTree(tree);

// change the contents of the right node of the right node of the root 
((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 || c)。即, X ,但副本将有原始内容: c

for the input "a && (b || c)". I.e., the tree has X, but the copy would will have the original contents: c.

请注意,我选择 CommonTree CommonToken 对象,因为这些是默认的令牌 Tree 实现。如果您选择创建自己的令牌和/或 Tree ,那么您可以将 CommonTree CommonToken 类,在这种情况下,我的建议不会中断。

Note that I choose CommonTree and CommonToken objects because those are the default Token and Tree implementations. If you choose to create your own Token and/or Tree, chances are that you'll subclass the CommonTree and CommonToken classes, in which case my suggestion would not break.

A CommonTree 只不过是一个围绕 CommonToken 的包装器,其中包含一些额外的信息:父节点,和子节点。这就是为什么我还从 CommonToken 对象中复制所有信息。

A CommonTree is nothing more than a wrapper around a CommonToken, holding a bit of extra information: a parent node, and child nodes. That is why I also copy all the information from the CommonToken objects.

这篇关于ANTLR复制树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆