2010-10-15 9 views
5

ich ein Token von '..' im antlr3 Lexer erstellen möchten, die wieantlr3 Lexer Vorrang

a..b  // [1] 
c .. x // [2] 
1..2  // [3] 
3 .. 4 // [4] 
So

aneinanderzureihen Ausdrücke verwendet werden, ich hinzugefügt haben,

DOTDOTSEP : '..' 
      ; 

Das Problem ist, dass ich bereits eine Regel:

FLOAT : INT (('.' INT (('e'|'E') INT)? 'f'?) | (('e'|'E') INT)? ('f')) 
     ; 

Und in Beispiel [3] über 1..2 i s wird als FLOAT gematcht (ich bin mir nicht sicher, warum seit der ersten . ist eine andere . kein INT, aber es ist).

Ich frage mich, ob es eine Möglichkeit gibt, den Vorrang der Lexer-Regeln zu ändern, so DOTDOTSEP wird zuerst und dann FLOAT.

Mit Blick auf here scheint es, ich bin zu verlieren, "The rule having the greatest count is the winner.", aber frage mich, ob es einen Weg gibt.

P.S. INT wie unten definiert ist ...

fragment DIGIT 
    : '0'..'9' 
    ; 

INT : DIGIT+ 
    ; 

bearbeiten. Ein paar weitere Tests lassen mich denken, dass es nicht ganz so einfach ist, wie es direkt an die FLOAT Regel angepasst wird. (Ich wollte die Frage ändern, aber da ich jetzt Antworten habe, werde ich das nicht tun.) Das Problem (glaube ich) liegt immer noch in der Vorrangstellung der Lexerregeln, so dass die Frage immer noch dieselbe bleibt.

Antwort

7

Haben Sie sich http://sds.sourceforge.net/src/antlr/doc/lexer.html angesehen?

Eine mögliche Lösung ist die folgende Definition:

fragment 
INT : DIGIT+ 
    ; 

fragment 
RANGE : INT DOTDOTSEP INT 
     ; 

fragment 
FLOAT : INT (('.' INT (('e'|'E') INT)? 'f'?) | (('e'|'E') INT)? ('f')) 
     ; 

NUMBER 
    : (INT '.') => FLOAT  { $type=FLOAT; } 
    | (INT DOTDOTSEP) => RANGE { $type=RANGE; } 
    | INT      { $type=INT; } 
    ; 
+0

Das wird immer mir viel näher, nur ein wenig mehr Optimierungen erforderlich. Der Link hatte ich nicht gefunden, aber er sieht gut aus; genau die Art von Sache, die ich lesen sollte, also mache ich jetzt das. Vielen Dank. – tjm

+0

Ich habe es jetzt gut gemacht, nur ein paar Notizen für irgendjemand anderen, der damit kommen könnte. In ANTLRWorks v1.4 kann der Interpreter nicht mit Prädikaten umgehen, daher sieht es so aus, als gäbe es Fehler, wenn nicht (was mich etwas verlangsamte), und ich musste '$ settype (TYPE);' in 'ändern $ type = TYPE; ' – tjm

+0

@tjm, ich habe das ANTLR-Sample leicht bearbeitet. Ist es jetzt v3 kompatibel? –