2011-06-27 19 views

Respuesta

72

Un fragmento es algo parecido a una función en línea: hace que la gramática sea más legible y más fácil de mantener.

Un fragmento nunca se contará como un token, solo sirve para simplificar una gramática.

considerar:

NUMBER: DIGITS | OCTAL_DIGITS | HEX_DIGITS; 
fragment DIGITS: '1'..'9' '0'..'9'*; 
fragment OCTAL_DIGITS: '0' '0'..'7'+; 
fragment HEX_DIGITS: '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+; 

En este ejemplo, haciendo coincidir un número siempre devuelve un número al léxico, independientemente de si coincide con "1234", "0xab12", o "0777".

See item 3

+26

Tienes razón sobre lo que significa 'fragmento' en ANTLR. Pero el ejemplo que das es pobre: ​​no quieres que un lexer produzca un token 'NUMBER' que puede ser un número hexadecimal, decimal u octal. Eso significa que necesitarás inspeccionar el token 'NUMBER' en una producción (regla del analizador). Podrías dejar que el lexer produzca tokens 'INT',' OCT' y 'HEX' y crear una regla de producción:' number: INT | OCT | HEX; '. En dicho ejemplo, un 'DIGIT' podría ser un fragmento que sería utilizado por los tokens' INT' y 'HEX'. –

+5

Tenga en cuenta que "pobre" puede sonar un poco duro, pero no pude encontrar una palabra mejor para eso ... ¡Lo siento! :) –

+1

No parecías duro ... ¡estabas en lo cierto! – asyncwait

8

Según la Definitive Antlr4 referencias libro:

Reglas con el prefijo fragmento sólo se puede llamar de otras reglas analizadoras; no son fichas por derecho propio.

en realidad mejorarán la legibilidad de tus gramáticas.

vistazo a este ejemplo:

STRING : '"' (ESC | ~["\\])* '"' ; 
fragment ESC : '\\' (["\\/bfnrt] | UNICODE) ; 
fragment UNICODE : 'u' HEX HEX HEX HEX ; 
fragment HEX : [0-9a-fA-F] ; 

CADENA es un analizador léxico usando la regla fragmento como ESC .Unicode se utiliza en la regla Esc y Hex se utiliza en la regla fragmento de Unicode. ESC y las reglas UNICODE y HEX no se pueden usar explícitamente.

4

Este blog post tiene un ejemplo muy claro de dónde fragment hace una diferencia significativa:

grammar number; 

number: INT; 
DIGIT : '0'..'9'; 
INT : DIGIT+; 

La gramática reconocerá '42', pero no '7'. Puede solucionarlo haciendo un fragmento de dígito (o moviendo DIGIT después de INT).