如何使自动生成的解析器类在 ANTLR4 中实现接口?

jam*_*iss 5 java parsing antlr4

我正在使用 ANTLR 4 创建一个解析器,并且我已经完成了我的语法。我需要将一些 Java 代码注入到 ANTLR 为我自动生成的结果解析器文件中。

如果我想在结果解析器中包含一个方法,我可以将其添加到 ANTLR 语法中:

@parser::members
{
  @Override
  public CGrammarParser.CSnippetContext call()
  {
    return cSnippet();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我想包含一些导入语句,我可以将其添加到语法中:

@header
{
  import java.lang.Thread;
  import java.lang.InterruptedException;
  import java.util.concurrent.Callable;
}
Run Code Online (Sandbox Code Playgroud)

如果我想修改类声明以实现 interface,我该怎么做?换句话说,这就是 ANTLR 自动生成的:

public class CGrammarParser extends Parser 
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

但这就是我希望它生成的内容:

public class CGrammarParser extends Parser implements Callable<CGrammarParser.CSnippetContext> 
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

jam*_*iss 0

这个答案归功于Lucas Trzesniewski

要让 ANTLR 解析器实现接口,语法文件 (.g4) 本身不需要 Java。只需执行以下操作:

1)创建一个可调用的解析器类,该类扩展 ANTLR 解析器并实现相关接口,例如:

public class CallableParser extends CGrammarParser implements Callable<CGrammarParser.CSnippetContext>
{
    public CallableParser(TokenStream input)
    {
        super(input);
    }

    @Override
    public CGrammarParser.CSnippetContext call()
    {
        return cSnippet();
    }
}
Run Code Online (Sandbox Code Playgroud)

2) 不要调用 ANTLR 解析器,而是调用 ANTLR 解析器CallableParser,如下所示:

CharStream in = new ANTLRInputStream(input);
CGrammarLexer lexer = new CGrammarLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
// Instead of doing this...
// CGrammarParser parser = new CGrammarParser(tokens);
// Do this...
CallableParser parser = new CallableParser(tokens);
Run Code Online (Sandbox Code Playgroud)