Departamento de Tecnologías de la Información Área de Ciencias de la Computación e Inteligencia Artificial Teoría de Autómatas y Lenguajes Formales Práctica 2 1.- OBJETIVOS El objetivo de esta práctica es desarrollar un analizador léxico escrito en C para un lenguaje sencillo. Para ello se tomará el código desarrollado en la práctica 1 y se sustituirá el módulo de análisis léxico generado por FLEX por un nuevo módulo programado manualmente. 2.- ESTRUCTURA DEL CÓDIGO A GENERAR El proyecto a desarrollar debe estar formado por varios módulos que se relacionan entre sí tal y como muestra a siguiente figura: fentrada Tokens.h Analex.c Analex.h Error.c Error.h Simbolos.c Simbolos.h Ppal.c Inicio.c Inicio.h ferror fsalida El proyecto a desarrollar debe estar formado por los siguientes módulos: • Tokens.h: contiene las definiciones de los tokens. • Analex.c: es el analizador léxico, contiene la función yylex(). • Analex.h: fichero cabecera del analizador léxico. • Simbolos.c: contiene las rutinas de manejo de la Tabla de Símbolos. • Simbolos.h: archivo de cabecera asociado al fichero Simbolos.c. • Inicio.c: llama a las rutinas de Simbolos.c para inicializar la Tabla de Símbolos. • Inicio.h: archivo de cabecera asociado al fichero Inicio.c. • Error.c: tratamiento de los errores (por ej. void error(int e)). 1 Teoría de Autómatas y Lenguajes Formales 2 • Error.h: archivo de cabecera asociado al fichero Error.c. • Ppal.c: contiene el programa principal 3.- DESCRIPCIÓN DEL MÓDULO DE ANÁLISIS LÉXICO El contenido de los módulos que forman el proyecto es el mismo que el desarrollado en la práctica 1. El único módulo que hay que programar en esta práctica es el módulo analex.c, que sustituye al módulo generado automáticamente por la herramienta FLEX. El esquema de funcionamiento de este módulo es el siguiente: Utiliza getc() para leer un carácter fentrada Reinserta un carácter utilizando ungetc() Analex.c yylex() Devuelve el componente léxico numfila numcolumna yylval Las rutinas getc(fen) y ungetc(fen,c) del archivo incluido estándar <stdio.h> se encargan del manejo del buffer de entrada; yylex() lee y devuelve los caracteres de la entrada llamando a las rutinas getc() y ungetc(), respectivamente. La función es también responsable de actualizar el contador de fila y columna. La función yylex() devuelve un entero que es el código de un componente léxico. Estos códigos se definen en el archivo Token.h, descrito en la práctica anterior. El contenido de este fichero Token.h debe ampliarse para añadir la declaración de la variable global yylval. Esta variable servirá de futuro interface con otros módulos del programa. Cada vez que se reconozca un entero o un hexadecimal deberá actualizarse yylval.entero con su valor numérico, cada vez que se reconozca operadores de más de un carácter o un identificador deberemos copiar su lexema en yylval.id. #define ENTERO 256 ........ typedef union{ int entero; char *id; } STYPE; STYPE yylval; A continuación se describe un ejemplo de pseudocódigo de un analizador lexico que puede tomarse como punto de partida para programar el analizador planteado. Es importante señalar que este pseudocódigo no describe completamente el lenguaje planteado (por ejemplo, no contempla el tipo de dato hexadecimal). Se trata sólamente de un ejemplo para facilitar el desarrollo de la práctica. Ciencias de la Computación e Inteligencia Artificial 2010-2011 Teoría de Autómatas y Lenguajes Formales 3 funcion yylex:integer; var buflex:array[0..100] of char; c:char; begin begin loop Leer ( c ); Si (c=EOF) return 0; sino si (c=' ') /* elimina espacios en blanco */ numcolumna=numcolumna+1; sino si (c='\n') numlinea=numlinea+1; numcolumna=1; sino si c es letra ó '_' entonces begin /* codigo para reconocer identificadores*/ entero p=0, pos=0; Mientras (c es letra ó digito ) hacer buflex[p]=c; Leer ( c ); p=p+1; Si (p>=TAMBUFF) entonces error("error del compilador"); fmientras; buflex[p]=FDC; Devolver(c); pos=busca(buflex); Si (pos=0) entonces pos=inserta(buflex,ID); Asignar a yylval.id el valor de buflex; return tablasimb[pos].complex; end sino si c es digito entonces Begin /* código para reconocer enteros*/ entero p=0; buflex[p]=c; Mientras (c es digito ) hacer buflex[p]=c; Leer ( c ); p=p+1; Si (p>=TAMBUFF) entonces error("error del compilador"); fmientras; buflex[p]=FDC; Devolver(c); Asignar a yylval.entero el valor de buflex; return ENTERO; end sino Si (c='(' ó c=')' ó c=’;’ ó c=’,’ ó c=’+’ ó c=’-' ó c=’=’ ó c='{' ó c='}' ó c='<' ó c='>') return c; Ciencias de la Computación e Inteligencia Artificial 2010-2011 Teoría de Autómatas y Lenguajes Formales 4 sino Si (c='/') /*es //, comienzo comentario linea*/ Leer ( c ); Si (c='/') repetir Leer ( c ) hasta (c <> '\n'); numlinea++; sino Devolver ( c ); /* aquí vendrá comentario de párrafo */ sino error_léxico(); end; 4.- DOCUMENTACIÓN A PRESENTAR La documentación a presentar de la práctica debe contener los ficheros fuentes indicados, el ejecutable generado, un conjunto de pruebas desarrolladas y un fichero memoria.doc con una breve descripción de la implementación realizada. 5.- PLAZO DE ENTREGA La fecha límite de entrega de la práctica es el día 29 de abril. La práctica se entregará por medio de la plataforma moodle. Ciencias de la Computación e Inteligencia Artificial 2010-2011