C# 上的 ANTLR 4:不匹配的输入 '<EOF>' 期望 'HEAD'

ANTLR 4 on C#: mismatched input '<EOF>' expecting 'HEAD'

我目前正在为一种旧的类似标记的专有语言开发解析器,该语言必须转换为更新的标准。我正在使用 ANTLR 4.8 生成 C# 解析器,我将其与官方 Antlr4.Runtime.Standard.

一起使用

解析器语法以这样的入口规则开始:

parser grammar ParstParser;

options {
  tokenVocab=ParstLexer;
}

report
  :
    input
    lines
    fields
    mod
    head?
    body
    foot?
    EOF
  ;

[...]

使用 grun 或 Rider 中的官方 ANTLR 插件测试语法,它可以很好地解析我的虚拟文件(抱歉隐藏标记代码,但它是我公司的 属性我正在为:

工作

我使用 C# 为更高级别的模型编写了一个构建器,它接受来自 ANTLR 解析树的上下文,但是解析失败并显示 InputMismatchException,它在控制台上的记录如下:

line 20:0 mismatched input '<EOF>' expecting 'HEAD'

我的虚拟 C# 入口点如下所示:

public static class Program
{
    public static void Main()
    {
        var lexer = new ParstLexer(new AntlrInputStream(Examples.ExampleResources.DUMMY));
        var tokens = new CommonTokenStream(lexer);
        var parser = new ParstParser(tokens);
        var parseTree = parser.report();
        var modelBuilder = new ModelBuilder();
        modelBuilder.AddInput(new InputBlock(
            parseTree.input().vars().squote_string().GetText().Trim('\''),
            Examples.ExampleResources.PSTARKIV522));
        modelBuilder.AddLines(parseTree.lines());
        modelBuilder.AddFields(parseTree.fields());
        modelBuilder.AddMod(parseTree.mod());
        modelBuilder.AddHead(parser.head());
        modelBuilder.AddBody(parser.body());
        modelBuilder.AddFoot(parser.foot());
        var model = modelBuilder.GetModel();
        Console.WriteLine(JsonConvert.SerializeObject(model));
    }
}

我不明白为什么我会遇到这种情况。 我实际上搜索了这个错误,发现很多人对许多不同的问题都有这种错误;我尝试使用 EOF 令牌(例如,未明确声明它,或在 report 周围的包装器规则中移动它),但没有结果。

基于 Java 的工具(如 grun 或 Rider 插件不会像我的 C# 代码那样抱怨这一事实确实让我认为这个问题可以在 C# 目标或我自己的 Main(),但我不知道在哪里。

问题与重复的解析器调用有关:由于在我的 C# 代码中引用正确的对象时出错,我再次调用解析器而不是第一个解析器生成的树 运行。

解析器再次从 head 解析器规则开始(因为那是我用 head() 方法请求的规则),但是输入已经被第一次调用消耗掉了解析器,所以解析器正在寻找打开 headHEAD 标记,而是寻找输入的结尾 EOF.