Documente Academic
Documente Profesional
Documente Cultură
especificación
FLEX
FLEX
FLEX
lex.yy.c
menor →
menor → <<
mayor →
mayor → >>
menorIgual →
menorIgual → <=
<=
mayorIgual →
mayorIgual → >=
>=
igual →
igual → ==
distinto →
distinto → <>
<>
letra →
letra → a|b|...|z|A|B|....|Z
a|b|...|z|A|B|....|Z
digito →
digito → 0|1|...|9
0|1|...|9
identificador →
identificador → letra
letra (letra
(letra |digito)*
|digito)*
constEntera →
constEntera → digito
digito digito
digito **
• Comportamiento deseado:
v0<>27 segundos= 1000
analizador
analizador
léxico
léxico
(IDENTIFICADOR,v0)
(DISTINTO,)
(CONSTENTERA,27)
(IDENTIFICADOR,segundos)
(IGUAL,)
(CONSTENTERA ,1000)
• Estructura de sección
sección de
de definiciones
definiciones
un programa FLEX %%
%%
sección
sección de
de reglas
reglas
%%
%%
sección
sección de
de rutinas
rutinas del
del usuario
usuario
• Sección 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
%{
%{ /*
/* 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;
%}
%}
%%
%%
sección
sección dede reglas
reglas
%%
%%
sección
sección dede rutinas
rutinas de
de usuario
usuario
• Sección de reglas
– Formato: patrón {acciones}
%{
%{
sección
sección de
de definiciones
definiciones
%}
%}
%%
%%
(\t|\n|"
(\t|\n|" ")+
")+ {/*
{/* no
no hace
hace nada
nada */};
*/};
[0-9]([0-9])*
[0-9]([0-9])* {sscanf(yytext,"%d",&yylval);
{sscanf(yytext,"%d",&yylval);
return(CONSTENTERA);}
return(CONSTENTERA);}
"<"
"<" {return(MENOR);}
{return(MENOR);}
....
....
....
....
"<>"
"<>" {return(DISTINTO);}
{return(DISTINTO);}
[a-zA-Z]([a-zA-Z]|[0-9])*
[a-zA-Z]([a-zA-Z]|[0-9])* {return(IDENTIFICADOR);}
{return(IDENTIFICADOR);}
.. {ECHO;}
{ECHO;}
%%
%%
sección
sección de
de rutinas
rutinas de
de usuario
usuario
patrón
acción
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 9
FLEX: Un generador de analizadores léxicos
%{
sección de definiciones
%}
%% /*--------------------------------------
Cuando EOF, yylex() dev. 0
sección de reglas ---------------------------------------*/
%% int main()
/*--------------------------------------
Sólo para comprobación
{ token elToken;
---------------------------------------
*/ elToken=yylex();
void escribeInfo(token elToken) while(elToken){
{ switch(elToken){ escribeInfo(elToken);
case IDENTIFICADOR: elToken=yylex();
fprintf(stdout, }
"ident.\t%s",yytext); }
break;
..........
}
}
invocación a FLEX
flex expresiones.l
fuente con el
analizador
lex.yy.c
-lfl: biblioteca
necesaria
gcc -o expresiones
lex.yy.c -lfl
analizador
expresiones
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 12
FLEX: Un generador de analizadores léxicos
#=====================================================
# Fichero: Makefile
# Tema: genera un analizador léxico 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
• Ejemplo de invocación:
– el fichero ‘entrada’ es v0<>27
segundos= 1000
{separadores}<>separadores
• Extensiones .. cualquier
cualquier carácter
carácter excepto
excepto “\n”
“\n”
de FLEX a r*
r*
r+
00 óó más concat. de
más concat. de r
11 óó más
r
e.r. r+ más concat.
concat. de
de rr
r?
r? 00 óó 11 veces
veces rr
[c
[c11...c
...cnn]] conj.caracteres
conj.caracteres {c {c11...c
...cnn}}
a-b
a-b caracteres
caracteres {a,succ(a),...}
{a,succ(a),...}
^r
^r rr debe
debe concordar al
concordar al principio
principio
de la línea
de la línea
[^c
[^c11...c
...cnn]] cualquier
cualquier car.∉{c
car.∉{c11...c
...cnn}}
r$
r$ rr debe
debe concordar
concordar al
al terminar
terminar
la línea
la línea
r{m,n}
r{m,n} entre
entre mm yy nn concatenaciones
concatenaciones
de r
de r
\\ para
para concordancia
concordancia exacta
exacta de de
caracteres
caracteres especiales: \\ \.
especiales: \\ \. \?
\?
r1|r2
r1|r2 lo habitual
lo habitual
“c
“c11...c
...cnn““ literalmente
literalmente cc11...c
...cnn
r1/r2
r1/r2 reconoce
reconoce r1 sólo si
r1 sólo si vava
seguida de
seguida de r2 r2 (¿e.r.?)
(¿e.r.?)
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta- 17
FLEX: Un generador de analizadores léxicos
#include <stdio.h>
int nCar=0, nPal=0, nLin=0;
Una versión
%}
“a las bravas”
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
);
}