Los reconocedores generados por FLEX son
deterministas. Esto quiere decir que una palabra es analizada
únicamente una sóla vez y las acciones de las reglas disparadas se
llevan a cabo una sóla vez. Sin embargo, mediante la utilización
de la acción REJECT se puede indicar al reconocedor
que rechace la entrada reconocida en los patrones de las reglas de la
condición de arranque actual y que seleccione la segunda mejor regla
cuyo patrón coincida con la entrada
.
Aunque el propósito para el que fue
creada esta acción se refiere fundamentalmente a la recuperación
de errores, su utilización permite conseguir un comportamiento no
determinista local en la condición de arranque en la que se
ejecutó
Sin embargo, mediante la utilización de REJECT no es posible ir atrás en el análisis más que hasta el comienzo de la condición de arranque actual. Si el reconocedor pasa por varias de estas condiciones de arranque hasta llegar al final de la palabra, como es nuestro caso, no es posible ir retrocediendo paso a paso hasta la condición inicial.
Puestos en contacto con Vern Paxon, creador de Flex, nos confirma
que, efectivamente, el comportamiento
no determinista que se consigue mediante la utilización de la
acción REJECT es sólo local, pues Flex tan sólo
almacena información de la condición de arranque en la
que se encuentra en cada momento. Nos sugiere que para conseguir un
comportamiento no determinista global probemos a utilizar,
al final del reconocimiento de cada palabra, una llamada a
yyless(0) e inmediatamente a continuación una llamada a
BEGIN(INITIAL). Con ello se consigue vaciar el contenido de
yytext y enviar al reconocedor a la condición inicial, denominada
INITIAL. Sin embargo, esto provocaba la entrada del reconocedor
en un bucle infinito, puesto que al carecer de información global
sobre el reconocimiento, el analizador léxico no recordaba las reglas de la
condición de arranque inicial que ya habían sido activadas, por
lo que siempre lanzaba una y
otra vez la mejor regla de la condición inicial.