How to report errors from ANTLR 4 Visitor?
Asked Answered
K

1

6

I created a grammar for boolean expressions and now I'm trying to implement visitor for evaluating it.

It is told that there is no need to overcomplicate grammar lexer and parser rules with semantic analysis because it is much better to provide meaningful error messages from the Visitor.

So I'm trying to check type consistency, date correctness etc in the Visitor. And the surprise I get is there is no way (at least I don't see it) to report an error from the Visitor other than throwing exceptions. And if I throw an exception I won't be able to proceed with expression validation and detect all errors at once. In addition I have to catch somehow all parsing exception types (how should I know them?). All in all, exception throwing doesn't seem to be correct solution.

Could you give me a direction how it is planned to report errors in expression semantics during Visitor traversal?

Kumamoto answered 3/9, 2015 at 16:33 Comment(0)
K
10

Since you define the visitor, you can create and pass it an object it will report errors to.

Simple example:

public interface IErrorReporter
{
    void ReportError(ParserRuleContext context, string error);
}
public class ValidationVisitor : YourLanguageBaseVisitor<Whatever>
{
    private readonly IErrorReporter _errorReporter;

    public ValidationVisitor(IErrorReporter errorReporter)
    {
        _errorReporter = errorReporter;
    }

    public override Whatever VisitSomeNode(YourLanguageParser.SomeNodeContext context)
    {
        if (context.GetText() != "expected")
            _errorReporter.ReportError(context, "Invalid text");

        return Visit(context.someSubNode());
    }
}

Then validate like this:

var parseTree = DoTheParsingStuff();

// Implement that one, store the errors in a list
var errorReporter = new SimpleErrorReporter();  

new ValidationVisitor(errorReporter).Visit(parseTree);

if (errorReporter.Errors.Count > 0)
{
    // Display errors
}

The ParserRuleContext can be useful to locate where the error occurred (line/column etc), but otherwise you may implement whatever fits your error reporting needs.


Side note: If you plan on having many visitors, then building an AST and then validating based on that may be beneficial in the long run. You need to decide whether it's worth it.

Koerner answered 3/9, 2015 at 17:8 Comment(3)
Thank you for the answer. That's an option. Do you know if it is correct way of doing it or just a workaround? As I see, Lexer and Parser have common mechanism of errorListeners for reporting errors. I was surprised visitor don't.Kumamoto
That's a simplified version of what I do, and it works very well. There's no standard way, as you're free to do whatever you want in visitors/listeners. Lexers/parsers need an error reporting mechanism, but visitors and listeners don't need that in the general case.Koerner
Also worth noting, Lexer and Parser only report syntax errors. The listener and visitor can check whether a syntactically correct input is semantically valid by checking the current context, previous values etc. - eg a country code has two letters but is XX a valid country code? Is it a country we do business with ? etcFreedwoman

© 2022 - 2024 — McMap. All rights reserved.