我正在设计一种声明性语言。在我的语言中是“节点”的定义,可以在以后重用。把它们想象成原型或模板。您可以根据需要创建它们的副本。我有一个解释器版本,在定义阶段生成适当的Java对象。直到最近,我一直在使用深拷贝库来创建节点的Java表示的副本,以创建节点的实例。由于我发现的大多数深度复制库的局限性以及我不希望为系统中的每个对象编写复制构造函数,我想采取不同的方法。我的部分语言指定了GUI Java Swing对象,这些对象会导致深层复制库出现问题。
有没有办法可以为我的对象声明保存AST子图并在我想创建节点实例时重新处理它?我用ANTLR AST来问这个问题,但是如果你有语言实现建议我也欢迎。
答案 0 :(得分: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。