Está en la página 1de 19

INSTITUTO TECNOLÓGICO SUPERIOR DE IRAPUATO

Ing. Sistemas Computacionales

Lenguajes Autómatas 2

Generación de código intermedio

GRANADOS DIAZ BRAYAN EVERARDO

Nelly Beatriz Santoyo Rivera

04 de diciembre del 2021


Contenido
Referencias...........................................................................................................................3
Resumen................................................................................................................................4
2.1 Notaciones......................................................................................................................5
2.1.1 Prefija.......................................................................................................................5
2.1.2 Infija..........................................................................................................................5
2.1.3 Postfija......................................................................................................................5
2.2 Representaciones de código intermedio...................................................................6
2.2.1 Notación Polaca......................................................................................................6
2.2.2 Código P..................................................................................................................6
2.2.3 Triplos.......................................................................................................................7
2.2.4 Cuádruplos..............................................................................................................7
2.3 Esquema de generación..............................................................................................8
2.3.1 Variables y constantes..........................................................................................8
2.3.2 Expresiones.............................................................................................................8
2.3.3 Instrucción de asignación.....................................................................................9
2.3.4 Instrucciones de control........................................................................................9
2.3.5 Funciones..............................................................................................................10
2.3.6 Estructuras............................................................................................................10
Bibliografías.........................................................................................................................11
Referencias
Ilustración 1 Ejemplo de operacion en prefijo obtenido de
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWgAAABxCAMAAAD
PlckAAAAAhFBMVEX///
8AAABVVVXMzMyLi4vT09P19fW+vr6ysrLu7u4FBQUNDQ38/
Pz4+PhgYGB4eHiCgoKqqqpERERMTExoaGhxcXEkJCQcHBwTExOZmZnDw8Mr
Kyu2trYRERHY2Njl5eU1NTW..................................................................................4
Ilustración 2 Ejemplo de operacion en infijo obtenido de
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASQAAACtCAMAAAAu
7/J6AAACc1BMVEX///8AAAD/AAChoaH//81UKxnLy8u/v7+NWT0YAAD/6KT/
4eHl5eV1dXX/kpL/6+sAABErVKDo////oKDG//8AAAf///kjNHprvv//a2v/Xl7/sFX/
c3OoqKj39/f/8vL/3/f/..................................................................................................5
Ilustración 3 Ejemplo de operacion en postfija obtenido de
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWgAAABxCAMAAAD
PlckAAAAAe1BMVEX///
8AAABVVVXMzMxJSUn19fWysrLT09Pu7u6Li4sNDQ0FBQVgYGD7+/
tEREQzMzN4eHiCgoIdHR2ZmZk6Ojrl5eXd3d27u7urq6suLi6goKBlZWUWFhYbGx
vDw8Pq6uokJC.........................................................................................................5
Ilustración 4 Ejemplo de triplo obtenido de
https://slideplayer.es/slide/3401690/12/images/32/Generaci%C3%B3n+de+c
%C3%B3digo+intermedio.jpg....................................................................................7
Ilustración 5 Ejemplo de cuadruplo obtenido de
https://slideplayer.es/slide/3401690/12/images/32/Generaci%C3%B3n+de+c
%C3%B3digo+intermedio.jpg....................................................................................7
Ilustración 6 Ilustración 6 fase de generador de codigo intermedio en la
compilacion obtenido de https://encrypted-tbn0.gstatic.com/images?
q=tbn:ANd9GcRxbf94bRAoke1WMWuOIxHyamNLCeIZrkKVBQ&usqp=CAU......10
Resumen

En esta investigación abordaremos el tema de la fase de generación de código


intermedio del proceso de compilación, en este mostramos las diferentes tipos de
notaciones con las cuales podemos representar las operaciones aritméticas y ver
cual nos conviene usar ya que algunas son más fáciles de leer para nosotros y
otras las puede interpretar mejor la computadora, así mismo mostramos las tipos
de representaciones de código intermedio como cuadruplos o triplos, o también el
código P que fue diseñado como código ensamblador pero también fue útil para
representar el código intermedio, concluimos mostrando las acciones y estrategias
básicas que tenemos que tomar en cuenta a la hora de generar nuestro código
intermedio en el subtema de esquema de generación
2.1 Notaciones
Las notaciones sirven de base para expresar sentencias bien definidas. El uso
más extendido de las notaciones sirve para expresar operaciones aritméticas. Las
expresiones aritméticas se pueden expresar de tres formas distintas: infija, prefija
y postfija. La diversidad de notaciones corresponde en que para algunos casos es
más sencillo un tipo de notación.

2.1.1 Prefija
También conocida como notación polaca, es aquella en la que el operador se
coloca delante de los operandos.
En esta notación no es necesaria la utilización de paréntesis u otros signos de
agrupación, la posición de los operadores y de los operandos va a determinar el
orden en que la operación se va a realizar
El orden es operador, primer operando, segundo operando.

Ilustración 1 Ejemplo de operacion en prefijo obtenido de


data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWgAAABxCAMAAADPlckAAAAAhFBMVEX///
8AAABVVVXMzMyLi4vT09P19fW+vr6ysrLu7u4FBQUNDQ38/
Pz4+PhgYGB4eHiCgoKqqqpERERMTExoaGhxcXEkJCQcHBwTExOZmZnDw8MrKyu2trYRERHY2Njl5eU1N
TW

2.1.2 Infija
Es la notación común de fórmulas aritméticas y lógicas, en la cual se escriben los
operadores entre los operandos en que están actuando. No es tan simple de
analizar por las computadoras, como la notación de prefijo o la notación de
postfijo, aunque muchos lenguajes de programación la utilizan debido a su
familiaridad.

En la notación de infijo, a diferencia de las notaciones de prefijo o posfijo, es


necesario rodear entre paréntesis a los grupos de operandos y operadores, para
indicar el orden en el cual deben ser realizadas las operaciones. En la ausencia de
paréntesis, ciertas reglas de prioridad determinan el orden de las operaciones 
El orden es primer operando,operador, segundo operando.

Ilustración 2 Ejemplo de operacion en infijo obtenido de


data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASQAAACtCAMAAAAu7/J6AAACc1BMVEX///
8AAAD/AAChoaH//81UKxnLy8u/v7+NWT0YAAD/6KT/4eHl5eV1dXX/kpL/6+sAABErVKDo////oKDG//8AAAf///
kjNHprvv//a2v/Xl7/sFX/c3OoqKj39/f/8vL/3/f/
2.1.3 Postfija
La notación postfija pone el operador al final de los dos operandos, La notación
postfija utiliza una estructura del tipo LIFO (Last First Out) pila, la cual es la más
utilizada para la implementación. Llamada también polaca inversa, se usa para
representar expresiones sin necesidad de paréntesis.
El orden es primer operando, segundo operando, operador .

Ilustración 3 Ejemplo de operacion en postfija obtenido de


data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWgAAABxCAMAAADPlckAAAAAe1BMVEX///
8AAABVVVXMzMxJSUn19fWysrLT09Pu7u6Li4sNDQ0FBQVgYGD7+/
tEREQzMzN4eHiCgoIdHR2ZmZk6Ojrl5eXd3d27u7urq6suLi6goKBlZWUWFhYbGxvDw8Pq6uokJC

2.2 Representaciones de código intermedio.

2.2.1 Notación Polaca


La notación polaca es la originada por un Autómata con pila, en la que los
operadores siempre preceden a los operandos sobre los que actúan, y que tiene la
ventaja de no necesitar paréntesis:

 Se utiliza principalmente para la representación de expresiones aritméticas.


 Expresión a notación polaca inversa.
 Algoritmo. Representa la expresión en forma de árbol sintáctico.
 Recorrer el árbol en postorden.

Ejemplo: a + b * c-d
Código a b c * + d-

Ventajas y desventajas de la notación polaca.


 Generación de código: simple, no utiliza registros.
 Optimización: es difícil de reordenar ya que hay que considerar el contenido
 de la pila.
 Interpretación rápida: es muy fácil de interpretar ya que solo necesita una
pila.
 Transportable: si, ya que todos los procesadores implementan una pila.

2.2.2 Código P

El código P comenzó como


un código ensamblador
objetivo estándar
producido por
varios compiladores Pascal
en la década de 1970 y
principios de la de 1980.
Fue diseñado
para código real para una
máquina de pila hipotética
la idea era hacer que los
compiladores
de Pascal se
transportaran fácilmente
requiriendo solo que se
volviera a escribir el
intérprete de la maquina P
para una plataforma, el
código P también a
probado ser útil
como código intermedio y
sean utilizado varias
extensiones y
modificaciones del mismo
en
diverso compiladores de
código nativo, la mayor
parte para lenguaje tipo
Pascal.
Como el código P fue
diseñado para ser
directamente ejecutable,
contiene una
descripción implícita de un
ambiente de ejecución
particular que incluye
tamaños de datos,
además de mucha
información específica para
la maquina P, que debe
conocer si se desea
que un programa de código
P se comprensible. La
máquina P está
compuesta por una
memoria de código, una
memoria de datos no
específica para variables
nombre das y una
pila para datos temporales,
junto como cualquiera
registro que sea necesario
para mantener
la pila y apoyar la
ejecución.
El código P comenzó como un código ensamblador objetivo estándar producido
por
varios compiladores Pascal en la década de 1970 y principios de la de 1980. Fue
diseñado para código real para una máquina de pila hipotética la idea era hacer
que los compiladores de pascal se transportaran fácilmente requiriendo solo que
se volviera a escribir el intérprete de la maquina P para una plataforma, el código
P también ha probado ser útil como código intermedio y sean utilizado varias
extensiones y modificaciones de este. en diversos compiladores de código nativo,
la mayor parte para lenguaje tipo Pascal.

Como el código P fue diseñado para ser directamente ejecutable, contiene una
descripción implícita de un ambiente de ejecución particular que incluye tamaños
de datos, además de mucha información específica para la maquina P, que debe
conocer si se desea que un programa de código P se comprensible. La máquina P
está compuesta por una memoria de código, una memoria de datos no específica
para variables nombre das y una pila para datos temporales, junto como
cualquiera registro que sea necesario para mantener
la pila y apoyar la ejecución.

2.2.3 Triplos
En la historia de los compiladores han sido utilizadas una amplia variedad de
representaciones intermedias como lo es la siguiente clase de representación de
código intermedio de un árbol de 3 direcciones, 2 para los operandos y una para la
ubicación del resultado. Esta clase incluye un amplio número de representaciones
diferentes entre las cuales encontramos cuádruplos y triples. La principal
diferencia entre estas notaciones y la notación postfija es que ellos incluyen
referencias explicitas para los resultados de los cálculos intermedios, mientras que
la notación posfija los resultados son implícitos al representarlos en una pila.

 La diferencia entre triples y cuádruplos es que con los triples es


referenciado el 1valor intermedio hacia el número del triple que lo creo, pero
en los cuádruplos requiere que ellos tengan nombres implícitos.
 Los triples tienen una ventaja obvia de ser más consistente, pero ellos
dependen de su posición, y hacen que la optimización presente cambios de
código mucho más compleja.
 Para evitar tener que introducir nombres temporales en la tabla de
símbolos, se hace referencia a un valor temporal según la posición de la
proposición que lo calcula. Las propias instrucciones representan el valor
del nombre temporal. La implementación se hace mediante registros de
solo tres campos (op, arg1,arg2).
 En la notación de tripletes se necesita menor espacio y el compilador no
necesita generar los nombres temporales. Sin embargo, en esta notación,
trasladar una proposición que defina un valor temporal exige que se
modifiquen todas las referencias a esa proposición

Ilustración 4 Ejemplo de triplo obtenido de https://slideplayer.es/slide/3401690/12/images/32/Generaci


%C3%B3n+de+c%C3%B3digo+intermedio.jpg

2.2.4 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.

Por ejemplo, la proposición de tres direcciones x = y + z se podría representar


mediante el cuádruplo (ADD, x,y, z). Las proposiciones con operadores unarios no
usan el arg2. Los campos que no se usan se dejan vacíos o un valor NULL. Como
se necesitan cuatro campos se le llama representación mediante cuádruplos.
Ilustración 5 Otro ejemplo de cuadruplo obtenido de
https://slideplayer.es/slide/3401690/12/images/32/Generaci%C3%B3n+de+c%C3%B3digo+intermedio.jpg

2.3 Esquema de generación.

os esquemas de
generación son las
estrategias o acciones que
se deberán realizarse
y tomarse en cuenta en el
momento de generar
código intermedio.
Los esquemas de
generación dependen de
cada lenguaje.
Tomaremos algunos
esquemas de generación
del lenguaje C.
os esquemas de
generación son las
estrategias o acciones que
se deberán realizarse
y tomarse en cuenta en el
momento de generar
código intermedio.
Los esquemas de
generación dependen de
cada lenguaje.
Tomaremos algunos
esquemas de generación
del lenguaje C.
os esquemas de
generación son las
estrategias o acciones que
se deberán realizarse
y tomarse en cuenta en el
momento de generar
código intermedio.
Los esquemas de
generación dependen de
cada lenguaje.
Tomaremos algunos
esquemas de generación
del lenguaje C.
os esquemas de
generación son las
estrategias o acciones que
se deberán realizarse
y tomarse en cuenta en el
momento de generar
código intermedio.
Los esquemas de
generación dependen de
cada lenguaje.
Tomaremos algunos
esquemas de generación
del lenguaje C.
os esquemas de
generación son las
estrategias o acciones que
se deberán realizarse
y tomarse en cuenta en el
momento de generar
código intermedio.
Los esquemas de
generación dependen de
cada lenguaje.
Tomaremos algunos
esquemas de generación
del lenguaje C.
Los esquemas de generación son las estrategias o acciones que se deberán
realizarse y tomarse en cuenta en el momento de generar código intermedio. Los
esquemas de generación dependen de cada lenguaje.

2.3.1 Variables y constantes.


Una constante es un dato numérico o alfanumérico que no cambia durante la
ejecución del programa.

 double pi = 3.1416
 int b = 2
 int suma = 23 + 34
 double GRAVEDAD = 9.8
Una variable es un espacio en la memoria de la computadora que permite
almacenar temporalmente un dato durante la ejecución de un proceso, su
contenido puede cambiar durante la ejecución del programa.

Las variables son: el radio, el área y la constate es pi


double area = pi * radio^2

2.3.2 Expresiones.
En esta función recibe una cadena que representa una línea de código intermedio
y toma las medidas oportunas para que ese código se utilice. Estas
medidas pueden se rescribir la línea en un fichero adecuado, almacenar la
instrucción en una lista que después se pasará a otros módulos, o cualquier otra
que necesitemos en nuestro compilador.

Expresiones aritméticas
Son aquella donde los operadores que intervienen en ella son numéricos, el
resultado es un número y los operadores son aritméticos. Los operadores
aritméticos más comúnmente utilizados son: +, - , * , / y %. Comenzamos el
estudio por las expresiones aritméticas. Lo que tendremos que haceres crear por
cada tipo de nodo un método que genere el código para calcular la expresión y lo
emita.

Ese código dejará el resultado en un registro, cuyo nombre devolverá el método


como resultado. Para reservar estos registros temporales, utilizaremos una
función, reserva. En principio bastar ‘a con que esta función devuelva un registro
distinto cada vez que se le llame. Cada nodo generará el código de la siguiente
manera:

 Por cada uno de sus operandos, llamara al método correspondiente para


que se evalúe la sub-expresión. Si es necesario, reservara un registro para
guardar su resultado.
 Emitirá las instrucciones necesarias para realizar el cálculo a partir de
los operandos.

2.3.3 Instrucción de asignación.


La instrucción de asignación consiste en delegar/asignar un resultado de una
evaluación de una expresión a una variable.
La sintaxis general de la instrucción de asignación es:

En donde de lado izquierdo tenemos el tipo de variable y su nombre, después el


signo igual para hacer crear la igualdad y del lado derecho el valor, puede ser una
constante, otra variable, una expresión, etc.

2.3.4 Instrucciones de control.


En los lenguajes de programación hay estructuras y operadores que permiten
controlar el flujo de la ejecución, estos pueden ser ciclos, saltos, condiciones entre
otros. Expresiones booleanas En los lenguajes de programación, las expresiones
booleanas tienen dos propósitos principales. Se utilizan para calcular valores
lógicos y como expresiones condicionales en proposiciones que alteran el flujo del
control, como las proposiciones if-else o do-while.

Las expresiones booleanas se componen de los operadores boleanos (and, or y


not) aplicados a los elementos que son variables booleanas o expresiones
relacionales.

Algunos lenguajes permiten expresiones más generales donde se pueden aplicar


operadores booleanos, aritméticos y relacionales a expresiones de cualquier tipo,
sin diferenciar valores booleanos de aritméticos; si es necesario se realiza una
coerción.

Saltos En el código de los saltos los operadores lógicos &&, y! son traducidos a
saltos, aunque estos no aparecen realmente en el código.

2.3.5 Funciones
Función del Lenguaje, entendemos que es el uso de la lengua que hace un
hablante. En simples palabras, las funciones del lenguaje son los diferentes
objetivos, propósitos y servicio que se le da al lenguaje al comunicarse, dándose
una función del lenguaje por cada factor que tiene éste, en donde la función que
prevalece es el factor en donde más se pone énfasis al comunicarse. Diversos
lingüistas (Karl Bühler, Román Jakobson, Michael Halliday...) han propuesto
distintas clasificaciones de las funciones del lenguaje: Bühler propuso que existían
únicamente tres funciones:

 La Representativa (por la cual se trasmiten informaciones objetivamente)


 La Expresiva o emotiva (que expresa sentimientos del emisor)
 La Conativa, mediante la que se influye en el receptor del mensaje a través
de órdenes, mandatos o sugerencias.

2.3.6 Estructuras
El código intermedio no es el lenguaje de programación de ninguna máquina real,
sino que corresponde a una máquina abstracta, que se debe de definir lo más
general posible, de forma que sea posible traducir este código intermedio a
cualquier máquina real. El objetivo del código intermedio es reducir el número de
programas necesarios para construir traductores, y permitir más fácilmente la
transportabilidad de unas máquinas a otras. Supóngase que se tienen n lenguajes,
y se desea construir traductores entre ellos. Sería necesario construir n*(n-1)
traductores. Sin embargo, si se construye un lenguaje intermedio, tan sólo son
necesarios2*n traductores. Así por ejemplo un fabricante de compiladores puede
construir un compilador para diferentes máquinas objeto con tan sólo cambiar las
dos últimas fases de la tarea de síntesis.
Aunque un programa fuente se puede traducir directa mente al lenguaje objeto,
algunas ventajas de utilizar una forma intermedia independiente de la máquina
son:

 Se facilita la redestinación: se puede crear un compilador para una máquina


distinta uniendo una etapa final para la nueva máquina a una etapa inicial
ya existente.
 Se puede aplicar a la representación intermedia un optimizador de código
independiente de la máquina.

Ilustración 6 Ilustración 6 fase de generador de codigo intermedio en la compilacion obtenido de


https://encrypted-tbn0.gstatic.com/images?
q=tbn:ANd9GcRxbf94bRAoke1WMWuOIxHyamNLCeIZrkKVBQ&usqp=CAU

Bibliografías

Lenguaje y Autómatas II. Unidad VI Generación de Código Intermedio. M.C.


Juan Carlos Olivares Rojas. pág. 1-36. Año 2010.

Universidad técnica de México Generación de código procesador de


lenguaje. Recuperado 04 de diciembre de 2021, de
http://dsc.itmorelia.edu.mx/~jcolivares/courses/ps207a/ps2_u6.pdf

José D. Triplos y cuádruplos. Recuperado 04 de diciembre de 2021, de


https://lenguajesdeprogramacion.net/assembler/

También podría gustarte