我已经读了很多资料,试图找到一种干净的方式来处理ANTLR的树语法中的列表。下面是我尝试过的方法及其结果(我真的希望我错过了一些微不足道的东西)...
使用+=语法
program returns [someInterface result]
: m+=method* EOF {result = new SomeClass(m);};
method returns [SomeMethod result] : <definition here>
这个方法失败了...
规则“+=”列表标签不允许没有输出选项
如果我将输出设置为“AST”或“template”(仅有的选项),生成类的方法签名会发生变化。也就是说,m
将不再是SomeMethod(s)的列表,而是Nodes或Templates的列表。如果有办法使该方法正常工作,我很乐意听取建议。
使用规则范围
program returns [CompilesToJavaByteCode result]
scope {
List<SomeMethod> methods;
}
@init {
$program::methods = new ArrayList<SomeMethod>();
}
: (m=method {$program::methods.add(m);})*
EOF {result = new SomeClass($program::methods);};
这个看起来可行,但我必须承认,我还没有测试过其中的嵌套/递归情况。
最终目标
我想构建一组代表我的语言 (类、方法、变量、语句等) 的类,以便我可以在生成编译后代码之前进行一些静态分析和优化。为此,我需要能够消耗列表。我预计使用 += 语法“只需工作”,但我可能错过了什么。第二种方法可行,但似乎过于冗长和不优美。
问题
在 ANTLR 的树语法中,消耗列表并传递给我的具体类的正确方式是什么?
output=AST
使它们成为CommonTree
类型)时,+=
才能正常工作。我认为这与ANTLR的代码基本上是Java 1.4有关,因为规则也可以返回原始类型,如int
或double
等,因为1.4没有自动装箱。 - Bart Kiers