在Antlr4,C#中,错误处理未按预期触发

shu*_*i17 6 c# antlr antlr4

在Antlr 4中,我有一个语法,它采用x*Y,x + y等格式的字符串

我想在使用无效运算符时捕获错误,例如x和y.如果我添加如下代码:

parser.RemoveErrorListeners();
parser.AddErrorListener(new MyErrorListener());
Run Code Online (Sandbox Code Playgroud)

并将MyErrorListener定义为:

public class MyErrorListener : BaseErrorListener
{
    public override void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
    {
Run Code Online (Sandbox Code Playgroud)

...

在X&Y情况下没有调用SyntaxError ....但是将在X&case中调用...

我很困惑,因为控制台监听器将显示两个表单的错误,但我的自定义不会.我真正想做的就是说"如果有任何类型的解析错误,请执行x",但我似乎无法弄清楚这一点.

救命!

这是语法btw的一部分:

equation  : boolEquation (op=(AND|OR)  boolEquation)*  ;
boolEquation : NOT? boolExpression ;
boolExpression   : 
    left=expression (op=relop right=expression)?    #BoolExpressionMatch  ;
expression   : 
      name=ID LPAREN expList=expressionList RPAREN  #FunctionMatch
      | left=expression op=(TIMES | DIV | MODULUS) right=expression # ExpressionMatch
      | left=expression op=(PLUS | MINUS) right=expression                  #ExpressionMatch
      | LPAREN expression RPAREN                                            #ParenthesizedExpressionMatch
      | atom                                                                #AtomMatch   ;

atom   : number                       #NumberMatch
   | string                     #StringMatch
   | variable                   #AtomVariableMatch
   | unaryValue                  #UnaryValueMatch
   | boolean                      #BooleanMatch   ;
string    :    ID    ;
boolean    :   TRUE    |   FALSE;
unaryValue    :  EMPTY    |  PRESENT    ;
func   : name=ID LPAREN expList=expressionList RPAREN   ;
expressionList   : (expression (COMMA expression)*)?   ;
variable   :  WORD(POINT WORD)*     #VariableMatch   ;
Run Code Online (Sandbox Code Playgroud)

...

有趣的是,即使我删除了所有的错误监听器,我仍然会看到这个输出到控制台:第1:1行令牌识别错误:'?'

Mik*_*hke 0

在没有看到你的语法的情况下,我只能猜测出了什么问题,但我假设你有一个规则接受 & 作为它的一部分,所以当你输入它时,它X&Y被接受为令牌,因此是有效的输入。

在这种情况下,调试的第一步应该是打印出词法分析器看到的所有标记的列表。看TokenStream.getTokens()。这将显示标记是否按照您编写语法时所期望的方式被识别。