2. Código intermedio
es un codigo abstracto independiente de la máquina
para la que se generará el código objeto.
3. El código intermedio ha de cumplir dos
requisitos importantes
ser fácil de producir a
partir del análisis
sintáctico
ser fácil de traducir al
lenguaje objeto
4. Implementación de los tercetos
Los tercetos fueron implementados a través de herencia. Diseñamos
una clase padre c_terceto, que contenía los campos comunes a todos
los tercetos (todos), y que declaraba una serie de métodos virtuales
como show y generar_codigo.
Cada objeto hijo de la clase c_terceto, implementa cada uno de esos
métodos, de manera que acabada la optimización del código
intermedio, solo tenemos que ir llamando al método generar_codigo
del terceto contenido en la lista.
5. Tercetos empleados
BRANCH genera el salto cuando la condición no se cumple.
PUSH solamente se usa para introducir los parámetros antes de una
llamada a función o a constructor.
RET se emplea para indicar el valor a devolver por la subrutina.
PUSHN y POPN se emplean para indicar al generador de código final
el número de temporales que van a ser necesarios (PUSHN) o los que
han dejado de serlo (POPN).
PROMPT y DOCWRI fueron implementados como tercetos aparte para
mejorar la claridad de los listados de los tercetos. En realidad, podíamos
haberlos implementado a través de los tercetos PUSH, CALL y RET.
CTE_CAD no van insertados junto con el resto de tercetos, sino que
van en una lista auxiliar especial, que contiene todas las cadenas
utilizadas por el proceso de compilación.
7. Hay muchos tipos y estilos de código intermedio:
Formas de código intermedio:
Árbol sintáctico
Notación Postfija
Código de tres direcciones
8. Es una especie de código maquina de la forma general:
x:=y op z
No se permite ninguna expresión aritmética
compuesta, pues solo hay operadores del lado derecho
de la proposición.
Expresiones compuestas se descomponen en una
secuencia generando elementos temporales.