Documente Academic
Documente Profesional
Documente Cultură
2
Prcticas de compiladores 2004-2005
Funciones del analizador lxico/morfolgico
Fichero del
programa fuente Analizador lxico tokens
3
Prcticas de compiladores 2004-2005
4
Prcticas de compiladores 2004-2005
Funcionamiento bsico de Lex/Flex
Lex/Flex
lex.yy.c
Fichero del
programa yylex() tokens
fuente
5
Prcticas de compiladores 2004-2005
seccin de definiciones
%{
/* delimitadores de cdigo C */
%}
%%
seccin de reglas
%%
6
Prcticas de compiladores 2004-2005
El fichero de especificacin Lex/Flex (II)
La seccin de definiciones (i)
La seccin de definiciones contiene la siguiente informacin
Cdigo C encerrado entre lneas con los caracteres %{ y %} que se copia
literalmente en el fichero de salida lex.yy.c antes de la definicin de la funcin
yylex(). Habitualmente esta seccin contiene declaraciones de variables y
funciones que se utilizan posteriormente en la seccin de reglas as como directivas
#include.
Definiciones propias de Lex/Flex, que permiten asignar un nombre a una expresin
regular o a una parte, y posteriormente utilizar ese nombre en la seccin de reglas.
Estas definiciones se vern con ms detalle cuando se estudien los patrones de
Lex/Flex.
Opciones de Lex/Flex similares a las opciones de la lnea de comandos.
Definicin de condiciones de inicio. Estas definiciones se vern con ms detalle
cuando se estudien los patrones de Lex/Flex.
Cualquier lnea que empiece con un espacio en blanco se copia literalmente en el
fichero de salida lex.yy.c. Habitualmente se utiliza para incluir comentarios
encerrados entre /* y */.
7
Prcticas de compiladores 2004-2005
ej1.l %{
#include <stdio.h> /* para utilizar printf en la
seccin de reglas */
%}
%option noyywrap
%%
8
Prcticas de compiladores 2004-2005
El fichero de especificacin Lex/Flex (IV)
La seccin de definiciones (iii)
Significado de la opcin noyywrap:
Existe la posibilidad de que la funcin yylex() analice morfolgicamente varios
ficheros, encadenando uno detrs de otro con el siguiente mecanismo.
Cuando yylex() encuentra un fin de fichero, llama a la funcin yywrap(). Si la
funcin devuelve 0, el anlisis contina con otro fichero, y si devuelve 1, el anlisis
termina.
Quin proporciona la funcin yywrap()?
En Linux, la librera de lex proporciona una versin por defecto de yywrap()
que devuelve 1. Hay que enlazar con esa librera.
En Windows la tiene que proporcionar el usuario incorporndola en la ltima
seccin del fichero de especificacin. En Linux tambin la puede proporcionar
el usuario.
La opcin noyywrap provoca que no se invoque a la funcin yywrap() cuando se
encuentre un fin de fichero, y se asuma que no hay ms ficheros que analizar.
Esta solucin es ms cmoda que tener que escribir la funcin o bien enlazar con
alguna librera.
9
Prcticas de compiladores 2004-2005
ej1.l %{
#include <stdio.h> /* para utilizar printf en la
seccin de reglas */
%}
%option noyywrap
%%
begin { printf(reconocido-begin-\n); }
end { printf(reconocido-end-\n); }
%%
11
Prcticas de compiladores 2004-2005
int main()
{
return yylex();
}
Esta llamada nica a yylex() permite realizar el anlisis lxico hasta encontrar
el fin de la entrada siempre que en ningn fragmento de cdigo C asociado a los
patrones de los tokens aparezca una sentencia return que haga terminar a
yylex(). En ese caso el main sera distinto como se mostrar mas adelante.
12
Prcticas de compiladores 2004-2005
Primer ejemplo (I)
El fichero de especificacin ej1.l
Se completa el fichero ej1.l incluyendo una funcin main en la seccin de
funciones de usuario.
ej1.l %{
#include <stdio.h> /* para utilizar printf en la
seccin de reglas */
%}
%option noyywrap
%%
begin { printf(reconocido-begin-\n); }
end { printf(reconocido-end-\n); }
%%
int main()
{
return yylex();
}
13
Prcticas de compiladores 2004-2005
Generar el ejecutable:
Linux: gcc -Wall -o ej1 lex.yy.c se crea el fichero ej1
Windows: cl /W4 /Feej1.exe lex.yy.c se crea el fichero ej1.exe
14
Prcticas de compiladores 2004-2005
Primer ejemplo (III)
Realizacin de pruebas
Para probar el funcionamiento del analizador lxico implementado en el primer
ejemplo, se arranca el ejecutable y se realizan las siguientes pruebas:
15
Prcticas de compiladores 2004-2005
En el primer ejemplo, la funcin main invoca a la funcin yylex() una sola vez, y
como en ninguna de las reglas aparece una sentencia return, la funcin
yylex() se ejecuta hasta encontrar el fin de la entrada.
En el segundo ejemplo, se quiere modificar la especificacin Lex/Flex para que la
funcin yylex() devuelva un valor diferente para cada token identificado, y la
funcin main sea la responsable de mostrar por la salida estndar el aviso
correspondiente del token identificado.
Los cambios que hay que hacer son los siguientes:
definir constantes diferentes para los tokens. En la seccin de definiciones se aaden
las siguientes sentencias:
#define TOK_BEGIN 1
#define TOK_END 2
modificar la seccin de reglas para que el cdigo C asociado a cada token en lugar de
mostrar en la salida estndar un aviso, devuelva la constante definida para el token.
16
Prcticas de compiladores 2004-2005
Segundo ejemplo (II)
Diseo del fichero de especificacin (ii)
Modificar la funcin main para que llame a la funcin yylex() y muestre un mensaje
de aviso diferente para cada token en funcin del valor devuelto por yylex(). La
funcin main llama repetidas veces a la funcin yylex() hasta que se termina la
entrada, es decir, hasta que la funcin yylex() devuelve 0.
int main()
{
int token;
while (1)
{
token = yylex();
if (token == TOK_BEGIN)
printf(reconocido-begin-\n);
if (token == TOK_END)
printf(reconocido-end-\n);
if (token == 0)
break;
}
return 0;
}
17
Prcticas de compiladores 2004-2005
Generar el ejecutable:
Linux: gcc -Wall -o ej2 lex.yy.c se crea el fichero ej2
Windows: cl /W4 /Feej2.exe lex.yy.c se crea el fichero ej2.exe
Si se realizan las mismas pruebas que se hicieron con ej1.exe se obtendrn los
mismos resultados ya que no se ha modificado la funcionalidad del analizador
lxico sino su diseo.
19
Prcticas de compiladores 2004-2005
#define TOK_BEGIN 1
#define TOK_END 2
#endif
ej2.l %{
#include <stdio.h>
#include tokens_ej2.h
%}
%option noyywrap
%%
begin { return TOK_BEGIN; }
end { return TOK_END; }
%%
int main()
{
int token;
...................
20
Prcticas de compiladores 2004-2005
Los patrones de Lex/Flex (I)
Descripcin
Los patrones de Lex/Flex son:
el mecanismo para representar los tokens.
una extensin de las expresiones regulares.
Los patrones estn formados por:
caracteres normales que se representan a s mismos
metacaracteres que tienen un significado especial
Para utilizar un metacaracter como caracter normal hay que ponerlo entre
comillas. Por ejemplo, el asterisco es un metacaracter, y si se quiere reconocer
el token asterisco, hay que definirlo como *.
En los siguientes apartados se describen algunos de los metacaracteres de
Lex/Flex, en concreto, aquellos que son necesarios para especificar los tokens
del lenguaje ASPLE.
Un mismo token se puede expresar con distintos patrones.
21
Prcticas de compiladores 2004-2005
22
Prcticas de compiladores 2004-2005
Los patrones de Lex/Flex (III)
Metacaracteres (ii)
ab* representa todas las palabras que empiezan por una "a" seguida de 0 o ms
"b", por ejemplo "a", "ab", "abb", "abbb".
[a-zA-Z][a-zA-Z0-9]* representa todas las palabras que empiezan por una
letra minscula o mayscula seguida de 0 o ms letras o dgitos, como por
ejemplo "v1", "indice", "maximo", "D".
x+ representa todas las palabras formadas por "x", por ejemplo "x", "xx", "xxx".
[0-9]+ representa los nmeros de uno o ms dgitos, por ejemplo "12", "465",
"000", "097".
23
Prcticas de compiladores 2004-2005
A|B representa la letra "A" o la letra "B". Este patrn se comporta de la misma
manera que el patrn [AB].
"..." Representa lo que est entre las comillas literalmente. Los metacaracteres pierden
su significado excepto "\".
El metacaracter \ si va seguido de una letra minscula se asume que es una
secuencia de escape de C, como por ejemplo el tabulador \t. Si no va seguido de
minscula, \ se utiliza para quitar el significado especial de los metacaracteres, por
ejemplo \* representa un asterisco.
() Agrupan expresiones.
24
Prcticas de compiladores 2004-2005
Los patrones de Lex/Flex (V)
Metacaracteres (iv)
DIGITO [0-9]
LETRA [a-zA-Z]
La expresin regular de todas las palabras que empiezan por una letra
minscula o mayscula seguida de 0 o ms letras o dgitos:
[a-zA-Z]([0-9]|[a-zA-Z])*
es idntica a:
{LETRA} ({DIGITO}|{LETRA})*
25
Prcticas de compiladores 2004-2005
26
Prcticas de compiladores 2004-2005
Los patrones de Lex/Flex (VII)
Cmo se identifican los patrones en la entrada (ii)
La entrada begin se identificar como TOK_ID porque hay concordancia con dos
patrones, el de TOK_BEGIN y el de TOK_ID, pero el patrn de TOK_ID aparece
antes en el fichero de especificacin.
27
Prcticas de compiladores 2004-2005
28
Prcticas de compiladores 2004-2005
Tercer ejemplo (I)
Enunciado
Las acciones que debe realizar el analizador lxico cuando reconozca alugn token
son las siguientes:
Cuando se reconozca un identificador se mostrar el mensaje TOK_ID
Cuando se reconozca un nmero se mostrar el mensaje TOK_NUM.
29
Prcticas de compiladores 2004-2005
smbolos simples:
+ - * ( ) ; , = >
smbolos compuestos:
<= :=
36
Prcticas de compiladores 2004-2005
Fichero de especificacin Lex/Flex para el lenguaje ASPLE (II)
El orden de las reglas
Otras de las funciones del analizador morfolgico adems de identificar los tokens
en el fichero de entrada, es ignorar los espacios en blanco, los tabuladores y los
saltos de lnea que aparecen en la entrada.
Una solucin para incorporar esta funcionalidad es:
disear el patrn que identifique los caracteres que se quieran ignorar.
Incorporar una regla para dicho patrn y que tenga como accin no hacer nada, que
en Lex/Flex se especifica con un punto y coma en el lugar del cdigo C.
42
Prcticas de compiladores 2004-2005
Control de la posicin de los tokens en el fichero de entrada (I)
%{
int lineno = 1; /* nmero de lnea */
int charno = 0; /* nmero de carcter */
%}
44
Prcticas de compiladores 2004-2005
45
Prcticas de compiladores 2004-2005
Gestin de los comentarios (I)
47
Prcticas de compiladores 2004-2005
49
Prcticas de compiladores 2004-2005
Ficheros de entrada/salida de Lex/Flex
FILE* yyin
es el fichero de entrada, del que lee la funcin yylex().
Por defecto es la entrada estndar.
El usuario puede asignarle cualquier variable de tipo FILE*, por supuesto, antes de que
se inicie el anlisis, es decir, antes de invocar a la funcin yylex().
FILE* yyout
es el fichero de salida, en el que se escribe la regla por defecto (cuando no concuerda
ningn patrn se copia la entrada en la salida)
Por defecto es la salida estndar.
El usuario puede asignarle cualquier variable de tipo FILE*.
51
Prcticas de compiladores 2004-2005