2010-10-15 21 views
5

Quiero crear un token de '..' en el léxico ANTLR3 que se utiliza para encadenar expresiones comoANTLR3 lexer precedencia

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

lo tanto, he añadido,

DOTDOTSEP : '..' 
      ; 

El problema es que ya tengo una regla:

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

Y en el ejemplo [3] por encima de 1..2 i s coincidiendo como un FLOAT (no estoy seguro de por qué desde el siguiente . es otro . no es un INT, pero lo es).

Me pregunto si hay una manera de cambiar la precedencia de las reglas del lexer para que DOTDOTSEP coincida primero y luego FLOAT.

Buscando here parece que estoy perdiendo, "The rule having the greatest count is the winner.",, pero me pregunto si hay una forma de evitarlo.

P.S. INT se define de la siguiente manera ...

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

INT : DIGIT+ 
    ; 

Editar. Un poco más de prueba me hace pensar que no es tan simple como hacer coincidir directamente con la regla FLOAT. (Iba a cambiar la pregunta, pero dado que tengo respuestas ahora, no lo haré). El problema (creo) aún está en la prioridad de las reglas más lejanas, por lo que la pregunta sigue siendo la misma.

Respuesta

7

¿Has mirado http://sds.sourceforge.net/src/antlr/doc/lexer.html?

Una posible solución es definir lo siguiente:

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

ese soy yo conseguir mucho más cerca, sólo un poco más ajustes necesarios. El enlace que no había encontrado pero se ve genial; solo el tipo de cosas que debería leer, así que me voy a hacer eso ahora. Gracias. – tjm

+0

Lo estoy haciendo bien ahora, solo un par de notas para cualquier otra persona que pueda venir por esto. En ANTLRWorks v1.4, el intérprete no puede tratar los predicados por lo que parece que hay errores cuando no los hay (eso me ralentizó un poco) y también tuve que cambiar '$ settype (TYPE);' to ' $ type = TYPE; ' – tjm

+0

@tjm, edité ligeramente la muestra ANTLR. ¿Ahora es compatible con v3? –