martes, 4 de abril de 2017

Código Intermedio.

Generación de código intermedio.

Ventajas:
– Permite abstraer la máquina, separar operaciones de alto nivel de su implementación a bajo nivel.
– Permite la reutilización de los front-ends y backends.
– Permite optimizaciones generales.

Desventajas:
– Implica un recorrido más para el compilador (no se puede utilizar el modelo de un recorrido, conceptual mente simple).
– Dificulta llevar a cabo optimizaciones específicas de la arquitectura destino.
– Suele ser ortogonal a la máquina destino, la traducción a una arquitectura específica será más larga e ineficiente.

Tipos de Código Intermedio.


AST : (Abstract SyntaxTrees): forma condensada de árboles de análisis, con sólo nodos semánticos y sin nodos para símbolos terminales (se supone que el programa es sintácticamente correcto).



Por ejemplo:
a = b + c * d;
El generador de código intermedio, tratar de dividir esta expresión en sub-expresiones y, a continuación, generar el código correspondiente.
r1 = c * d;
r2 = b + r1; 
r3 = r2 + r1;
a = r3
R que se utilizan como registros en el programa de destino.
Un código de dirección tiene un máximo de tres direcciones para calcular la expresión. Un código de dirección puede estar representado en dos formas : cuádruples y triples.
DAG: (Directed Acyclic Graphs): árboles sintácticos concisos.
– Ahorran espacio
– Resaltan operaciones duplicadas en el código
– Difíciles de construir

TAC (Three-AddressCode): secuencia de instrucciones de la forma:

– operador: aritmético / lógico
– operandos/resultado:
constantes, nombres, temporales.
• Se corresponde con instrucciones del tipo:
• Las operaciones más complejas requieren varias instrucciones:
• Este ‘desenrollado’ facilita la optimización y generación de código final.


Cuadruplica

Cada instrucción cuadruplica exposición se divide en cuatro campos: operador, arg1, arg2, y resultado. El ejemplo anterior se representa a continuación cuadruplica en formato:
Op.Arg1Arg2Resultado
*cdr1
+br1r2
+r2r1r3
=r3a

Triples

Cada instrucción en triples presentación tiene tres campos : op, arg1, arg2.Los resultados de las respectivas sub-expresiones son indicados por la posición de expresión. Similitud con Triples representan DAG y árbol de sintaxis. Son equivalentes a DAG al tiempo que representan las expresiones.
OpArg1Arg2
*cd
+b(0)
+(1)(0)
=(2)
Triples ante el problema de optimización código un inmovilismo mientras que, en la medida en que los resultados son posicionales y cambiar el orden o la posición de una expresión puede causar problemas.

Indirectos Triples


Esta representación es una mejora sobre representación triples. Se usa punteros en lugar de su posición para almacenar los resultados. Esto permite a los optimizadores libremente volver a colocar la sub-expresión para producir un código optimizado.

Declaraciones

Una variable o procedimiento tiene que ser declarado antes de que se pueda utilizar. Declaración implica asignación de espacio en la memoria y la entrada de tipo y nombre de la tabla de símbolos. Un programa puede ser codificada y diseñado siguiendo la estructura de la máquina destino en mente, pero es posible que no siempre se pueda convertir con precisión un código fuente para su idioma de destino.
Tomando el conjunto del programa, como una colección de procedimientos y sub-procedimientos, es posible declarar que todos los nombres locales en el procedimiento. Asignación de memoria se realiza de manera consecutiva y nombres son asignados a la memoria en la secuencia en la que se declara en el programa. Podemos utilizar el desplazamiento variable y ponerlo a cero {offset = 0} que denotan la dirección base.
La fuente lenguaje de programación y la arquitectura del equipo de destino puede variar en la forma los nombres se almacenan, por lo tanto se utiliza direccionamiento relativo. Mientras que el primer nombre se asigna memoria a partir de la posición de memoria 0 {offset= 0}, el siguiente nombre declaró después, debe ser asignada la memoria junto a la primera.
Ejemplo:
Tomamos el ejemplo de lenguaje de programación C en una variable de tipo entero se le asigna 2 bytes de memoria y una variable de tipo float se asigna 4 bytes de memoria.
int a;
float b;
Allocation process:
{offset = 0}
   int a;
   id.type = int
   id.width = 2
offset = offset + id.width 
{offset = 2}
   float b;
   id.type = float
   id.width = 4
offset = offset + id.width 
{offset = 6}
Para entrar en este detalle en una tabla de símbolos, un procedimientoentrar puede ser utilizado. Este método puede tener la siguiente estructura:
enter(name, type, offset)
Este procedimiento debe crear una entrada en la tabla de símbolos, de nombre de la variable, en su tipo y el tipo dedesplazamiento de dirección relativa en su área de datos.