Get all Antlr parsing errors as list of string
Asked Answered
M

2

20
  • How can I get all parsing errors of Antlr in a list of strings?

I use antlr as follows:

ANTLRInputStream input = new ANTLRInputStream(System.in);
grLexer lexer = new grLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
grParser parser = new grParser(tokens);
ParseTree tree = parser.formula();
System.out.println(tree.toStringTree(parser));

For example

line 1:0 token recognition error at: '('
line 1:1 token recognition error at: ')'
line 1:2 token recognition error at: '('
  • How can I find out that parsing is executed without an error? I would stop if there is only one parsing error.

For example

if(tree.hasError()) // FOR EXAMPLE
   return;
Murdocca answered 9/2, 2014 at 16:46 Comment(0)
M
21
  • You need to provide an implementation of ANTLRErrorListener to gather information about the errors that occur. For example, the IntelliJ plugin uses its SyntaxErrorListener to track this information.

  • You can check Parser.getNumberOfSyntaxErrors() after the parse is complete to see if an error occurred. Note that this doesn't report errors from the lexer. The best way to make sure all errors are reported properly is to write your lexer in such a way that it can never encounter a syntax error itself, but instead passes invalid tokens on to the parser for handling.

Mcbroom answered 9/2, 2014 at 18:19 Comment(0)
R
12

Similar to how Sam Harwell described it, the following code demonstrates getting a list of the syntax errors after invoking a parser rule such as functionDefinition for a C parser:

Syntax checker:

import c.grammar.CLexer;
import c.grammar.CParser;
import org.antlr.v4.runtime.CodePointCharStream;
import org.antlr.v4.runtime.CommonTokenStream;

import java.util.List;

import static org.antlr.v4.runtime.CharStreams.fromString;

public class CSyntaxChecker
{
    public static List<SyntaxError> getSyntaxErrors(String sourceCode)
    {
        CodePointCharStream inputStream = fromString(sourceCode);
        CLexer lexer = new CLexer(inputStream);
        CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
        CParser parser = new CParser(commonTokenStream);
        SyntaxErrorListener listener = new SyntaxErrorListener();
        parser.addErrorListener(listener);
        parser.functionDefinition();

        return listener.getSyntaxErrors();
    }
}

Syntax error listener:

import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.misc.Utils;

import java.util.ArrayList;
import java.util.List;

public class SyntaxErrorListener extends BaseErrorListener
{
    private final List<SyntaxError> syntaxErrors = new ArrayList<>();

    SyntaxErrorListener()
    {
    }

    List<SyntaxError> getSyntaxErrors()
    {
        return syntaxErrors;
    }

    @Override
    public void syntaxError(Recognizer<?, ?> recognizer,
                            Object offendingSymbol,
                            int line, int charPositionInLine,
                            String msg, RecognitionException e)
    {
        syntaxErrors.add(new SyntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e));
    }

    @Override
    public String toString()
    {
        return Utils.join(syntaxErrors.iterator(), "\n");
    }
}

Syntax error:

import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;

public class SyntaxError
{
    private final Recognizer<?, ?> recognizer;
    private final Object offendingSymbol;
    private final int line;
    private final int charPositionInLine;
    private final String message;
    private final RecognitionException e;

    SyntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e)
    {
        this.recognizer = recognizer;
        this.offendingSymbol = offendingSymbol;
        this.line = line;
        this.charPositionInLine = charPositionInLine;
        this.message = msg;
        this.e = e;
    }

    public Recognizer<?, ?> getRecognizer()
    {
        return recognizer;
    }

    public Object getOffendingSymbol()
    {
        return offendingSymbol;
    }

    public int getLine()
    {
        return line;
    }

    public int getCharPositionInLine()
    {
        return charPositionInLine;
    }

    public String getMessage()
    {
        return message;
    }

    public RecognitionException getException()
    {
        return e;
    }
}
Russia answered 17/7, 2018 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.