Está en la página 1de 8

“GENERACIÓN CÓDIGO INTERMEDIO”

MATERIA: LENGUAJES Y AUTOMATAS II

NOMBRE: ROMARIO ALDAIR CAMACHO ROMERO

PROFESORA: MATÍNEZ IBARRA JUAN DE JESÚS

GRUPO: 7S11
INTRODUCCIÓN

En la presente de este trabajo se realizará la investigación sobre el código intermedio y su


generalización para ello empezaremos con conceptos básicos dentro del desarrollo de dicho
documento, como sabrán La generación de código intermedio se realiza a partir de la semántica
denotacional del lenguaje, es decir, se elige un modelo que permite pensar las ecuaciones
semánticas como traducciones al lenguaje intermedio. El modelo semántico que se elige es una
categoría funtorial que permite explicitar en las ecuaciones algunas propiedades deseadas del
lenguaje. La implementación se realiza en Agda, un lenguaje funcional con tipos dependientes.
La fase de 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. Por lo general, mejor significa
más rápido, pero pueden lograrse otros objetivos, como un código más corto, o un código de
destino que consuma menos poder. Por ejemplo, un algoritmo directo genera el código intermedio,
usando una instrucción para cada operador en la representación tipo árbol que produce el
analizador semántico.

Un algoritmo simple de generación de código intermedio, seguido de la optimización de código, es


una manera razonable de obtener un buen código de destino. 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 en la siguiente secuencia más corta:

t1 = id3 * 60.0 (2.4)

id1 = id2 + t1

Hay una gran variación en la cantidad de optimización de código que realizan los distintos
compiladores. En aquellos que realizan la mayor optimización, a los que se les denomina como
"compiladores optimizadores", se invierte mucho tiempo en esta fase. Hay optimizaciones simples
que mejoran en forma considerable el tiempo de ejecución del programa destino, sin reducir
demasiado la velocidad de la compilación.
Código intermedio

Algunos compiladores generan un código intermedio a partir del árbol de derivación. La ventaja de
tener una representación intermedia es que entonces todas las fases vistas hasta ahora (incluída
ésta) son independientes del código objeto. El código intermedio puede pensarse como un
programa para una máquina abstracta, en el que las variables son posiciones de memoria. El
siguiente es el código intermedio generado a partir del árbol que produjo el analizador semántico:

id1: = 1.0

temp1: = 2.0 *R id1

temp2: = toreal 1

id2: = temp1 +R temp2

Cada asignación del lenguaje intermedio tiene a lo sumo un operador. Cuando se usan más
operadores es necesario crear variables temporales para almacenar resultados intermedios. Los
lenguajes intermedios generalmente tienen árboles de derivación más pequeños que su
contraparte original. Se puede representar un árbol sintáctico con un Grafo Dirigido Acíclico (GDA).
La notación postfija es una manera linealizada de representar un árbol sintáctico.

Generador código objeto:

La última fase del compilador es la generación de código objeto. En general, el código objeto
consiste de instrucciones en un lenguaje ensamblador. Para cada variable que ocurre en el
programa se selecciona una dirección de memoria (esta tarea no es trivial, ver la sección 2.3) y
luego se traduce cada instrucción en el lenguaje intermedio a una secuencia de instrucciones en
código objeto. En nuestro caso, la salida del generador de código es la siguiente:

MOVF #1.0, id1

MOVF id1, R1

MULF #2.0, R1

ADDF #1.0, R1

MOVF R1, id2


El primer y segundo operando de cada instrucción indican el origen y el destino de los datos,
respectivamente. Por ejemplo, la primera instrucción mueve la constante 1.0 a la dirección id1. La
F al final de cada instrucción indica que estamos operando con números faltantes.

Notaciones

La diversidad de notaciones corresponde en que para algunos casos es más sencillo un tipo de
notación. Las notaciones también dependen de cómo se recorrerá el árbol sintáctico, el cual puede
ser en inorden, preorden o postorden; teniendo una relación de uno a uno con la notación de los
operadores.

Infija

La notación infija es la más utilizada por los humanos porque es la más comprensible ya que ponen
el operador entre los dos operandos. Por ejemplo, a+b-5. No existe una estructura simple para
representar este tipo de notación en la computadora por esta razón se utilizan otras notaciones.

Postfija

La notación postfija pone el operador al final de los dos operandos, por lo que la expresión queda:
ab+5-

La notación posftfija utiliza una estructura del tipo LIFO (Last In First Out) pila, la cual es la más
utilizada para la implementación.

Prefija

La notación prefija pone el operador primero que los dos operandos, por lo que la expresión
anterior queda: +ab-5. Esto se representa con una estructura del tipo FIFO (First In First Out) o cola.

Las estructuras FIFO son ampliamente utilizadas, pero tienen problemas con el anidamiento
aritmético.
Código P

El código P hace referencia a máquinas que utilizan o se auxilian de pilas para generar código
objeto. En muchos casos la P se asociado a código portable el cual garantiza que el código
compilado en una máquina se pueda ejecutar en otras.

Intérpretes

Los interpretes generalmente utilizan este triplos para generar el código intermedio para
ejecutarse una vez considerado la instrucción como válido. En este sentido, un compilador es más
difícil de implementar ya que tendrá que mantener todas las estructuras generadas que en muchas
ocasiones serán cuádruplos.

Cuádruplos

Es una estructura tipo registro con cuatros campos que se llaman: op, arg1, arg2 y resultado. OP
tiene un código intermedio. Los operadores unarios como x:=-y no utilizan arg2. Generalmente
arg1, arg2 y resultado son valores de tipo puntero y apuntan a una entrada en la tabla de símbolos.
Conclusión

En principio, el código intermedio es independiente del lenguaje de programación


fuente. En la practica, son habituales los códigos intermedios que facilitan la
representación de determinadas características de un lenguaje concreto. Así, el P-
conde esta pensado para traducir Pascal y el Java-bytecode es muy bueno para el
Java. Otra de las ventajas del código intermedio es que facilita la escritura de
compiladores para distintas maquinas. La traducción del lenguaje a código
intermedio seria idéntica en todas y lo único que cambiaria seria el traductor de
código intermedio a código de maquina. Esta idea de un código intermedio
independiente de la maquina puede llevarse un paso más allá, como se hace en
diversos lenguajes, de los cuales Java es quizá el más representativo. La idea es
compilar el lenguaje a un código intermedio. Al ejecutar el programa, se interpreta
este código intermedio o se compila “al vuelo” para la maquina destino. De esta
manera, un mismo “binario” puede ejecutarse en máquinas con arquitecturas y
sistemas operativos totalmente distintos.
Bibliografía

htps://rdu.unc.edu.ar/bitstream/handle/11086/41/15762.pdf?sequence=1&isAllo
wed=y#:~:text=La%20generaci%C3%B3n%20de%20c%CS%B3digo%20intermedio,co
mo%20traducciones%20al%20lenguaje%20intermedio

https://www3.uji.es/~vjimenez/AULASVIRTUALES/PL-0910/T5-
GENERACION/codigo.apun.pdf

http://www.di-mare.com/adolfo/cursos/2008-1/pp-GenCodInterMed.pdf

También podría gustarte