Je ne suis pas sûr à 100% pourquoi vous obtenez cette erreur : Il faudrait que je voie toute votre grammaire pour le savoir. Quoi qu'il en soit, il n'est pas nécessaire de vérifier les deux éléments suivants is_a
et !is_a
. Et les deux $is_a
y is_a
sont valables.
Imaginons que vous analysiez une liste de nombres, et que tous les 4 nombres, vous souhaitiez passer par une "branche" différente. Une grammaire pour cela ressemblerait à :
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();}
;
(notez que le %
est un caractère réservé dans les grammaires ANTLR (mais pas dans les chaînes de caractères et les commentaires), il faut donc l'échapper avec une barre oblique inversée.)
Et peut être testé avec la classe :
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();
}
}
Maintenant, générez un analyseur/lexeur (A), compilez tous les fichiers sources (B) et exécutez la classe principale (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
(sous Windows, exécutez-le en faisant java -cp .;antlr-3.2.jar Main
)
qui produit le résultat suivant :
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
Donc, oui, vous aviez besoin d'un "prédicat sémantique gated" ( {boolean}?=>
) dans ce cas, et non un "Validation du prédicat sémantique" ( {boolean}?
). La différence entre les deux prédicats est expliquée dans ce précédent Q&R de SO : Qu'est-ce qu'un "prédicat sémantique" dans ANTLR ?