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

Java 如何使自动生成的解析器类在ANTLR4中实现接口?,java,parsing,antlr4,Java,Parsing,Antlr4,我正在使用Antlr4创建一个解析器,我已经完成了语法。我需要将一些Java代码注入ANTLR自动生成的解析器文件中 如果我想在生成的解析器中包含一个方法,我可以将其添加到ANTLR语法中: @parser::members { @Override public CGrammarParser.CSnippetContext call() { return cSnippet(); } } 如果我想包含一些导入语句,我可以将其添加到语法中: @header { impo

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

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

@parser::members
{
  @Override
  public CGrammarParser.CSnippetContext call()
  {
    return cSnippet();
  }
}
如果我想包含一些导入语句,我可以将其添加到语法中:

@header
{
  import java.lang.Thread;
  import java.lang.InterruptedException;
  import java.util.concurrent.Callable;
}
如果我想修改类声明,使其实现接口,我该怎么做?换句话说,这是ANTLR自动生成的:

public class CGrammarParser extends Parser 
{
  ...
}
但这就是我想要它产生的:

public class CGrammarParser extends Parser implements Callable<CGrammarParser.CSnippetContext> 
{
  ...
}
公共类CGrammarParser扩展解析器实现可调用
{
...
}
不,不像您描述的那样(通过接口)。但是,您可以定义一个解析器应该从中扩展的超类。当然,这个超类应该扩展ANTLR的
解析器
类。在自己的(抽象)解析器类中,定义要实现的接口

以下是如何做到这一点:

可调用解析器
这个答案归功于卢卡斯·特泽斯涅夫斯基

要让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();
    }
}

您也可以通过另一种方式来实现这一点:您可以从生成的解析器继承并在派生类中实现所需的内容(这比使用
@parser::members
构造IMO更简洁,因为语法和逻辑之间有更多的分离)。为了记录在案,对于C#解析器来说,这个问题的答案更简单:它们是
部分
类。它抛出一个
异常InInitializeRerror
。如果我手动添加所需的扩展和实现(请参见我的问题),它可以正常工作。我觉得这个答案非常接近,但ANTLR对此并不满意。我试过你的答案,@Lucastrezesniewski,它奏效了!如果你想给这个问题添加一个答案,我会接受它作为正确答案。非常感谢。
grammar CGrammar;

options
{
  superClass = CallableParser;
}

@header
{
  import java.lang.Thread;
  import java.lang.InterruptedException;
  import java.util.concurrent.Callable;
}

@parser::members
{
  @Override
  public CGrammarParser.CSnippetContext call()
  {
    return cSnippet();
  }
}

cSnippet
 : ANY*? EOF
 ;

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

    @Override
    public CGrammarParser.CSnippetContext call()
    {
        return cSnippet();
    }
}
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);