Categorías: Todo - compilador - código - generación - optimización

por Sandra Dayanira López Gómez hace 3 años

250

Estructura del Compilador

El proceso de compilación de un programa implica diversas etapas cruciales para la traducción del código fuente a código máquina. Una de las fases fundamentales es la generación de código intermedio, el cual actúa como un puente entre el código fuente y el código destino.

Estructura del Compilador

Bibliografía

COMPILADORES. PRINCIPIOS, TÉCNICAS Y

HERRAMIENTAS. Segunda edición

Estructura del Compilador

201504459

Sandra Dayanira López Gómez

Generación de Código

Generación de Código

Recibe como entrada una representación intermedia del programa fuente y la asigna al lenguaje destino. Si el lenguaje destino es código maquina, se seleccionan registros o ubicaciones(localidades.) Un aspecto crucial en en la generación de código es la asignación juiciosa de los registros para guardar variables.

Asignación de Especio de Almacenamiento

La organización del espacio de almacenamiento en tiempo de ejecución depende del lenguaje que se esté compilando. Se realiza durante la generación de código intermedi, o la generación de código.

Optimización de Código

Optimización de Código

Independiente de la máquina trata de mejorar el código intermedio, de manera que se produzca un mejor código destino.


Compiladores Obtimizadores

Aquellos que realizan la mayor optimización

El optimizador puede deducir que la conversión del 60, de entero a punto flotante, puede realizarse de una vez por todas en tiempo de compilación, por lo que se puede eliminar la operación inttofloat sustituyendo

el entero 60 por el número de punto flotante 60.0. Lo que es más, t3 se utiliza sólo una vez para transmitir su valor a id1, para que el optimizador pueda transformar.

Generación de Código Intermedio

Generación de Código Intermedio

El proceso de traducir un programa fuente a código destino, un compilador puede construir una o más representaciones intermedias. Los compiladores generan un nivel bajo explícito, o una representación intermedia similar al código máquina, que podemos considerar como un programa para una máquina abstracta, el cual debe tener dos propiedades importantes:

  1. Fácil de Traducir.
  2. Fácil de Traducir en la máquina destino.
Código tres direcciones

Código tres direcciones

Consiste en una secuencia de instrucciones similares a ensamblador, con tres operados por instrucción. Cada operando puede actuar como registro. La salida del generador de código intermedio consiste en una secuencia de código de tres direcciones.



Análisis Semántico

Análisis Semántico:

Utiliza el árbol sintáctico y la información en la tabla de símbolos para comprobar la conciencia semántica del programa fuente con la dedición del lenguaje. También recopila información sobre el tipo y la guarda.

Comprobación (verificación)de tipos

El compilador verifica que cada operador tenga operandos que coinciden.



Coerciones

La especificación del lenguaje que permite ciertas conversiones de tipo.

Suponga que posición, inicial y velocidad se han declarado como números de punto flotante, y que el lexema 60 por sí solo forma un entero. El comprobador de tipo en el analizador semántico de la descubre que se aplica

el operador * al número de punto flotante velocidad y al entero 60.

En este caso, el entero puede convertirse en un número de punto flotante. La salida del analizador semántico tiene un nodo adicional para el operador inttofloat, que convierte de manera explícita su argumento tipo entero en un número de punto flotante. En el capítulo 6 hablaremos sobre la comprobación de tipos y el análisis semántico.

Análisis Sintáctico

El Análisis sintáctico o parsing, utiliza los primeros componentes de los tokens producidos por el analizador de léxico para crear una representación intermedia en forma de árbol que describa las estructura gramatical del flujo de tokens.

Árbol sintáctico

¿QUÉ SON LOS ÁRBOLES SINTÁCTICSO?

Es una representación que describe la estructura gramatical de los tokens, en el cual cada nodo interior representa una operación y los hijos representan los argumentos de la operación.

https://drive.google.com/file/d/11_gXvivWDb8yU5FuW1AlrIMd53Bqbrob/view?usp=sharing


Ejemplo





Este ordenamiento de operaciones es consistente con las convenciones usuales de la aritmética, las cuales nos indican

que la multiplicación tiene mayor precedencia que la suma y, por ende, debe realizarse antes que la suma.

Análisis Léxico

El análisis léxico lee flujo de caracteres que componen el programa fuente y los agrupa en secuencias significativas conocidas como lexemas, para cada lexema el analizador léxico produce como salida un token.

Token

La producción de salida del analizador léxico de un lexema.

Apunta a una entrada de la tabla de símbolos para este token.

Es un símbolo abstracto que se utiliza durante el análisis sintáctico.

Lexemas

Agrupación de secuencias significativas.

posicion = inicial + velocidad * 60
  1. Posición es un lexema que se asigna a un token <id,1>
  2. El símbolo de asignación = es un lexema que se le asigna el nombre de <=>
  3. Inicial es un lexema que se asigna a un token <id,2>
  4. El símbolo de más + es un lexema que se le asigna el nombre de <+>
  5. Velocidad es un lexema que se asigna a un token <id,3>
  6. El símbolo de más * es un lexema que se le asigna el nombre de <*>
  7. 60 es un lexema que se le asigna el nombre de <60> (hablando en sentido técnico, para el lexema 60 formaríamos un token como <número,4> donde 4 apunta a la tabla de símbolos para representación interne del entero 60 )