我已经阅读了很多内容,试图找到一种干净地使用 ANTLR 树语法中的列表的方法。这是我尝试过的方法及其结果(我真的希望我遗漏了一些微不足道的东西)......
使用 += 语法
program returns [someInterface result]
: m+=method* EOF {result = new SomeClass(m);};
method returns [SomeMethod result] : <definition here>
这失败了......
规则 '+=' 列表标签不允许没有输出选项
如果我将输出设置为“AST”或“模板”(唯一的选项),生成的类的方法签名会发生变化。也就是说,m
不是通过 SomeMethod(s) 的列表,而是分别通过节点或模板的列表。如果有办法使这种方法起作用,我愿意接受建议。
使用规则范围
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 的树语法中使用列表传递给我的具体类的正确原因是什么?