2017-06-13 2 views
0

Ich verwende die Java-Grammatik ANTLR v4, verfügbar here, um Java-Code zu analysieren. Eine der Produktionen sieht wie folgt aus:Warum werden diese Muster in dieser ANTLR-Produktion nicht erreicht?

expression 
    : primary 
    | expression '.' Identifier 
    | expression '.' 'this' 
    | expression '.' 'new' nonWildcardTypeArguments? innerCreator 
    | expression '.' 'super' superSuffix 
    | expression '.' explicitGenericInvocation 
    | expression '[' expression ']' 
    | expression arguments 
    | // Lots of other patterns... 
    ; 

expression '.' Identifier entspricht einem einfachen Mitglied Zugang und expression arguments entspricht einem Methodenaufruf. Sie können die vollständige Quelle dieser Produktion here ansehen.

Zum Zwecke der Syntaxhervorhebung möchte ich zusätzliche redundante Muster einführen, um zu erkennen, was ich benannte Methodenaufrufe. bar() oder foo.bar() würde als Aufruf einer benannten Methode zählen, wobei bar der Name der Methode ist. Für solche Ausdrücke möchte ich, dass bar grün gefärbt wird, obwohl Kennungen normalerweise weiß gefärbt sind. In foo.bar oder foo.bar[0]() sollte jedoch nichts grün gefärbt sein. In der ehemaligen bar ruft keine Methode, und in letzterer bar[0] ist keine gültige Kennung.

Ich habe diese beiden zusätzlichen Muster vor expression arguments (Anmerkung: arguments mit '(' expressionList? ')' in dem ursprünglichen Quellcode ist ein Synonym.):

expression 
    : // ... 
    | expression '[' expression ']' 
    | Identifier arguments namedMethodInvocationStub // Detect bar() 
    | expression '.' Identifier arguments namedMethodInvocationStub // Detect (some().complicated().expression()).bar() 
    | expression arguments 
    | // ... 
    ; 

namedMethodInvocationStub 
    : 
    ; 

(Hier namedMethodInvocationStub eine zusätzliche Dummy-Produktion, die ich hinzugefügt haben Die Idee kann ich überschreiben VisitExpression und überprüfen, ob das letzte Kind ist ein namedMethodInvocationStub. Wenn ja, dann haben wir eine benannte Methode Aufruf, so gehen Sie durch alle direkten Kinder des Typs Identifier und färben sie grün.Allerdings ist dies nur zu entmystifizieren, was das heißt, es ist nicht direkt mit meiner Frage unten verbunden.)

Ich erwartete diese Regeländerung zu machen foo.bar(), die zuvor als (expression '.' Identifier) arguments geparst hatte, jetzt als expression '.' Identifier arguments namedMethodInvocationStub parsen. Es analysiert jedoch immer noch die gleiche Weise wie zuvor, ob ich die namedMethodInvocationStub entferne oder nicht. Warum ist das?

Antwort

0

Ich glaube, Sie nicht leere Regel/Token (namedMethodInvocationStub) in ANTLR (oder jede andere Lexer) mithalten können

ANTLR: empty condition not working

What is the equivalent for epsilon in ANTLR BNF grammar notation?

sehen Sie alle Fehler/Warnung während ANTLR Code Generationsphase?

+0

Es scheint jedoch zu geschehen mit oder ohne 'namedMethodInvocationStub'. –

+0

Ich habe nicht gefunden Muster "Ausdruck Argumente" an der Stelle, die Sie bereitgestellt haben https://github.com/antlr/grammars-v4/blob/master/java/Java.g4#L497-L538 –

+0

Sorry, ich zwickte der Code ein wenig, um es besser zu machen. 'arguments' ist ein anderes nonterminal ([hier] (https://github.com/antlr/grammmars-v4/blob/master/java/Java.g4#L604-L606)) synonym mit' '(' expressionList? ') "". –

Verwandte Themen