简体   繁体   English

ANTLR的AST树语法+列表

[英]ANTLR's AST tree grammar + lists

I've have read a lot trying to find a way to cleanly consume lists in ANTLR's tree grammar. 我已经阅读了很多试图找到一种方法来干净地使用ANTLR的树语法中的列表。 Here is what I have tried and their results (I really hope I'm missing something trivial)... 这是我尝试过的和他们的结果(我真的希望我错过了一些微不足道的事情)......

Using += Syntax 使用+ =语法

program returns [someInterface result]
  : m+=method* EOF {result = new SomeClass(m);};

method returns [SomeMethod result] : <definition here>

This fails with... 这失败了......

rule '+=' list labels are not allowed w/o output option 规则'+ ='列表标签不允许没有输出选项

If I set the output to either "AST" or "template" (the only options) the method signatures of the generated class change. 如果我将输出设置为“AST”或“template”(唯一选项),则生成的类的方法签名会更改。 That is, m will not by a List of SomeMethod(s) but rather a List of Nodes or Templates respectively. 也就是说, m不是由SomeMethod列表,而是分别是节点或模板列表。 I am open to suggestions if there is a way to make this method work. 如果有办法使这种方法有效,我愿意接受建议。

Using Rule Scopes 使用规则范围

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);};

This seems to work, though I'll admit that I haven't tested it with nested/recursive cases yet. 这似乎有效,但我承认我还没有用嵌套/递归的情况测试它。

The End Goal 最终目标

I want to build a set of classes that represent my language (Class, Method, Variable, Statement, ect) so that I can do some static analysis and optimization before I generate compiled code. 我想构建一组代表我的语言的类(Class,Method,Variable,Statement,ect),这样我就可以在生成编译代码之前做一些静态分析和优化。 To that end, I need to be able to consume lists. 为此,我需要能够使用列表。 I expected += syntax to "just work" but I might be missing something. 我希望+ =语法“正常工作”,但我可能会遗漏一些东西。 The second method works but seem overly verbose and inelegant. 第二种方法有效,但看起来过于冗长和不优雅。

The Question 问题

What is the proper why to consume a list, in ANTLR's tree grammar, to pass to my concrete classes? 在ANTLR的树语法中使用列表传递给我的具体类的原因是什么?

You can cut the scope from your example and do it all with local variables. 您可以从示例中删除范围,并使用局部变量完成所有操作。

program returns [CompilesToJavaByteCode result]
    @init {
      List<SomeMethod> methods = new ArrayList<SomeMethod>();
    }
    : (m=method { methods.add($m.result); })* EOF 
      { $result = new SomeClass(methods); };

This is what we do for this case at work. 这就是我们在工作中为此案例所做的工作。 Another option is to have your method rule handle it: 另一种选择是让您的方法规则处理它:

program returns [CompilesToJavaByteCode result]
    @init {
      List<SomeMethod> methods = new ArrayList<SomeMethod>();
    }
    : method[methods]* EOF { $result = new SomeClass(methods); };

method [List<SomeMethod> methods]
    : ...
      { methods.add(new SomeMethod(...); };

I don't really like the second option as a method rule probably shouldn't care what is being done with its results like that. 我不太喜欢第二个选项,因为方法规则可能不应该关心它的结果是做什么的。 But you can imagine a structure where the top rule creates a ClassBeingCompiled and the rest of the code incrementally fills it out with .addMethod() . 但是你可以想象一个结构,其中顶级规则创建一个ClassBeingCompiled ,其余的代码用.addMethod()逐步填充它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM