Reputation: 1581
Basically, I've extended the BaseErrorListener, and I need to know when the error is semantic and when it's syntactic. So I want the following to give me a failed predicate exception, but I'm getting a NoViableAltException
instead (I know the counting is working, because I can print out the value of things
, and it's correct). Is there a way I can re-work it to do what I want? In my example below, I want there to be a failed predicate exception if we don't end up with 6 things
.
grammar Test;
@parser::members {
int things = 0;
}
.
.
.
samplerule : THING { things++; } ;
.
.
.
// Want this to be a failed predicate instead of NoViableAltException
anotherrule : ENDTOKEN { things == 6 }? ;
.
.
.
I'm already properly getting failed predicate exceptions with the following (for a different scenario):
somerule : { Integer.valueOf(getCurrentToken().getText()) < 256 }? NUMBER ;
.
.
.
NUMBER : [0-9]+ ;
Upvotes: 0
Views: 1572
Reputation: 1581
Due to 280Z28's answer and the apparent fact that predicates should not be used for what I was trying to do, I went a different route.
If you know what you're looking for, ANTLR4's documentation is actually pretty useful--visit Parser.getCurrentToken()'s documentation and poke around further to see what more you can do with my implementation below.
My driver ended up looking something like the following:
// NameOfMyGrammar.java
public class NameOfMyGrammar {
public static void main(String[] args) throws Exception {
String inputFile = args[0];
try {
ANTLRInputStream input = new ANTLRFileStream(inputFile);
NameOfMyGrammarLexer lexer = new NameOfMyGrammarLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
MyCustomParser parser = new MyCustomParser(tokens);
try {
// begin parsing at "start" rule
ParseTree tree = parser.start();
// can print out parse tree if you want..
} catch (RuntimeException e) {
// Handle errors if you want..
}
} catch (IOException e) {
System.err.println("Error: " + e);
}
}
// extend ANTLR-generated parser
private static class MyCustomParser extends NameOfMyGrammarParser {
// Constructor (my understanding is that you DO need this)
public MyCustomParser(TokenStream input) {
super(input);
}
@Override
public Token getCurrentToken() {
// Do your semantic checking as you encounter tokens here..
// Depending on how you want to handle your errors, you can
// throw exceptions, print out errors, etc.
// Make sure you end by returning the current token
return _input.LT(1);
}
}
}
Upvotes: 0
Reputation: 99989
In ANTLR 4, predicates should only be used in cases where your input leads to two different possible parse trees (ambiguous grammar) and the default handling is producing the wrong parse tree. You should create a listener or visitor implementation containing your logic for semantic validation of the source.
Upvotes: 1