Está en la página 1de 20

FLEX: Un generador de analizadores lxicos

Como hemos visto, el paso de una expresin regular a un AF se


puede hacer de manera automatizada
Existen varias herramientas que relizan dicho trabajo
Generadores de analizadores lxicos

AT&T Lex (ms comn en UNIX)


MKS Lex (MS-Dos)
Flex
Abraxas Lex
Posix Lex
ScanGen
JLex
...

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

Qu hace LEX?
especifica un analizador
lxico

especificacin
FLEX
FLEX
FLEX
lex.yy.c

int yylex(): funcin que realiza el anlisis


lxico

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

FLEX sigue el esquema:


donde:

patrn1
{ accin1 }
patrn2
{ accin2 }
.......
patrnk
{ accink }

patrn: expresin regular


accin: fuente C con las acciones a realizar cuando el patrn concuerde
con un lexema

Funcionamiento:
FLEX recorre entrada estndar hasta que encuentra una concordancia
un lexema correspondiente al lenguaje de algunas de las e.r.
representadas por los patrones
entonces, ejecuta el cdigo asociado (accin)
permite acceder a la informacin asociada al lexema (string, longitud del
mismo, n de lnea en el fuente,...)
Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

Ejemplo: implementar en LEX, un analizador lxico para


menor
menor

mayor
mayor

menorIgual
menorIgual

mayorIgual
mayorIgual

igual
igual

distinto

distinto
letra
letra

digito

digito
identificador
identificador

constEntera

constEntera

Compiladores I. C.P.S. Universidad de Zaragoza

<<
>>
<=
<=
>=
>=
==
<>
<>
a|b|...|z|A|B|....|Z
a|b|...|z|A|B|....|Z
0|1|...|9
0|1|...|9
letra
letra (letra
(letra |digito)*
|digito)*
digito
digito digito
digito **

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

Comportamiento deseado:
v0<>27

segundos=

1000

analizador
analizador
lxico
lxico

(IDENTIFICADOR,v0)
(DISTINTO,)
(CONSTENTERA,27)
(IDENTIFICADOR,segundos)
(IGUAL,)
(CONSTENTERA ,1000)

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

Estructura de
un programa FLEX

seccin
seccin de
de definiciones
definiciones
%%
%%
seccin
seccin de
de reglas
reglas
%%
%%
seccin
seccin de
de rutinas
rutinas del
del usuario
usuario

Seccin de definiciones:
bloques literales
se copian tal cual al fuente lex.yy.c
entre %{ y %}
definiciones regulares (bautismo)
declaraciones propias para el manejo de tablas de LEX
condiciones iniciales
cambiar el funcionamiento del reconocedor

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

%{
%{ /*
/* fichero:
fichero: expresiones.l
expresiones.l */
*/
#include
#include ....
....

enum
enum {MENOR=255,MENORIGUAL,MAYOR,
{MENOR=255,MENORIGUAL,MAYOR,
MAYORIGUAL,IGUAL,DISTINTO,
MAYORIGUAL,IGUAL,DISTINTO,
IDENTIFICADOR,CONSTENTERA};
IDENTIFICADOR,CONSTENTERA};
int
int yylval;
yylval;
/*
/* para
para atributo
atributo cte.
cte. entera*/
entera*/
typedef
int
token;
typedef int token;
%}
%}
%%
%%
seccin
seccin de
de reglas
reglas
%%
%%
seccin
seccin de
de rutinas
rutinas de
de usuario
usuario

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

Seccin de reglas
Formato:

patrn

{acciones}

dos tipos de lneas:


empiezan por blanco, %{ %} fuente C
empiezan por otra cosa: lnea patrn-cdigo
las lneas de fuente C se copian directamente en el fuente lex.yy.c
al encontrar concordancia, ejecutar cdigo asociado
si no encuentra concordancia, ejecuta ECHO (copia el lexema en salida
estndar)

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos


%{
%{
%}
%}

seccin
seccin de
de definiciones
definiciones

%%
%%

(\t|\n|"
(\t|\n|" ")+
")+
[0-9]([0-9])*
[0-9]([0-9])*
"<"
"<"
....
....
....
....
"<>"
"<>"
[a-zA-Z]([a-zA-Z]|[0-9])*
[a-zA-Z]([a-zA-Z]|[0-9])*
..

%%
%%

{/*
{/* no
no hace
hace nada
nada */};
*/};
{sscanf(yytext,"%d",&yylval);
{sscanf(yytext,"%d",&yylval);
return(CONSTENTERA);}
return(CONSTENTERA);}
{return(MENOR);}
{return(MENOR);}
{return(DISTINTO);}
{return(DISTINTO);}
{return(IDENTIFICADOR);}
{return(IDENTIFICADOR);}
{ECHO;}
{ECHO;}

seccin
seccin de
de rutinas
rutinas de
de usuario
usuario

patrn
Compiladores I. C.P.S. Universidad de Zaragoza

accin
-J.Ezpeleta-

FLEX: Un generador de analizadores lxicos

Seccin de rutinas de usuario


su contenido se copia literalmente en el fuente lex.yy.c
contiene funciones C escritas por el usuario y necesarias para el
analizador
manejo de tabla de smbolos
generacin de salidas (cuando no es necesario generacin de cdigo)

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

10

FLEX: Un generador de analizadores lxicos


%{
seccin de definiciones
%}
%%

/*-------------------------------------Cuando EOF, yylex() dev. 0


---------------------------------------*/

seccin de reglas
%%
/*-------------------------------------Slo para comprobacin
--------------------------------------*/

void escribeInfo(token elToken)


{ switch(elToken){
case IDENTIFICADOR:
fprintf(stdout,
"ident.\t%s",yytext);
break;
..........
}
}

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

int main()
{ token elToken;
elToken=yylex();
while(elToken){
escribeInfo(elToken);
elToken=yylex();
}
}

11

FLEX: Un generador de analizadores lxicos

Ejemplo de uso de LEX:

sufijo .l
para fuente FLEX

expresiones.l
invocacin a FLEX

flex expresiones.l
fuente con el
analizador

lex.yy.c
gcc -o expresiones
lex.yy.c -lfl

-lfl: biblioteca
necesaria

analizador

expresiones
Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

12

FLEX: Un generador de analizadores lxicos


#=====================================================
# Fichero: Makefile
# Tema:
genera un analizador lxico para
#
introducir Flex/Lex
# Fecha:
Septiembre-03
# Uso:
make
#=====================================================
LEX=flex
CC=gcc
expresiones: lex.yy.o
$(CC) -o expresiones lex.yy.o -lfl
#-L/opt/flex/lib -lfl para Merlin
lex.yy.o: lex.yy.c
$(CC) -c lex.yy.c
lex.yy.c: expresiones.l
$(LEX) expresiones.l
Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

13

FLEX: Un generador de analizadores lxicos

Ejemplo de invocacin:
el fichero entrada es

invocacin:

v0<>27
segundos=

expresiones < entrada

genera la siguiente salida

Compiladores I. C.P.S. Universidad de Zaragoza

1000

identificador
distinto
numero
identificador
igual
numero

-J.Ezpeleta-

v0
<>
27
segundos
=
1000

14

FLEX: Un generador de analizadores lxicos

Tambin se pueden dar nombres a expresiones regulares


%{
%{

/*
/* fichero:
fichero: expresiones.l
expresiones.l */
*/

......
......
int
yylval;
/*
int yylval;
/* hab.
hab. los
los define
define Yacc
Yacc */
*/
typedef
int
token;
typedef int token;
%}
%}
separadores
[\n\t
separadores
[\n\t ]+
]+
.....
.....
letra
[a-zA-Z]
letra
[a-zA-Z]
digito
[0-9]
digito
[0-9]
identificador
{letra}({letra}|{digito})*
identificador {letra}({letra}|{digito})*
constEntera
constEntera {digito}({digito})*
{digito}({digito})*
%%
%%
seccin
seccin de
de reglas
reglas
%%
%%
seccin
seccin de
de rutinas
rutinas de
de usuario
usuario

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

15

FLEX: Un generador de analizadores lxicos


%{
%{
%}
%}

seccin
seccin de
de definiciones
definiciones

%%
%%

{separadores}
{separadores} {/*
{/* no
no hace
hace nada
nada */};
*/};
{constEntera}
{sscanf(yytext,"%d",&yylval);
{constEntera} {sscanf(yytext,"%d",&yylval);
return(CONSTENTERA);}
return(CONSTENTERA);}
....
....
{identificador}
{identificador} {return(IDENTIFICADOR);}
{return(IDENTIFICADOR);}
..
{ECHO;}
{ECHO;}

%%
%%

seccin
seccin de
de rutinas
rutinas de
de usuario
usuario
Nota: el nombre de la ER en la parte
de patrones debe ponerse entre
{ y } para distinguirlo del
patrn literal
{separadores}<>separadores

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

16

FLEX: Un generador de analizadores lxicos

Extensiones
de FLEX a
e.r.

..
r*
r*
r+
r+
r?
r?
[c
[c11...c
...cnn]]
a-b
a-b
^r
^r
[^c
[^c11...c
...cnn]]
r$
r$
r{m,n}
r{m,n}
\\
r1|r2
r1|r2
c
c11...c
...cnn
r1/r2
r1/r2

Compiladores I. C.P.S. Universidad de Zaragoza

cualquier
cualquier carcter
carcter excepto
excepto \n
\n
00 ms
concat.
de
r
ms concat. de r
11 ms
ms concat.
concat. de
de rr
00 11 veces
veces rr
conj.caracteres
conj.caracteres {c
{c11...c
...cnn}}
caracteres
caracteres {a,succ(a),...}
{a,succ(a),...}
rr debe
concordar
debe concordar al
al principio
principio
de
la
lnea
de la lnea
cualquier
cualquier car.{c
car.{c11...c
...cnn}}
rr debe
debe concordar
concordar al
al terminar
terminar
la
lnea
la lnea
entre
entre mm yy nn concatenaciones
concatenaciones
de
r
de r
para
para concordancia
concordancia exacta
exacta de
de
caracteres
especiales:
\\
caracteres especiales: \\ \.
\. \?
\?
lo
habitual
lo habitual
literalmente
literalmente cc11...c
...cnn
reconoce
r1
slo
reconoce r1 slo si
si va
va
seguida
de
r2
(e.r.?)
seguida de r2
(e.r.?)

-J.Ezpeleta-

17

FLEX: Un generador de analizadores lxicos

Qu pasa cuando
hay ambigedad?
FLEX aplica dos
reglas:
Regla 1

.....
letra
[a-zA-Z]
digito
[0-9]
identificador {letra}({letra}|{digito})*
%%
if
{return(IF);}
{identificador} {return(IDENT);}
%%

Aplica el patrn que concuerde con el string ms


largo
Regla 2
Si dos patrones representa el mismo string, aplica
el que aparece antes en las declaraciones de LEX

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

18

Un ejemplo: contar caracteres, lneas y palabras


#include <stdio.h>
int nCar=0, nPal=0, nLin=0;
%}
palabra [^ \t\n]+
finLin
\n
%%
{palabra} {nCar+=yyleng;nPal++;}
{finLin} {nCar++;nLin++;}
.
{nCar++;}
%%
int main(){
yylex();
fprintf(stdout,
"car:%d pal:%d lin:%d\n",
nCar, nPal, nLin
);
}

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

Una versin
a las bravas

19

Un ejemplo: contar caracteres, lneas y palabras

#include <stdio.h>
enum {PALABRA=128,FINLINEA,
OTROSEP};
int nCar=0, nPal=0, nLin=0;
%}
palabra [^ \t\n]+
finLin
\n
%%
{palabra} {return PALABRA;}
{finLin} {return FINLINEA;}
.
{return OTROSEP;}
%%
int main(){
}

Compiladores I. C.P.S. Universidad de Zaragoza

int elToken;
elToken=yylex();

un poco ms
estructurada
y elegante

while(elToken){
switch(elToken){
case PALABRA: nPal++;nCar+=yyleng;
break;
case FINLINEA:nCar++;nLin++;
break;
case OTROSEP: nCar++;
}
elToken=yylex();
}
fprintf(stdout,
"car:%d pal:%d lin:%d\n",
nCar, nPal, nLin
);

-J.Ezpeleta-

20

También podría gustarte