I'm not 100% sure why you get that error: I'd need to see your entire grammar for that. Anyway, there is no need to check for both is_a
and !is_a
. And both $is_a
and is_a
are valid.
Let's say you're parsing a list of numbers, and every 4th number, you want to handle through a different "branch". A grammar for that would look like:
grammar T;
parse
@init{int n = 1;}
: (number[n\%4 == 0] {n++;})+ EOF
;
number [boolean multipleOf4]
: {multipleOf4}?=> Int {System.out.println("branch A -> " + $Int.text);}
| Int {System.out.println("branch B :: " + $Int.text);}
;
Int
: '0'..'9'+
;
Space
: (' ' | '\t' | '\r' | '\n') {skip();}
;
(note that the %
is a reserved character inside ANTLR grammars (not inside String literals and comments though), so it needs escaping with a backslash)
And can be tested with the class:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("11 22 33 44 55 66 77 88 99");
TLexer lexer = new TLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
TParser parser = new TParser(tokens);
parser.parse();
}
}
Now generate a parser/lexer (A), compile all source files (B) and run the main class (C):
java -cp antlr-3.2.jar org.antlr.Tool T.g // A
javac -cp antlr-3.2.jar *.java // B
java -cp .:antlr-3.2.jar Main // C
(on Windows, run it by doing java -cp .;antlr-3.2.jar Main
)
which produces the following output:
branch B :: 11
branch B :: 22
branch B :: 33
branch A -> 44
branch B :: 55
branch B :: 66
branch B :: 77
branch A -> 88
branch B :: 99
So, yes, you needed a "gated semantic predicate" ({boolean}?=>
) in this case, not a "validating semantic predicate" ({boolean}?
). The difference between the two predicates is explained in this previous SO Q&A: What is a 'semantic predicate' in ANTLR?