flex [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -osalida -Pprefijo -Sesqueleto]
[--help --version] [nombrefichero ...]
flex tiene las siguientes opciones:
`-b' Genera información de retroceso en
`lex.backup'. Esta es una lista de estados del analizador que requieren retroceso y los caracteres de entrada con los que la hace. Añadiendo reglas uno puede eliminar estados de retroceso. Si
todos los estados de retroceso se eliminan y se usa `-Cf' ó `-CF', el analizador generado funcionará más rápido (ver la bandera `-p'). Únicamente los usuarios que desean exprimir hasta el último ciclo de sus analizadores necesitan preocuparse de esta opción. (see section
Consideraciones de rendimiento∞) `-c' es una opción que no hace nada, incluída para cumplir con POSIX. `-d' hace que el analizador generado se ejecute en modo de
depuración. Siempre que se reconoce un patrón y la variable global
`yy_flex_debug' no es cero (que por defecto no lo es), el analizador escribirá en
stderr una línea de la forma: --accepting rule at line 53 ("el texto emparejado")
El número de línea hace referencia al lugar de la regla en el fichero que define al analizador (es decir, el fichero que se le introdujo a flex). Los mensajes también se generan cuando el analizador retrocede, acepta la regla por defecto, alcanza el final de su buffer de entrada (o encuentra un NUL; en este punto, los dos parecen lo mismo en lo que le concierne al analizador), o alcance el fin-de-fichero. `-f' especifica un
analizador rápido. No se realiza una compresión de tablas y se evita el uso de stdio. El resultado es grande pero rápido. Esta opción es equivalente a `-Cfr' (ver más abajo). `-h' genera un sumario de "ayuda" de las opciones de
flex por
stdout y entonces finaliza. `-?' y `--help' son sinónimos de `-h'. `-i' indica a
flex que genere un analizador
case-insensitive. Se ignorará si las letras en los patrones de entrada de
flex son en mayúsculas o en minúsculas, y los tokens en la entrada serán emparejados sin tenerlo en cuenta. El texto emparejado dado en
yytext tendrá las mayúsculas y minúsculas preservadas (es decir, no se convertirán). `-l' activa el modo de máxima compatibilidad con la implementación original de
lex de AT&T. Fíjese que esto no significa una compatibilidad
completa. El uso de esta opción cuesta una cantidad considerable de rendimiento, y no puede usarse con las opciones `-+', `-f', `-F', `-Cf', ó `-CF'. Para los detalles a cerca de la compatibilidad que se ofrece, vea la section
Incompatibilidades con ##lex## y POSIX∞. Esta opción también hace que se defina el nombre
YY_FLEX_LEX_COMPAT en el analizador generado. `-n' es otra opción que no hace nada, incluída para cumplir con POSIX. `-p' genera un informe de rendimiento en stderr. El informe consta de comentarios que tratan de las propiedades del fichero de entrada de
flex que provocarán pérdidas serias de rendimiento en el analizador resultante. Si indica esta bandera dos veces, también obtendrá comentarios que tratan de las propiedades que producen pérdidas menores de rendimiento. Fíjese que el uso de
REJECT, `%option yylineno', y el contexto posterior variable (see section
Deficiencias / Errores∞) supone una penalización substancial del rendimiento; el uso de `yymore()', el operador `^', y la bandera `-I' supone penalizaciones del rendimiento menores. `-s' hace que la
regla por defecto (que la entrada sin emparejar del analizador se repita por
stdout) se suprima. Si el analizador encuentra entrada que no es reconocida por ninguna de sus reglas, este aborta con un error. Esta opción es útil para encontrar agujeros en el conjunto de reglas del analizador. `-t' indica a
flex que escriba el analizador que genera a la salida estándar en lugar de en
`lex.yy.c'. `-v' especifica que
flex debería escribir en
stderr un sumario de estadísticas respecto al analizador que genera. La mayoría de las estadísticas no tienen significado para el usuario casual de
flex, pero la primera línea identifica la versión de
flex (la misma que se informa con `-V'), y la próxima línea las banderas utilizadas cuando se genera el analizador, incluyendo aquellas que se encuentran activadas por defecto. `-w' suprime los mensajes de aviso. `-B' dice a
flex que genere un analizador
batch, que es lo opuesto al analizador
interactivo generador por `-I' (ver más abajo). En general, use `-B' cuando esté
seguro de que su analizador nunca se usará de forma interactiva, y quiere con esto exprimir un
poco más el rendimiento. Si por el contrario su objetivo es exprimirlo
mucho más, debería estar utilizando la opción `-Cf' ó `-CF' (comentadas más abajo), que activa `-B' automáticamente de todas maneras. `-F' especifica que se debe utilizar la representación de la tabla
rápida (y elimina referencias a stdio). Esta representación es aproximadamente tan rápida como la representación completa de la tabla `(-f)', y para algunos conjuntos de patrones será considerablemente más pequeña (y para otros, mayor). En general, si el conjunto de patrones contiene "palabras clave" y una regla "identificador" atrápalo-todo, como la del conjunto: "case" return TOK_CASE;
"switch" return TOK_SWITCH;
...
"default" return TOK_DEFAULT;
[a-z]+ return TOK_ID;
entonces será mejor que utilice la representación de la tabla completa. Si sólo está presente la regla "identificador" y utiliza una tabla hash o algo parecido para detectar palabras clave, mejor utilice `-F'. Esta opción es equivalente a `-CFr' (ver más abajo). Esta opción no puede utilizarse con `-+'. `-I' ordena a
flex que genere un analizador
interactivo. Un analizador interactivo es uno que solo mira hacia delante para decidir que token ha sido reconocido únicamente si debe hacerlo. Resulta que mirando siempre un caracter extra hacia delante, incluso si el analizador ya ha visto suficiente texto para eliminar la ambigüedad del token actual, se es un poco más rápido que mirando solamente cuando es necesario. Pero los analizadores que siempre miran hacia delante producen un comportamiento interactivo malísimo; por ejemplo, cuando un usuario teclea una línea nueva, esta no se reconoce como un token de línea nueva hasta que introduzca
otro token, que a menudo significa introducir otra línea completa. Los analizadores de
flex por defecto son
interactivos a menos que use la opción `-Cf' ó `-CF' de compresión de tablas (ver más abajo). Esto es debido a que si está buscando un rendimiento alto tendría que estar utilizando una de estas opciones, así que si no lo ha hecho
flex asume que prefiere cambiar un poco de rendimiento en tiempo de ejecución en beneficio de un comportamiento iteractivo intuitivo. Fíjese también que
no puede utilizar `-I' conjuntamente con `-Cf' ó `-CF'. Así, esta opción no se necesita realmente; está activa por defecto para todos esos casos en los que se permite. Usted puede forzar al analizador que
no sea interactivo usando `-B' (ver más arriba). `-L' ordena a
flex que no genere directivas `#line'. Sin esta opción,
flex acribilla al analizador generado con directivas `#line' para que los mensajes de error en las acciones estén localizadas correctamente respecto al fichero original de
flex (si los errores son debidos al código en el fichero de entrada), o a
`lex.yy.c' (si los errores son fallos de
flex --debería informar de este tipo de errores a la dirección de correo dada más abajo). `-T' hace que
flex se ejecute en modo de
traza. Este generará un montón de mensajes en
stderr relativos a la forma de la entrada y el autómata finito no-determinista o determinista resultante. Esta opción generalmente es para usarla en el mantenimiento de
flex. `-V' imprime el número de la versión en
stdout y sale. `--version' es un sinónimo de `-V'. `-7' ordena a
flex que genere un analizador de 7-bits, es decir, uno que sólo puede reconocer caracteres de 7-bits en su entrada. La ventaja de usar `-7' es que las tablas del analizador pueden ser hasta la mitad del tamaño de aquellas generadas usando la opción `-8' (ver más abajo). La desventaja es que tales analizadores a menudo se cuelgan o revientan si su entrada contiene caracteres de 8-bits. Fíjese, sin embargo, que a menos que genere su analizador utilizando las opciones de compresión de tablas `-Cf' ó `-CF', el uso de `-7' ahorrará solamente una pequeña cantidad de espacio en la tabla, y hará su analizador considerablemente menos portable. El comportamiento por defecto de
flex es generar un analizador de 8-bits a menos que use `-Cf' ó `-CF', en cuyo caso
flex por defecto genera analizadores de 7-bits a menos que su sistema siempre esté configurado para generar analizadores de 8-bits (a menudo este será el caso de los sistemas fuera de EEUU). Puede decir si flex generó un analizador de 7 u 8 bits inspeccionando el sumario de banderas en la salida de `-v' como se describió anteriormente. Fíjese que si usa `-Cfe' ó `-CFe' (esas opciones de compresión de tablas, pero también el uso de clases de equivalencia como se comentará más abajo), flex genera aún por defecto un analizador de 8-bits, ya que normalmente con estas opciones de compresión las tablas de 8-bits completas no son mucho más caras que las tablas de 7-bits. `-8' ordena a
flex que genere un analizador de 8-bits, es decir, uno que puede reconocer caracteres de 8-bits. Esta bandera sólo es necesaria para analizadores generados usando `-Cf' ó `-CF', ya que de otra manera flex por defecto genera un analizador de 8-bits de todas formas. Vea el comentario sobre `-7' más arriba a cerca del comportamiento por defecto de flex y la discusión entre los analizadores de 7-bits y 8-bits. `-+' especifica que quiere que flex genere un analizador como una clase de C++. Vea la section
Generando escáneres en C++∞, para los detalles. `-C[aefFmr]' controla el grado de compresión de la tabla y, más generalmente, el compromiso entre analizadores pequeños y analizadores rápidos. `-Ca' ("alinea") ordena a flex que negocie tablas más grandes en el analizador generado para un comportamiento más rápido porque los elementos de las tablas están mejor alineados para el acceso a memoria y computación. En algunas arquitecturas RISC, la búsqueda y manipulación de palabras largas es más eficiente que con unidades más pequeñas tales como palabras cortas. Esta opción puede doblar el tamaño de las tablas usadas en su analizador. `-Ce' ordena a
flex que construya
clases de equivalencia, es decir, conjunto de caracteres que tienen identicas propiedades léxicas (por ejemplo, si la única aparición de dígitos en la entrada de
flex es en la clase de caracteres "[0-9]" entonces los dígitos `0', `1', ..., `9' se pondrán todos en la misma clase de equivalencia). Las clases de equivalencia normalmente ofrecen notables reducciones en los tamaños de los ficheros finales de tabla/objeto (típicamente un factor de 2-5) y son juiciosamente bastante baratos en cuanto al rendimiento (una localización en un vector por caracter analizado). `-Cf' especifica que se deben generar las tablas del analizador
completas flex no debería comprimir las tablas tomando ventaja de las funciones de transición similares para diferentes estados. `-CF' especifica que debería usarse la representación del analizador rápido alternativo (descrito anteriormente en la bandera `-F' ) Esta opción no puede usarse con `-+'. `-Cm' ordena a
flex que construya
clases de meta-equivalencias, que son conjuntos de clases de equivalencia (o caracteres, si las clases de equivalencia no se están usando) que comunmente se usan de forma conjunta. Las clases de meta-equivalencias son a menudo un gran ahorro cuando se usan tablas comprimidas, pero tienen un impacto moderado en el rendimiento (uno o dos tests "if" y una localización en un array por caracter analizado). `-Cr' hace que el analizador generado
elimine el uso de la librería de E/S estándar para la entrada. En lugar de llamar a `fread()' o a `getc()', el analizador utilizará la llamada al sistema `read()', produciendo una ganancia en el rendimiento que varía de sistema en sistema, pero en general probablemente es insignificante a menos que también esté usando `-Cf' ó `-CF'. El uso de `-Cr' puede producir un comportamiento extraño si, por ejemplo, lee de
yyin usando stdio antes de llamar al analizador (porque el analizador perderá cualquier texto que sus lecturas anteriores dejaron en el buffer de entrada de stdio). `-Cr' no tiene efecto si usted define
YY_INPUT (see section
El escáner generado∞). Con solamente `-C' se especifica que las tablas del analizador deberían comprimirse pero no debería utilizarse ni las clases de equivalencia ni las clases de meta-equivalencias. Las opciones `-Cf' ó `-CF' y `-Cm' no tienen sentido juntas --no hay oportunidad para las clases de meta-equivalencias si la tabla no está siendo comprimida. De otra forma las opciones podrían mezclarse líbremente, y son acumulativas. La configuración por defecto es `-Cem', que especifica que
flex debería generar clases de equivalencia y clases de meta-equivalencias. Esta configuración provee el mayor grado de compresión. Puede llegarse a un compromiso entre analizadores de ejecución más rápida con el coste de tablas mayores siendo generalmente verdadero lo siguiente: lo más lento y pequeño
-Cem
-Cm
-Ce
-C
-C{f,F}e
-C{f,F}
-C{f,F}a
lo más rápido y grande
Fíjese que los analizadores con tablas más pequeñas normalmente se generan y compilan de la forma más rápida posible, así que durante el desarrollo usted normalmente querrá usar como viene por defecto, compresión máxima. `-Cfe' a menudo es un buen compromiso entre velocidad y tamaño para la producción de analizadores. `-osalida' ordena a flex que escriba el analizador al fichero
`salida' en lugar de a
`lex.yy.c'. Si combina `-o' con la opción `-t', entonces el analizador se escribe en
stdout pero sus directivas `#line' (vea la opción `-L' más arriba) hacen referencia al fichero
`salida'. `-Pprefijo' cambia el prefijo `yy' usado por defecto por
flex para todas las variables visibles globalmente y nombres de funciones para que sea prefijo. Por ejemplo, `-Pfoo' cambia el nombre de
yytext a
`footext'. Este también cambia el nombre por defecto del fichero de salida de
`lex.yy.c' a
`lex.foo.c'. Aquí están todos los nombres afectados: yy_create_buffer
yy_delete_buffer
yy_flex_debug
yy_init_buffer
yy_flush_buffer
yy_load_buffer_state
yy_switch_to_buffer
yyin
yyleng
yylex
yylineno
yyout
yyrestart
yytext
yywrap
(Si usted está utilizando un analizador en C++, entonces únicamente
yywrap y
yyFlexLexer se ven afectados.) Dentro de su analizador, puede aún hacer referencia a las variables globales y funciones usando cualquier versión de su nombre; pero externamente, estas tienen el nombre modificado. Esta opción le deja enlazar fácilmente múltiples programas
flex conjuntamente en el mismo ejecutable. Fíjese, sin embargo, que usando esta opción también se renombra `yywrap()', de manera que ahora
debe o bien proveer su propia versión de la rutina (con el nombre apropiado) para su analizador, o usar `%option noyywrap', ya que enlazar con `-lfl' no podrá proveerle una por defecto. `-Sfichero_esqueleto' ignora el fichero de esqueleteo por defecto con el que
flex construye sus analizadores. Usted probablemente nunca necesitará utilizar esta opción a menos que este haciendo mantenimiento o un desarrollo de
flex.
flex también ofrece un mecanismo para controlar las opciones dentro de la propia especificación del analizador, en vez de a partir de la línea de comando. Esto se hace incluyendo las directivas `%option' en la primera sección de la especificación del analizador. Usted puede especificar varias opciones con una sola directiva `%option', y varias directivas en la primera sección de su fichero de entrada de flex.
La mayoría de las opciones vienen dadas simplemente como nombres, opcionalmente precedidos por la palabra "no" (sin intervenir un espacio) para negar su significado. Las banderas de flex o su negación son equivalentes a un número:
7bit opción -7
8bit opción -8
align opción -Ca
backup opción -b
batch opción -B
c++ opción -+
caseful o
case-sensitive opuesto de -i (por defecto)
case-insensitive o
caseless opción -i
debug opción -d
default opuesto de la opción -s
ecs opción -Ce
fast opción -F
full opción -f
interactive opción -I
lex-compat opción -l
meta-ecs opción -Cm
perf-report opción -p
read opción -Cr
stdout opción -t
verbose opción -v
warn opuesto de la opción -w
(use "%option nowarn" para -w)
array equivalente a "%array"
pointer equivalente a "%pointer" (por defecto)
Algunas directivas `%option' ofrecen propiedades que de otra manera no están disponibles:
`always-interactive' ordena a flex que genere un analizador que siempre considere su entrada como "interactiva". Normalmente, sobre cada fichero de entrada nuevo el analizador llama a `isatty()' como intento para determinar si la entrada del analizador es interactiva y por lo tanto debería leer un caracter a la vez. Cuando esta opción se utilice, sin embargo, entonces no se hace tal llamada. `main' ordena a flex que facilite un programa `main()' por defecto para el analizador, que simplemente llame a `yylex()'. Esta opción implica
noyywrap (ver más abajo). `never-interactive' ordena a flex que genere un analizador que nunca considere su entrada como "interactiva" (de nuevo, no se hace ninguna llamada a `isatty()'). Esta es la opuesta a `always-interactive'. `stack' activa el uso de pilas de condiciones de arranque (see section
Condiciones de arranque∞). `stdinit' si se establece (es decir, `%option stdinit') inicializa
yyin e
yyout a
stdin y
stdout, en lugar del que viene por defecto que es
nil. Algunos pogramas de
lex existentes dependen de este comportamiento, incluso si no sigue el ANSI C, que no requiere que
stdin y
stdout sean constantes en tiempo de compilación. `yylineno' ordena a
flex a generar un analizador que mantenga el número de la línea actual leída desde su entrada en la variable global
yylineno. Esta opción viene implícita con `%option lex-compat'. `yywrap' si no se establece (es decir, `%option noyywrap'), hace que el analizador no llame a `yywrap()' hasta el fin-de-fichero, pero simplemente asume que no hay más ficheros que analizar (hasta que el usuario haga apuntar
yyin a un nuevo fichero y llame a `yylex()' otra vez).
flex analiza las acciones de sus reglas para determinar si utiliza las propiedades
REJECT o `yymore()'. Las opciones
reject e
yymore están disponibles para ignorar sus decisiones siempre que use las opciones, o bien estableciendolas (p.ej., `%option reject') para indicar que la propiedad se utiliza realmente, o desactivándolas para indicar que no es utilizada (p.ej., `%option noyymore').
Tres opciones toman valores delimitados por cadenas, separadas por `=':
%option outfile="ABC"
es equivalente a `-oABC', y
%option prefix="XYZ"
es equivalente a `-PXYZ'. Finalmente,
%option yyclass="foo"
sólo se aplica cuando se genera un analizador en C++ (opción `-+'). Este informa a
flex que ha derivado a `foo' como una subclase de
yyFlexLexer, así que
flex pondrá sus acciones en la función miembro `foo::yylex()' en lugar de `yyFlexLexer::yylex()'. Este también genera una función miembro `yyFlexLexer::yylex()' que emite un error en tiempo de ejecución (invocando a `yyFlexLexer::LexerError()') si es llamada. See section
Generando escáneres en C++∞, para información adicional.
Están disponibles un número de opciones para los puristas de lint que desean suprimir la aparición de rutinas no necesarias en el analizador generado. Cada una de la siguientes, si se desactivan (p.ej., `%option nounput'), hace que la rutina correspondiente no aparezca en el analizador generado:
input, unput
yy_push_state, yy_pop_state, yy_top_state
yy_scan_buffer, yy_scan_bytes, yy_scan_string
(aunque `yy_push_state()' y sus amigas no aparecerán de todas manera a menos que use `%option stack').