R71
R71

Reputation: 4523

How to override error reporting in c++ target of antlr4?

To report errors in a different way in antlr4-java target, we do the following:

(1) define a new listener:

class DescriptiveErrorListener extends BaseErrorListener {
    public static DescriptiveErrorListener INSTANCE =
        new DescriptiveErrorListener();
    @Override
    public void syntaxError(Recognizer<?, ?> recognizer,
            Object offendingSymbol,
                        int line, int charPositionInLine,
                        String msg, RecognitionException e)
    {
        String printMsg = String.format("ERR: %s:%d:%d: %s",
            recognizer.getInputStream().getSourceName(), line,
            charPositionInLine+1, msg);
        System.err.println(printMsg);
    }
}

(2) override the reporter for lexer and parser:

lexer.removeErrorListeners();
lexer.addErrorListener(DescriptiveErrorListener.INSTANCE);
..
parser.removeErrorListeners();
parser.addErrorListener(DescriptiveErrorListener.INSTANCE);

What would be the corresponding code in c++ target?

Upvotes: 1

Views: 1324

Answers (1)

Mike Lischke
Mike Lischke

Reputation: 53357

In C++ it's almost identical (aside from the language specific aspects). Code I use:

    struct MySQLParserContextImpl : public MySQLParserContext {
      ANTLRInputStream input;
      MySQLLexer lexer;
      CommonTokenStream tokens;
      MySQLParser parser;
      LexerErrorListener lexerErrorListener;
      ParserErrorListener parserErrorListener;
      ...    
      MySQLParserContextImpl(...)
        : lexer(&input), tokens(&lexer), parser(&tokens), lexerErrorListener(this), parserErrorListener(this),... {
    
      ...    
        lexer.removeErrorListeners();
        lexer.addErrorListener(&lexerErrorListener);
    
        parser.removeParseListeners();
        parser.removeErrorListeners();
        parser.addErrorListener(&parserErrorListener);
      }
    
      ...
    }

and the listeners:

    class LexerErrorListener : public BaseErrorListener {
    public:
      MySQLParserContextImpl *owner;
    
      LexerErrorListener(MySQLParserContextImpl *aOwner) : owner(aOwner) {}
    
      virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, size_t charPositionInLine,
                               const std::string &msg, std::exception_ptr e) override;
     };
    
    class ParserErrorListener : public BaseErrorListener {
    public:
      MySQLParserContextImpl *owner;
    
      ParserErrorListener(MySQLParserContextImpl *aOwner) : owner(aOwner) {}
    
      virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, size_t charPositionInLine,
                               const std::string &msg, std::exception_ptr e) override;
    };

Upvotes: 6

Related Questions