next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Versión Utilizada Sup: Expresiones Regulares en Flex Ant: Expresiones Regulares en Flex Err: Si hallas una errata ...


Estructura de un programa LEX

Estructura de un programa

LEX y FLEX son ejemplos de generadores léxicos. Flex lee desde la entrada estándar si no se especifica explícitamente un fichero de entrada. El fichero de entrada reglen.l (se suele usar el tipo l) debe tener la forma:

%{
declaration C1
.
.
.

declaration CM
%}
macro_name1 regular_definition1
.
.
.

macro_nameR regular_definitionR

%x exclusive_state
%s inclusive_state
%%

regular_expression1 { action1(); }
.
.
.

regular_expressionN { actionN(); }

%%
support_routine1() {
}
.
.
.

support_routineS() {
}

Como vemos, un programa LEX consta de 3 secciones, separadas por %%. La primera sección se denomina sección de definiciones, la segunda sección de reglas y la tercera sección de código. La primera y la última son opcionales, así el programa legal LEX mas simple es:

%%

que genera un analizador que copia su entrada en stdout.

Compilación

Una vez compilado el fichero de entrada regleng.l mediante la correspondiente orden:

flex reglen.l

obtenemos un fichero denominado lex.yy.c. Este fichero contiene la rutina yylex() que realiza el análisis léxico del lenguaje descrito en regleng.l. Supuesto que una de las support_routines es una función main() que llama a la función yylex(), podemos compilar el fichero generado con un compilador C para obtener un ejecutable a.out:

cc lex.yy.c -lfl

La inclusión de la opción -fl enlaza con la librería de flex, que contiene dos funciones: main y yywrap().

Ejecución

Cuando ejecutamos el programa a.out, la función yylex() analiza las entradas, buscando la secuencia mas larga que casa con alguna de las expresiones regulares (regular_expressionK) y ejecuta la correspondiente acción (actionK()). Si no se encuentra ningun emparejamiento se ejecuta la regla por defecto, que es:

(.|\n) { printf("%s",yytext); }

Si encuentran dos expresiones regulares con las que la cadena mas larga casa, elige la que figura primera en el programa lex. Una vez que yylex() ha encontrado el token, esto es, el patrón que casa con la cadena mas larga, dicha cadena queda disponible a través del puntero global yytext , y su longitud queda en la variable entera global yyleng .

Una vez que se ha ejecutado la correspondiente acción, yylex() continúa con el resto de la entrada, buscando por subsiguientes emparejamientos. Asi continúa hasta encontrar un end of file, en cuyo caso termina, retornando un cero o bien hasta que una de las acciones explicitamente ejecuta una sentencia return.

Sección de definiciones

La primera sección contiene, si las hubiera, las definiciones regulares y las declaraciones de los estados de arranque.

Las definiciones tiene la forma:

name regular_definition

donde name puede ser descrito mediante la expresión regular:

[a-zA-Z_][a-zA-Z_0-9-]*

La regular_definition comienza en el primer carácter no blanco que sigue a name y termina al final de la línea. La definición es una expresión regular extendida. Las subsiguientes definiciones pueden ``llamar'' a la macro {name} escribiéndola entre llaves. La macro se expande entonces a (regular_definition) en flex y a regular_definition en lex.

El código entre los delimitadores %{ y %} se copia verbatim al fichero de salida, situándose en la parte de declaraciones globales. Los delimitadores deben aparecer (sólos) al comienzo de la línea.

El Lenguaje de las Expresiones Regulares Flex

La sintáxis que puede utilizarse para la descripción de las expresiones regulares es la que se conoce como ``extendida'':

Los operadores han sido listados en orden de precedencia, de la mas alta a la mas baja. Por ejemplo foo|bar+ es lo mismo que (foo)|(ba(r)+).

Las Acciones Semánticas

Cada patrón regular tiene su correspondiente acción asociada. El patrón termina en el primer espacio en blanco (sin contar aquellos que están entre comillas dobles o prefijados de secuencias de escape). Si la acción comienza con {, entonces se puede extender a través de multiples líneas, hasta la correspondiente }. El programa flex no hace un análisis del código C dentro de la acción. Existen tres directivas que pueden insertarse dentro de las acciones: BEGIN, ECHO y REJECT. Su uso se muestra en los subsiguientes ejemplos.

La sección de código se copia verbatim en lex.yy.c. Es utilizada para proveer las funciones de apoyo que se requieran para la descripción de las acciones asociadas con los patrones que parecen en la sección de reglas.



Subsecciones
next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Versión Utilizada Sup: Expresiones Regulares en Flex Ant: Expresiones Regulares en Flex Err: Si hallas una errata ...
Casiano Rodríguez León
2013-03-05