ANTLR错误始终是"在输入时没有可行的替代方案"

时间:2015-09-29 19:36:22

标签: c# antlr antlr4

我试图通过实施ANTLR

向用户显示BaseErrorListener个错误
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世界语法,如果我输入token recognition error,我可以得到2 + e之类的其他错误。如果我输入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)
    ;

1 个答案:

答案 0 :(得分:0)

  

我的语法有问题吗?

没有。问题(如果有的话)是了解Antlr在错误点正在做什么。规则堆栈将显示成功调用规则的顺序。在这种情况下,只有prog只会expr alts完全匹配(或者甚至可能没有prog完成)。所有Antlr都可以肯定地说,从输入column >开始,它找不到任何匹配的规则的替代。

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