Parsing 由于解析错误,ANTLR4在到达文件结尾之前成功终止解析的情况

Parsing 由于解析错误,ANTLR4在到达文件结尾之前成功终止解析的情况,parsing,antlr4,Parsing,Antlr4,我在单独的文件中为ANTLR4提供了以下解析器和词法分析器语法(参考BNF语法的简单语法) 及 主程序 private static void Main(string[] args) { StreamReader reader = new StreamReader(args[0]); AntlrInputStream stream = new AntlrInputStream(reader); BNFLexer lexer

我在单独的文件中为ANTLR4提供了以下解析器和词法分析器语法(参考BNF语法的简单语法)

主程序

private static void Main(string[] args) {
            StreamReader reader = new StreamReader(args[0]);
            AntlrInputStream stream = new AntlrInputStream(reader);
            BNFLexer lexer = new BNFLexer(stream);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            BNFParser parser = new BNFParser(tokens);
            IParseTree root = parser.compileUnit();
            Console.WriteLine(root.ToStringTree());
}
还提供了以下用于测试语法的测试文件

 compileunit : x a
        ;

 x : S b
   ;

 S : compileunit f
  ;
请注意,从lexer语法中,非终端以小写字母开头,而终端以大写字母开头。给定的语法有一个错误。第三条规则使用大写字母来定义非终端。预期的行为是将其报告为错误。相反,解析通过使用前2条规则并忽略第3条规则来成功,而不报告任何错误。我还看到了生成的文件,并注意到以下内容

try {
    EnterOuterAlt(_localctx, 1);
    {
    State = 7;
    _errHandler.Sync(this);
    _la = _input.La(1);
    do {
        {
        {
        State = 6; grammar_rule();
        }
        }
        State = 9;
        _errHandler.Sync(this);
        _la = _input.La(1);
    } while ( _la==NON_TERMINAL );
    }
 }
 catch (RecognitionException re) {
     _localctx.exception = re;
     _errHandler.ReportError(this, re);
     _errHandler.Recover(this, re);
 }

上面的代码表明解析器希望语法规则的开头有一个非终结符符号,这正是我所期望的。然而,如果情况并非如此,会发生什么?另一个奇怪的问题是,包含lexer识别的令牌的CommonTokenStream对象只包含第二条规则结束之前的令牌,而不包含第三条规则的令牌。这是正确的行为吗?

将EOF令牌添加到主规则(
compileUnit
)。这将迫使解析器在EOF之前使用所有输入,如果不完全匹配,则报告错误

 compileunit : x a
        ;

 x : S b
   ;

 S : compileunit f
  ;
try {
    EnterOuterAlt(_localctx, 1);
    {
    State = 7;
    _errHandler.Sync(this);
    _la = _input.La(1);
    do {
        {
        {
        State = 6; grammar_rule();
        }
        }
        State = 9;
        _errHandler.Sync(this);
        _la = _input.La(1);
    } while ( _la==NON_TERMINAL );
    }
 }
 catch (RecognitionException re) {
     _localctx.exception = re;
     _errHandler.ReportError(this, re);
     _errHandler.Recover(this, re);
 }