In Antlr4, C#, Error Handling isn't getting fired as expected
Asked Answered
M

2

6

In Antlr 4, I have a grammar which takes strings of format x*Y, x+y, etc

I want to catch an error when an invalid operator is used, such as x&y. If I add code like:

parser.RemoveErrorListeners();
parser.AddErrorListener(new MyErrorListener());

And define MyErrorListener as :

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

...

SyntaxError isn't called in the X&Y case....but will be called in the X& case...

I am thoroughly confused, as the console listener will show an error for both forms, yet my custom one won't. All I really want to be able to do is say "If there is a parsing error of any kind, do x" but I can't seem to figure this out.

Help!

Here is part of the grammar 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   ;

...

Interestingly enough, even when I remove all the error listeners, I still see this output to the console: line 1:1 token recognition error at: '?'

Metabolize answered 9/5, 2016 at 22:41 Comment(1)
There might be recovery logic you need to disable if you want to listen to all errors.Whiffletree
Y
0

Without seeing your grammar I can only guess what's wrong, but I assume you have a rule that accepts & as part of it, so when you feed in X&Y it is accepted as a token and hence valid input.

In cases like this the first step to debug should be to print out a list of all tokens the lexer sees. See TokenStream.getTokens(). This will show you if tokens are recognized the way you expected them when you wrote your grammar.

Yellowgreen answered 10/5, 2016 at 6:57 Comment(1)
I appreciate the answer, btut I don't accept x&y anywhere in my grammar. I even tried changing to x?y with the same problem.Metabolize
M
0

I figured it out. Essentially, the problem was it was a Lexical error, not a syntax error. So replacing the lexical analyzer's Error Listener did the trick.

Metabolize answered 10/5, 2016 at 16:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.