Hace unos días en un curso de compiladores, se nos pidió investigar que era LEX y generar un analizador léxico que reconociera una sentencia FOR del tipo for (a=1; a<50; a++), investigando un poco encontré que LEX es un programa para generar scanners o lexers. Lex fue escrito originalmente por Eric Schmidt y Mike Lesk, es el analizador léxico estándar en los sistemas Unix pero este es un programa propietario ósea licenciado eso hasta donde pude leer, pero existe su versión libre llamada FLEX la cual pueden descargar en su versión 2.5 para Windows desde acá descargar.
Como funciona pues simple:
1. Se crea un archivo de texto con el código lex se guarda como archivo.l (extensión .l)
2. Desde línea de comando se compila de esta manera "flex archivo.l"
3. Esto genera en el mismo directorio un archivo de nombre lex.yy.c (del tipo de código C)
4. Desde cualquier utilitario de C/C++ como Dev-C se crea un proyecto y se importa este archivo .c
5. Este archivo debe ser compilado lo cual genera un ejecutable .exe con lo que nosotros pedimos que hiciera.
Acá les pongo un ejemplo como diríamos en Guatemala macheteado de un código lex que analizaría una sentencia FOR correcta, cabe mencionar que todo esto lo hice en unas horas por lo que para expertos en C o en LEX esto podría ser un juego de niños, el codigo ya esta probado y espero les pueda ser util en algun caso.
/* escáner para una sentencia for */
%{
/* se necesita esto para la llamada a atof()*/
#include <math.h>
%}
DIGITO [0-9]
PALABRA for
VARIABLE [a-z]
PI "("
PF ")"
ASIGNA "="
COMPARA <|<=|>|>=|<>
PUNCOM ";"
AUMENTA "+"
ESPACIOS [ \t\n]
%%
{PALABRA}+{ESPACIOS}*+{PI}+{ESPACIOS}*+{VARIABLE}+{ESPACIOS}*+{ASIGNA}+{ESPACIOS}*+{DIGITO}+{ESPACIOS}*+{PUNCOM}+{ESPACIOS}*+{VARIABLE}+{ESPACIOS}*+{COMPARA}+{ESPACIOS}*+{DIGITO}+{ESPACIOS}*+{PUNCOM}+{ESPACIOS}*+{VARIABLE}+{ESPACIOS}*+{AUMENTA}+{AUMENTA}+{ESPACIOS}*+{PF} {
printf( "SENTENCIA FOR CORRECTA: %s (%d)\n\n", yytext,
atoi( yytext ) );
}
{DIGITO}+ {
printf( "ENTERO: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PALABRA}+ {
printf( "PALABRA RESERVADA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{VARIABLE}+ {
printf( "VARIABLE: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PI}+ {
printf( "INICIA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PF}+ {
printf( "FINALIZA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{ASIGNA}+ {
printf( "ASGINACION DE VALOR: %s (%d)\n", yytext,
atoi( yytext ) );
}
{COMPARA}+ {
printf( "COMPARA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PUNCOM}+ {
printf( "PUNTO Y COMA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{AUMENTA}+{AUMENTA} {
printf( "AUMENTA VALOR: %s (%d)\n", yytext,
atoi( yytext ) );
}
"{"[^}\n]*"}"
[ \t\n]+
. printf( "CARACTER NO RECONOCIDO: %s\n", yytext );
%%
int yywrap()
{
return(1);
}
main( int argc, char *argv[] )
{
++argv, --argc;
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
}
No hay comentarios:
Publicar un comentario