Cap4 compiladores

3,142 views

Published on

Cap4 Compiladores

Published in: Education
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,142
On SlideShare
0
From Embeds
0
Number of Embeds
50
Actions
Shares
0
Downloads
0
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Cap4 compiladores

  1. 1. FASES DE UN COMPILADOR <ul><li>Capítulo 4 </li></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  2. 2. Introducción <ul><li>¿Qué es un compilador? </li></ul><ul><ul><li>Programa que lee un programa (fuente) en un lenguaje. </li></ul></ul><ul><ul><li>Lo traduce a un programa EQUIVALENTE en otro lenguaje (objeto). </li></ul></ul><ul><ul><li>Además: </li></ul></ul><ul><ul><ul><li>da mensajes de error </li></ul></ul></ul><ul><ul><ul><li>lleva a cabo determinadas “correcciones” (recuperación de errores). </li></ul></ul></ul><ul><ul><ul><li>puede optimizar el código generado. </li></ul></ul></ul><ul><li>Permite programar “independientemente” de la máquina. </li></ul><ul><ul><li>Importante, ya que el número de máquinas diferente crece deprisa. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  3. 3. Fases de Compilación Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  4. 4. Agrupación de Fases <ul><li>Las fases se agrupan en dos partes o etapas: </li></ul><ul><ul><li>Front end (las fases de análisis). </li></ul></ul><ul><ul><ul><li>Depende del lenguaje fuente y casi siempre es independiente (o debe serlo) de la máquina objeto para la que se va a generar código. </li></ul></ul></ul><ul><ul><li>Back end (las fases de generación y optimización de código). </li></ul></ul><ul><ul><ul><li>Depende del lenguaje objeto y debe ser independiente del lenguaje fuente (excepto quizá para algún tipo de optimización). </li></ul></ul></ul><ul><li>Estas dos etapas se comunican mediante una representación intermedia (generada por el front end) </li></ul><ul><ul><li>Puede ser una representación de la sintaxis del programa (un árbol sintáctico abstracto) o bien puede ser un programa en un lenguaje intermedio. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  5. 5. Front End: Fases que dependen del lenguaje fuente Materia: Compiladores Docente: Ing. Carlos J. Archondo O. Front End
  6. 6. Back End: Fases que dependen de la máquina objetivo Materia: Compiladores Docente: Ing. Carlos J. Archondo O. Back End
  7. 7. Fases <ul><li>Primera fase (precompilador) </li></ul><ul><ul><li>no siempre se realiza </li></ul></ul><ul><ul><li>sustituciones de macros </li></ul></ul><ul><ul><li>eliminación de comentarios </li></ul></ul><ul><ul><li>inclusión de ficheros </li></ul></ul><ul><ul><li>extensiones al lenguaje (C+SQL) </li></ul></ul><ul><li>Segunda fase </li></ul><ul><ul><li>es la parte fundamental (y siempre presente) </li></ul></ul><ul><ul><li>consta de: </li></ul></ul><ul><ul><ul><li>analizador léxico </li></ul></ul></ul><ul><ul><ul><li>analizador sintáctico </li></ul></ul></ul><ul><ul><ul><li>generador de código </li></ul></ul></ul><ul><ul><li>traduce el código fuente a otro objeto </li></ul></ul><ul><ul><li>puede ser el definitivo </li></ul></ul><ul><ul><li>puede ser un código intermedio </li></ul></ul><ul><li>Tercera fase: </li></ul><ul><ul><li>no siempre presente </li></ul></ul><ul><ul><li>realiza algunas optimizaciones sobre el código intermedio </li></ul></ul><ul><li>Cuarta fase: </li></ul><ul><ul><li>traduce el código intermedio optimizado a </li></ul></ul><ul><ul><ul><li>Ensamblador </li></ul></ul></ul><ul><ul><ul><li>Binario </li></ul></ul></ul><ul><li>Quinta fase: </li></ul><ul><ul><li>Optimización ligada a la máquina de destino </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. <ul><li>Existen muchas variaciones posibles: </li></ul><ul><ul><li>sin preprocesador </li></ul></ul><ul><ul><li>sin usar código intermedio </li></ul></ul><ul><ul><li>optimizando directamente sobre el ensamblador de la máquina </li></ul></ul><ul><ul><li>generar directamente binario, sin pasar por el ensamblador </li></ul></ul><ul><ul><li>Etc. </li></ul></ul>
  8. 8. Precompilación <ul><li>Suele haber preprocesadores para: </li></ul><ul><ul><li>Eliminar comentarios. </li></ul></ul><ul><ul><li>Incluir archivos. </li></ul></ul><ul><ul><li>Expandir macros. </li></ul></ul><ul><ul><li>Efectuar compilación condicional. </li></ul></ul><ul><ul><li>Reemplazar constantes simbólicas. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  9. 9. El Analizador Léxico (scanner) Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  10. 10. Ejemplo <ul><li>Consideremos la siguiente sentencia: </li></ul><ul><ul><li>posición = inicial + velocidad * 60 </li></ul></ul><ul><li>El scanner deberá reconocer sucesivamente: </li></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  11. 11. Fases Sintáctica (parser) y Semántica <ul><li>Las fases de análisis sintáctico y semántico por lo general manejan una gran proporción de los errores detectables por el compilador. </li></ul><ul><li>Fase Sintáctica </li></ul><ul><ul><li>Los errores donde la cadena de componentes léxicos violan las reglas de estructura (sintaxis) del lenguaje son determinados por la fase del análisis sintáctico. </li></ul></ul><ul><li>Fase Semántica </li></ul><ul><ul><li>Durante el análisis semántico el compilador intenta detectar construcciones que tengan la estructura sintáctica correcta, pero que no tengan significado para la operación implicada. </li></ul></ul><ul><ul><ul><li>Por ejemplo, si se intenta sumar dos identificadores. </li></ul></ul></ul><ul><ul><ul><ul><li>Uno de los cuales es el nombre de una matriz, y el otro, el nombre de un procedimiento. </li></ul></ul></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  12. 12. El Analizador Sintáctico (Parser) <ul><li>Objetivo: agrupar los tokens suministrados por el scanner para reconocer “ frases”. </li></ul><ul><li>¿Cómo lo hace? </li></ul><ul><ul><li>La sintaxis se suele especificar formalmente mediante una GLC. </li></ul></ul><ul><ul><li>También de otros tipos. </li></ul></ul><ul><ul><li>El parser recibe tokens y los agrupa de acuerdo a producciones especificadas por la GLC. </li></ul></ul><ul><li>El parser detecta errores sintácticos. </li></ul><ul><ul><li>Y si es bueno, puede además realizar algunas correcciones. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. G.L.C.: Gramática Libre de Contexto
  13. 13. Ejemplo <ul><li>Consideremos el mismo ejemplo: </li></ul><ul><ul><li>posición = inicial + velocidad * 60 </li></ul></ul><ul><li>El árbol sintáctico correspondiente es: </li></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  14. 14. El Analizador Semántico <ul><li>Realiza dos funciones: </li></ul><ul><ul><li>Análisis de la semántica estática. </li></ul></ul><ul><ul><ul><li>¿Es cada construcción legal y “con sentido”? </li></ul></ul></ul><ul><ul><ul><ul><li>variables en una expresión definidas. </li></ul></ul></ul></ul><ul><ul><ul><ul><li>del tipo adecuado. </li></ul></ul></ul></ul><ul><ul><ul><ul><li>alcance de los objetos. </li></ul></ul></ul></ul><ul><ul><li>Generación del código (intermedio). </li></ul></ul><ul><ul><ul><li>Generalmente se lleva a cabo mediante gramáticas de atributos. </li></ul></ul></ul><ul><ul><ul><ul><li>la GLC se completa con atributos necesarios: </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>Tipo. </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>Valor. </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>acciones a ejecutar cuando se detecta una construcción legal. </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>Etc. </li></ul></ul></ul></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  15. 15. Generación de Código Intermedio Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  16. 16. Ejemplo <ul><li>De: </li></ul><ul><ul><li>Posición = inicial + velocidad * 60 (1) </li></ul></ul><ul><li>El programa fuente de (1) puede aparecer en código de tres direcciones como: </li></ul><ul><ul><li>temp1 := entarea1(60) </li></ul></ul><ul><ul><li>temp2 := id3 * temp1 (2) </li></ul></ul><ul><ul><li>temp3 := id2 + temp2 </li></ul></ul><ul><ul><li>id1 := temp3 </li></ul></ul><ul><li>Propiedades de la representación intermedia: </li></ul><ul><ul><li>Cada instrucción de tres direcciones tiene a lo sumo un operador, además de la asignación. </li></ul></ul><ul><ul><ul><li>Por tanto, cuando se generan esas instrucciones el compilador tiene que decidir el orden en que deben efectuarse, las operaciones; la multiplicación precede a la adición al programa fuente de (1). </li></ul></ul></ul><ul><ul><li>El compilador debe generar un nombre temporal para guardar los valores calculados por cada instrucción. </li></ul></ul><ul><ul><li>Algunas instrucciones de “tres direcciones” tienen menos de tres operadores, por ejemplo la primera y la última instrucciones de (2). </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. Utiliza variables auxiliares temporales
  17. 17. Código Intermedio Ejemplo <ul><ul><li>Tasa := Base + Recargo / 100  ID := ID + ID / CTE </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. El árbol sintáctico permite la división en sub expresiones
  18. 18. El Optimizador <ul><li>El código intermedio generado es analizado y transformado en uno equivalente optimizado. </li></ul><ul><li>Es una tarea muy costosa. </li></ul><ul><ul><li>De hecho, generalmente se puede invocar al compilador activando/desactivando esta opción. </li></ul></ul><ul><ul><li>Es una tarea difícil. </li></ul></ul><ul><li>Otras veces, optimiza el código objeto </li></ul><ul><ul><li>Usual la optimización “peephole”: </li></ul></ul><ul><ul><ul><li>Tomar una porción pequeña de código y hacer una optimización local. </li></ul></ul></ul><ul><ul><li>“ desenrrollado” de bucles. </li></ul></ul><ul><ul><li>Eliminación de recursividad final. </li></ul></ul><ul><ul><li>Etc. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. Costosa en tiempo y recursos.
  19. 19. Optimización Ejemplo <ul><ul><li>Tasa := Base + Recargo / 100  ID := ID + ID / CTE </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. Tercetos, se refiere a las sub-expresiones
  20. 20. El Generador de Código <ul><li>Toma código intermedio y genera código objeto para la máquina considerada. </li></ul><ul><li>Es la parte más próxima a la arquitectura de la máquina </li></ul><ul><ul><li>Habitualmente, se escriben “a mano”. </li></ul></ul><ul><ul><ul><li>desarrollo “a medida” para cada máquina específica. </li></ul></ul></ul><ul><li>Dada la complejidad, si no se va a realizar optimización, se asocia la generación de código a las rutinas semánticas. </li></ul><ul><ul><li>Compiladores de “una pasada” (no hay pasos 1,3,4). </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  21. 21. Tabla de Símbolos <ul><li>Es una estructura de datos que contiene un registro para cada identificador utilizado en el código fuente. </li></ul><ul><li>Posee campos que contienen información relevante para cada símbolo (atributos). </li></ul><ul><ul><li>Cuando el Análisis Léxico detecta un token de tipo identificador, lo ingresa en la Tabla de Símbolos. </li></ul></ul><ul><ul><li>Durante la Generación de Código se ingresa información para los atributos de los símbolos, y se usa esa información de diversas maneras. </li></ul></ul><ul><ul><li>Durante la Generación de Código puede ser necesario incorporar nuevas entradas a la Tabla de Símbolos. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  22. 22. Administrador de la Tabla de Símbolos <ul><li>Una función esencial de un compilador es registrar los identificadores utilizados en el programa fuente y reunir información sobre los distintos atributos de cada identificador. </li></ul><ul><ul><li>Estos atributos pueden proporcionar información sobre: </li></ul></ul><ul><ul><ul><li>La memoria asignada a un identificador. </li></ul></ul></ul><ul><ul><ul><li>Su tipo. </li></ul></ul></ul><ul><ul><ul><li>Su ámbito (la parte del programa donde tiene validez). </li></ul></ul></ul><ul><ul><ul><li>En el caso de nombres de procedimientos: </li></ul></ul></ul><ul><ul><ul><ul><li>El número y tipos de sus argumentos. </li></ul></ul></ul></ul><ul><ul><ul><ul><li>El método de pasar cada argumento (por ejemplo, por referencia). </li></ul></ul></ul></ul><ul><ul><ul><ul><li>El tipo que devuelve, si los hay. </li></ul></ul></ul></ul><ul><li>Una tabla de símbolos es una estructura de datos que contiene un registro por cada identificador, con los campos para los atributos del identificador. </li></ul><ul><ul><li>La estructura de datos permite encontrar rápidamente el registro de cada identificador y almacenar o consultar rápidamente datos en un registro </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  23. 23. Administrador de la Tabla de Símbolos Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  24. 24. Detección e Información de Errores <ul><li>Cada fase puede encontrar errores. </li></ul><ul><li>Sin embargo, después de detectar un error. </li></ul><ul><ul><li>Cada fase debe tratar de alguna forma ese error, para poder continuar la compilación, permitiendo la detección de más errores en el programa fuente. </li></ul></ul><ul><ul><li>Un compilador que se detiene cuando encuentra el primer error, no resulta tan útil como debiera. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  25. 25. Las Fases de Análisis <ul><li>Conforme avanza la traducción, la representación interna del programa fuente que tiene el compilador se modifica. </li></ul><ul><li>Para ilustrar esas representaciones, consideremos la traducción de la proposición: </li></ul><ul><li>La figura muestra la representación de esa proposición después de cada fase. </li></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. <ul><ul><li>Posición := inicial + velocidad * 60 (1) </li></ul></ul>
  26. 26. Estructura Jerárquica <ul><li>El análisis sintáctico impone una estructura jerárquica a la cadena de componentes léxicos, que se representará por medio de árboles sintácticos, como se muestra en la figura A. </li></ul><ul><ul><li>Una estructura de datos típica para el árbol se muestra en la figura B, en la que un nodo interior es un registro con un campo para el operador y dos campos que contienen apuntadores a los registros de los hijos izquierdo y derecho. </li></ul></ul><ul><li>Una hoja es un registro con dos o más campos, uno para identificar el componente léxico de la hoja, y los otros para registrar información sobre el componente léxico. </li></ul><ul><li>Se puede tener información adicional sobre las construcciones del lenguaje añadiendo más campos a les registros de los nodos. </li></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. Se puede tener información adicional sobre las construcciones del lenguaje añadiendo más campos a los registros de los nodos.
  27. 27. Generación de Código Propiamente Dicho <ul><li>Se traduce la representación intermedia del programa fuente en el código nativo de la máquina objetivo. </li></ul><ul><li>El código generado efectuará el chequeo de las reglas de semántica dinámica del lenguaje, que no pudieron ser verificadas durante la compilación. </li></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  28. 28. Generación Código en Assembler Ejemplo <ul><ul><li>Tasa := Base + Recargo / 100  ID := ID + ID / CTE </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. El código ya en Assembler
  29. 29. Generación de Código en Ensamblador <ul><li>Mediante las instrucciones del Ensamblador queda representado el árbol sintáctico </li></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O. Desde la asignación hacia las expresiones y sus hijos.
  30. 30. Optimación de Código <ul><li>La fase de optimación de código trata de mejorar el código intermedio de modo que resulte un código de máquina más rápido de ejecutar. </li></ul><ul><li>Algunas optimaciones son triviales. </li></ul><ul><ul><li>Por ejemplo, un algoritmo natural genera el código intermedio (2) utilizando una instrucción para cada operador de la representación del árbol después del análisis semántico, aunque hay una forma mejor de realizar los mismos cálculos usando las dos instrucciones: </li></ul></ul><ul><ul><ul><li>Temp1 := id3 * 60.0 (3) </li></ul></ul></ul><ul><ul><ul><li>id1 := id2 + temp1 </li></ul></ul></ul><ul><ul><li>Este sencillo algoritmo no tiene nada de malo, puesto que el problema se puede solucionar en la fase de optimación de código. </li></ul></ul><ul><ul><li>Esto es, el compilador puede deducir que la conversión de 60 de entero a real se puede hacer de una vez por todas en el momento de la compilación, de modo que la operación entreal se puede eliminar. </li></ul></ul><ul><ul><li>Además, temp3 se usa sólo una vez, para transmitir su valor a id1. Entonces resulta seguro sustituir a id1 por temp3, a partir de lo cual la última proposición de (2) no se necesita y se obtiene el código de (3). </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  31. 31. Variaciones <ul><li>Hay muchas variaciones en la cantidad de optimación de código que ejecutan los distintos compiladores. </li></ul><ul><li>En los que hacen mucha optimación llamados “compiladores optimadores”, una parte significativa del tiempo del compilador se ocupa en esta fase. </li></ul><ul><ul><li>Sin embargo hay optimaciones sencillas que mejoran significativamente el tiempo de ejecución del programa objeto sin retardar demasiado la compilación. </li></ul></ul>Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  32. 32. Generación de Código Materia: Compiladores Docente: Ing. Carlos J. Archondo O.
  33. 33. Fase 1 Fase 2 Fase 3 Fase 4 Fase 5 … hacia el linker Front end (análisis-c. fuente) Back end (síntesis-c.objeto) … comunicación por: -árbol sintáctico ó -prog. en un leng. intermedio Los comp. léxicos están compuestos por tokens (unid. indiv.) y estos por lexemas Los tokens son generados por autómatas finitos El parser reconoce frases por el GLC Programa para una máquina abstracta. Ej: código de 3 direcciones (para 3 operandos) Reorganizar, reducir operaciones Son un conjunto de identifica-dores

×