2017-09-29 4 views
0

me reste que cette grammaire:Comment ne pas compter le nombre d'éléments dans la fonction de sortie antlr listener?

xor_expression 
    : or_expression (XOR or_expression)* 
    ; 

Comment puis-je compter combien de répétitions (XOR or_expression)* est produit dans cette règle. Ceci est nécessaire pour obtenir de la pile un nombre valide d'arguments. Par exemple pour 1 xor 1 xor 1 - J'ai besoin de 3 pour 1 xor 1 J'ai besoin de 2, etc.

Cela me donne total des enfants, mais ce n'est pas pertinent.

public override void ExitXor_expression([NotNull] preprintParser.Xor_expressionContext context) 
{ 
    Debug.WriteLine(context.ChildCount); 
} 
+0

Pourquoi ne passez-vous pas tous les enfants et ne comptez pas ceux qui sont de type 'or_expressionContext'? – Raven

Répondre

0

Pour compter le nombre de or_expression enfants dans la règle, utilisez des étiquettes:

xor_expression 
    : expr+=or_expression (XOR expr+=or_expression)* 
    ; 

Cela produira, dans le Xor_expressionContext, un champ

List<ParseTree> expr; 

contenant les or_expression cas effectivement apparié. Évidemment, expr.size() donnera alors le compte demandé.

0
grammar Question; 

/* Count xor. */ 

question 
@init {System.out.println("Question last update 1950");} 
    : expr+ EOF 
    ; 

expr 
    : xor_expression 
    ; 

xor_expression 
    : or_expression (xors+='xor' or_expression)* 
     {System.out.println($text + " : " + $ctx.or_expression().size() + " or_expression with " + $ctx.xors.size() + " XOR");} 
    ; 

or_expression 
    : atom 
    ; 

atom 
    : ID 
    | NUMBER 
    ; 

ID  : [a-z]+ ; 
NUMBER : [0-9]+ ; 
WS  : [ \t\r\n]+ -> channel(HIDDEN) ; 

fichier d'entrée t.text:

1 xor 1 
1 xor 1 xor 1 

Exécution avec Antlr 4.6:

$ grun Question question -tokens -diagnostics t.text 
[@0,0:0='1',<NUMBER>,1:0] 
[@1,1:1=' ',<WS>,channel=1,1:1] 
[@2,2:4='xor',<'xor'>,1:2] 
[@3,5:5=' ',<WS>,channel=1,1:5] 
[@4,6:6='1',<NUMBER>,1:6] 
... 
[@16,22:21='<EOF>',<EOF>,3:0] 
Question last update 1950 
1 xor 1 : 2 or_expression with 1 XOR 
1 xor 1 xor 1 : 3 or_expression with 2 XOR 

Ces chiffres doivent être accessibles à partir de l'auditeur. Ils appartiennent au contexte de la règle. Extrait du Parser:

public static class Xor_expressionContext extends ParserRuleContext { 
    public Token s1; 
    public List<Token> xors = new ArrayList<Token>(); 
    public List<Or_expressionContext> or_expression() { 
     return getRuleContexts(Or_expressionContext.class); 
    } 
0

I (1) modifié votre grammaire un peu, en ajoutant une règle de visiteur, l'appelant XOR:

// file xor.g4 
grammar: xor ; 
prog : xor_expression+ EOF ; 
xor_expression 
    : or_expression (XOR or_expression)* NEWLINE   #XOR 
    ; 
or_expression : 'true' | 'false' ; 
XOR : 'XOR' ; 
WS : [ \t]+ -> skip ; // toss out whitespace 
NEWLINE : '\r'? '\n' ; 

Ensuite, antlr xor.g4 -visitor génère automatiquement une impl de base des visiteurs dans xorBaseVisitor.java qui inclut une méthode visitXOR(xorParser.XORContext ctx). (2) J'étendu cette classe et réimplémentées cette méthode, où je peux obtenir les deux types de compte - jetons ou « parties réelles » (je ne sais pas ce qu'ils sont appelés CS)

public Integer visitXOR(xorParser.XORContext ctx) { 
    List<xorParser.Or_expressionContext> mylist = ctx.or_expression(); 
    System.out.println("visitXOR - #or children = " + mylist.size()); 
    System.out.println("visitXOR - #getChildCount() = " + ctx.getChildCount()); 
    for(xorParser.Or_expressionContext x : mylist) { 
      System.out.println("\t" + x.getText()); 
    } 
    return 0; 
} 

La clé ce qui se trouve dans xorParser.java génère une classe de contexte de la règle avec une méthode pour retourner une liste de or_expression s

public static class XORContext extends Xor_expressionContext { 
    public List<Or_expressionContext> or_expression() { 
     return getRuleContexts(Or_expressionContext.class); 
    } 
... 

Voici un échantillon analysé

$ antlr4 -visitor -no-listener xor.g4 && javac -g XorTest.java *xor*java 
Note: XorTest.java uses or overrides a deprecated API. 
Note: Recompile with -Xlint:deprecation for details. 
$ java XorTest 
true 
true XOR false XOR true 
^D 
visitXOR - #or children = 1 
visitXOR - #getChildCount() = 2 
     true 
visitXOR - #or children = 3 
visitXOR - #getChildCount() = 6 
     true 
     false 
     true 
$ 

HTH