INFORME LEX Y YACC

COMPILADORES HERRAMIENTAS LEX Y YACC LEX Es una herramienta utilizada para especificar analizadores léxicos. Suele llama

Views 62 Downloads 4 File size 390KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

COMPILADORES HERRAMIENTAS LEX Y YACC LEX Es una herramienta utilizada para especificar analizadores léxicos. Suele llamarsele compilador Lex a la herramienta, y lenguaje Lex a sus especificaciones de entrada. YACC Genera un analizador sintáctico (la parte de un compilador que comprueba que la estructura del código fuente se ajusta a la especificación sintáctica del lenguaje). Como se realiza Lex genera el código C para un analizador léxico, y yacc genera el código para un parser. Tanto lex como yacc toman como entrada un archivo de especificaciones que es típicamente más corto que un programa hecho a medida y más fácil de leer y entender. Por convención, la extensión del archivo de las especificaciones para lex es .l y para yacc es .y. La salida de lex y yacc es código fuente C. Lex crea una rutina llamada yylex en un archivo llamado lex.yy.c. Yacc crea una rutina llamada yyparse en un archivo llamado y.tab.c. Estas rutinas son combinadas con código fuente C provisto por el usuario, que se ubica típicamente en un archivo separado pero puede ser ubicado en el archivo de especificaciones de yacc. El código provisto por el usuario consiste de una rutina main que llama a Especific llama Especific yyparse, que en su momento, a yylex.

Diagrama lex y yacc Lex

.

. Yacc

lex

yacc

yylex()

yyparse( )

nombre_archivo.l

lex.yy.c

nombre_archivo.y

y.tab.c

Rutinas C

Compilador C Librería

COMPILADOR

s

CONSTRUCCIÓN DEL COMPILADOR Para llegar a la construcción del compilador el usuario debe tener instalados el compilador MINGW y el paquete de YACC.

Pasos para la instalación del paquete yacc Asumiendo que usted ha instalado este paquete en el directorio c:\yacc, prepare su ambiente de la siguiente manera: Bajo la consola DOS de Windows escriba el siguiente PATH, como se ilustra en la “figura A”. SET PATH=c:\yacc\bin;%PATH% SET BISON_SIMPLE=c:\yacc\bin\bison.simple SET BISON_HAIRY=c:\yacc\bin\bison.hairy Esta versión de YACC y LEX funcionan sin problemas con la versión del compilador MINGW32.

Esta es una distribución mínima del compilador MINGW solo soporta el modo consola de Windows. Su uso básicamente es para compilar algunos ejemplos sencillos y muy útil para el proyecto de lenguajes y compiladores. Si usted ya

tiene instalada la versión completa del mingw, no tiene sentido usar esta versión -

Su ventaja principal es su pequeño tamaño que facilita su descarga, y traslado de una máquina a otra sin complicaciones.

Pasos para la instalación del paquete MgwCon Copie la carpeta llamada "\MgwCon" en el disco local C.

En XP se puede, ejecutando el comando SET PATH=... estando en el modo consola de Dos, ponga la ruta en el PATH : como se ilustra en la “figura B” SET PATH=%PATH%;C:\MgwCon\Bin;

FIGURA B Asumimos que instalo el compilador en la unidad C: aunque podría haber sido cualquier otra. Usted puede tener otra distribución del mingw instalada en su disco duro (normalmente \MinGW) no habrá problemas ya que trabajarán en forma independiente. Uso de los archivos .l .y Para trabajar con los archivos escritos en lex y yacc .l y .y por ejemplo con los nombres de COM_BAS.l y COM_BAS.y.

Los dos últimos archivos (COM_BAS.L y COM_BAS.Y)

cópielos a la

dirección c:\yacc\bin anteriormente instalada.

Bajo consola DOS coloque la dirección o ruta donde se encuentran los archivos (COM_BAS.L y COM_BAS.Y) mediante comandos básicos como “CD”

FIGURA C Una vez en la carpeta c:\yacc\bin escriba como se muetra en la “figura C” y se creará el archivo lex.yy.c, donde lex.yy.c es una representación tabulada de un diagrama de transiciones construido a partir de las expresiones regulares de COM_BAS.L. Las acciones asociadas a las expresiones regulares de COM_BAS.L son partes de código en C y se transfieren directamente a lex.yy.c.

Ahora escriba se especifica que

–d es para

generar un fichero de cabecera llamado y.tab.h. COM_BAS.Y constituye una especificación en yacc, luego al someter COM_BAS.Y al compilador yacc so obtiene un programa en C llamado y.tab.c. El archivo y.tab.c es el analizador sintáctico en C incluye además otras rutinas de apoyo que pudo generar el usuario.

Copie todos los archivos (COM_BAS.L, COM_BAS.Y, lex.yy.c, y.tab.c, y.tab.h) a la dirección c:\mgwcon\bin.

Bajo consola DOS, para generar el programa ejecutable .exe deberá escribir la siguiente línea de código, (asegúrese de encontrarse en la carpeta c:\mgwcon\bin en DOS).

Se puede cambiar el nombre del programa .exe solamente indicando otro nombre de su elección por ejemplo gcc y.tab.c lex.yy.c –o COMPILADOR.exe. Para nuestro ejemplo el programa ejecutable tendrá

nombre

com_bas.exe como se muestra en la siguiente figura.

Nota: Si esta trabajando en modo DOS y aparece un error como el siguiente debe volver a escribir las líneas de código del PATH. Estas se encuentra en la “figura A” y “figura B”

COMPILADORES CREADOS TRADUCTOR DE EXPRESIONES INFIJAS A POSTFIJAS Archivo lex (.l) %{ #include "y.tab.h" %} %% "EOF"|"eof"

{return SALIR;}

[Dd][Ii][Vv] [Mm][Oo][Dd]

{return DIV;} {return MOD;}

[A-Za-z]([A-Za-z]|[0-9])* { yylval = *yytext; printf("%s ",yytext); return VARIABLE; } [0-9]+

{ yylval = strtol(yytext, (char **)NULL, *yytext=='0' ? 8:10); return INTEGER;

} [0-9]+(\.[0-9]+)?(E[+\-]?[0-9]+)? { yylval = *yytext; printf("%s ",yytext); return REAL; } [-()=+/*;\n] { //printf("\n\n "); return *yytext; } [ \t]+

;

[~`!#%^&_'":?] { ECHO; yyerror("es caracter Desconocido !Error¡"); }

%% int yywrap(void) { return 1; }

--------------------%token INTEGER REAL VARIABLE DIV MOD SALIR %left '+' '-' %left '*' '/' %{ static int variables[100]; static int dim[80]; int i=1; int j=1; %} %% lineas: '\n' | lineas declaracion '\n' ={ i=i+1; } | lineas SALIR '\n' { for(i=1;i $5 ) $$ = $3; else $$ = $5; } | expr FUNC_DIV expr { $$=$1; printf(" div "); } ; %% int yyerror(char *s) {

/*PARTE DE DEFINICIONES DE USUARIO*/

char mensaje[100]; if ( !strcmp( s, "parse error" ) ) strcpy( mensaje, "Error de sintaxis" ); else strcpy( mensaje, s ); fprintf(stderr, "Error en linea %d: %s\n", linea, mensaje); printf("ha ocurrido un error\n"); getch(); return 0; }

int main(void) { printf("\t\tUNIVERSIDAD CENTRAL DEL ECUADOR"); printf("\t\tDISEÑO DE COMPILADORES"); printf("\nFabián Silva Muñoz\n"); printf("\n\nIngrese la expresion a calcular: "); yyparse(); return 0; }

EJECUTABLE

CONVIERTE DE ENTEROS A ROMANOS Archivo lex (.y) %{ #include #include /*#include*/ char *ts[30]={ "I","II","III","IV","V","VI","VII","VIII","IX","X","XX","XXX","XL"," L","LX","LXX","LXXX","XC","C","CC","CCC","CD","D","DC","DCC","DCCC ","CM","M","MM","MMM"}; void mil(int); void cien(int); void decena(int); void unidad(int); void yyerror(char *s); %} %token NUMERO %% expresion: NUMERO ; %% yylex(){ int c; scanf("%d",&c); while(c!=0){ if(c>999) mil(c); else if(c>99) cien(c); else if(c>9) decena(c); else unidad(c); return NUMERO; } return c; } void mil(int c){

int a; a=c%1000; c=c/1000; printf("%s",ts[26+c]); if(a>99) cien(a); else if(a>9) decena(a); else unidad(a); } void cien(int c){ int a; a=c%100; c=c/100; printf("%s",ts[17+c]); if(a>9) decena(a); else unidad(a); } void decena(int c){ int a; a=c%10; c=c/10; printf("%s",ts[8+c]); unidad(a); } void unidad(int c){ if(c>0) printf("%s",ts[c-1]); else yyerror; } void yyerror(char *s) { printf("%s", s); } void main() { printf("Ingrese un nùmero: "); yyparse();/*llama a la yylex para tener otro componente lexico*/ getch(); }

EJECUTABLE