You are on page 1of 34

Procesadores de Lenguajes

Ingeniería Técnica superior de Ingeniería Informática
Departamento de Lenguajes y Sistemas informáticos

Generación de código
intermedio I
Sentencias y expresiones
Javier Vélez Reyes
jvelez@lsi.uned.es
Departamento de Lenguajes Y Sistemas Informáticos
UNED

Generación de código intermedio. Sentencias y expresiones
Objetivos

Objetivos
› Aprender en qué consiste la generación de código intermedio
› Aprender qué es el código intermedio
› Conocer los distintos tipos de lenguajes intermedios
› Valorar la importaría de realizar una buena elección del lenguaje intermedio
› Conocer cómo son los lenguajes intermedios lineales
› Entender el significado de las variables temporales en el código intermedio lineal
› Entender el significado de las etiquetas en el código intermedio lineal
› Aprender a construir esquemas de traducción para generar código intermedio
› Conocer los artefactos computacionales que son necesarios para darles soporte
› Aprender a generar código intermedio para expresiones
› Aprender a generar código intermedio para sentencias de control

Javier Vélez Reyes jvelez@lsi.uned.es

Generación de código intermedio. Sentencias y expresiones
Índice

Índice
› Introducción
› Qué es el código intermedio
› La fase de generación de código intermedio
› El código intermedio como punto de desacoplamiento
› Lenguajes intermedios
› Representaciones jerárquicas de código intermedio
› Representaciones lineales de código intermedio
› Generación de código intermedio en la práctica
› Artefactos para la generación de código intermedio
› Generación de código intermedio para expresiones
› Generación de código intermedio para sentencias
› Desarrollo paso a paso
› Bibliografía

Javier Vélez Reyes jvelez@lsi.uned.es

Independencia del juego de instrucciones La independencia del entorno de ejecución se El código intermedio de un programa es refiere al hecho de que el código intermedio una abstracción establecida a través de un debe ser agnóstico del modelo de organización compromiso de consenso entre los equipos de memoria.es . Esto significa que la referencias a datos en código intermedio colección de operadores disponibles en un siguen haciéndose a través de símbolos código intermedio se debe mantener registrados o generados durante el proceso de independiente y equidistante de cualquier compilación lenguaje y juego de instrucciones propio de una arquitectura física real para garantizar la traducción a distintos códigos finales Javier Vélez Reyes jvelez@lsi. el número.uned. etc.Generación de código intermedio. Independencia del entorno de ejecución II. el compilador debe ser capaz de generar una representación simbólica del programa lo más aproximada a los potenciales lenguajes objetivos al que se va a traducir el mismo pero lo suficientemente distante de éstos como para garantizar su aplicabilidad en distintas arquitecturas físicas finales El código intermedio es una representación abstracta del programa cercana a los lenguajes objetivos potenciales pero independiente de cualquier consideración específica de una arquitectura física concreta I. Sentencias y expresiones Introducción ¿Qué es el código intermedio? Una vez superadas todas las fases de análisis del código fuente. Esto implica que todas las dedicados a la síntesis. tipo y propósito de dedicados al análisis de lenguajes y los registros.

Generación de código intermedio. Sentencias y expresiones Introducción La fase de generación de código intermedio La fase de generación de código intermedio se encarga de traducir el programa a una representación de código intermedio para que luego ésta pueda ser transformada en las fases subsiguientes a un código ejecutable en una determinada arquitectura física Etapa de análisis Etapa de síntesis While ( a > b ) do a := a + 1. PR> S √ S LD a t1 0000 0011 WHILE E DO S WHILE E DO S LD b t2 0000 0011 GRT t3 t1 t2 0100 0001 E > E E > E BRZ t3 L1 … 0100 0000 0001 0010 … › Expertos en lenguajes › Expertos en arquitecturas › Independencia de arquitectura › Dependencia de arquitectura › Dependencia de lenguaje › Independencia de lenguaje › Optimización de lenguajes › Optimización de ejecución Javier Vélez Reyes jvelez@lsi. Analizador sintáctico Código intermedio Analizador léxico Código final Analizador semántico e·l·i· h·w <WHILE.es .uned.

Sentencias y expresiones Introducción El código intermedio como punto de desacoplamiento El código intermedio permite multiplexar los esfuerzos de desarrollo de los equipos de análisis de lenguajes y de síntesis de manera que se pueden crear M x N compiladores distintos a partir de M especificaciones y N traducciones a arquitecturas físicas reales While ( a > b ) do while ( a > b ) a := a + 1.Generación de código intermedio.es . Pascal C Analizador léxico Analizador léxico Equipo de Lenguaje Analizador sintáctico Analizador sintáctico M … Analizador semántico Analizador semántico Código intermedio Código intermedio LD a t1 Código LD b t2 GRT t3 t1 t2 intermedio BRZ t3 L1 … Intel Solaris Optimización Código Optimización Código arquitectura Equipo de intermedio intermedio N Código final … Código final Javier Vélez Reyes jvelez@lsi.uned. a++.

Existen distintas alternativas que describiremos a continuación I. I. Representaciones lineales II. Representaciones jerárquicas I.es .I Arboles sintácticos abstractos Son una representación similar a los árboles de Las representaciones jerárquicas de análisis sintácticos donde los artefactos código intermedio reflejan los programas semánticamente superfluos se omiten y los no de un lenguaje como una estructura terminales se sustituyen por operadores relacional de nodos y arcos entre nodos. Sentencias y expresiones Lenguajes intermedios Lenguajes intermedios El primer paro para la generación de código intermedio consiste en el diseño de un lenguaje intermedio que permita representar de forma fiel y suficientemente abstracta los programas de un compilador.II Lenguajes de cuartetos o cuádruplas resultan más apropiados para la etapa de síntesis puesto que se encuentran más En los lenguajes de cuartetos cada operación cercanas a la estructura típica los tiene hasta 2 operandos de entrada y uno lenguajes objetivos más comunes independiente de salida para el resultado Javier Vélez Reyes jvelez@lsi.uned.I Lenguajes de tercetos o tripletas  Foco de atención Las representaciones lineales de código En los lenguajes de tercetos cada operación intermedio codifican un programa como tiene hasta dos operandos de entrada y uno de una secuencia de instrucciones de bajo salida que se sobrescribe sobre alguno de los nivel abstractas próximas al lenguaje de entrada ensamblador.Generación de código intermedio. Este tipo de lenguajes II.I Grafos dirigidos acíclicos Lenguajes intermedios Estas representaciones son aconsejables para tareas de análisis y transformación Cuando los nodos de un árbol sintáctico pero no para sintetizar ejecutables en una abstracto son referenciados por más de un arquitectura física real padre surgen los grafos dirigidos acíclicos II.

Sentencias y expresiones Lenguajes intermedios Representaciones jerárquicas Las representaciones jerárquicas describen el código fuente de un programa como una colección de nodos relacionados entre sí a través de arcos con el mismo nivel de abstracción que lo hacen los árboles de análisis sintáctico Árboles sintácticos abstractos Los arboles sintácticos abstractos representan el › Apto para análisis semántico código fuente de un programa de acuerdo a una estructura jerárquica de forma similar a como lo haces › Apto para procesos de transformación los árboles de análisis sintáctico.es . En estas › Inadecuado para la etapa de síntesis representaciones no obstante se omiten todos tipo de › Representación excesivamente abstracta símbolos semánticamente superfluos y se eliden los no terminales que dan información sobre el proceso de derivación gramatical Árbol de análisis sintáctico Código intermedio SWhile transformación WHILE WHILE ( E ) DO S > ++ E > E ID ID ID while (a>b) do a++ while (a>b) do a++ Javier Vélez Reyes jvelez@lsi.Generación de código intermedio.uned.

Generación de código intermedio. Sentencias y expresiones Lenguajes intermedios Representaciones jerárquicas Las representaciones jerárquicas describen el código fuente de un programa como una colección de nodos relacionados entre sí a través de arcos con el mismo nivel de abstracción que lo hacen los árboles de análisis sintáctico Grafos dirigidos acíclicos Los arboles dirigidos acíclicos realizan una › Apto para análisis semántico representación del código fuente en forma de grafo.es .uned. El método constructivo es similar al de los árboles › Apto para procesos de transformación sintácticos con la diferencia de que aquí se reutilizan › Inadecuado para la etapa de síntesis los nodos que reflejen la misma estructura én aras a › Representación excesivamente abstracta resultar más eficiente su representación en memoria Árbol de análisis sintáctico Código intermedio Asignación := ID := E transformación ID + E + E * E * E E * E ID ID a := b * c + b * c a := b * c + b * c Javier Vélez Reyes jvelez@lsi.

Para articular el proceso de secuenciamiento se utilizan varios elementos como operandos de dichas instrucciones que serán utilizados en lo venidero a lo largo del tema I.es .uned. Variables En numerosas ocasiones las operaciones de Muchos de los símbolos declarados por el código intermedio utilizan operandos que programador. representan valores literales enteros con o sin variables globales o locales y parámetros. tales como constantes. Sentencias y expresiones Lenguajes intermedios Representaciones lineales Las representaciones lineales suponen un secuenciamiento de la información codificada en los árboles de análisis sintácticos en forma de una colección de instrucciones abstractas de bajo nivel pero manteniendo las referencias simbólicas introducidas por el programador. La fase de traducción a código final se son referidos de forma general dentro del encarga posteriormente de traducir esos código intermedio como operandos de tipo valores a la representación numérica ‘variable’ correspondiente utilizada por la arquitectura Los valores literales utilizados como Las variables de código intermedio operandos en las operaciones de los representan las constantes. signo. variables lenguajes de código intermedio lineales globales o locales y parámetros declarados representan valores enteros con signo por el programador a lo largo del código fuente Javier Vélez Reyes jvelez@lsi. Valores literales II.Generación de código intermedio.

etc.es .) requieren insertar espacios de memoria específicamente etiquetas en el código final para luego realizar reservados para ello. invocación de resultados parciales de las subexpresiones en subprogramas.uned. Sentencias y expresiones Lenguajes intermedios Representaciones lineales Las representaciones lineales suponen un secuenciamiento de la información codificada en los árboles de análisis sintácticos en forma de una colección de instrucciones abstractas de bajo nivel pero manteniendo las referencias simbólicas introducidas por el programador. Los elementos de código saltos a ellas. La forma de referirse a estas intermedio que se utilizan para referencias esas etiquetas en código intermedio es mediante direcciones se llaman variables temporales las etiquetas de código Una variable temporal es la representación Una etiqueta de código es una referencia de simbólica en código intermedio de un código intermedio a una zona de memoria espacio de memoria destinado a almacenar donde comienza cierta porción de código un resultado parcial de alguna expresión final Javier Vélez Reyes jvelez@lsi. Etiquetas de código El secuenciamiento de expresiones complejas Muchas de las sentencias de un lenguaje de requiere del almacenamiento temporal de los alto nivel (control de flujo. Para articular el proceso de secuenciamiento se utilizan varios elementos como operandos de dichas instrucciones que serán utilizados en lo venidero a lo largo del tema III. Variables temporales IV.Generación de código intermedio.

Generación de código intermedio. Sentencias y expresiones Lenguajes intermedios Representaciones lineales Las representaciones lineales suponen un secuenciamiento de la información codificada en los árboles de análisis sintácticos en forma de una colección de instrucciones abstractas de bajo nivel pero manteniendo las referencias simbólicas introducidas por el programador.uned.es . un operando de entrada y otro de entrada y › Complejidad en la traducción de construcciones salida para almacenar el resultado Resultado En los lenguajes de tercetos uno de los operandos hace de almacén para el resultado de la operación lo que supone que el operando de entrada se pierde tras su ADD x y ejecución Código de operación Operandos El código de operación es un Los operandos identifican los elementos acrónimo que representa el tipo sobre los que se efectúa la operación de operación que se aplican referida por el código de operación. variables. A continuación describimos los 2 tipos de representaciones lineales Lenguajes de tercetos Las representaciones de código intermedio basadas en › Apto para la etapa de síntesis tercetos están formados por una secuencia de instrucciones constituida por 3 elementos: un código de › Representación cercana al lenguaje objetivo operación. entre los operandos del terceto Pueden ser valores literales. variables temporales o etiquetas Javier Vélez Reyes jvelez@lsi.

A continuación describimos los 2 tipos de representaciones lineales Lenguajes de tercetos Las representaciones de código intermedio basadas en › Apto para la etapa de síntesis tercetos están formados por una secuencia de instrucciones constituida por 3 elementos: un código de › Representación cercana al lenguaje objetivo operación. Sentencias y expresiones Lenguajes intermedios Representaciones lineales Las representaciones lineales suponen un secuenciamiento de la información codificada en los árboles de análisis sintácticos en forma de una colección de instrucciones abstractas de bajo nivel pero manteniendo las referencias simbólicas introducidas por el programador.es .Generación de código intermedio.uned. un operando de entrada y otro de entrada y › Complejidad en la traducción de construcciones salida para almacenar el resultado Árbol de análisis sintáctico Asignación Código intermedio ID := E LOAD t0 b t0  b transformación LOAD t1 c t1  c (a) E * E MUL t1 t0 t1  t1 * t0 STORE t1 a t1  a ID ID (b) (c) a := b * c a := b * c Javier Vélez Reyes jvelez@lsi.

uned. entre los operandos del terceto Pueden ser valores literales. A continuación describimos los 2 tipos de representaciones lineales Lenguajes de cuartetos Las representaciones de código intermedio basadas en › Apto para la etapa de síntesis cuartetos están formados por una secuencia de instrucciones constituida por 4 elementos: un código de › Representación cercana al lenguaje objetivo operación.Generación de código intermedio.es . Sentencias y expresiones Lenguajes intermedios Representaciones lineales Las representaciones lineales suponen un secuenciamiento de la información codificada en los árboles de análisis sintácticos en forma de una colección de instrucciones abstractas de bajo nivel pero manteniendo las referencias simbólicas introducidas por el programador. dos operando de entrada y otro de salida › Mayor sencillez en la traducción de construcciones para almacenar el resultado Resultado En los lenguajes de cuartetos el almacén para el resultado de la operación es un operando de salida independiente lo que supone que no hay perdida de información ADD x y z tras la ejecución de la operación Código de operación Operandos El código de operación es un Los operandos identifican los elementos acrónimo que representa el tipo sobre los que se efectúa la operación de operación que se aplican referida por el código de operación. variables. variables temporales o etiquetas Javier Vélez Reyes jvelez@lsi.

A continuación describimos los 2 tipos de representaciones lineales Lenguajes de cuartetos Las representaciones de código intermedio basadas en › Apto para la etapa de síntesis cuartetos están formados por una secuencia de instrucciones constituida por 4 elementos: un código de › Representación cercana al lenguaje objetivo operación. dos operando de entrada y otro de salida › Mayor sencillez en la traducción de construcciones para almacenar el resultado Árbol de análisis sintáctico Asignación Código intermedio ID := E LOAD t0 b t0  b transformación LOAD t1 c t1  c (a) E * E MUL t2 t1 t0 t2  t1 * t0 STORE t2 a t2  a ID ID (b) (c) a := b * c a := b * c Javier Vélez Reyes jvelez@lsi. Sentencias y expresiones Lenguajes intermedios Representaciones lineales Las representaciones lineales suponen un secuenciamiento de la información codificada en los árboles de análisis sintácticos en forma de una colección de instrucciones abstractas de bajo nivel pero manteniendo las referencias simbólicas introducidas por el programador.es .Generación de código intermedio.uned.

Generación de código intermedio. Para llevar esto a cabo.es .uned. el framework de desarrollo proporciona una colección de artefactos que conviene conocer ScopeManager TypeTable TypeIF TemporalTable Scope SymbolTable SymbolIF < uses Create > IntermediateCodeBuilder Quadruple OperandIF Create > Reference to > LabelFactory Label Variable Create > TemporalFactory Temporal Value Javier Vélez Reyes jvelez@lsi. Sentencias y expresiones Generación de código intermedio en la práctica Artefactos para la generación de código intermedio La generación de código intermedio se realiza a través de la definición de accesos semánticas en los esquemas de traducción gramaticales.

Representan cada una de las operaciones atómicas que pueden ser referenciadas dentro del código intermedio para que surtan cierto efecto o realicen cierto cálculo a partir de los operandos  Los objetos de tipo Quadruple se utilizan para Quadruple representar operaciones atómicas del código + String getOperation () intermedio.es . Una cuadrupla está formado por un código + void setOperation () de operación.uned. Para llevar esto a cabo. Sentencias y expresiones Generación de código intermedio en la práctica Artefactos para la generación de código intermedio La generación de código intermedio se realiza a través de la definición de accesos semánticas en los esquemas de traducción gramaticales. en función del tipo de operación el numero + void setFirstOperand (OperandIF o) de operandos puede variar. como + void setSecondOperand (OperandIF o) HALT. Puede haber + OperandIF getSecondOperand () instrucciones con ningún operando ni resultado.Generación de código intermedio. + OperandIF getFirstOperand () En efecto. el framework de desarrollo proporciona una colección de artefactos que conviene conocer Cuádruplas Las cuádruplas son el elemento central de la arquitectura. O puede haber instrucciones + OperandIF getResult () con un resultado y dos operandos como en la suma + void setResult (OperandIF o) ADD t3 t1 t2. un operando opcional resultado y a lo sumo dos operandos de entrada también opcionales. Javier Vélez Reyes jvelez@lsi. Puede haber otras con un sólo operando como los saltos del tipo BR L.

valores literales enteros y etiquetas.uned. Sentencias y expresiones Generación de código intermedio en la práctica Artefactos para la generación de código intermedio La generación de código intermedio se realiza a través de la definición de accesos semánticas en los esquemas de traducción gramaticales. valores y etiquetas Los operandos sobre los que operan las cuádruplas son de uno de cuatro tipos: variables.Generación de código intermedio. el framework de desarrollo proporciona una colección de artefactos que conviene conocer Variables. Para llevar esto a cabo.es . Dentro de la arquitectura existe una clase abierta para representar cada uno de estos tipos que el alumno debe carácter con atributos Variable Label -String name -String name -ScopeIF scope -ScopeIF scope -Boolean isGlobal Temporal Value -String name -Integer value -ScopeIF scope -Integer address Javier Vélez Reyes jvelez@lsi. temporales. variables temporales.

el framework de desarrollo proporciona una colección de artefactos que conviene conocer Tabla de temporales Los temporales que se van generando a medida que el compilador procesa las expresiones del lenguaje deben almacenarse en una tabla de temporales asociada a cada ámbito. El artefacto TemporalTable gestiona los temporales de un ámbito TemporalTable  Cada tabla de temporales se crea de forma automática asociada a un ámbito cuando este -ScopeIF scope es abierto a través del gestor de ámbitos. Para llevar esto a cabo.uned.Generación de código intermedio.es . Este es un aspecto importante para las fases posteriores. Los + List <TemporalIF> getTemporals () métodos addTemporal y getTemporals sirven + void addTemporal (TemporalIF temporal) para registrar y tener acceso a los temporales + boolean containsTemporal (TemporalIF temporal) respectivamente y son de utilidad en ésta y en las fases posteriores de generación de código final Javier Vélez Reyes jvelez@lsi. Por -List <TemporalIF> temporals tanto existe una tabla de temporales para cada ámbito. La responsabilidad de este artefacto es + ScopeIF getScope () gestionar la colección de temporales generados durante el proceso de compilación + TemporalTable (ScopeIF scope) del bloque sintáctico asociado al ámbito. Sentencias y expresiones Generación de código intermedio en la práctica Artefactos para la generación de código intermedio La generación de código intermedio se realiza a través de la definición de accesos semánticas en los esquemas de traducción gramaticales.

es .Generación de código intermedio.uned. el framework de desarrollo proporciona una colección de artefactos que conviene conocer Factorías de etiquetas y temporales Aunque la construcción de temporales y etiquetas puede realizarse haciendo uso directo de los constructores en sendas clases. Sentencias y expresiones Generación de código intermedio en la práctica Artefactos para la generación de código intermedio La generación de código intermedio se realiza a través de la definición de accesos semánticas en los esquemas de traducción gramaticales. El primer método + TemporalIF create (String name) create construye un temporal con nombre propio y lo + TemporalIF create () registra automáticamente en la tabla de temporales. el framework proporciona dos tipos de factorías cuyo uso para construir objetos de estas clases resulta recomendable por las ventajas que ello supone TemporalFactory  La factoría de temporales es un artefacto asociado a un ámbito pasado como argumento en el constructor + TemporalFactory (ScopeIF scope) que se utiliza para crear temporales. El primer método create construye una + LabelFactory (ScopeIF scope) etiqueta con nombre propio. es que éste método construye la etiqueta con + LabelIF create () un nombre autogenerado que garantiza la unicidad Javier Vélez Reyes jvelez@lsi. La diferencia del segundo create. La diferencia del segundo + LabelIF create (String name) create. es que éste método construye el temporal con un nombre autogenerado que garantiza la unicidad dentro del ámbito LabelFactory  La factoría de etiquetas es un que se utiliza para crear etiquetas. Para llevar esto a cabo.

o1.Generación de código intermedio. Después se utilizan los métodos addQuadruple para ir › Sino se busca en TS’s.es . r) interna de código intermedio. r. Al finalizar la acción semántica el código se obtiene invocando el método create () Javier Vélez Reyes jvelez@lsi. se crea Variable y se inserta acumulando cuartetos internamente. No obstante. resulta más sencillo y económico utilizar instancias de IntermediateCodeBuilder para realizar esta labor IntermediateCodeBuilder  Las operaciones addQuadruple se encargan de insertar un nuevo cuarteto dentro de la lista + void addQuadruple (String op.uned. Sin embargo su + void addQuadruple (String op. o1) semántica depende del tipo y formato de los + void addQuadruple (String op. r. o2) operandos + void addQuadruple (QuadrupleIF q) › Si es de tipo OperandIF se inserta tal cual + void addQuadruples (List <QuiadrupleIF> code) › Si es de tipo int se crea un Value y se inserta + List <QuadrupleIF> create () › Si es de tipo String  › Si comienza por “L_” se crea Label y se inserta Primero se instancia el code builder pasándole › Si comienza por “T_” se crea Temporal y se inserta como argumento de constructo el ámbito. Para llevar esto a cabo. Sentencias y expresiones Generación de código intermedio en la práctica Artefactos para la generación de código intermedio La generación de código intermedio se realiza a través de la definición de accesos semánticas en los esquemas de traducción gramaticales. el framework de desarrollo proporciona una colección de artefactos que conviene conocer IntermediateCodeBuilder La construcción de las cuádruplas que componen el código intermedio puede realizarse por invocación de sus constructores de clase.

uned. SP++ LS x y z x := (y < z) ? 1 : 0 POP x x := *SP . salto a L MUL x y z x := y * z BRF x L Si !x. salto a L DIV x y z x := y / z INL L Insertar L: MOD x y z x := y % z MV x y x := y INC x y x := y + 1 MVP x y x := *y DEC x y x := y – 1 MVA x y x := &y NEG x y x := – y STP x y *x := y GR x y z x := (y > z) ? 1 : 0 STA x y &x := y EQ x y z x := (y == z) ? 1 : 0 PUSH x *SP := x . SP -- AND x y z x := y && z CALL f Llamada a función f OR x y z x := y || z RET x Retorno de f con valor x XOR x y z x := y ^ z HALT Stop Javier Vélez Reyes jvelez@lsi.es . Estudie para ello el/los lenguajes objetivos finales Cuarteto Descripción Cuarteto Descripción NOP Nada NOT x y x := !y ADD x y z x := y + z BR L Salto a L SUB x y z x := y – z BRT x L Si x. Sentencias y expresiones Generación de código intermedio en la práctica Diseño del lenguaje intermedio Antes de proceder con la generación de código intermedio es necesario determinar el juego de instrucciones (cuartetos) que será empleado.Generación de código intermedio.

addQuadruple (“ADD”. estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup Expresiones Expresiones exp ::= exp:e1 MAS exp:e2 {: exp ::= exp:e1 MENOS exp:e2 {: . :} <<comprobación de tipos de e1 y e2>> .es .getCurrentScope(). :} IntermediateCodeBuilder cb = new …Builder (scope) exp ::= NOT exp:e1 {: . Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado.addQuadruple (“NOT”. temp. e.. cb.create()). temp1.create ().setCode (cb.create (). cb.addQuadruples (e2...getCode ())..getTemporal ()... TemporalFactory tF = new TemporalFactory (scope)..create()). TemporalIF temp2 = e2.addQuadruples (e1. ScopeIF scope = scopeManager. TemporalIF temp = tF. TemporalIF temp = tF.getCurrentScope().getTemporal ().getCode ()). TemporalIF temp1 = e1..addQuadruples (e1.setCode (cb.setTemporal (temp).setTemporal (temp). ScopeIF scope = scopeManager..getCode ()). exp ::= exp:e1 POR exp:e2 {: . RESULT = e e.getTemporal (). e. cb. temp..uned. :} TemporalFactory tF = new TemporalFactory (scope). :} RESULT = e :} Javier Vélez Reyes jvelez@lsi.. e. cb. IntermediateCodeBuilder cb = new …Builder (scope) cb. temp1). temp2).Generación de código intermedio. exp ::= exp:e1 OR exp:e2 {: . exp ::= exp:e1 AND exp:e2 {: . :} Exp e = new Exp(). TemporalIF temp1 = e1..

e.getCurrentScope().getCurrentScope().setCode (cb. temp1). exp ::= rNumero:rn {: TemporalFactory tF = new TemporalFactory (scope). IntermediateCodeBuilder cb = new …Builder (scope) Integer value = rn. <<comprobación de tipos de e1 y e2>> :} ScopeIF scope = scopeManager. :} e. e.uned. IntermediateCodeBuilder cb = new …Builder (scope).getTemporal ().create (). cb.create ().addQuadruple (“MV”.addQuadruples (e1. :} Javier Vélez Reyes jvelez@lsi. cb.getCode ()). RESULT = e1. e.addQuadruple (“NEG”.getValue ().Generación de código intermedio. temp. temp. Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado.create ()): RESULT = e. ScopeIF scope = scopeManager.setCode (cb. TemporalFactory tF = new TemporalFactory (scope). estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup Expresiones Expresiones exp ::= MENOS exp:e1 {: exp ::= PI exp:e1 PD {: Exp e = new Exp().setTemporal (temp). Exp e = new Exp (). TemporalIF temp = tF. TemporalIF temp1 = e1.es . <<Comprobación de tipos>> TemporalIF temp = tF.setTemp (temp). RESULT = e. value).create()). cb.

<<Comprobación de tipos>> TemporalFactory tF = new TemporalFactory (scope).addQuadruples (r.searchSymbol (name). :} RESULT = referencia.getTemporal (). Variable var = new Variable (name.getScope ()). temp.setCode (cb. SymbolVariable sV = scopeManager. referencia.getType ()). ScopeIF scope = scopeManager. cb. IntermediateCodeBuilder cb = new …Builder (scope). :} Javier Vélez Reyes jvelez@lsi. Referencia r = new Referencia ().getCode ()). TemporalIF rTemp = r. var). temp. cb. e.getLexema ().setCode (cb.addQuadruple (“MVA”.uned. IntermediateCodeBuilder cb = new …Builder (scope).setTemporal (temp). ScopeIF scope = scopeManager.getCurrentScope().setType (r.addQuadruple (“MVP”. e. e. cb.create (). estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup Expresiones Referencias exp ::= referencia:r {: referencia ::= ID:id {: Exp e = new Exp ().create ()). TemporalIF temp = tF. TemporalFactory tF = new TemporalFactory (scope).Generación de código intermedio.es . RESULT = e. Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado.create ().create ()): referencia.setTemp (temp). sV. rTemp). String name = id.getCurrentScope(). TemporalIF temp = tF.

k IntermediateCodeBuilder cb = new …Builder (scope).getLexema (). 0). j D2 <<Comprobación de tipos>> ScopeIF scope = scopeManager.addQuadruple (“MV”. + k x size t4 := t3 x D3 + k RESULT = referencia. t1 := 0 &v + i x (D2 x D3 x size) referencia. + j x (D3 x size) = t3 := t2 x D2 + j referencia.uned. TemporalIF temp = tF. V [i][j][k] cb.setTemporal (temp).addQuadruple (“MVA”. D1 TemporalIF tempI = tF.getCurrentScope(). Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado.setTemporalIndex (tempI). temp. size cb. TemporalFactory tF = new TemporalFactory (scope).create ().es .create ()). tempI. String name = id. t5 := &v + t4 x size :} Javier Vélez Reyes jvelez@lsi.Generación de código intermedio. t2 := t1 x D1 + i referencia. name). estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup D3 Referencias a elementos de Arrays V referencia ::= ID:id {: i Referencia r = new Referencia ().create ().setCode (cb.

es . t1 := 0 &v + i x (D2 x D3 x size) cb. r. Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado. t2 := t1 x D1 + i cb. k TemporalIF rTemp = r. V [i][j][k] IntermadiateCodeBuilder cb = new …Builder (scope).getBaseType()). eTemp). D1 TemporalIF eTemp = e.getTemporal ().getCode ()). rn.setTemporalIndex (rnTempI).getMin () + 1. RESULT = rn.addQuadruple (“MUL”.getTemporalIndex ().Generación de código intermedio.getType().getTemporal (). <<comprobación de tipos>> j D2 TypeIF rType = r.addQuadruples (r. rnTempI.uned. int rDim = rType. + j x (D3 x size) = t3 := t2 x D2 + j cb. rDim). TemporalFactoryIF tF = new TemporalFactory (scope). t5 := &v + t4 x size rn. rnTempI. size TemporalIF rnTempI = tF. estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup D3 Referencias a elementos de Arrays V referencia ::= referencia:r CI exp:e CD {: i Referencia rn = new Referencia ().getCode ()). + k x size t4 := t3 x D3 + k cb. rn.addQuadruples (e. TemporalIF rTempI = r.create ().setCode (cb. rnTempI. :} Javier Vélez Reyes jvelez@lsi.setType (rType.setTemporal (rTemp).getMax () – rType. rTempI.addQuadruple (“ADD”.create()).

TemporalIF eTemp = tF. rTemp). t1 := 0 &v + i x (D2 x D3 x size) cb. Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado.setTemporal (eTemp). estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup D3 Referencias a elementos de Arrays V exp ::= referencia:r {: i Exp e = new Exp ().getSize ().es .setCode (cb.addQuadruples (r.Generación de código intermedio. + j x (D3 x size) = t3 := t2 x D2 + j cb. + k x size t4 := t3 x D3 + k cb.getCode ()).getTemporalIndex (). <<comprobación de tipos>> j D2 ScopeIF scope = scopeManager.addQuadruple (“MVP”.uned. size int rSize = rType.addQuadruple (“ADD”. D1 TypeIF rType = r. :} Javier Vélez Reyes jvelez@lsi.create()). eTemp. e.getTemporal (). t5 := &v + t4 x size e. k TemporalIF rTempI = r.addQuadruple (“MUL”. eTemp.getCurrentScope (). eTemp. TemporalFactoryIF tF = new TemporalFactory (scope). RESULT = e. TemporalIF rTemp = r. t2 := t1 x D1 + i cb. rSize). eTemp).create (). rTempI. eTemp. V [i][j][k] IntermadiateCodeBuilder cb = new …Builder (scope).getType().

serCode (cb. rn.getSize ().create ().create()).create ().create()).getCurrentScope ().getType().getTemporalIndex (). int rSize = rType.addQuadruples (r. eTemp).getCurrentScope().setTemporalIndex (rTempI). rTempI. <<comprobación de tipos>> <<comprobación de tipos>> ScopeIF scope = scopeManager. rSize). TemporalIF eTemp = tF.addQuadruple (“MVP”.getTemporalIndex (). ScopeIF scope = scopeManager.setCode (cb. TemporalIF rTempO = tF.addQuadruples (r. TemporalIF rTempI = r. TemporalIF rTempI = r.Generación de código intermedio.getTemporalOffset (). rn.addQuadruple (“ADD”.getOffset (name). rn. IntermadiateCodeBuilder cb = new …Builder (scope). TypeRecord rType = r. cb.getCode ()). rTempO).getTemporal (). eTemp. TemporalIF rTemp = r. RESULT = e. idOffset).getType (). TypeIF rType = r. rTemp). IntermediateCodeBuilder cb = new …Builder (scope).setTemporal (rTemp).setTemporal (eTemp).uned. cb.getLexema (). TemporalFactory tF = new TemporalFactory (scope).addQuadruple (“ADD”. rn. int idOffset = rType. RESULT = rn.setTemporalOffset (rTempO) .addQuadruple (“MV”. eTemp. eTemp. rTempO. TemporalIF rTempO = r.getCode ()). cb. TemporalIF rTemp = r.es . e. Exp e = new Exp (). cb.getTemporal (). String name = id. eTemp. :} e. cb. Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado. cb. eTemp. TemporalFactoryIF tF = new TemporalFactory (scope). :} Javier Vélez Reyes jvelez@lsi.addQuadruple (“MUL”. estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup Referencia a campos de registro Referencia a campos de registro referencia ::= referencia:r PUNTO ID:id {: expr ::= referencia:r {: Referencia rn = new Referencia (). eTemp. cb.

setCode (cb. cb. eTemp).addQuadruple (“BR”.getCurrentScope().addQuadruple (“MUL”.uned. rSize).getTemporal ().addQuadruple (“INL”. TemporalIF rTempO = r. IntermadiateCodeBuilder cb = new …Builder (scope). temp.getTemporal (). temp. rTemp).create (). TemporalIF eTemp = e. temp.getCode ()).getCode ()).getCode ()). sa. <<comprobación de tipos>> <<comprobación de tipos>> ScopeIF scope = scopeManager. RESULT = sa.getTemporalOffset ().addQuadruple (“INL”. IntermediateCodeBuilder cb = new …Builder (scope). cb.Generación de código intermedio.addQuadruples (r. TemporalFactoryIF tF = new TemporalFactory (scope). cb.addQuadruples (e. cb.getCurrentScope (). cb. rTempO). Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado. ScopeIF scope = scopeManager.addQuadruples (s1. LabelFactoryIF lF = new LabelFactory (scope). cb.addQuadruple (“STP”.create (). TemporalIF rTempI = r. cb.getCode ()). cb. l1). cb.create()). cb. TemporalIF eTemp = e.getTemporalIndex (). l2). TemporalIF rTemp = r.setCode (cb. rTempI. eTemp. TemporalIF temp = tF.addQuadruple (“ADD”. l2). temp. sIF. cb. cb. :} RESULT = sIF. LabelIF l1 = lF.addQuadruple (“ADD”. temp. LabelIF l2 = lF.create ().getCode ()). temp.addQuadruples (e. :} Javier Vélez Reyes jvelez@lsi.create ()). estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup Sentencia asignación Sentencia If sentenciaAsignacion ::= referencia:r IGUAL exp:e {: sentenciaIF ::= IF PI exp:e PD s:s1 ELSE s:s2 {: SentenciaAsignacion sa = new SAsignacion (). cb.addQuadruple (“BRF”.es .addQuadruples (s2. l1).getTemporal (). SentenciaIf sIf = new SIf ().

addQuadruple (“INL”. cb. <<comprobación de tipos>> <<comprobación de tipos>> ScopeIF scope = scopeManager. SentenciaFor sFor = new SFor (). LabelIF l1 = lF. l1).Generación de código intermedio. l2). cb.addQuadruple (“INL”. l1). cb.getCode ()). cb.getTemporal (). cb. l1). cb.create (). estamos en disposición de articular dicha generación dentro del esquema de traducción dirigida por la sintaxis de cup Sentencia While Sentencia For sentenciaWhile ::= WHILE PI exp:e PD s:s1 {: sentenciaFor ::= FOR sAsignacion:sa TO exp:e DO s:s1 {: SentenciaWhile sWhile = new SWhile (). LabelFactoryIF lF = new LabelFactory (scope).addQuadruples (e.uned.addQuadruple (“BRF”.addQuadruple (“BR”. l2). LabelFactoryIF lF = new LabelFactory (scope). :} sFor. :} Javier Vélez Reyes jvelez@lsi.addQuadruples (s1. RESULT = sFor. sWhile. LabelIF l1 = lF. Sentencias y expresiones Generación de código intermedio en la práctica Generación de código intermedio en Cup Una vez que conocemos los artefactos proporcionados por el framework para la fase de generación de código y diseñado un lenguaje de código intermedio apropiado. cb.es . cb.getCode ()). cb.addQuadruples (s1.addQuadruple (“BRF”. eTemp.create ().getTemporal (). LabelIF l2 = lF.setCode (cb. LabelIF l2 = lF.getCode ()).create ()). l2). cb. RESULT = sWhile. ScopeIF scope = scopeManager.setCode (cb.getCurrentScope ().getCurrentScope ().addQuadruples (e.create ()). cb. TemporalIF eTemp = e.getCode ()).create ().create ().addQuadruple (“INL”.addQuadruple (“BR”. l1). IntermadiateCodeBuilder cb = new …Builder (scope).getCode ()). TemporalIF eTemp = e. l2). IntermadiateCodeBuilder cb = new …Builder (scope). eTemp.addQuadruple (“INL”. cb.addQuadruples (sa. cb.

Ejecutar el finalTestCase . Código intermedio para expresiones.Generación de código intermedio. Implementar las clases necesarias del framework . sentencias… . Tomar como referencia el lenguaje objeto de la arquitectura real . Probar el código intermedio .uned. A continuación se resumen los pasos recomendados para esta fase 1. Label. Incorporar este código al del comprobador de tipos implementado en la fase anterior 4.es . Identificar todas las operaciones necesarias y asignarles un acrónimo y semántica . Incluir atributos necesarios a cada no terminal (Expresión. semanticErrorManager. … 3. Comenzar por un juego sencillo e ir refinándolo bajo demanda 2. Referencias. Considerar revisar la definición de otros artefactos: TypeIF. Value . Implementar las acciones semánticas que generan código intermedio . …) . Caracterizar mediante atributos los operandos: Variable. Sentencias y expresiones Generación de código intermedio en la práctica Desarrollo paso a paso La fase de generación de código intermedio requiere de la implementación de acciones semánticas en el esquema de traducción dirigidas a producir un código lineal cercano al código objeto pero independiente de una arquitectura física real. Diseñar un lenguaje intermedio . Sentencias.debug en reglas para que imprima el código intermedio generado Javier Vélez Reyes jvelez@lsi. referencias. Temporal.

Sentencias y expresiones Bibliografía Material de estudio Bibliografía básica Construcción de compiladores: principios y práctica Kenneth C. Louden International Thomson Editores.uned.es .Generación de código intermedio. 2004 ISBN 970-686-299-4 Javier Vélez Reyes jvelez@lsi.

Segunda Edición Aho. Pérez. técnicas y herramientas. Garrido. J. A. Ullman Addison – Wesley. Moreno y J. 2002. Sentencias y expresiones Bibliografía Material de estudio Bibliografía complementaria Compiladores: Principios.es .Generación de código intermedio. Lam. Edita Universidad de Alicante Javier Vélez Reyes jvelez@lsi. F. Iñesta. Sethi.uned. México 2008 Diseño de compiladores. Pearson Educación.