1

我正在设计一种声明性语言。在我的语言中是可以在以后重用的“节点”的定义。把它们想象成原型或模板。您可以根据需要创建它们的副本。我有一个解释器版本,可以在定义阶段生成适当的 Java 对象。直到最近,我一直在使用深拷贝库来创建节点的 Java 表示的副本以创建节点的实例。由于我发现的大多数深度复制库的局限性,以及我不想为系统中的每个对象编写复制构造函数,我想采用不同的方法。我的语言的一部分指定了 GUI Java Swing 对象,这会导致深层复制库出现问题。

有没有办法可以为我的对象声明保存 AST 子图并在我想创建节点的实例时重新处理它?我问的是关于 ANTLR AST 的问题,但是如果您有语言实现建议,我也欢迎。

4

1 回答 1

1

在 ANTLR 解析器/词法分析器语法中,您可以访问$ruleName.tree. 该规则属性是对解析过程中生成的 AST 子树的引用。使用@after字段和@members字段,您可以存储子树。让我演示给你看。

@members{
private List<CommonTree> defs = new ArrayList<CommonTree>();

public List<CommonTree> getDefs(){
    return defs;
}

}

在你的语法下面

ruleName 
@after{
    defs.add($ruleName.tree);
}
: IDENT ;

这将创建所有 ruleName AST 子树的列表。这些树可以转换为 CommonTreeNodeStream 并与您的树语法代码一起使用。

CommonTree defTree = Parser.getDefs().get(0); // just getting the first tree for example
CommonTreeNodeStream defStream = new CommonTreeNodeStream(defTree);
TreeWalker walker = new TreeWalker(defStream);
//assuming that I have a tree grammar that has been defined to return a list of nodes

有关从 ANTLR 语法规则返回数据的更多信息,请参阅此问题。

List<Node> nodes = walker.topRule() 

这将允许您通过重新处理保存的 AST 子图来创建节点实例。您可以创建 TreeNodeStream 并在需要创建实例时调用 walker。

于 2012-08-25T00:46:08.453 回答