2010-10-15 14 views
5

Voglio creare un token da '..' nel lexer ANTLR3 che verrà utilizzato di stringa insieme espressioni comeANTLR3 lexer precedenza

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

Così, ho aggiunto,

DOTDOTSEP : '..' 
      ; 

Il problema è che ho già una regola:

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

E nell'esempio [3] sopra i 1..2 s viene abbinato come un FLOAT (non so perché, dal momento che seguire il primo . è un altro . non un INT, ma lo è).

Mi chiedo se c'è un modo per modificare la precedenza delle regole del lexer in modo che DOTDOTSEP venga abbinato prima e poi FLOAT.

Alla ricerca di here sembra che mi stia perdendo, "The rule having the greatest count is the winner.", ma mi chiedo se c'è un modo per aggirarlo.

P.S. INT è definito come di seguito ...

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

INT : DIGIT+ 
    ; 

Modifica. Un po 'più di test mi fa pensare che non è così semplice come si arriva direttamente alla regola FLOAT. (Stavo per cambiare la domanda, ma dato che ora ho delle risposte, non lo farò.) Il problema (credo) risiede ancora nella precedenza delle regole lessicali, quindi la domanda rimane la stessa.

risposta

7

Hai guardato a http://sds.sourceforge.net/src/antlr/doc/lexer.html?

Una possibile soluzione è quella di definire quanto segue:

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

Questo mi sta facendo molto più vicino, solo un po 'più di tweaking necessario. Il link che non avevo trovato, ma sembra fantastico; solo il genere di cosa che dovrei leggere, quindi ora me ne vado. Grazie. – tjm

+0

Ora sto andando bene, solo un paio di note per chiunque altro possa venire da questo. In ANTLRWorks v1.4, l'interprete non può gestire i predicati, quindi sembra che ci siano degli errori quando non ci sono (che mi ha rallentato un po ') e inoltre ho dovuto cambiare '$ settype (TYPE);' a ' $ type = TYPE; ' – tjm

+0

@tjm, ho modificato leggermente il campione ANTLR. È ora compatibile con v3? –