2012-08-24 9 views
1

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

有没有一种方法,我可以节省AST子对我的对象声明并重新处理它,当我要创建节点的实例?我用ANTLR AST来提问,但如果你有语言实施建议,我也欢迎。

回答

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 

this question for more info on returning data from an ANTLR grammar rule.

List<Node> nodes = walker.topRule() 

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

相关问题