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: '('
For example
if(tree.hasError()) // FOR EXAMPLE
return;
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.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With