You are on page 1of 72

FACULTAD DE INGENIERA E.A.P.

INGENIERA DE SISTEMAS E INFORMTICA

MANUAL DEL CURSO:

Teora de Lenguajes
(Unidad III)
T ema: Descripcin de lenguajes de programacin

Dictado por:
DIANA CECILIA MUOZ CASANOVA
M.S. en Ingeniera de Sistemas e Informtica

CHIMBOTE PER 2007

CAPTULO I: INTRODUCCIN A LOS COMPILADORES 1.1. 1.2. 1.3. 1.4. 1.5. 1.6. Introduccin Historia Conceptos bsicos Concepto de compilador Interpretar vs compilar Tipos de compiladores 101 104 108 109 110 112

CAPTULO II: CONCEPTOS FUNDAMENTALES DE LOS COMPILADORES 2.1. Estructura de un compilador. 2.1.1.Preprocesador 2.1.2.Compilacin 2.1.3.Ensamblado 2.1.4.Enlazado Proceso de compilacin 2.2.1.Fase de anlisis 2.2.2.Fase de sntesis Ejemplo del proceso de compilacin Herramientas para construccin de compiladores El lenguaje y la herramienta Aspectos acadmicos y de investigacin de compiladores 114 115 115 115 116 117 118 119 120 125 126 127

2.2. 2.3. 2.4. 2.5. 2.6.

CAPTULO III: ANLISIS LXICO 3.1. 3.2. 3.3. 3.4. 3.5. 3.6. 3.7. Anlisis lxico (scanner) El proceso del anlisis lxico que es un analizador lxico? Funciones del analizador lxico Necesidad del analizador lxico Ventajas de separar el anlisis lxico y el anlisis sintctico: Componentes lxicos, patrones, lexemas 3.7.1.Componente lxico o token 3.7.2.Patrn o expresin regular 3.7.3.Lexema 3.8. Descripcin de un analizador lxico 3.9. Unidades de lxico 3.10. El rol del analizador lxico 3.11. Tratamiento de los errores 3.12. Tratamiento de palabras reservadas 3.13. Construccin de un analizador lxico 3.14. Concepto de expresin regular 3.15. Definicin de expresin regular 3.16. Operaciones de expresiones regulares 128 128 129 130 131 133 133 133 134 134 136 137 138 139 140 140 141 141 142

3.17. 3.18. 3.19. 3.20. 3.21. 3.22.

Lenguaje descrito por una expresin regular Teoremas de equivalencia Matrices de transicin Representacin de los autmatas Autmata finito determinista Autmata finito no determinista

142 143 143 144 145 147

CAPTULO IV: ANLISIS SINTCTICO 4.1. 4.2. 4.3. 4.4. Gramticas Gramticas libres de contexto y anlisis sintctico Gramticas libres de contexto Conceptos sobre GLCS 4.4.1.rbol de derivacin 4.4.2.Gramticas no ambiguas 4.4.3.Gramticas ambiguas 4.5. Gramtica BNF 4.6. rboles de anlisis sintcticos 4.7. Extensin de la notacin BNF 4.8. La notacin BNF extendida 4.9. El proceso de anlisis sintctico 4.10. Anlisis sintctico ascendente 4.11. Analizador sintctico SLR 4.12. Anlisis sintctico descendente 4.13. Analizador con retroceso 4.14. Tcnicas de anlisis predictivo 4.15. Conjuntos de prediccin 4.16. Conjunto primero 4.17. Conjunto siguiente 4.18. Factorizacin por la izquierda 4.19. Eliminacin de la recursividad 149 151 151 152 152 153 154 156 157 158 158 158 159 161 163 164 165 165 165 166 166 166

CAPTULO I: INTRODUCCIN A LOS COMPILADORES


1.1. INTRODUCCIN En un mundo informatizado como en el que vivimos, en el que cada da que pasa dependemos ms y ms de un sistema informtico eficiente, el cual debe estar preparado para brindarnos la ms alta calidad de servicios y prestaciones. Adems de ser sencillo en su manejo y sobre todo confiable, siendo estas caractersticas indispensables para el usuario final. Quien no se fija, ni pregunta como se realiza determinada tarea, pero si es buen critico a la hora de ver resultados, pero hay otros que contrarios a estos, se hace la pregunta del milln, "Cmo se logra hacer tal y tal cosa? ,"Cmo es posible que un graficador trabaje tan rpido?, Cmo es posible que un procesador de palabra a la hora de usar un diccionario sea tan eficiente?, Cmo es posible llevar los resultados de una aplicacin a otra?, o Cmo es posible que un programa que fue creado por una empresa puede trabajar con los datos de obtenidos de otro programa, echo por otra empresa?. Muchas pueden ser las respuestas, algunos argumentaran que es el sistema operativo, otros dirn que son las normas y estndares establecidos, otros dirn irnicamente que es ms sencillo de lo que se piensa, dirn que se hace clac con la rata aqu, se arrastra y se lleva a donde se quiere. Todos ellos tienen razn, sin embargo si indagamos ms a fondo. Surgirn preguntas ms directas como por ejemplo "Cmo se logra tal velocidad, con tan buen manejo de grfico?", claro que a todas ellas se puede responder diciendo, que todo se logra gracias al Hardware, y no estaramos totalmente errados, porque un buen Hardware conlleva a un buen resultado, a una buena calidad de impresin en caso de volcado al papel, una buena imagen si hablamos de grficos, o un buen tiempo de respuesta a la hora de realizar algn calculo matemtico, pero siempre el Hardware ser una parte, solo una parte. Es en este punto donde surge el Software, los programas, o como el modismo denota hoy en da, las aplicaciones. Es decir que para obtener un buen resultado no solo hace falta un buen Hardware acorde a los requerimientos de la tarea que se quiere realizar, sino que calidad, eficiencia, velocidad, y confiabilidad hoy en da son sinnimos de un buen trabajo en conjunto de la dupla Hardware y Software. Dejando de lado lo que es el Hardware, y profundizando lo que representa su par,

palabra ya adoptada en nuestro idioma, y muy usada en el mundo de la informtica, deducimos que para obtener un buen software, ante todo esta el aspecto creador de quien lo realiza, luego hay que ver cual ser el entorno de trabajo en que actuara, cuales sern los requerimientos del mismo, hay que saber elegir que paradigma de programacin se usar. Despus de formuladas estas preguntas y de haber respondido a las mismas de manera apropiada. Hay que elegir cual es el lenguaje de programacin ms conveniente para realizar dicha tarea. Un lenguaje de programacin o ms genricamente de computacin, es el medio por el cual el hombre interacta con un ordenador. Pero el lenguaje de computacin no es lo nico que se necesita para que se produzca la comunicacin, hace falta otro componente importante para completar el medio de comunicacin, y es en este punto donde surge la palabra "interprete", cuya definicin dice "persona que explica a otra en lengua que entienda" en el mbito informtico, olvidmonos por un instante de la palabra persona, e "interpretemos" su significado. Se puede decir entonces que a travs de un intrprete podramos pedir a un ordenador que realice una tarea determinada sin preocuparnos de los detalles. Claro que este interprete no es ms que una aplicacin (programa), que realiza la traduccin de lo que pedimos que comunique a un ordenador, por lo tanto un interprete es capaz de conocer dos lenguajes el del emisor y el del receptor. En el mundo de la informtica existen muchos lenguajes de programacin, que trabajan con uno o varios paradigmas de programacin (estilos, formas, mtodos de programacin), por lo tanto es de suponer que existen distintas reglas de sintaxis y semntica para cada lenguaje de programacin como lo existe en cualquier otro lenguaje, sea cualquiera el tipo y contexto al que pertenezca. En tiempos ya muy remotos segn cuentan los que saben proliferaban los intrpretes, quienes tomaban la peticin del usuario (hombre) e "interpretaban" la misma y se la comunicaban al ordenador quien la ejecutaba, y esperaba una nueva peticin. La peticin era declarada dentro los parmetros de definicin del lenguaje usado. Con el tiempo se vio que el estar realizando una interpretacin y traduccin cada vez que se necesita realizar algo era poco efectivo, en cuanto a tiempo de trabajo del Hardware se refiere, y ms aun si se trataba de un conjunto grande de instrucciones (peticiones), es aqu donde entraron en juego los compiladores, quien al igual que sus antecesores realizan una traduccin de los programas

(conjunto de intrusiones de un lenguaje) revisando que este dentro del marco de definicin del lenguaje de programacin utilizado. Con la diferencia que la traduccin se realiza una sola vez y de todo el programa. Despus de todos estos tpicos previos, podemos decir que la calidad de un buen software es producto de un lenguaje de computacin verstil, flexible y veloz, todo sinnimo de buen compilador, claro sin dejar de lado la capacidad creadora del programador (usuario, nosotros). "Cmo funciona un compilador? ", es la pregunta de todo aquel que se hace llamar programador, a grandes rasgos un compilador toma un programa escrito en un lenguaje de programacin con una gramtica, sintaxis y semntica definida, revisa que este dentro de las pautas de definicin del lenguaje, y lo traduce en programa de salida escrito en lenguaje binario, el cual es entendido por el ordenador y por lo tanto puede ser ejecutado por el mismo (recordar que un interprete a diferencia de un compilador no traduce todo el programa sino que va realizando la traduccin e interpretacin de la misma paso a paso, sin crear ningn programa de salida ejecutable). Las partes del proceso de compilacin se dividen en dos: una llamada fase de Anlisis y otra llamada fase de Sintaxis, las cuales interactan entre si para la creacin de la tabla de smbolos y el control del manejador de errores, dentro del anlisis hay tres etapas llamadas anlisis lexicogrfico, anlisis sintctico, anlisis semntico. Dentro de la fase de Sntesis existen las etapas de generacin de cdigo intermedio, optimizacin de cdigo intermedio, y generacin de cdigo. Al tener que describir como funciona un compilador tenemos que tener en claro en no confundir los trminos compilador y compilacin, se debe entender que al decir compilador nos referimos al programa, y al decir compilacin al proceso en s. En esencia ambos trminos cumplen con la definicin ms simple de un compilador, es decir, sea el programa compilador o el proceso de compilacin, ambos reciben como entrada un cdigo escrito en algn lenguaje y producen como salida otro cdigo escrito en otro lenguaje.

1.2. HISTORIA En 1946 se desarroll el primer ordenador digital. En un principio, estas mquinas ejecutaban instrucciones que consistan en cdigos numricos que sealan a los circuitos de la mquina los estados correspondientes a cada operacin. Pronto los primeros usuarios de estos ordenadores descubrieron la ventaja de escribir sus programas mediante claves ms fciles de recordar que esos cdigos numricos; al final, todas esas claves juntas se traducan manualmente a Lenguaje Mquina. Estas claves constituyen los llamados lenguajes ensambladores, que se generalizaron en cuanto se dio el paso decisivo de hacer que las propias mquinas realizaran el proceso mecnico de la traduccin. A este trabajo se le llama ensamblar el programa. Las instrucciones de los lenguajes ensambladores obligan a programar cualquier funcin de una manera minuciosa e iterativa. A pesar de ello, el lenguaje ensamblador segua siendo el de una mquina, pero ms fcil de manejar. Los trabajos de investigacin se orientaron entonces hacia la creacin de un lenguaje que expresara las distintas acciones a realizar de una manera lo ms sencilla posible para el hombre. As, en 1950, desarrollaron el FORTRAN con el cual surgi as por primera vez el concepto de un traductor (como un programa que traduca un lenguaje a otro lenguaje). En el caso particular de que el lenguaje a traducir es un lenguaje de alto nivel y el lenguaje traducido de bajo nivel, se emplea el trmino compilador. Inicio del Compilador La tarea de realizar un compilador no fue fcil. El primer compilador de FORTRAN tard 18 aos en realizarse y era muy sencillo. El FORTRAN estaba muy influenciado por la mquina objeto en la que iba a ser implementado. Como un ejemplo de ello tenemos el hecho de que los espacios en blanco fuesen ignorados, debido a que el perifrico que se utilizaba como entrada de programas (una lectora de tarjetas perforadas) no contaba correctamente los espacios en blanco. Paralelamente al desarrollo de FORTRAN en Amrica, en Europa surgi una corriente ms universitaria, que pretenda que la definicin de un lenguaje fuese

independiente de la mquina y en donde los algoritmos se pudieran expresar de forma ms simple. Esta corriente estuvo muy influida por los trabajos sobre gramticas de contexto libre publicados por Chomsky. Con estas ideas surgi un grupo europeo los cuales pidieron colaboracin a la asociacin americana y se form un comit elcual desarroll el lenguaje llamado ALGOL 58. En 1969, el lenguaje fue revisado y llev a una nueva versin que se llam ALGOL 60 y posteriormente ALGOL 68. Avances en Compilacin Junto a este desarrollo en los lenguajes (ALGOL), tambin se iba avanzando en la tcnica de compilacin. En 1958 proponan una solucin al problema de que un compilador fuera utilizable por varias mquinas objeto. Para ello, se divida por primera vez el compilador en dos fases, designadas como el "front end" y el "back end". La primera fase (front end) es la encargada de analizar el programa fuente y la segunda fase (back end) es la encargada de generar cdigo para la mquina objeto. El puente de unin entre las dos fases era un lenguaje intermedio que se design con el nombre de UNCOL (UNiversal Computer Oriented Language). Para que un compilador fuera utilizable por varias mquinas bastaba nicamente modificar su back end. Aunque se hicieron varios intentos para definir el UNCOL, el proyecto se ha quedado simplemente en un ejercicio terico. De todas formas, la divisin de un compilador en front end y back end fue un adelanto importante. Bases de las Tareas en un Compilador En los aos 1958 y 1959 se van poniendo las bases para la divisin de tareas en un compilador. As, en 1959 se propone el empleo de autmatas deterministas y no deterministas para el reconocimiento lexicogrfico de los lenguajes. Rpidamente se aprecia que la construccin de analizadores lxicos a partir de expresiones regulares es muy til en la implementacin de los compiladores. En 1975 surge el concepto de un generador automtico de analizadores lxicos a partir de expresiones regulares, basado en el sistema operativo UNIX. A partir de los trabajos de Chomsky ya citados, se produce una sistematizacin de la sintaxis de los lenguajes de programacin, y con ello un desarrollo de diversos mtodos de anlisis sintctico.

Con la aparicin de la notacin BNF, se tiene una gua para el desarrollo del anlisis sintctico.
1959: Se describe un mtodo de parsing de FORTRAN que introduca

parntesis adicionales alrededor de los operandos para ser capaz de analizar las expresiones.
1960: Se desarrollan los diversos mtodos de parsers ascendentes y

descendentes
1961: Se realiza el uso por primera vez de un parsing descendente recursivo. 1965: Se define las gramticas LR y describe la construccin de una tabla

cannica de parser LR.


1968: Se estudian y definen las gramticas LL as como los parsers

predictivos.
1970: Se describen los mtodos SLR y LALR de parser LR. Debido a su

sencillez y a su capacidad de anlisis para una gran variedad de lenguajes, la tcnica de parsing LR va a ser la elegida para los generadores automticos de parsers.
1975: Se crea el generador de analizadores sintcticos YACC para funcionar

bajo un entorno UNIX . Junto al anlisis sintctico, tambin se fue desarrollando el anlisis semntico. En los primeros lenguajes (FORTRAN y ALGOL 60) los tipos posibles de los datos eran muy simples, y la comprobacin de tipos era muy sencilla. No se permita la correccin de tipos, pues sta era una cuestin difcil. Con la aparicin del ALGOL 68 se permita que las expresiones de tipo fueran construidas sistemticamente. Ms tarde, de ah surgi la equivalencia de tipos por nombre y estructural. Tambin se desarrollaron estrategias para mejorar las rutinas de entrada y de salida de un procedimiento . As mismo, y ya desde los aos 60, se estudi el paso de parmetros a un procedimiento por nombre, valor y variable. Optimizacin en la Compilacin La tcnica de la optimizacin apareci desde el desarrollo del primer compilador de FORTRAN. Backus comenta cmo durante el desarrollo del FORTRAN se tena el miedo de que el programa resultante de la compilacin fuera ms lento

que si se hubiera escrito a mano. Para evitar esto, se introdujeron algunas optimizaciones en el clculo de los ndices dentro de un bucle. Pronto se sistematizan y se recoge la divisin de optimizaciones independientes de la mquina y dependientes de la mquina.
Entre las primeras estn la propagacin de valores , el arreglo de expresiones,

la eliminacin de redundancias, etc.


Entre las segundas se podra encontrar la localizacin de registros, el uso de

instrucciones propias de la mquina y el reordenamiento de cdigo. A partir de 1970 comienza el estudio sistemtico de las tcnicas del anlisis de flujo de datos. Su repercusin ha sido enorme en las tcnicas de optimizacin global de un programa. Compilacin en la Actualidad En la actualidad, el proceso de la compilacin ya est muy asentado. Un compilador es una herramienta bien conocida, dividida en diversas fases. Algunas de estas fases se pueden generar automticamente (analizador lxico y sintctico) y otras requieren una mayor atencin por parte del escritor de compiladores (las partes de traduccin y generacin de cdigo). De todas formas, y en contra de lo que quiz pueda pensarse, todava se estn llevando a cabo varias vas de investigacin en este fascinante campo de la compilacin:
Por una parte, se estn mejorando las diversas herramientas disponibles (por

ejemplo, el generador de analizadores lxicos Aardvark para el lenguaje PASCAL).


Tambin la aparicin de nuevas generaciones de lenguajes -ya se habla de la

quinta generacin, como de un lenguaje cercano al de los humanos-ha provocado la revisin y optimizacin de cada una de las fases del compilador. El ltimo lenguaje de programacin de amplia aceptacin que se ha diseado, el lenguaje Java, establece que el compilador no genera cdigo para una mquina determinada sino para una virtual, la Java Virtual Machine (JVM), que posteriormente ser ejecutado por un intrprete, normalmente incluido en un navegador de Internet. El gran objetivo de esta exigencia es conseguir la mxima portabilidad de los programas escritos y compilados en Java, pues es nicamente

la segunda fase del proceso la que depende de la mquina concreta en la que se ejecuta el intrprete.

Grfico N 1: Historia de la compilacin 1.3. CONCEPTOS BSICOS


Traductor.

Cualquier programa que toma como entrada un texto escrito en un lenguaje llamado fuente y da como salida un programa equivalente en otro lenguaje, el lenguaje objeto. Si el lenguaje fuente de un lenguaje de programacin de alto nivel y el objeto un lenguaje de bajo nivel (ensamblador o cdigo de mquina), al traductor se le denomina compilador.
Ensamblador.

Es un programa traductor cuyo lenguaje fuente es el lenguaje ensamblador.

Grfico N 2: Ensambladores

Intrprete.

Es un programa que no genera un programa equivalente, sino que toma una sentencia del programa fuente en un lenguaje de alto nivel y la traduce al cdigo equivalente y al mismo tiempo lo ejecuta. En un principio debido a la escasez de memoria se utilizaban ms los intrpretes, ahora se usan ms los compiladores (a excepcin de JAVA) 1.4. CONCEPTO DE COMPILADOR En el caso de que el lenguaje fuente sea un lenguaje de programacin de alto nivel y el objeto sea un lenguaje de bajo nivel (ensamblador o cdigo de mquina), a dicho traductor se le denomina compilador. Un ensamblador es un compilador cuyo lenguaje fuente es el lenguaje ensamblador. Histricamente, con la escasez de memoria de los primeros ordenadores, se puso de moda el uso de intrpretes frente a los compiladores, pues el programa fuente sin traducir y el intrprete juntos daban una ocupacin de memoria menor que la resultante de los compiladores. Por ello los primeros ordenadores personales iban siempre acompaados de un intrprete de BASIC (Spectrum, Commodore VIC20, PC XT de IBM, etc.). La mejor informacin sobre los errores por parte del compilador as como una mayor velocidad de ejecucin del cdigo resultante hizo que poco a poco se impusieran los compiladores. Hoy en da, y con el problema de la memoria prcticamente resuelto, se puede hablar de un gran predominio de los compiladores frente a los intrpretes, aunque intrpretes como los incluidos en los navegadores de Internet para interpretar el cdigo JVM de Java son la gran excepcin. La razn principal para querer usar un compilador es querer traducir un programa de un lenguaje de alto nivel, a otro lenguaje de nivel inferior (tpicamente lenguaje mquina). De esta manera un programador puede disear un programa en un lenguaje mucho ms cercano a como piensa un ser humano, para luego compilarlo a un programa ms manejable por una computadora.

Programa fuente

Compilador

Programa objeto

Mensaje de error

Grfico N 3: Resultado de la compilacin 1.5. INTERPRETAR VS COMPILAR Hay dos maneras de ejecutar un programa escrito en un lenguaje de alto nivel
Compilacin: traducir todo el programa a otro programa equivalente en

cdigo mquina. Entonces se ejecuta el programa obtenido


Interpretacin: interpretar las instrucciones del programa escrito en lenguaje

de alto nivel y ejecutarla una por una. Ventajas de compilar frente a interpretar:
Se compila una vez, se ejecuta n veces. En bucles, la compilacin genera cdigo equivalente al bucle, pero

interpretndolo se traduce tantas veces una lnea como veces se repite el bucle.
El compilador tiene una visin global del programa, por lo que la informacin

de mensajes de error es ms detallada. Ventajas del intrprete frente al compilador:


Un intrprete necesita menos memoria que un compilador. En principio eran

ms abundantes dado que los ordenadores tenan poca memoria.


Permiten una mayor interactividad con el cdigo en tiempo de desarrollo.

Un compilador no es un programa que funciona de manera aislada, sino que necesita de otros programas para conseguir su objetivo: obtener un programa ejecutable a partir de un programa fuente en un lenguaje de alto nivel. Algunos de esos programas son el preprocesador, el linker, el depurador y el ensamblador.

El preprocesador se ocupa (dependiendo del lenguaje) de incluir ficheros, expandir macros, eliminar comentarios, y otras tareas similares. El linker (Enlazador) se encarga de construir el fichero ejecutable aadiendo al fichero objeto generado por el compilador las cabeceras necesarias y las funciones de librera utilizadas por el programa fuente. El depurador permite, si el compilador ha generado adecuadamente el programa objeto, seguir paso a paso la ejecucin de un programa. Finalmente, Muchos compiladores, en vez de generar cdigo objeto, generan un programa en lenguaje ensamblador que debe despus convertirse en un ejecutable mediante un programa ensamblador.

Grfico N 4: Diagrama a bloques de la operacin de un buen compilador.

1.6. TIPOS DE COMPILADORES El programa compilador traduce las instrucciones en un lenguaje de alto nivel a instrucciones que la computadora puede interpretar y ejecutar. Para cada lenguaje de programacin se requiere un compilador separado. El compilador traduce todo el programa antes de ejecutarlo. Los compiladores son, pues, programas de traduccin insertados en la memoria por el sistema operativo para convertir programas de cmputo en pulsaciones electrnicas ejecutables (lenguaje de mquina). Los compiladores pueden ser de: una sola pasada: examina el cdigo fuente una vez, generando el cdigo o programa objeto. pasadas mltiples: requieren pasos intermedios para producir un cdigo en otro lenguaje, y una pasada final para producir y optimizar el cdigo producido durante los pasos anteriores. Optimacin: lee un cdigo fuente, lo analiza y descubre errores potenciales sin ejecutar el programa. Compiladores incrementales: generan un cdigo objeto instruccin por instruccin (en vez de hacerlo para todo el programa) cuando el usuario teclea cada orden individual. El otro tipo de compiladores requiere que todos los enunciados o instrucciones se compilen conjuntamente. Ensamblador: el lenguaje fuente es lenguaje ensamblador y posee una estructura sencilla. Compilador cruzado: se genera cdigo en lenguaje objeto para una mquina diferente de la que se est utilizando para compilar. Es perfectamente normal construir un compilador de Pascal que genere cdigo para MS-DOS y que el compilador funcione en Linux y se haya escrito en C++. Compilador con montador: compilador que compila distintos mdulos de forma independiente y despus es capaz de enlazarlos. Autocompilador: compilador que est escrito en el mismo lenguaje que va a compilar. Evidentemente, no se puede ejecutar la primera vez. Sirve para hacer ampliaciones al lenguaje, mejorar el cdigo generado, etc. Metacompilador: es sinnimo de compilador de compiladores y se refiere a un programa que recibe como entrada las especificaciones del lenguaje para el

que se desea obtener un compilador y genera como salida el compilador para ese lenguaje. El desarrollo de los metacompiladores se encuentra con la dificultad de unir la generacin de cdigo con la parte de anlisis. Lo que s se han desarrollado son generadores de analizadores lxicos y sintcticos. Por ejemplo, los conocidos: LEX: generador de analizadores lxicos YACC: generador de analizadores sintcticos desarrollados para UNIX. Los inconvenientes que tienen son que los analizadores que generan no son muy eficientes. Descompilador: es un programa que acepta como entrada cdigo mquina y lo traduce a un lenguaje de alto nivel, realizando el proceso inverso a la compilacin. Esta taxonoma de los tipos de compiladores no es excluyente, por lo que puede haber compiladores que se adscriban a varias categoras: Compiladores cruzados: generan cdigo para un sistema distinto del que estn funcionando. Compiladores optimizadores: realizan cambios en el cdigo para mejorar su eficiencia, pero manteniendo la funcionalidad del programa original. Compiladores de una sola pasada: generan el cdigo mquina a partir de una nica lectura del cdigo fuente. Compiladores de varias pasadas: necesitan leer el cdigo fuente varias veces antes de poder producir el cdigo mquina. Compiladores JIT (Just In Time): forman parte de un intrprete y compilan partes del cdigo segn se necesitan.

CAPTULO II: CONCEPTOS FUNDAMENTALES DE LOS COMPILADORES


2.1. ESTRUCTURA DE UN COMPILADOR. Cualquier compilador debe realizar dos tareas principales: anlisis del programa a compilar y sntesis de un programa en lenguaje maquina que, cuando se ejecute, realizara correctamente las actividades descritas en el programa fuente. Para el estudio de un compilador, es necesario dividir su trabajo en fases. Cada fase representa una transformacin al cdigo fuente para obtener el cdigo objeto. La siguiente figura representa los componentes en que se divide un compilador. Las tres primeras fases realizan la tarea de anlisis, y las dems la sntesis. En cada una de las fases se utiliza un administrador de la tabla de smbolos y un manejador de errores.

Grfico N 5: Estructura de un compilador

2.1.1.PREPROCESADOR Es el encargado de transformar el cdigo fuente de entrada original en el cdigo fuente puro. Es decir en expandir las macros, incluir las libreras, realizar un preprocesado racional (capacidad de enriquecer a un lenguaje antiguo con recursos ms modernos), extender el lenguaje y todo aquello que en el cdigo de entrada sea representativo de una abreviatura para facilitar la escritura del mismo.

2.1.2.COMPILACIN Recibe el cdigo fuente puro, este es l modulo principal de un compilador, pues si ocurriera algn error en esta etapa el compilador no podra avanzar. En esta etapa se somete al cdigo fuente puro de entrada a un anlisis lxico grfico, a un anlisis sintctico, a un anlisis semntico, que construyen la tabla de smbolos, se genera un cdigo intermedio al cual se optimiza para as poder producir un cdigo de salida generalmente en algn lenguaje ensamblador.

2.1.3.ENSAMBLADO Este modulo no es ni ms mi menos que otro compilador pues recibe un cdigo fuente de entrada escrito en ensamblador, y produce otro cdigo de salida, llamado cdigo binario no enlazado. Si por un momento viramos a

este modulo como un programa independiente, veramos que en este caso los trminos programa compilador y proceso de compilacin son los mismos. Pues este modulo no es mas que un compilador, que en su interior realiza como su antecesor un anlisis lxico grfico, un anlisis sintctico, un anlisis semntico, crea una tabla de smbolos, genera un cdigo intermedio lo optimiza y produce un cdigo de salida llamado cdigo binario no enlazado, y a todo este conjunto de tares se los denomina proceso de compilacin. Como se puede ver este compilador (llamado ensamblador) a diferencia de los dems compiladores no realiza una expansin del cdigo fuente original(cdigo fuente de entrada), tiene solamente un proceso de compilacin y por supuesto no enlaza el cdigo fuente. Es un compilador que carece de los mdulos de preprocesado y enlazado, y donde los mdulos de compilacin y ensamblado son los mismos.

2.1.4.ENLAZADO El cuarto y ultimo modulo es el encargado de realizar el enlazado del cdigo de fuente de entrada (cdigo maquina relocalizable) con las libreras que necesita, como as tambin de proveer al cdigo de las rutinas necesarias para poder ejecutarse y cargarse a la hora de llamarlo para su ejecucin, modifica las direcciones relocalizables y ubica los datos en las posiciones apropiadas de la memoria. Este ultimo modulo es el que produce como salida el cdigo binario enlazado. Ya sea dinmico o esttico, al decir dinmico se refiere a que el cdigo producido utiliza libreras dinmicas (libreras ya cargadas en el sistema), esto implica que se obtendr un cdigo ms corto y que se actualizara automticamente si aparece alguna nueva versin de las libreras, mientras que el esttico se refiere al echo que no se realiza enlace con ninguna librera y por lo tanto se obtendr un cdigo mas largo con una copia de las rutinas de librera que necesita.

Biblioteca (Archivos objeto relocalizables)

2.2. PROCESO DE COMPILACIN

Grfico N 6: estructura del proceso de compilacin

Analizando en detalle el proceso de compilacin, se divide en dos grandes fases:


Fase de Anlisis Anlisis Lxico Anlisis Sintctico Anlisis Semntico Fase de Sntesis Etapa de Generacin de Cdigo Intermedio Etapa de Optimizacin de Cdigo Etapa de Generacin de Cdigo

2.2.1.FASE DE ANLISIS En esta fase se crea una representacin intermedia de cdigo


Anlisis lxico (scanner).

En la fase de anlisis lxico se leen los caracteres del programa fuente y se agrupan en cadenas que representan los componentes lxicos. Cada componente lxico es una secuencia lgicamente coherente de caracteres relativa a un identificador, una palabra reservada, un operador o un carcter de puntuacin. A la secuencia de caracteres que representa un componente lxico se le llama lexema (o con su nombre en ingls token). En el caso de los identificadores creados por el programador no solo se genera un componente lxico, sino que se genera otro lexema en la tabla de smbolos.
Anlisis sintctico (parser).

En esta fase, los componentes lxicos se agrupan en frases gramaticales que el compilador utiliza para sintetizar la salida.
Anlisis semntico.

La fase de anlisis semntico se intenta detectar instrucciones que tengan la estructura sintctica correcta, pero que no tengan significado para la operacin implicada.

2.2.2.FASE DE SNTESIS Genera un cdigo a partir de la representacin intermedia


Generacin de cdigo intermedio.

Algunos compiladores generan una representacin intermedia explcita del programa fuente, una vez que se han realizado las fases de anlisis. Se puede considerar esta operacin intermedia como un subprograma para una mquina abstracta. Esta representacin intermedia debe tener dos propiedades importantes: debe ser fcil de producir y fcil de traducir al programa objeto.
Optimizacin de cdigo.

En esta fase se trata de mejorar el cdigo intermedio, de modo que resulte un cdigo de mquina ms rpido de ejecutar.
Generacin de cdigo.

Esta constituye la fase final de un compilador. En ella se genera el cdigo objeto que por lo general consiste en cdigo en lenguaje mquina (cdigo relocalizable) o cdigo en lenguaje ensamblador. Adems existen:
Administrador de la tabla de smbolos.

Una tabla de smbolos es una estructura de datos que contiene un registro por cada identificador. El registro incluye los campos para los atributos del identificador. El administrador de la tabla de smbolos se encarga de manejar los accesos a la tabla de smbolos, en cada una de las etapas de compilacin de un programa.
Manejador de errores.

En cada fase del proceso de compilacin es posibles encontrar errores. Es conveniente que el tratamiento de los errores se haga de manera centralizada a travs de un manejador de errores. De esta forma podrn controlarse ms eficientemente los errores encontrados en cada una de las fases de la compilacin de un programa.

2.3. EJEMPLO DEL PROCESO DE COMPILACIN Supongamos que un compilador tiene que analizar la siguiente preposicin:

suma= var1 + var2 + 10


Anlisis Lxico El analizador lxico lee los caracteres del programa fuente, y verifica que correspondan a una secuencia lgica (identificador, palabra reservada etc.). Esta secuencia de caracteres recibe el nombre componente lxico o lexema. En este caso el analizador lxico verifica si el identificador id1 (nombre interno para "suma") encontrado se halla en la tabla de smbolos, si no esta produce un error porque todava no fue declarado, si la preposicin hubiese sido la declaracin del identificador "suma" en lenguajes C, C++ (int suma;) el analizador lxico agregaria un identificador en la tabla de smbolos, y as sucesivamente con todos los componentes lxicos que aparezcan, los componentes lxicos resultantes de la expresin son: Identificador: El smbolo de asignacin: Identificador: Operador: Identificador: Operador: Numero: suma.

=
var1 + var2 + 10 id1= id2+ id3 * 10

Que en el anlisis lxico y con la tabla de smbolos es:

Anlisis Sintctico El analizador sintctico impone una estructura jerrquica a la cadena de componentes lxicos, generada por el analizador lxico, que es representada en forma de un rbol sintctico.

= / \ id1 + / \ id2 + / \ id3 10 Anlisis Semntico El analizador semntico verificara en este caso que cada operador tenga los operandos permitidos. = / \ id1 + / \ id2 + / \ id3 tipo_ent | 10 Generador de cdigo intermedio En esta etapa se lleva la preposicin a una representacin intermedia como un programa para una maquina abstracta. temp1= tipo_ent(10) temp2= id3 * temp1 temp3= id2 + tem2 id1= temp3 Optimizacin de cdigo El cdigo intermedio obtenido es representado de una forma mas optima y eficiente. temp1= id3 * 10.0 id1= id2 + temp1 Generador de cdigo Finalmente lleva el cdigo intermedio a un cdigo objeto que en este caso es un cdigo relocalizable o cdigo ensamblador (tambin llamado cdigo no enlazado). MOVF id3, R2 MULT #10.0, R2

MOVF id2, R1 ADDF R2, R1 MOVF R1, id1 Este el cdigo objeto obtenido que es enviado al modulo de ensamblado. Para entender todo esto veamos un ejemplo utilizando como lenguaje en este caso al popular lenguaje de programacin C creado por Kernighan y Ritchie. El siguiente cdigo esta definido de acuerdo al standard ANSI C.
#include<stdio.h> void main() { char* frase= " Hola Mundo...!!!"; printf("%s", frase ); };

En la primer lnea se encuentra una directiva de preprocesador, esta lnea le indica al compilador que tiene que incluir la librera stdio.h, es decir transformar el cdigo fuente de entrada en el cdigo fuente puro (expandido). Al pasar por el modulo de preprocesado, el cdigo fuente queda de la siguiente manera.
# 1 "hmundo.c" # 1 "c:/compilador/include/stdio.h" 1 3 # 1 " c:/compilador/include/sys/types.h" 1 3 # 12 " c:/compilador/include/stdio.h" 2 3 typedef void *va_list; typedef long unsigned int size_t; typedef struct { int _cnt; char *_ptr; char *_base; int _bufsiz; int _flag; int _file; char *_name_to_remove; } FILE; typedef unsigned long fpos_t; extern FILE __stdin, __stdout, __stderr; void clearerr(FILE *_stream); int fclose(FILE *_stream); int feof(FILE *_stream); int ferror(FILE *_stream); int fflush(FILE *_stream); int fgetc(FILE *_stream); int fgetpos(FILE *_stream, fpos_t *_pos); char * fgets(char *_s, int _n, FILE *_stream); FILE * fopen(const char *_filename, const char *_mode); int fprintf(FILE *_stream, const char *_format, ...); int fputc(int _c, FILE *_stream); int fputs(const char *_s, FILE *_stream);

size_t fread(void *_ptr, size_t _size, size_t _nelem, FILE *_stream); FILE * freopen(const char *_filename, const char *_mode, FILE *_stream); int fscanf(FILE *_stream, const char *_format, ...); int fseek(FILE *_stream, long _offset, int _mode); int fsetpos(FILE *_stream, const fpos_t *_pos); long ftell(FILE *_stream); size_t fwrite(const void *_ptr, size_t _size, size_t _nelem, FILE *_stream); int getc(FILE *_stream); int getchar(void); char * gets(char *_s); void perror(const char *_s); int printf(const char *_format, ...); int putc(int _c, FILE *_stream); int putchar(int _c); int puts(const char *_s); int remove(const char *_filename); int rename(const char *_old, const char *_new); void rewind(FILE *_stream); int scanf(const char *_format, ...); void setbuf(FILE *_stream, char *_buf); int setvbuf(FILE *_stream, char *_buf, int _mode, size_t _size); int sprintf(char *_s, const char *_format, ...); int sscanf(const char *_s, const char *_format, ...); FILE * tmpfile(void); char * tmpnam(char *_s); int ungetc(int _c, FILE *_stream); int vfprintf(FILE *_stream, const char *_format, va_list _ap); int vprintf(const char *_format, va_list _ap); int vsprintf(char *_s, const char *_format, va_list _ap); int fileno(FILE *_stream); FILE * fdopen(int _fildes, const char *_type); int pclose(FILE *_pf); FILE * popen(const char *_command, const char *_mode); extern FILE _stdprn, _stdaux; void _stat_describe_lossage(FILE *_to_where); int _doprnt(const char *_fmt, va_list _args, FILE *_f); int _doscan(FILE *_f, const char *_fmt, void **_argp); int _doscan_low(FILE *, int (*)(FILE *_get), int (*_unget)(int, FILE *), const char *_fmt, void **_argp); int fpurge(FILE *_f); int getw(FILE *_f); int mkstemp(char *_template); char * mktemp(char *_template); int putw(int _v, FILE *_f); void setbuffer(FILE *_f, void *_buf, int _size); void setlinebuf(FILE *_f); char * tempnam(const char *_dir, const char *_prefix); int _rename(const char *_old, const char *_new); # 1 "hmundo.c" 2 void main() { char* frase= " Hola Mundo...!!!"; printf("%s", frase ); };

El nuevo cdigo contiene el encabezado o prototipo de la/s funcin/es que se encuentran en el archivo de cabecera stdio.h, y que sern posiblemente utilizadas

en el cdigo fuente original. Este cdigo es pasado al modulo de compilacin quien luego de analizarlo y verificar si se encuentra correcto, transformara el cdigo fuente puro (expandido) en cdigo ensamblador y lo enva al modulo de ensamblado.
.file "hmundo.c" compiler_compiled.: ___compiled_c: .text LC0: .ascii " Hola Mundo...!!!\0" LC1: .ascii "%s\0" .align 2 .globl _main _main: pushl %ebp movl %esp,%ebp subl $4,%esp call ___main movl $LC0,-4(%ebp) movl -4(%ebp),%eax pushl %eax pushl $LC1 call _printf addl $8,%esp L1: leave ret

Este cdigo ser analizado por l modulo de ensamblado, que lo llevara a cdigo binario no enlazado, y lo enviara al modulo de enlazado. El cdigo de salida enviado al modulo de enlazado es el siguiente.
L&#0;(7&#0;.text&#0; @&#0;&#0;&#0;&#0; &#0; ............. .data&#0;@&#0;@&#0;@&#0; .bss&#0;@&#0;@&#0;&#128; Hola Mundo...!!!&#0;%s&#0; v&#0; UE&#0;EPh&#0; v&#0;.file&#0;&#0; ghmundo.c&#0;&#0;&#0;&#0;. ............. _main&#0;&#0;&#0;&#0; ___main&#0;&#0; _printf&#0;&#0;%&#0; _compiled.&#0; ___compiled_c&#0;

Finalmente l modulo de enlazado, vincula el cdigo binario sin enlazar con las libreras dinmicas necesarias segn sea el caso o no. Y produce como salida el cdigo binario enlazado o cdigo binario ejecutable.

MZ&#0;&#0; &#0;'&#0;&#0;`&#0;T&#0; $Id: xxx.asm built mm/dd/aa 00:00:00 by ...asm $ @(#) xxx.asm built mm/dd/aa 00:00:00 by ...asm ............. ] v&#0; Hola Mundo...!!!&#0;%s&#0; v&#0; U &#0;Ex"EPh", &#0; v&#0;387 No &#0;80387 detected. Warning: Coprocessor not present and DPMI setup failed! If application attempts floating operations system may hang! '&#0; v&#0;"&#0;Call frame traceback EIPs: 0x&#0; 0x&#0; Alignment Check&#0;Coprocessor Error&#0;Page fault&#0;General Protection Fault&#0;Stack Fault&#0;Segment Not Present&#0;Invalid TSS&#0;Coprocessor overrun&#0;Double ............ Division by Zero&#0;: sel=&#0; invalid&#0; base=&#0; limit=&#0; v&#0;US]ju j?&#0; ............

Este es el cdigo final conocido como cdigo maquina. 2.4. HERRAMIENTAS PARA CONSTRUCCIN DE COMPILADORES
Sistema de ayuda para escribir compiladores Generadores de compiladores Sist. Generadores de traductores

Herramientas generales para el diseo automtico de componentes

especficos de un comp.
Utilizan

lenguajes especficos para especificar e implementar la

componente
Ocultan detalles del algoritmo de generacin Producen componentes que se pueden integrar al resto del compilador

Generadores de analizadores sintcticos Producen AS a partir de una Gramtica Libre de Contexto Hoy esta es una de las fases ms fciles de aplicar

Generadores de analizadores lxicos Producen AL a partir de una especificacin en Expresiones Regulares.

El AL resultante es un Autmata Finito Dispositivos de traduccin dirigida por la sintaxis Producen grupos de rutinas que recorren el rbol de AS generando cdigo

intermedio
Generadores automticos de cdigo Las proposiciones en cod. Int. se reemplazan por plantillas que representan

secuencia de instrucciones de mquina


Dispositivos para anlisis de flujo de datos Inf. sobre como los valores se transmiten de una parte a otra del programa

LEX y YACC Herramientas que nos permiten desarrollar componentes o la mayor parte

de un compilador
Son un recurso invaluable para el profesional y el investigador Existen paquetes freeware

2.5. EL LENGUAJE Y LA HERRAMIENTA Tabla N 1: lenguajes y la herramienta


MODELO LENGUAJE CARACTERSTICAS

Compilado

Fortran, COBOL, C/C++, Sintaxis Pascal tamao

rigurosa,

velocidad

Interpretado

Lisp, AWK; SQL Java

BASIC; Desempeo lento, actividades no planeadas, sintaxis relajadas Transportabilidad absoluta, desempeo intermedio, sintaxis rigurosa

Pseudocompilado

2.6. ASPECTOS ACADMICOS Y DE INVESTIGACIN DE COMPILADORES Tabla N 2: Aspectos acadmicos de la investigacin de compiladores

REA Lenguaje de programacin

BENEFICIOS Principios para su desarrollo Herramientas para la implementacin

Inteligencia artificial

Interfases de reconocimiento de lenguaje natural

Sistemas operativos

Desarrollo de interfases de control y usuario final. Interpretes de comandos (Shell)

Diseo de interfases

Desarrollo de interfases orientadas a comando y carcter. Voz o escritura.

Administracin de proyectos Seleccin de herramientas de desarrollo.

informticos

Evaluacin de costo de beneficio

CAPTULO III: ANLISIS LXICO


3.1. ANLISIS LXICO (SCANNER) El analizador lxico, tambin conocido como scanner, lee los caracteres uno a uno desde la entrada y va formando grupos de caracteres con alguna relacin entre s (tokens), que constituirn la entrada para la siguiente etapa del compilador. Cada token representa una secuencia de caracteres que son tratados como una nica entidad. Por ejemplo, en Pascal un token es la palabra reservada BEGIN, en C: WHILE, etc. Las tiras especficas slo tienen tipo (lo que representan), mientras que las tiras no especficas tienen tipo y valor. Por ejemplo, si Contador es un identificador, el tipo de token ser identificador y su valor ser la cadena Contador. El Analizador Lxico es la etapa del compilador que va a permitir saber si es un lenguaje de formato libre o no. Frecuentemente va unido al analizador sintctico en la misma pasada, funcionando entonces como una subrutina de este ltimo. Ya que es el que va leyendo los caracteres del programa, ignorar aquellos elementos innecesarios para la siguiente fase, como los tabuladores, comentarios, espacios en blanco, etc. 3.2. EL PROCESO DEL ANLISIS LXICO El proceso de anlisis lxico se refiere al trabajo que realiza el scanner con relacin al proceso de compilacin. El scanner representa una interfaz entre el programa fuente y el analizador sintctico o parser. El scanner, a travs del examen carcter por carcter del texto, separa el programa fuente en piezas llamadas tokens, los cuales representan los nombres de las variables, operadores, etiquetas, y todo lo que comprende el programa fuente. El parser, usualmente genera un rbol de sintaxis del programa fuente como ha sido definido por una gramtica. Las hojas del rbol son smbolos terminales de la gramtica. Son esos smbolos terminales o tokens los que el scanner extrae del cdigo fuente y se los pasa al parser. Es posible para el parser usar el conjunto de caracteres terminales del lenguaje como el conjunto de tokens, pero ya que los tokens pueden ser definidos en trminos de gramticas regulares ms simples que

en las gramticas ms complejas utilizadas por los parsers, es deseable usar scanners. Usar solo parsers es costoso en trminos de tiempo de ejecucin y requerimientos de memoria, y la complejidad y el tiempo de ejecucin puede reducirse con el uso de un scanner. La separacin entre anlisis lxico (scanning) y anlisis sintctico (parsing) puede tener tambin otras ventajas. El anlisis lxico de caracteres generalmente es lento en los compiladores, y separndolo del componente de anlisis semntico de la compilacin, el nfasis particular puede darse para hacer ms eficiente el proceso. Un analizador de lxico tiene como funcin principal el tomar secuencias de caracteres o smbolos del alfabeto del lenguaje y ubicarlas dentro de categoras, conocidas como unidades de lxico. Las unidades de lxico son empleadas por el analizador gramatical para determinar si lo escrito en el programa fuente es correcto o no gramaticalmente. Algunas de las unidades de lxico no son empleadas por el analizador gramatical sino que son descartadas o filtradas. Tal es el caso de los comentarios, que documentan el programa pero que no tienen un uso gramatical, o los espacios en blanco, que sirven para dar legibilidad a lo escrito. En la terminologa empleada en la construccin de un analizador de lxico se encuentran los siguientes trminos. 3.3. QUE ES UN ANALIZADOR LXICO? Se encarga de buscar los componentes lxicos (tokens En ingles) o palabras que componen el programa fuente, segn unas reglas o patrones. La entrada del analizador lxico podemos definirla como una secuencia de caracteres.

Grfico N 7: Analizador lxico El analizador lxico tiene que dividir la secuencia de caracteres en palabras con significado propio y despus convertirlo a una secuencia de terminales desde el punto de vista del analizador sintctico, que es la entrada del analizador sintctico.

El analizador lxico reconoce las palabras en funcin de una gramtica regular de manera que sus NO TERMINALES se convierten en los elementos de entrada de fases posteriores. En LEX, por ejemplo, esta gramtica se expresa mediante expresiones regulares. 3.4. FUNCIONES DEL ANALIZADOR LXICO El analizador lxico es la primera fase de un compilador. Su principal funcin consiste en leer los caracteres de entrada y elaborar como salida una secuencia de componentes lxicos que utiliza el analizador sintctico para hacer el anlisis. Esta interaccin, suele aplicarse convirtiendo al analizador lxico en una subrutina o corrutina del analizador sintctico. Recibida la orden Dame el siguiente componente lxico del analizador sintctico, el analizador lxico lee los caracteres de entrada hasta que pueda identificar el siguiente componente lxico. Estos componentes lxicos representan:
palabras reservadas: if, while, do, . . . identicadores: asociados a variables, nombres de funciones, tipos definidos

por el usuario, etiquetas,... Por ejemplo:


Forma: una letra seguida de letras o nmeros. Ej. a, b1, c3D Atributo nombre: string con la secuencia de caracteres que forma el

identificador en maysculas. Ej. A, B1, C3D


operadores: = * + - / == > < &! = . . . smbolos especiales: ; ( ) [ ] f g ... constantes numricas: literales que representan valores enteros, en coma

flotante, etc, 982, 0xF678, -83.2E+2,...


Forma: secuencia de dgitos que puede empezar con el signo menos y

puede contener un punto. Ej. 10, -3, 15.4, -54.276, .10


Atributo valor: Double con el valor numrico. Precisin: entero o real. constantes de caracteres: literales que representan cadenas concretas de

caracteres, \hola mundo",...

Grfico N 8: Interaccin de un analizador lxico con el analizador sintctico Otras funciones que realiza:
Eliminar los comentarios del programa. Eliminar espacios en blanco, tabuladores, retorno de carro, etc, y en general,

todo aquello que carezca de significado segn la sintaxis del lenguaje.


Reconocer los identificadores de usuario, nmeros, palabras reservadas del

lenguaje,..., y tratarlos correctamente con respecto a la tabla de smbolos (solo en los casos que debe de tratar con la tabla de smbolos).
Llevar la cuenta del nmero de lnea por la que va leyendo, por si se produce

algn error, dar informacin sobre donde se ha producido.


Avisar de errores lxicos. Por ejemplo, si @ no pertenece al lenguaje, avisar de

un error.
Puede hacer funciones de preprocesador.

3.5. NECESIDAD DEL ANALIZADOR LXICO Un tema importante es el porqu se separan los dos anlisis lexicogrfico y sintctico, en vez de realizar slo el anlisis sintctico, del programa fuente, cosa perfectamente posible aunque no plausible. Algunas razones de esta separacin son:
Un diseo sencillo es quizs la consideracin ms importante. Separar el

anlisis lxico del anlisis sintctico a menudo permite simplificar una u otra de dichas fases. El analizador lxico nos permite simplificar el analizador sintctico.

Grfico N 9: Necesidad del analizador lxico Si el sintctico tuviera la gramtica de la Opcin 1 , el lexicogrfico sera: Opcin 1: ( 0 | 1 | 2 | ... | 9) + (+ | - | * | /) NUM OPARIT

Si en cambio el sintctico toma la Opcin 2, el lexicogrfico sera: Opcin 2: ( 0 | 1 | 2 | ... | 9) + + - * / NUM MAS MENOS MULT DIV

Es ms, si ni siquiera hubiera anlisis lxico, el propio anlisis sintctico vera incrementado su nmero de reglas: NUM |1 |2 |3 .... | NUM NUM 0

3.6. VENTAJAS DE SEPARAR EL ANLISIS LXICO Y EL ANLISIS SINTCTICO:


Facilita transportabilidad del traductor (por ejemplo, si decidimos en un

momento dado cambiar las palabras reservadas begin y end de inicio y en de bloque, por f y g, solo hay que cambiar este modulo.
Se simplifica el diseo: el analizador es un objeto con el que se interacta

mediante ciertos mtodos. Se localiza en un nico modulo la lectura fsica de los caracteres, por lo que facilita tratamientos especializados de E/S.
Se mejora la eficiencia del compilador. Un analizador lxico independiente

permite construir un procesador especializado y potencialmente ms eficiente para esa funcin.


Gran parte del tiempo se consume en leer el programa fuente y dividirlo en

componentes lxicos. Con tcnicas especializadas de manejo de buffers para la lectura de caracteres de entrada y procesamiento de componentes lxicos se puede mejorar significativamente el rendimiento de un compilador.
Otra razn por la que se separan los dos anlisis es para que el analizador

lxico se centre en el reconocimiento de componentes bsicos complejos. 3.7. COMPONENTES LXICOS, PATRONES, LEXEMAS 3.7.1.COMPONENTE LXICO O TOKEN El valor asociado a una categora o unidad de lxico. Se representa como un nmero entero o una constante de un byte. Ejemplo: el token de un identificador puede ser 1 id (si id fue definida como 1). Los tokens son las unidades lxicas bsicas de igual forma que las palabras y signos de puntuacin son las unidades bsicas de un enunciado. Los tokens varan del lenguaje al lenguaje e incluso de compilador a compilador para el mismo lenguaje, la eleccin de los tokens es tarea del diseador del compilador. En la mayora de lenguajes tendremos tokens para :
palabras clave: IF THEN THEN THEN = ELSE; ELSE ELSE = THEN; operadores

identificadores constantes (reales, enteras y de tipo carcter), strings de caracteres y

signos de puntuacin 1. Tipos de tokens:


tiras especficas, tales como palabras reservadas (if, while, begin,

etc.), el punto y coma, la asignacin, los operadores aritmticos o lgicos, etc.


tiras no especficas, como identificadores, constantes o etiquetas.

2. Prioridad de los tokens


Se da prioridad al token con el lexema ms largo:

Si se lee >= y > se reconoce el primero.


Si el mismo lexema se puede asociar a dos tokens, estos patrones

estarn definidos en un orden determinado. Ejemplo:


While palabra reservada while letra (letra | digito)* identificador Si en la entrada aparece while, se elegir la palabra reservada por

estar primero.
Si estas especificaciones iniciales aparecieran en orden inverso, se

reconocera un token identificador. 3.7.2.PATRN O EXPRESIN REGULAR Definen las reglas que permiten identificar los componentes lxicos o tokens. 3.7.3.LEXEMA Es cada secuencia de caracteres concreta que encaja con un patrn, es decir, es como una instancia de un patrn. Ejm: 8, 23, 50 (son lexemas que encajan con el patrn ( 0 | 1 | 2 | ... | 9) + ) Una vez detectado que un grupo de caracteres coincide con un patrn, se ha detectado un lexema. A continuacin se le asocia un nmero, que se le pasar

al sintctico, y, si es necesario, informacin adicional, como puede ser una entrada en la tabla de smbolos. La tabla de smbolos suelen ser listas encadenadas de registros con parte variable: listas ordenadas, rboles binarios de bsqueda, tablas hash, etc. Ejm: Hacer un analizador lxico que nos reconozca los nmeros enteros, los nmeros reales y los identificadores de usuario. Vamos a hacer este ejemplo en C. Terminales ( 0 ... 9) + (0 ... 9)*. (0 ... 9) + (a ... z) (a ... z 0 ... 9) * Expresin Regular NUM_ENT NUM_REAL ID

Asociado a la categora gramatical de nmero entero tendremos el token NUM_ENT que puede equivaler por ejemplo al nmero 280; asociado a la categora gramatical nmero real tendremos el token NUM_REAL que equivale al nmero 281; asociado a la categora gramatical identificador de usuario tendremos el token ID que equivale al nmero 282. ( 0 ... 9) + (0 ... 9)*. (0 ... 9) + (a ...z) (a ...z 0...9) * { return 280;} { return 281;} { return 282;}

Si tuviramos como texto de entrada el siguiente: 95.7 99 hola El analizador lxico intenta leer el lexema ms grande; el 95 encaja con el primer patrn, pero sigue, al encontrarse el punto, se da cuenta de que tambin encaja con el segundo patrn, entonces como este es ms grande, toma la accin del segundo patrn, return NUM_REAL. El 99 coincide con el patrn NUM_ENT, y la palabra con ID. Los espacios en blanco no coinciden con ningn patrn. En vez de trabajar con los nmeros 280, 281, 282, se definen mnemotcnicos. # define NUM_ENT # define NUM_REAL 280 281

# define NUM_ID ( \t \n) (0 ... 9) + (0 ... 9) *. (0 ... 9) + (a ... z) (a ... z 0 ... 9)*

282 {return NUM_ENT;} {return NUM_REAL;} {return ID;}

Las palabras que entran por el patrn ( \t \n) no tienen accin asociada, por lo que , por defecto, se consideran solo espaciadores. Ejemplo: Programa UNO; Inicio Escribe (Hola); Fin. Cuya tabla de tokens es la siguiente: Programa UNO ; Inicio Escribe ( Hola ) ; Fin. Palabra reservada Identificador Delimitador Palabra reservada Palabra reservada Smbolo Identificador compuesto Smbolo Delimitador Palabra reservada

3.8. DESCRIPCIN DE UN ANALIZADOR LXICO El anlisis lxico es un anlisis de los caracteres:


Parte de stos y por medio de patrones reconoce los lexemas Enva al analizador sintctico el componente lxico y sus atributos Puede hacer tareas adicionales: eliminar blancos, control lneas.

Grfico N 10: Descripcin del analizador lxico El analizador lxico y el sintctico forman un par productor-consumidor. En algunas situaciones, el analizador lxico tiene que leer Algunos caracteres por adelantado para decidir de qu token se trata.

Grfico N 11: Par Productor-Consumidor 3.9. UNIDADES DE LXICO Categoras en que se clasifican las cadenas de caracteres vlidos en un lenguaje. Los caracteres vlidos reciben el nombre de alfabeto. Por ejemplo, el alfabeto de Pascal es: A-Z, a-z, 0-9, _, =, :, ;, ,, , -, ', ", *, /, (, ), [, ], ., <, > y las unidades de lxico para pascal son:
identificadores literales numricas operadores aritmticos cadenas de caracteres

separadores operadores relacionales operadores lgicos comentarios Con respecto al lenguaje para controlar al ROBOT, tenemos que su alfabeto

es: n,o,r,t,e,s, ,u,i,c y las unidades de lxico son:


rdenes (norte, sur, este, oeste, inicio) y espacios en blanco.

3.10.EL ROL DEL ANALIZADOR LXICO Aunque el analizador de lxico es la primera etapa del proceso de compilacin, no es quien lo inicia. Pudiera considerarse que el analizador de lxico hace su procesamiento y enva sus resultados al analizador gramatical, como secuencialmente se aprecia en el proceso de compilacin; no es as: La compilacin empieza con el analizador gramatical quien solicita un token para realizar su trabajo; el analizador de lxico reune smbolos y enva el token correspondiente a la unidad de lxico que conform al analizador gramatical y espera una nueva solicitud de token. Como se aprecia en la figura siguiente, el analizador de lxico est supeditado por el analizador gramatical.

Grfico N 12: Rol del analizador lxico Durante estas etapas se tiene comunicacin con la tabla de smbolos que concentra informacin de las entidades empleadas en el programa.

3.11.TRATAMIENTO DE LOS ERRORES Un traductor debe adoptar alguna estrategia para detectar, informar y recuperarse para seguir analizando hasta el final. Las respuestas ante el error pueden ser:

Inaceptables: Provocadas por fallos del traductor, entrada en lazos infinitos, producir resultados errneos, y detectar slo el primer error y detenerse. Aceptables: Evitar la avalancha de errores (mala recuperacin) y, aunque ms complejo, informar y reparar el error de forma automtica. La conducta de un Analizador de Lxico es el de un Autmata finito o scanner. Deteccin del error: El analizador de Lxico detecta un error cuando no existe transicin desde el estado que se encuentra con el smbolo de la entrada. El smbolo en la entrada no es el esperado.

Los errores lxicos se detectan cuando el analizador lxico intenta reconocer componentes lxicos y la cadena de caracteres de la entrada no encaja con ningn patrn. Son situaciones en las que usa un carcter invalido (@,$,",>,...), que no pertenece al vocabulario del lenguaje de programacin, al escribir mal un identificador, palabra reservada u operador. Errores lxicos tpicos son: 1. nombre ilegales de identificadores: un nombre contiene caracteres invlidos. 2. Nmeros incorrectos: un numero contiene caracteres invlidos o no esta formado correctamente, por ejemplo 3,14 en vez de 3.14 o 0.3.14. 3. errores de ortografa en palabras reservadas: caracteres omitidos, adicionales o cambiados de sitio, por ejemplo la palabra while en vez de while. 4. fin de archivo: se detecta un fin de archivo a la mitad de un componente lxico. Los errores lxicos se deben a descuidos del programador. En general, la recuperacin de errores lxicos es sencilla y siempre se traduce en la generacin de un error de sintaxis que ser detectado mas tarde por el analizador sintctico cuando el analizador lxico devuelve un componente lxico que el analizador sintctico no espera en esa posicin.

Los mtodos de recuperacin de errores lxicos se basan bien en saltarse caracteres en la entrada hasta que un patrn se ha podido reconocer; o bien usar otros mtodos ms sofisticados que incluyen la insercin, borrado, sustitucin de un carcter en la entrada o intercambio de dos caracteres consecutivos. Una buena estrategia para la recuperacin de errores lxicos:

si en el momento de detectar el error ya hemos pasado por algn estado final ejecutamos la accin correspondiente al ultimo estado final visitado con el lexema formado hasta que salimos de el; el resto de caracteres ledos se devuelven al flujo de entrada y se vuelve al estado inicial; Si no hemos pasado por ningn estado final, advertimos que el carcter encontrado no se esperaba, lo eliminamos y proseguimos con el anlisis.

3.12.TRATAMIENTO DE PALABRAS RESERVADAS Son aquellas que los lenguajes de programacin reservan para usos particulares. Cmo diferenciarlas de los identificadores? Resolucin implcita: reconocerlas todas como identificadores, utilizando una tabla adicional con las palabras reservadas que se consulta para ver si el lexema reconocido es un identificador o una palabra reservada.

Resolucin explcita: se indican todas las expresiones regulares de todas las palabras reservadas y se integran los diagramas de transiciones resultantes de sus especificaciones lxicas en la mquina reconocedora.

3.13.CONSTRUCCIN DE UN ANALIZADOR LXICO Los analizadores lxicos pueden construirse:

Usando generadores de analizadores lxicos: Es la forma ms sencilla pero el cdigo generado por el analizador lxico es ms difcil de mantener y puede resultar menos eficiente. Escribiendo el analizador lxico en un lenguaje de alto nivel: permite obtener analizadores lxicos con ms esfuerzo que con el mtodo anterior pero ms eficientes y sencillos de mantener.

Escribiendo el analizador lxico en un lenguaje ensamblador: Slo se utiliza en casos especficos debido a su alto coste y baja portabilidad.

3.14.CONCEPTO DE EXPRESIN REGULAR El objetivo de las expresiones regulares es representar todos los posibles lenguajes definidos sobre un alfabeto , basndose en una serie de lenguajes primitivos, y unos operadores de composicin. Lenguajes primitivos serian el lenguaje vaci, el lenguaje formado por la palabra vaca, y los lenguajes correspondientes a los distintos smbolos del alfabeto. Los operadores de composicin son la unin, la concatenacin, el cierre y los parntesis. 3.15.DEFINICIN DE EXPRESIN REGULAR Dado un alfabeto finito , las expresiones regulares sobre se definen de forma recursiva por las siguientes reglas: 1. Las siguientes expresiones son expresiones regulares primitivas:

, con

2. Sean y expresiones regulares, entonces son expresiones regulares derivadas:


+ (union) . (o simplemente ) (concatenacion) * (cierre) (A* repeticin l|A|AA|AAA..) ( )

3. No hay ms expresiones regulares sobre que las construidas mediante estas reglas. Observacin: La precedencia de los operadores es la siguiente (de mayor a menor): 1. ( ) 2. * cierre

3. . concatenacin 4. + unin Ejemplo: Algunos ejemplos de expresin regular son: (0 + 1)*01 (aa + ab + ba + bb)* a*(a + b) (aa)*(bb)*b 3.16.OPERACIONES DE EXPRESIONES REGULARES Seleccin entre alternativas. la cual se indica mediante el metacaracter | Concatenacin. La concatenacion entre dos expresiones regulares R y S se expresa por RS.

Repeticin. Se indica mediante el metacaracter *

3.17.LENGUAJE DESCRITO POR UNA EXPRESIN REGULAR Sea r una expresin regular sobre . El lenguaje descrito por r, L(r), se define recursivamente de la siguiente forma:

Ejemplo:

L(a*(a+b)) = L(a*)L((a+b)) = L(a)*L(a+b) = L(a)*(L(a) L(b)) = {a}*({a} {b}) = {, a, aa, aaa,...}{a,b} = {a, aa, ..., b, ab, aab, ...} = {an| n 1}{ an b | n 0}. L((aa)*(bb)*b)= {a2nb2m+1 | n,m 0}. Si = {a,b,c},entonces L(( a + b + c) )= *

L(a*(b + c)) L(0*10*)

3.18.TEOREMAS DE EQUIVALENCIA Tal como indica su nombre, mediante expresiones regulares se pueden representar lenguajes regulares. De hecho, la clase de lenguajes que se pueden representar mediante una expresin regular, es equivalente a la clase de lenguajes regulares. Hasta ahora hemos visto que los lenguajes regulares pueden describirse mediante:

Gramticas lineales por la izquierda, Gramticas lineales por la derecha, Autmatas finitos deterministas, Autmatas finitos no deterministas.

Por tanto, deben existir algoritmos que permitan obtener un autmata o una gramtica regular a partir de una expresin regular y viceversa. 3.19.MATRICES DE TRANSICIN Una matriz o tabla de transiciones es un arreglo bidimensional cuyos elementos proporcionan el resumen de un diagrama de transiciones. Para elaborar una tabla de transiciones, debe colocarse cada estado del diagrama de transiciones en una fila del arreglo y cada smbolo o categora de smbolos con posibilidades de ocurrencia en la cadena de entrada, en una columna. El elemento que se encuentra en la fila m columna n es el estado que se alcanzara en el diagrama de transiciones al dejar al estado m a travs de un arco de etiqueta n. Al no existir

algn arco que salga del estado m, entonces la casilla correspondiente de la tabla se marca como un estado de error. En la siguiente figura se presenta un ejemplo de un diagrama de transiciones que representa la sintaxis para un nmero de punto flotante, seguido de la tabla de transiciones correspondiente. Estado 1 2 3 4 5 6 7 Dgito 2 2 4 4 7 7 7 . Error 3 Error Error Error Error Error E Error 5 Error 5 Error Error Error + Error Error Error Error 6 Error Error Error Error Error Error 6 Error Error FDC Error Error Error Aceptar Error Error Aceptar

Existe tambin La matriz de transicin de estados se cre dando valores de estado a cada uno de los tipos de palabra y utilizando las reglas de la gramtica respecto a la relacin que existe entre cada tipo de palabra

3.20.REPRESENTACIN DE LOS AUTMATAS

Grfico N 13: representacin de un autmata

Acepta las secuencias: abc(dc)*

Ej. abc, abcdc, abcdcdc, abcdcdc... 3.21.AUTMATA FINITO DETERMINISTA Un autmata finito determinista consiste en un dispositivo que puede estar en un estado de entre un nmero finito de los mismos; uno de ellos ser el estado inicial y por lo menos uno ser estado de aceptacin. Tiene un flujo de entrada por el cual llegan los smbolos de una cadena que pertenecen a un alfabeto determinado. Se detecta el smbolo y dependiendo de este y del estado en que se encuentre har una transicin a otro estado o permanece en el mismo. El mecanismo de control (programa) es que determina cual es la transicin a realizar. La palabra finito se refiere a que hay un nmero finito de estados. La palabra determinista es porque el mecanismo de control (programa) no debe tener ambigedades, es decir, en cada estado solo se puede dar una y solo una (ni dos ni ninguna) transicin para cada smbolo posible (en el ejemplo anterior, la tabla de transiciones era determinista en ese caso, no as el diagrama, aunque podra serlo como veremos mas tarde). El autmata acepta la cadena de entrada si la mquina cambia a un estado de aceptacin despus de leer el ltimo smbolo de la cadena. Si despus del ltimo smbolo la mquina no queda en estado de aceptacin, se ha rechazado la cadena. Si la mquina llega al final de su entrada antes de leer algn smbolo la entrada es una cadena vaca (cadena que no contiene smbolos) y la representaremos con . Solo aceptar si su estado inicial es de aceptacin. Un autmata finito determinista (AFD) consiste en una quntupla (Q, , , q0, F) donde:

Q es un conjunto finito de estados es el alfabeto de la mquina :Q x ,Q (es la funcin total de transicin) q0 Q es el estado inicial F Q es el conjunto de los estados de aceptacin (estados finales).

Lee los caracteres de derecha a izquierda

Para cada carcter ledo, si para un a y q, p S se tiene que (q, a) = p, significa que siempre que el automata este en el estado q y le llega el carcter a pasar al estado p Ejemplo: Automata que acepta cadenas con un nmero par de ceros y un numero par de unos: AFD = {S, A, B, C}, {0,1},, Q, {Q} M se puede definir extensivamente con:

Representacin grfica:

3.22.AUTMATA FINITO NO DETERMINISTA La nica diferencia con los AFD est en que en la transicin en un estado determinado puede haber, para un mismo smbolo, ms de un arco o no haber ninguno. Decimos que un autmata finito no determinista acepta una cadena si es posible que su anlisis deje a la mquina en un estado de aceptacin. Decimos si es

posible, pues si se toma el camino equivocado no se aceptara una cadena que podra ser vlida (una cadena del lenguaje aceptado por este autmata, designado por L(M). Un autmata finito no determinista (AFN o AFND) consiste en una quntupla: (Q, , , q0, F) donde:

Q es un conjunto finito de estados posibles del automata es el alfabeto de la mquina :Q x ,2Q (es la funcin total de transicin) q0 Q es el estado inicial F Q es el conjunto de los estados de aceptacin (estados finales).

Ejemplo: AFND que reconoce en {a, b, c}* tales que el ultimp smbolo en la caden de entrada apareca tambin anteriormente en la cadena. En este AFND, seria F = {q0, q1, q2, q3, q4}, {a, ,b, c}, , q0, { q4}

Sea la entrada aca:

Concluyendo: (q0, aca) = { q0, q1, q3} { q1, q4} = { q0, q1, q3, q4} Y como (q0, aca) F = {q4}, la cadena se acepta.

CAPTULO IV: ANLISIS SINTCTICO


4.1. GRAMTICAS Tipo 0 o Sin Restricciones o Estructuradas por Fase (MT: Maquinas de Turing ) G = (N, T, P, S) N: T: P: Conjunto de Smbolos No Terminales Conjunto de Smbolos Terminales Conjunto de Reglas de Produccin

SN: Smbolo Inicial Tipo 1 o Sensibles al Contexto (CSG) (ALA: Autmata Linealmente Acotado ) G = (N, T, P, S) N: T: P: Conjunto de Smbolos No Terminales Conjunto de Smbolos Terminales Conjunto de Reglas de Produccin

SN: Smbolo Inicial P (TVn)* Vn (TVn)* x (TVn)* con || ||

Tipo 2 o Libres de Contexto (CFG) (AP: Autmatas de Pila) G = (N, T, P, S) N: T: P: Conjunto de Smbolos No Terminales Conjunto de Smbolos Terminales Conjunto de Reglas de Produccin

SN: Smbolo Inicial P N x (TVn)* Ejemplo: Supngase que utilizamos E en lugar de <expresion> para la variable de la gramtica. Podemos expresar esta gramtica de la manera formal como:

G = (N,T,P,S)

Donde: T = { + , * , ( , ) , id } N={E } P={EE+E EE*E E(E) E id } S=E

Tipo 3 o Regulares (AF: Autmatas Finitos) Definen la sintaxis de los identificadores, nmeros, cadenas y otros smbolos bsicos del lenguaje. G = (N, T, P, S) N: T: P: Conjunto de Smbolos No Terminales Conjunto de Smbolos Terminales Conjunto de Reglas de Produccin

SN: Smbolo Inicial Regular a Derecha: P N x (TN T {}) A a | aB (lineal por la derecha)

Regular a Izquierda: P N x (NT T {}) A a | Ba Donde: A , B N , a T* Las gramticas regulares guardan estrecha relacin con los autmatas finitos. Las gramticas estudiadas en la teora de lenguajes son la 2 y 3. (lineal por la izquierda)

4.2. GRAMTICAS LIBRES DE CONTEXTO Y ANLISIS SINTCTICO El anlisis gramatical es determinar la sintaxis, o estructura, de un programa. Por esta razn tambin se le conoce como anlisis sintctico. La sintaxis de un lenguaje de programacin por lo regular se determina mediante las reglas gramaticales de una gramtica libre de contexto. Una gramtica libre de contexto utiliza convenciones para nombrar y operaciones muy similares a las correspondientes en las expresiones regulares. Con la nica diferencia de que las reglas de una gramtica libre de contexto son recursivas. Las estructuras de datos utilizadas para representar la estructura sintctica de un lenguaje ahora tambin deben ser recursivas en lugar de lineales. La estructura bsica empleada es por lo regular alguna clase de rbol, que se conoce como rbol de anlisis gramatical o rbol sintctico. Existen dos categoras generales de algoritmos: de anlisis sintctico descendente y de anlisis sintctico ascendente (por la manera en que construyen el rbol de anlisis gramatical o rbol sintctico). 4.3. GRAMTICAS LIBRES DE CONTEXTO Como sabemos, en una gramtica libre de contexto (GLC) G = (N, T, P, S) las producciones tienen la siguiente forma:

Las GLCs tienen una gran importancia en la definicin de lenguajes etc...

de

programacin, interpretacin del lenguaje natural, construccin de compiladores, Por comodidad a la hora de definir lenguajes, la definicin anterior se extiende a la siguiente:

En este tema veremos que una GLC escrita de esta forma ms general, siempre puede escribirse en la versin ms restrictiva (slo S puede producir ).

4.4. CONCEPTOS SOBRE GLCs 4.4.1.RBOL DE DERIVACIN Sea G=(N,T,P,S) una GLC. Un rbol es un rbol derivacin para G si:
1. Todo vrtice tiene una etiqueta tomada de T N {} 2. La etiqueta de la raz es el smbolo inicial S. 3. Los vrtices interiores tienen etiquetas de N. 4. Si un nodo n tiene etiqueta A y n1, n2, n3, n4,...., nk, respectivamente

son hijos del vrtice n ordenados de izquierda a derecha, con etiquetas x1, x2, x3,.... xk, respectivamente, entonces:

Debe ser una produccin en P


5. Si el vrtice n tiene etiqueta , entonces n es ona hoja y es el unico

hijo de su padre. Ejemplo: Sea G = {N, T, P, S} una GLC cobn P: S ab | aSb. La derivacin de la cadena aaabbb sera S aSb aaSbb aaabbb y el arbol de derivacin:

4.4.2.GRAMTICAS NO AMBIGUAS Sea G = ( T , N , P , S ) que acepta expresiones aritmticas como: X+YX*Y T={X,Y,+,-,*,/,(,)} N = { EXPR , TERM , FACTOR } P = { EXPR TERM TERM | EXPR + TERM | EXPR TERM FACTOR | TERM * FACTOR | TERM / FACTOR X | Y | ( EXPR )

FACTOR S = {EXPR}

G no es ambigua, porque tiene un solo rbol de derivacin Derivacin por la izquierda Se realiza el reemplazo de cada N que esta ms a la izquierda EXPR EXPR TERM EXPR + TERM TERM TERM + TERM TERM FACTOR + TERM TERM X + TERM TERM X + FACTOR TERM X + Y TERM X + Y TERM * FACTOR X + Y FACTOR * FACTOR X + Y X * FACTOR X +YX *Y Derivacin por la derecha Se realiza el reemplazo de cada N que esta ms a la derecha EXPR EXPR TERM

EXPR - TERM * FACTOR EXPR - TERM * Y EXPR - FACTOR * Y EXPR - X * Y EXPR + TERM - X * Y EXPR + FACTOR - X * Y EXPR + Y - X * Y TERM + Y - X * Y FACTOR + Y - X * Y X +YX *Y Arbol de derivacion:

4.4.3.GRAMTICAS AMBIGUAS Sea G = ( T , N , P , S ) que acepta expresiones aritmticas como: X+YX*Y T={X,Y,+,-,*,/,(,)} N = { EXPR , OP } P = { EXPR OP S = {EXPR} EXPR OP EXPR | ( EXPR ) | X | Y

+ | - | * | /

G es ambigua, porque tiene ms de un rbol de derivacin Derivacin por la izquierda Se realiza el reemplazo de cada N que esta ms a la izquierda EXPR ( EXPR ) ( EXPR OP EXPR ) ( X OP EXPR ) ( X + EXPR ) ( X + ( EXPR ) ) ( X + ( EXPR OP EXPR ) ) ( X + ( Y OP EXPR ) ) ( X + ( Y - EXPR ) ) ( X + ( Y ( EXPR OP EXPR ) ) ) ( X + ( Y ( X OP EXPR ) ) ) ( X + ( Y ( X * EXPR ) ) ) (X+(Y(X*Y))) Derivacin por la derecha Se realiza el reemplazo de cada N que esta ms a la derecha EXPR EXPR OP EXPR EXPR OP Y EXPR * Y ( EXPR ) * Y ( ( EXPR ) ) * Y ( ( EXPR OP EXPR ) ) * Y ( ( EXPR OP ( EXPR ) ) ) * Y ( ( EXPR OP ( EXPR OP EXPR ) ) ) * Y ( ( EXPR OP ( EXPR OP X ) ) ) * Y ( ( EXPR OP ( EXPR - X ) ) ) * Y

( ( EXPR OP ( Y - X ) ) ) * Y ( ( EXPR + ( Y - X ) ) ) * Y ((X+(Y - X)))*Y

4.5. GRAMTICA BNF La Notacin BNF o gramtica libre de contexto, es una de las gramticas ms usadas en los lenguajes de programacin. BNF ( Backus Naur Form ) fue desarrollada para la definicin sintctica de Algol en 1960 por John Backus. Esta gramtica maneja una sintaxis de una forma muy sencilla ya que solo se interesa por la forma como estn estructuradas las distintas oraciones basndose en diversas reglas. El lenguaje a analizar se toma como una serie de cadenas de caracteres de longitud finita bajo un cierto orden. Cada cadena debe tener ciertas reglas para poder analizar su estructura. Por ejemplo la notacin de una cadena de un dgito definido puede ser: < dgito > ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 Aqu podemos ver que esta regla maneja las distintas alternativas que puede contener un dgito. El smbolo ' | ' significa ' o ' , ::= significa un implica, <dgito> significa la lo que estamos definiendo ( identificador ) y dgito es una categora sintctica o un no terminal . Con esto podemos empezar a definir algunas estructuras como el IF. < enunciado condicional > ::= if < expresin booleana > then < enunciado > else < enunciado > | if < espresin booleana > then < enunciado >

Una caracterstica de todo esto es que una categora sintctica se puede volver a llamar as mismo para ir definiendo estructuras recursivas y/o ms grandes. Por ejemplo : < entero sin signo > ::= < dgito > | < entero sin signo >< dgito > Con esto ,vemos que la notacin BNF maneja una serie de reglas gramaticales que empiezan desde a lo ms pequeo hasta lo ms grande. Ahora bien, existen otras gramticas que se basan en esta gramtica BNF.

4.6. RBOLES DE ANLISIS SINTCTICOS En esta gramtica podemos usar identificadores que se llamen a s mismos, pero en otra notacin : S -> SS | ( S ) | ( ) En esta expresin se usa -> en vez de ::= , pero sin embargo significan lo mismo. El smbolo ( ) nos dice el final de este llamamiento recursivo, el cual puede formar una serie de cadenas, donde S es cualquier expresin. Por decir :S forma a (S) y este a (SS) y este a ( ( ) S ) y este a ( ( ) ( ) ) . Ya que existe l | y las posibles terminaciones o smbolos terminales ( S ) y ( ). Cada derivacin se llama forma sentencial. Con ello aqu se puede decir que un lenguaje es un conjunto de formas sentnciales, dnde cada una tiene smbolos terminales. Cada cadena tiene la posibilidad de formar estructuras ms grandes y con ello se debe tener cuidado al formar las estructuras que puedan ser entendibles y no provoquen confusin para los programadores. Cada cadena es analizada por las reglas gramaticales, y el anlisis provocara una salida buena o una mala, si es lo ultimo, se produce un error en el anlisis sintctico. A medida que se vayan produciendo anlisis y creando estructuras ms grandes y recursivas , estas ultimas van formando rboles que pueden terminar en smbolos terminales en sus ramas ( rbol de anlisis sintctico ) pero existiendo una relacin entre ellas, as que cada identificador es el mismo en cada rama ( segn su

estructura propia de cada uno ) . Este rbol nos muestra la mayor parte de nuestro programa.

4.7. EXTENSIN DE LA NOTACIN BNF La sencillez de la notacin BNF puede llegar a complicarse, ya que cuando se van definiendo los identificadores, estos se pueden reducir a partes ms pequeas provocando problemas para definir todos los identificadores. Para ello se usa una notacin un poco ms fcil. 4.8. LA NOTACIN BNF EXTENDIDA Esta usa nuevas reglas y smbolos: 1.- [ ... ] significa cualquier elemento optativo 2.- [ , ] significa la posibilidad de escoger de una serie de alternativas solo una opcin 3.- { ... }* significa poder escoger identificadores arbitrarios. Ejemplos : < entero con signo > ::= [ + | - ] < dgito > { dgito ] * < identificador > ::= < letra > { < letra > | < dgito > } * 4.9. EL PROCESO DE ANLISIS SINTCTICO La tarea del analizador sintctico es determinar la estructura sintctica de un programa a partir de los tokens producidos por el analizador lxico y, ya sea de manera explcita o implcita, construir el rbol de anlisis gramatical o rbol sintctico que represente esta estructura. Dos tipos principales de anlisis:

De arriba a abajo ("top-down"). De abajo a arriba ("bottom-up").

Que sea una gramtica de tipo 2 (lenguaje independiente del contexto) no nos asegura que el autmata a pila sea determinista. Estos slo representan un subconjunto de los lenguajes i.c.. A lo largo de las pginas siguientes iremos imponiendo diversas restricciones a las gramticas. Las restricciones de un mtodo no tienen porqu ser las mismas que las de otro (complementariedad).

4.10.ANLISIS SINTCTICO ASCENDENTE Analizador sintctico ascendente: Intenta construir un rbol de anlisis sintctico, empezando desde la raz y descendiendo hacia las hojas. Lo que es lo mismo que intentar obtener una derivacin por la izquierda para una cadena de entrada, comenzando desde la raz y creando los nodos del rbol en orden previo. Parte de la cadena de entrada para construir la inversa de una derivacin por la derecha. Genera el rbol de Anlisis sintctico partiendo de las hojas hasta alcanzar el axioma.

Cuando puede reducirse por una parte izquierda lo que parece ser la parte derecha de una regla? Puede haber partes derechas comunes Puede haber producciones

Tipos de gramticas Gramticas LR


Conjunto ms amplio de gramticas que LL(1) Expresin ms sencillas

LR(1) Analizadores LR(1) LALR Analizadores LALR SLR Analizadores SLR Condiciones SLR

Se comprueban al construir el analizador Analizadores reduccin-desplazamiento

Analizadores por reduccin desplazamiento Los analizadores son tabulares Se diferencian por el algoritmo de construccin de la tabla

Analizador LR Analizador LALR Analizador SLR

El algoritmo de anlisis es comn

Utiliza una tabla para decidir


Un estado de pila por fila Una funcin Accin (s, a) = dj | rk dj. Desplazar al siguiente token y apilar el estado j rk. Reducir por regla k.

Una funcin IrA(si, A) = sj

Algoritmo de anlisis

4.11.ANALIZADOR SINTCTICO SLR Trminos comunes o Elemento. Una regla de produccin que incorpora en alguna posicin de su parte derecha un punto

o Prefijo viable. La parte situada a la izquierda del punto de algn elemento

Funciones comunes o Clausura (I)

o IrA (s, A)

Coleccin Cannica del conjunto de elementos o Coleccin de todos los conjuntos de elementos o C = { I0, I1, }

Construccin

Autmatas reconocedores de prefijos viables o Los estados Sj del autmata son los conjuntos Ij de C o Las transiciones son los smbolos N u T u {$}

Construccin

Construccin de tablas SLR

Construccin de tablas SLR a partir del autmata

4.12.ANLISIS SINTCTICO DESCENDENTE Analizador sintctico descendente: Intenta construir un rbol de anlisis

sintctico, empezando desde las hojas (la cadena) y ascendiendo hacia la raz. Lo que es lo mismo que intentar obtener una reduccin desde una cadena hasta llegar al axioma. El analizador sintctico tanto ascendente como descendente puede representarse de dos formas: mediante tabla de anlisis sintctico o mediante autmata de pilas.

Partir del axioma de la gramtica Escoger reglas gramaticales Hacer derivaciones por la izquierda Procesar la entrada de izquierda a derecha Obtener el rbol de anlisis sintctico o error

4.13.ANALIZADOR CON RETROCESO Usa retroceso para resolver la incertidumbre Sencillo de implementar Muy ineficiente

4.14.TCNICAS DE ANLISIS PREDICTIVO Propsito


Crear un analizador descendente O(n) Debe decidir qu regla aplicar segn token La gramtica debe ser LL(1) L. Anlisis de izquierda a derecha L. Derivaciones por la izquierda 1. Un token permite decidir la regla de produccin

Se elimina la recursividad

4.15.CONJUNTOS DE PREDICCIN Conjuntos de prediccin. Ayudan a decidir qu regla utilizar en cada paso Construccin

Conjunto Primero PRIM () Conjunto Siguiente SIG (A) Regla

4.16.CONJUNTO PRIMERO Si es una forma sentencial compuesta por una concatenacin de smbolos PRIM () es el conjunto terminales (o ) que pueden aparecer iniciando las cadenas que pueden derivar de Construccin

4.17.CONJUNTO SIGUIENTE Si A es un smbolo no Terminal de la gramtica SIG (A) es el conjunto de terminales (y $) que pueden aparecer a continuacin de A en alguna forma sentencial derivada del axioma.

4.18.FACTORIZACIN POR LA IZQUIERDA Se trata de rescribir las producciones de la gramtica con igual comienzo para retrasar la decisin hasta haber visto lo suficiente de la entrada como para elegir la Opcin correcta.

4.19.ELIMINACIN DE LA RECURSIVIDAD Tipos de recursividad

Directa. Una gramtica G es recursiva si tiene alguna regla de produccin que sea recursiva por la izquierda

Eliminacin de la recursividad

Indirecta. Si, a partir de una forma sentencial que empieza por un no terminal se puede derivar una nueva forma no sentencial donde reaparece al principio el no terminal

Eliminacin de la recursividad

http://html.rincondelvago.com/lenguajes-de-programacion_historia-y

evolucion.html http://www.desarrolloweb.com/articulos/2358.php http://www.monografias.com/trabajos16/lenguaje-miranda/lenguaje-miranda.shtml http://enciclopedia.us.es/index.php/Lenguaje_imperativo http://www.monografias.com/trabajos/tendprog/tendprog.shtml http://www.monografias.com/trabajos/lengprog/lengprog.shtml http://www.zonatenisatp.com/index.php http://www.zonatenisatp.com/tema1_1_01_abstraccion.php http://www.zonatenisatp.com/tema1_2_00_abstraccion_datos.php http://www.zonatenisatp.com/tema1_2_03_lenguajes_programacion.php http://ultimaorbita.com/wiki//index.php?title=Abstraccion_de_datos_y_abstraccion_ de_control._Evolucion_segun_los_paradigmas -http://yalma.fime.uanl.mx/~elisa/teaching/prog/herencia.pdf http://ib.cnea.gov.ar/CursoOO/tipos.htm http://es.wikipedia.org/wiki/Encapsulamiento_(programaci%C3%B3n_orientada_a_ objetos) http://www.cs.uu.nl/~jeroen/courses/fp-sp.pdf http://www.inf.unitru.edu.pe/~pelm/Modelos/Funcion.html http://www.dsic.upv.es/users/elp/temas/ProgFunc.html http://juanfc.lcc.uma.es/EDU/EP/trabajos/T201.Clasificaciondelostiposdelenguajes. pdf http://www.esimez.ipn.mx/acadcompu/apuntes_notas%20breves/programacion_orie ntada_objetos.pdf http://www.monografias.com/trabajos20/paradigmas-de-programacion/paradigmasde-programacion.shtml http://static.scribd.com/docs/7a6vhoquhqs22.pdf http://www.scribd.com/doc/9762/Programacion-Orientada-a-Objetos http://platea.cnice.mecd.es/~jmarti2/materiales/resumenLePr.pdf http://horustealth.tripod.com/pascal.htm http://decsai.ugr.es/~dpelta/ProgOrdenadores/tema5.pdf http://ar.geocities.com/luis_pirir/cursos/procedimiento.htm http://www.inf.udec.cl/~mvaras/estprog/cap41.html http://www.monografias.com/trabajos/objetos/objetos.shtml http://www.gnacademy.org/text/cc/Tutorial/Spanish/node5.html http://www.gnacademy.org/text/cc/Tutorial/Spanish/node6.html -http://www.desarrolloweb.com/articulos/2358.php http://www.desarrolloweb.com/articulos/2387.php http://es.wikipedia.org/wiki/Compilador http://www.investigacion.frc.utn.edu.ar/labsis/Publicaciones/InvesDes/Compiladore s/rxc.htm http://arantxa.ii.uam.es/~alfonsec/docs/compila1.htm http://www.monografias.com/trabajos11/compil/compil.shtml http://mx.geocities.com/alfonsoaraujocardenas/compiladores.html http://platon.escet.urjc.es/grupo/docencia/automatas/ http://kataix.umag.cl/~jaguila/Iec/Compiladores/Automatas/ta_cap1_2.html http://arantxa.ii.uam.es/~alfonsec/docs/compila4.htm

You might also like