ANTLR错误总是“在输入处没有可行的替代”

本文关键字:错误 输入 ANTLR | 更新日期: 2023-09-27 18:15:22

我试图通过实现BaseErrorListener向用户显示ANTLR错误

public class CustomErrorListener :BaseErrorListener
{
        public override void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
        {
            List<string> stack = ((Parser)recognizer).GetRuleInvocationStack().ToList();
            stack.Reverse();
            Debug.WriteLine("rule stack: " + stack);
            Debug.WriteLine("line " + line + ":" + charPositionInLine + " at " + offendingSymbol + ": " + msg);
        }
}

但是我总是得到no viable alternative at input错误

与以下语法

prog : expr+ EOF;
expr : COLUMN LESSTHAN DECIMAL BIGGERTHAN DECIMAL  # range
     | COLUMN BIGGERTHAN DECIMAL LESSTHAN DECIMAL  # inversedRange
     | COLUMN operator DECIMAL                     # simple
     ;
operator : LESSTHAN | BIGGERTHAN | EQUALS;
COLUMN     : 'all'? ('column' | 'otherColumn')
DECIMAL    : [0-9]+ '.'? [0-9]*;
LESSTHAN   : '<' | '<=';
BIGGERTHAN : '>' | '>=';
EQUALS     : '=';
WS         : [ 'r'n't] -> channel(HIDDEN); 

如果我输入column >我希望出现decimal is missing而不是no viable alternative at input column >这样的错误

我的语法有问题吗?

编辑

我问这个问题是因为我的hello world语法,如果我输入2 + e,我可以得到其他错误,如token recognition error。如果我输入column > d

,我希望我的语法也一样
/*
 * Parser Rules
 */
prog: expr+ ;
expr : expr op=('*'|'/') expr   # MulDiv
     | expr op=('+'|'-') expr   # AddSub
     | INT                      # int
     | '(' expr ')'             # parens
     ;
/*
 * Lexer Rules
 */
INT : [0-9]+;
MUL : '*';
DIV : '/';
ADD : '+';
SUB : '-';
WS
    :   (' ' | ''r' | ''n') -> channel(HIDDEN)
    ;

ANTLR错误总是“在输入处没有可行的替代”

我的语法有问题吗?

。如果有的话,问题在于理解Antlr在错误点上正在做什么。规则堆栈将显示成功调用的规则序列。在这种情况下,只有prog,因为没有一个expr选项完全匹配(或者可能没有,因为prog甚至没有完成)。Antlr所能确定的是,从输入column >开始,它找不到任何匹配的规则。

调试此类错误的最佳方法是使用规则堆栈在令牌流中定位错误点,并转储后面的令牌。这里转储的令牌将是<COLUMN> <BIGGERTHAN> <EOF>,使错误的性质清楚。