Generación de Código Intermedio

Anuncio
Generación de Código
Intermedio
Programación II
Margarita Álvarez
Generación de código intermedio
™ Con la generación de código intermedio se inicia la tarea de síntesis.
™ Aunque un programa fuente se puede traducir directamente a lenguaje objeto,
algunas ventajas de utilizar una forma intermedia son:
™Aumentar la portabilidad del compilador de una máquina a otra:
¾ Se puede utilizar el mismo analizador para diferentes generadores.
¾ Se pueden utilizar optimizadores independientes de la máquina.
¾ Facilitar la división en fases del proyecto.
Analizador
Sintáctico
Comprobación
estática
Gen. Código
intermedio
Código intermedio
Generador de
código
Distinto formato de las instrucciones:
z Notación polaca inversa o notación postfija
z Árboles sintácticos
z Código de tres direcciones
1
Notación postfijo
La notación postfija de una expresión E se puede definir como:
1.
Si E es una variable o una constante, entonces la notación
postfija de E es también E.
2.
Si E es una expresión de la forma E1opE2 donde op es
cualquier operador binario, entonces la notación postfija de
E es E1´E2´op donde E1´ y E2´ son las notaciones postfijas
de E1 y E2 respectivamente.
3.
Si E es una expresión de la forma (E1) entonces la notación
postfija de E1 es también la notación postfija de E.
Ejemplos
95-2+
(9-5)+2
9-(5+2)
952+abc-*bc-*+:=
a:= b*-c+b*-c
Notación postfijo - Ejemplo
Definición dirigida por la sintaxis
Producciones
expr ⇒ expr + término
expr ⇒ expr – término
expr ⇒ término
término ⇒ 0
…
término ⇒ 9
Reglas semánticas
expr.t ⇒ expr.t || término.t || +
expr.t ⇒ expr.t || término.t || expr.t ⇒ término.t
término.t ⇒ ´0´
…
término.t ⇒ ´9´
expr.t
9-5+2
= 95-2+
expr.t = 95- +
expr.t = 9 término.t = 9
término.t = 5
término.t
=2
2
5
Operador de
concatenación
A cada no terminal está
asociado un atributo t con
un valor de la cadena que
representa la notación
postfija de la expresión
generada por ese no
terminal en un árbol de
análisis sintáctico.
Resultado: 95-2+
9
2
Notación postfijo - Ejemplo
Esquema de Traducción
Acciones semánticas
{print(´+´)}
{print(´-´)}
Producciones
expr ⇒ expr + término
expr ⇒ expr – término
expr ⇒ término
término ⇒ 0
…
término ⇒ 9
{print(´0´)}
…
{print(´9´)}
expr.t
print(´+´)
9-5+2
expr.t
expr.t
-
término.t
término.t
9
término.t
print(´-´) +
5
2
Resultado:
print(´2´)
95-2+
print(5)
print(9)
Árbol sintáctico
™ El uso de árboles sintácticos como representación intermedia permite que la
traducción se separe del análisis sintáctico.
™ Es una forma condensada de un árbol de análisis sintáctico.
™ Útil para representar construcciones de lenguajes.
Ejemplos
S ⇒ if B then S1 else S2
Árbol de análisis sintáctico
Árbol sintáctico
3
Grafo dirigidos acíclicos para expresiones
(GDA)
z
Identifican las subexpresiones comunes de una expresión.
Un nodo interior representa un operador y sus hijos los
operandos.
z
Un nodo tiene más de un padre.
z
Ejemplo:
a + a * (b - c) + (b - c) * d
Código de tres direcciones
Es una secuencia de proposición de la forma general:
x:= y op z
donde x,y y z son nombres, constantes o variables temporales, op representa
cualquier operador.
Ejemplos
x+y*z
t1 := y*z
t2 := x + t1
=
a := b*-c+b*-c
t1 := -c
t2 := b * t1
t3 := -c
t4 := b * t3
t5 := t2 + t4
a := t5
a
+
*
*
b
c
b
c
4
Código de tres direcciones
Implementación de proposiciones de tres
direcciones
Una proposición de tres direcciones es una forma abstracta de
código intermedio. En un compilador estas proposiciones se
pueden implementar como registros con campos para el
operador y los operandos.
Las implementaciones pueden ser:
¾ Triplas
¾Cuádruplas
¾ Triplas Indirectas
5
Cuádruplas
Se implanta en una secuencia de registros con 4 campos:
o Operación
o Argumento1
o Argumento2
o Resultado
Ejemplo a:=b* -c+b* -c
Los nombres t1, t2 y t3 pueden ser registros de la máquina o posiciones de memoria
temporales, que desaparecen cuando se termina la compilación.
Cuádruplas
•
•
En general, las instrucciones que no requieren todos los campos dejan
vacíos los que no utilizan, por ejemplo: las proposiciones con operadores
unarios no utilizan arg2.
Los saltos condicionales e incondicionales ponen la etiqueta (label) en
Resultado.
Los contenidos de los campos Argumento1, Argumento2 y Resultado son
generalmente punteros a la Tabla de Símbolos.
6
Triplas
z
z
Para evitar introducir nombres temporales en la Tabla de Símbolos, se
hace referencia a un valor temporal mediante la posición de la proposición
que lo calcula.
En este caso los registros son de 3 campos.
Triplas Indirectas
z
Se hace una lista de los punteros a triplas.
7
Comparación de las representaciones
La diferencia en la implementación es cuestión de mayor o menor indirección:
™ Las triplas necesitan menos espacio y el compilador no genera
identificadores temporales, pero cambiar de sitio una proposición que defina
un valor temporal exige modificar todas las referencias a él.
™ Esto representa un inconveniente a la hora de optimizar el código, ya que
en cada paso del proceso de optimización hay que cambiar constantemente
las proposiciones de lugar.
™ Este problema no lo presentan las triplas indirectas. Una proposición
puede trasladarse reordenando únicamente la lista de proposiciones.
™ En la práctica se utiliza la notación de cuádruplas como implementación
del código de 3 direcciones.
8
Descargar