Está en la página 1de 5

PL. Generacin de cdigo 2 Csar Ignacio Garca Osorio. Universidad de Burgos.

Introduccin
En el modelo de anlisis y sntesis de un compilador, la etapa inicial traduce
un programa fuente a una representacin intermedia a partir de la cual la
etapa final genera el cdigo objeto. Los detalles del lenguaje objeto se
confinan en la etapa final, si esto es posible.
Al generar el cdigo intermedio facilito la independencia de la mquina,
adems es ms fcil la optimizacin del cdigo intermedio.
Los cdigos intermedios pueden ser:
rbol sintctico
Notacin postfija
Cdigo de 3 direcciones
Ejemplo: a:=b*-c+b*-c
a b c menosu * b c menosu * + asigna
asigna
a +
*
menosu b
c
*
menosu b
c
asigna
a +
*
menosu b
c
id
id
-
*
+
:=
1
2
3
4
5
6
7
8
1
4
6
3
4
5
alaentradaparab
alaentradaparac
1
id alaentradaparaa
asigna
id
+
*
menosu
alaentrada
paraa
id
alaentrada
parab
id
alaentrada
parac
PL. Generacin de cdigo 3 Csar Ignacio Garca Osorio. Universidad de Burgos.
Cdigo de tres direcciones (1)
Es una especie de cdigo mquina de la forma general:
x:=y op z
donde x, y y z son nombres, constantes o variables temporales
generadas por el compilador, op representan cualquier operador.
No se permite ninguna expresin aritmtica compuesta, pues slo
hay un operador en el lado derecho de una proposicin.
El uso de nombres para los valores intermedios calculados por un
programa permite que el cdigo de tres direcciones se reorganice
fcilmente a diferencia de la notacin postfija .
Es una representacin linealizadade un rbol sintctico o un GDA
en la que los nombres explcitos corresponden a los nodos
interiores del grafo.
Ejemplos t
1
:=-c t
1
:=-c
t
2
:=b*c t
2
:=b*t
1
t
3
:=-c t
5
:=t
2
+t
2
t
4
:=b*t
3
a:=t
5
t
5
:=t
2
+t
4
a:=t
5
Cdigo
para el
rbol
Cdigo
para el
GDA
PL. Generacin de cdigo 4 Csar Ignacio Garca Osorio. Universidad de Burgos.
Tipos de proposiciones de tres direcciones
1. Asignacin de operadores binarios:
x:=y op z
2. Asignacin de operadores unarios:
x:=op y
3. Proposiciones de copia:
x:=y
4. Salto incondicional:
goto E
5. Saltos condicionales:
if x oprel y goto E
6. Llamadas a procedimientos:
param x
call p, n
return y
Cdigo de tres direcciones (2)
PL. Generacin de cdigo 5 Csar Ignacio Garca Osorio. Universidad de Burgos.
7. Asignaciones con ndices:
x:=y[i]
x[i]:=y
8. Asignaciones de direcciones y apuntadores:
x:=&y
x:=*y
*x:=y
El conjunto de operadores debe ser lo bastante rico como para
implantar las operaciones del lenguaje fuente.
Aunque un conjunto de operadores pequeo es ms fcil de implantar,
un conjunto de instrucciones limitado puede obligar a la etapa inicial a
generar largas secuencias de proposiciones para algunas operaciones del
lenguaje fuente lo que obliga a trabajar ms al optimizador y al
generador de cdigo para producir buen cdigo.
Cdigo de tres direcciones (3)
PL. Generacin de cdigo 6 Csar Ignacio Garca Osorio. Universidad de Burgos.
D.D.S. para producir cdigo de tres direcciones
Cdigo de tres direcciones (4)
PRODUCCIN REGLAS SEMNTICAS
S id := E S.cdigo:=E.cdigo || gen(id.lugar ':=' E.lugar)
E E
1
+ E
2
E.lugar:=tempnuevo;
E.cdigo:=E
1
.cdigo||E
2
.cdigo||gen(E.lugar ':=' E
1
.lugar '+' E
2
.lugar)
E E
1
* E
2
/* similar al operador de suma de la regla anterior */
E - E
1
E.lugar:=tempnuevo;
E.cdigo:=E
1
.cdigo || gen(E.lugar ':=' 'menosu' E
1
.lugar)
E ( E
1
) E.lugar:=E
1
.lugar; E.cdigo:=E
1
.cdigo
E id E.lugar:=id.lugar; E.cdigo:=' '
S while E do S
1
S.comienzo:=etiqnueva;
S.despus:=etiqnueva;
S.cdigo:=gen(S.comienzo ':') || E.cdigo ||
gen('if' E.lugar '=' '0' 'goto' S.despues) ||
S
1
.cdigo || gen('goto' S.comienzo) ||
gen(S.despues ':')
PL. Generacin de cdigo 7 Csar Ignacio Garca Osorio. Universidad de Burgos.
Esquema de traduccin para producir cdigo de tres direcciones
Cdigo de tres direcciones (5)
S id:= E {emite(id.lugar ':=' E.lugar) }
E E
1
+E
2
{E.lugar:=tempnuevo; emite(E.lugar ':=' E
1
.lugar '+' E
2
.lugar) }
E E
1
*E
2
{E.lugar:=tempnuevo; emite(E.lugar ':=' E
1
.lugar '*' E
2
.lugar) }
E -E
1
{E.lugar:=tempnuevo; emite(E.lugar ':=' 'menosu' E
1
.lugar) }
E (E
1
) {E.lugar:=E
1
.lugar }
E id {E.lugar:=id.lugar }
S while {S.comienzo:=etiqnueva; S.despus:=etiqnueva; emite(S.comienzo ':') }
E do {emite('if' E.lugar '=' '0' 'goto' S.despues)}
S
1
{emite('goto' S.comienzo); emite(S.despues ':') }
S if {I.falso:=etiqnueva;}
E then {emite('if' E.lugar '=' '0' 'goto' I.falso); }
S
1
I
I endif {emite(I.falso ':') }
I else {I.despus:=etiqnueva; emite('goto' I.despus); emite(I.falso ':') }
S endif {emite(I.despus ':') }
PL. Generacin de cdigo 8 Csar Ignacio Garca Osorio. Universidad de Burgos.
Implantacin de proposiciones de tres direcciones
Cudruplos: Es una estructura tipo registro con cuatro campos, que se
llamarn op, arg1, arg2 y resultado. El campo op contiene un cdigo
interno para el operador. La proposicin de tres direcciones x:=y op z
se representan poniendo y en arg1, z en arg2 y x en resultado.
Los contenidos de los campos arg1, arg2 y resultado son generalmente
apuntadores a las entradas de la tabla de smbolos.
Ejemplo
Cdigo de tres direcciones (5)
op arg1 arg2 resultado
(0) menosu c t
1
(1) * b t
1
t
2
(2) menosu c t
3
(3) * b t
3
t
4
(4) + t
2
t
4
t
5
(5) := t
5
a
a:=b*-c+b*-c
PL. Generacin de cdigo 9 Csar Ignacio Garca Osorio. Universidad de Burgos.
Triples: Estructura tipo registro con slo tres campos: op, arg1 y arg2.
Para evitar introducir nombres temporales en la TS, se hace referencia a
un valor temporal segn la posicin de la proposicin que lo calcula.
Los campos arg1 y arg2 son apuntadores a la tabla de smbolos o
apuntadores dentro de la estructura de triple.
Ejemplos
Cdigo de tres direcciones (6)
op arg1 arg2
(0) menosu c
(1) * b (0)
(2) menosu c
(3) * b (2)
(4) + (1) (3)
(5) asigna a (4)
op arg1 arg2
(0) []= x i
(1) asigna (0) y
op arg1 arg2
(0) =[] y i
(1) asigna x (0)
a:=b*-c+b*-c
x[i]:=y
x:=y[i]
PL. Generacin de cdigo 10 Csar Ignacio Garca Osorio. Universidad de Burgos.
Cdigo de tres direcciones (7)
Triples indirectos: Se utiliza una lista de los apuntadores a triples, en
lugar de hacer una lista de los triples mismos.
Esta implantacin tiene la ventaja de que en un compilador optimizador
no sera necesario cambiar los triples (y por tanto el ndice mediante el
que son referenciados) sino nicamente el ndice en la matriz
proposicin.
Ejemplo
op arg1 arg2
(14) menosu c
(15) * b (14)
(16) menosu c
(17) * b (16)
(18) + (1) (17)
(19) := a (18)
proposicin
(0) (14)
(1) (15)
(2) (16)
(3) (17)
(4) (18)
(5) (19)
PL. Generacin de cdigo 11 Csar Ignacio Garca Osorio. Universidad de Burgos.
Declaraciones (1)
Clculo de los tipos y direcciones relativas de nombres declarados
P M D
M { desplazamiento:=0 }
D D
1
; D
2
D id : T { introduce(id.nombre, T.tipo, desplazamiento);
desplazamiento :=desplazamiento +T.ancho }
T integer { T.tipo:=integer; T.ancho:=4 }
T real { T.tipo:=real; T.ancho:=8 }
T array [ nm ] of T
1
{ T.tipo:=array(nm.val, T
1
.tipo);T.ancho:=nm.valT
1
.ancho }
T ^T
1
{ T.tipo:=pointer(T
1
.tipo); T.ancho:=4}
introduce(nombre, tipo, desplazamiento) crea una entrada en la TS para nombre, le
da el tipo tipo y la direccin relativa desplazamiento en su rea de datos.
El atributo tipo representa una expresin de tipos construida a partir de los tipos
bsicos integer y real aplicando los constructores de tipos pointer y array. Si las
expresiones de tipos se representan por medio de grafos, entonces el atributo tipo
puede ser un apuntador al nodo que representa una expresin de tipo.
PL. Generacin de cdigo 12 Csar Ignacio Garca Osorio. Universidad de Burgos.
Declaraciones (2)
Proceso de declaraciones en procedimientos anidados
P M D { aadeancho(tope(tblpn), tope(desplazamiento));
saca(tblapn); saca(desplazamiento) }
M { t:=creatabla(nil); mete(t, tblapn); mete(0, desplazamiento) }
D D
1
; D
2
D proc id ; N D
1
; S { t:=tope(tblapn);
aadeancho(t, tope(desplazamiento));
saca(tblapn); saca(desplazamiento);
introduceproc(tope(tblapn), id.nombre, t); }
D id : T { introduce(tope(tblapn), id.nombre, T.tipo, tope(desplazamiento));
tope(desplazamiento):=tope(desplazamiento) +T.ancho }
N { t:=creatabla(tope(tblapn));
mete(t, tblapn); mete(0, desplazamiento) }
T record L D end { T.tipo:=record(tope(tblapn)); T.ancho:=tope(desplazamiento));
saca(tblapn); saca(desplazamiento) }
L { t:=creatabla(tope(tblapn));
mete(t, tblapn); mete(0, desplazamiento) }
PL. Generacin de cdigo 13 Csar Ignacio Garca Osorio. Universidad de Burgos.
Proposiciones de asignacin (1)
Esquema de traduccin para producir cd. de 3 direcciones para las asignaciones
S id := E { p:=busca(id.nombre);
if pnil then
emite(p ':=' E.lugar)
else error }
E E
1
+ E
2
{ E.lugar:=tempnuevo;
emite(E.lugar ':=' E
1
.lugar '+' E
2
.lugar) }
E E
1
* E
2
{ E.lugar:=tempnuevo;
emite(E.lugar ':=' E
1
.lugar '*' E
2
.lugar) }
E - E
1
{ E.lugar:=tempnuevo;
emite(E.lugar ':=' 'menosu' E
1
.lugar) }
E ( E
1
) { E.lugar:=E
1
.lugar }
E id { p:=busca(id.nombre);
if pnil then
E.lugar:=p
else error }
PL. Generacin de cdigo 14 Csar Ignacio Garca Osorio. Universidad de Burgos.
Proposiciones de asignacin (2)
Acceso a elementos de matrices
Almacenamiento en memoria de
una matriz A de dimensiones
(n
1
=2)(n
2
=3)(n
3
=4)
A[inf
1
, inf
2
, inf
3
+3]
A[inf
1
, inf
2
+2, *]
A[inf
1
+1,*,*]
base
base+ n
3
a
base+n
3
n
2
a
La posicin del elemento A[i
1
,i
2
,i
3
] en esta matriz
viene dada por la frmula:
base+(n
3
n
2
(i
1
inf
1
)+n
3
(i
2
inf
2
) +(i
3
inf
3
))a
Factorizando queda:
base+(i
3
inf
3
+n
3
(i
2
inf
2
+n
2
(i
1
inf
1
)))a
Separando los elementos que dependen
exclusivamente de la estructura de la matriz:
[base(inf
3
+n
3
(inf
2
+n
2
inf
1
)))a]+(i
3
+n
3
(i
2
+n
2
i
1
)))a
Esta frmula se puede generalizar a una matriz de k
dimensiones n
1
n
2
... n
k
con n
m
=sup
m
inf
m
+1 para
la que los elementos que dependen de los ndices se
pueden calcular utilizando la recurrencia:
e
1
=i
1
e
m
=i
m
+n
m
e
m-1
PL. Generacin de cdigo 15 Csar Ignacio Garca Osorio. Universidad de Burgos.
Proposiciones de asignacin (3)
Esquema de traduccin para acceder a elementos de matrices
SL:=E { if L.desplazamiento=null then emite(L.lugar ':=' E.lugar);
else emite(L.lugar '[ ' L.desplazamiento ']' ':=' E.lugar); }
EE
1
+E
2
{ E.lugar:=tempnuevo; emite(E.lugar ':=' E
1
.lugar '+' E
2
.lugar) }
E(E
1
) { E.lugar:=E
1
.lugar }
EL { if L.desplazamiento=null then E.lugar:=L.lugar
else begin E.lugar:=tempnuevo;
emite(E.lugar ':=' L.lugar '[ ' L.desplazamiento ']');
end}
LlistaE] { L.lugar:=tempnuevo; L.desplazamiento:=tempnuevo;
emite(L.lugar ':=' c(listaE.matriz));
emite(L.desplazamiento ':=' listaE.lugar '*' ancho(listaE.matriz)); }
Lid { L.lugar:=id.lugar; L.desplazamiento:=null }
listaElistaE
1
,E { t:=tempnuevo; m:=listaE
1
.ndim+1 ;
emite(t ':=' lmite(listaE
1
.matriz,m) '*' listaE
1
.lugar);
emite(t ':=' E.lugar '+' t);
listaE.matriz:=listaE
1
.matriz; listaE.lugar:=t; listaE.ndim:=m }
listaEid[E { listaE.matriz:=id.lugar; listaE.lugar:=E.lugar; listaE.ndim:=1 }
PL. Generacin de cdigo 16 Csar Ignacio Garca Osorio. Universidad de Burgos.
Conversin de tipo dentro de asignaciones
En la prctica, hay muchos tipos diferentes de variables y constantes, as que el
compilador debe rechazar algunas operaciones de tipos mixtos o bien generar las
instrucciones de coercin (conversin de tipos) apropiadas.
Por ejemplo, para la produccin EE
1
+E
2
se podra tener la siguiente accin semntica.
Proposiciones de asignacin (4)
E.lugar:=tempnuevo
if E
1
.tipo=integer and E
1
.tipo=integer then begin
emite(E.lugar ':=' E
1
.lugar '+ent' E
2
.lugar); E.tipo=integer
end else if E
1
.tipo=real and E
2
.tipo=real then begin
emite(E.lugar ':=' E
1
.lugar '+real' E
2
.lugar); E.tipo=real
end else if E
1
.tipo=integer and E
2
.tipo=real then begin
u:=tempnuevo; emite(u ':=' 'entareal' E
1
.lugar);
emite(E.lugar ':=' u '+real' E
2
.lugar); E.tipo=real
end else if E
1
.tipo=real and E
2
.tipo=integer then begin
u:=tempnuevo; emite(u ':=' 'entareal' E
2
.lugar);
emite(E.lugar ':=' E
1
.lugar '+real' u); E.tipo=real
end else E.tipo=error_tipo;
PL. Generacin de cdigo 17 Csar Ignacio Garca Osorio. Universidad de Burgos.
Expresiones booleanas
Esq. traduc. utilizando una representacin numrica para los valores booleanos
E E
1
or E
2
{ E.lugar:=tempnuevo;
emite(E.lugar ':=' E
1
.lugar 'or' E
2
.lugar) }
E E
1
and E
2
{ E.lugar:=tempnuevo;
emite(E.lugar ':=' E
1
.lugar 'and' E
2
.lugar) }
E not E
1
{ E.lugar:=tempnuevo;
emite(E.lugar ':=' 'not' E
1
.lugar) }
E ( E
1
) { E.lugar:=E
1
.lugar }
E id
1
oprel id
2
{ E.lugar:=tempnuevo; despus:=etiqnueva; cierto:=etiqnueva;
emite('if' id
1
.lugar oprel.op id
2
.lugar 'goto' cierto);
emite(E.lugar ':=' '0'); emite('goto' despus);
emite(cierto ':'); emite(E.lugar ':=' '1');
emite(despus ':');
}
E true { E.lugar:=tempnuevo; emite(E.lugar ':=' '1'); }
E false { E.lugar:=tempnuevo; emite(E.lugar ':=' '0'); }