Está en la página 1de 61

Leccin 5: Generacin De Cdigo

1.! 2.! 3.! 4.! 5.! 6.! Introduccin Tipos de Cdigo Intermedio Declaraciones Expresiones y Asignacin Estructuras de Control Procedimientos y Funciones

Lecturas: Scott, captulo 9 Muchnick, captulos 4, 6 Aho, captulo 8 Fischer, captulos 10, 11 , 12 , 13, 14 Holub, captulo 6 Bennett, captulo 4, 10
12048 - J. Neira 1

1/6. Introduccin
! Cdigo intermedio: interfaz entre front-ends y back-ends ! Se busca:
! transportabilidad ! posibilidades de optimizacin

! Debe ser:
! abstracto ! sencillo

! No se tiene en cuenta:
! modos de direccionamiento ! tamaos de datos ! existencia de registros ! eficiencia de cada operacin

por qu no generar el cdigo final directamente?


12048 - J. Neira 2

Cdigo Intermedio
! Ventajas:
! Permite abstraer la mquina, separar operaciones de alto nivel de su implementacin a bajo nivel. ! Permite la reutilizacin de los front-ends y backends. ! Permite optimizaciones generales.

! Desventajas:
! Implica una pasada ms para el compilador (no se puede utilizar el modelo de una pasada, conceptualmente simple). ! Dificulta llevar a cabo optimizaciones especficas de la arquitectura destino. ! Suele ser ortogonal a la mquina destino, la traduccin a una arquitectura especfica ser ms larga e ineficiente.
3

12048 - J. Neira -

2/6. Tipos de Cdigo Intermedio


! AST (Abstract Syntax Trees): forma condensada de rboles de anlisis, con slo nodos semnticos y sin nodos para smbolos terminales (se supone que el programa es sintcticamente correcto). Arbol de anlisis:
E T P opad + P T opmul P * id(C) id(A)

! Ventajas: unificacin de pasos de compilacin


! Creacin del rbol y la tabla de smbolos ! Anlisis semntico ! Optimizacin ! Generacin de cdigo objeto

! Desventaja:
! espacio para almacenamiento

AST:
E + id(B) T * id(C)
4

id(A) id(B)
12048 - J. Neira -

ASTs
program gcd(input, output); var i,j : integer; begin read(i,j); while i <> j do if i > j then i := i j else j := j i; writeln(i); end.

12048 - J. Neira -

Tipos de Cdigo Intermedio


! DAG (Directed Acyclic Graphs): rboles sintcticos concisos

rbol sintctico:
E

DAG:
E +

T id(B) * id(C)

T id(B) * id(C)

id(B) * id(C)

! Ahorran algo de espacio ! Resaltan operaciones duplicadas en el cdigo ! Difciles de construir


12048 - J. Neira 6

Tipos de Cdigo Intermedio


! TAC (Three-Address Code): secuencia de instrucciones de la forma:
dir 1 dir 2 dir 3

resultado := operando1 op operando2

! Las operaciones ms complejas requieren varias instrucciones: ! Este desenrollado facilita la optimizacin y generacin de cdigo final.
(a + b) x (c (d / e))

! operador: aritmtico / lgico ! operandos/resultado: constantes, nombres, temporales.

! Se corresponde con instrucciones del tipo: a := b + c


12048 - J. Neira 7

TAC
! Ensamblador general y simplificado para una mquina virtual: incluye etiquetas, instrucciones de flujo de control ! Incluye referencias explcitas a las direcciones de los resultados intermedios (se les da nombre). ! La utilizacin de nombres permite la reorganizacin (hasta cierto punto). ! Algunos compiladores generan este cdigo como cdigo final; se puede interpretar fcilmente (UCSD PCODE, Java). ! Operadores:
CI muchos pocos corto largo generacin optimizacin compleja sencilla compleja sencilla

12048 - J. Neira -

TAC ! Variaciones sintcticas: (Aho) (Fischer)


(READI, A) (READI, B) (GT, A, B, t1) (JUMP0, t1, L1) (ADDI, A, 5, C) (JUMP, L2) (LABEL, L1) (ADDI, B, 5, C) (LABEL, L2) (SUBI,C, 1, t2) (MULTI, 2, t2, t3) (WRITEI, t3)
12048 - J. Neira -

1. Asignacin: x := y op z x := op y x := y x[i] := y x := y[i] x := &y x := *y *x := y 2. Saltos: goto L if x oprel y goto L 3. Procedimientos: param x1 ... param xn call p, n
9

Representaciones de TAC
Fuente: a := b * c + b * d; ! Cudruplas: el destino suele ser una temporal. (*, b, c, t1) (*, b, d, t2) (+, t1, t2, a) ! Tripletas: slo se representan los operandos (1) (2) (3) (4) (*, b, c) (*, b, d) (+, (1), (2)) (:=, (3), a) ! Supuesta ventaja: es ms concisa. Falso: estadsticamente se requieren ms instrucciones.

! Desventaja: el cdigo generado es dependiente de la posicin. Cierto: la dependencia posicional dificulta la optimizacin.
10

12048 - J. Neira -

Representaciones de TAC
! Tripletas Indirectas: + vector que indica el orden de ejecucin de las instrucciones.
a := (b * c + b * d) * b * c; 1 2 3 4 5 6 b * c b * d b * c (1) + (2) (4) * (3) a := (5); 2 1 3 4 5 6 b * d b * c b * c (1) + (2) (4) * (3) a := (5); 1 2 3 4 5 b * c b * d (1) + (2) (3) * (1) a := (4);

Reorganizar es eficiente
12048 - J. Neira -

Se puede compartir espacio


11

RTL: register transfer language


d = (a + b) * c;

12048 - J. Neira -

12

Notacin posfija
! Polaca inversa, cdigo de cero direcciones:
! notacin matemtica libre de parntesis ! los operadores aparecen despus de los operandos

Expresiones: 1. E tomo ! E 2. E1 op E2 ! E1 E2 op 3. (E) ! E Asignacin: id := E ! @id E asg


12048 - J. Neira -

a := b * c + b * c @a b c mult b c mult add asg


13

Notacin Postfija
! Ventajas:
! Cdigo generado conciso. ! No hacen falta temporales. ! Algunas optimizaciones sencillas. ! Mantiene la estructura a sintctica.

! Desventajas:
! Cdigo dependiente de la posicin. ! solo efectiva si el target es de pila.

:= b * c + b * c

@a b c mult dup add asg a + b * c


E + T id(A) * id(C) id(B)
12048 - J. Neira -

(a + b) * c a b add c mult 14

a b c mult add

E T *id(C)

+ id(B) id(A)

Generacin de cdigo intermedio


! Consideracin fundamental: generacin de cdigo correcto. a := b * c ; Direccin de A. INEFICIENCIA SRF 0 5 INEFICIENCIA EN TIEMPO: ; Acceso a B. EN ESPACIO: SRF 0 4 hay alguna forma est b * c DRF menos costosa de calculado ; Acceso a C. hacer la en algn sitio? multiplicacin? SRF 0 3 DRF TMS ; Asignacin. ASG ! Sin hacerse estas preguntas, es razonablemente sencillo.
12048 - J. Neira 15

3/6. Procesamiento de declaraciones


Esencialmente se trata de completar la tabla de smbolos ! no se genera cdigo (hay excepciones). ! se limita a resolver problemas relacionados con almacenamiento de los objetos:
! Espacio requerido ! Lugar en la memoria ! Valor

! Declaracin de variables:
int sig, nivel = 0; void abrir_bloque() { ... sig = INICIAL; ++nivel; } void cerrar_bloque() { ... nivel--; } void crear_var (char *nom, int tipo) { ..... simbolo->dir = sig; switch (tipo) { case ENTERO : sig += 2; break; case REAL : sig += 4; break; .... } } Al final, sig indica el tamao del bloque de activacin. 16

! hay informacin explcita e implcita en el fuente.


12048 - J. Neira -

Ejemplo
Programa p; entero i, j, m; 3 4 5 accion dato (ref entero d); Principio 3 Fin 3 4 5 accion mcd(Val entero a, b; ref entero m); entero r; 6 Principio Fin Principio Fin
12048 - J. Neira 17

Declaracin de Variables
! Y si se permite mezclar declaraciones de variables y procedimientos? ! C: este problema no existe. ! Pascal: muchos compiladores lo prohben. Posible solucin:
int sig[MAXANID], nivel = 0; void abrir_bloque () {... sig[++nivel] = INICIAL;} void cerrar_bloque () { ... nivel--;} void crear_var (char *nom, int tipo) { .... simbolo->dir = sig[nivel]; ... } 18

procedure P; i.dir = 0 var i,j,k : integer;j.dir = 2 procedure Q; var l,m : integer; begin .... end; var n : integer;
n.dir = 4 (igual que k!)

! k.dir = 4 l.dir = 0 m.dir = 2

! Y si necesitas mantener informacin sobre el tamao de cada bloque?


12048 - J. Neira -

Inicializadores, C:
! extern y static:
! Valor inicial por defecto: 0. ! Admiten slo valores constantes. ! El inicializador se ejecuta una sola vez. #include <stdio.h> /* legal? */ int i = 1, /* legal? */ j = i + 1, /* legal? */ m = 34 + 1, f(), /* legal? */ k = f(), /* legal? */ l; /* legal? */ extern int n = 0;
12048 - J. Neira -

! auto y struct:
! Valor inicial por defecto: ninguno. ! Admiten valores no constantes. ! Se ejecutan c/vez que se activa el bloque. int f() { /* legal? int i = 1, /* legal? j = i + 1, g(), /* legal? k = g(i), /* legal? n = f(), l; */ */ */ */

/* legal? */ static int m = 1; .....


19

Esquema general, secuencial


%union {... char *cadena;... } ... programa p; ... principio ... fin programa: tPROGRAMA tIDENTIFICADOR ';' { inicio_generacion_codigo (); $<cadena>$ = nueva_etiqueta (); generar (ENP, $<cadena>$); } declaracion_variables declaracion_acciones { comentario (sprintf(msg, "Comienzo de %s", $2.nombre)); etiqueta($<cadena>4); } bloque_instrucciones { comentario (sprintf(msg, "Fin de %s", $2.nombre)); generar (LVP); fin_generacion_codigo(); }
20

ENP L0 ... ; Comienzo de p L0: ... ; Fin de p LVP

12048 - J. Neira -

Esquema general, AST


%union {... LISTA cod; } ... %type <cod> bloque_instrucciones %type <cod> declaracion_acciones programa p; ... principio ... fin programa: tPROGRAMA tIDENTIFICADOR ';' declaracion_variables declaracion_acciones bloque_instrucciones { char *lenp = newlabel(), msg[100]; $$ = code (ENP, lenp); concatenar (&($$), $5); sprintf(msg, "Comienzo de %s,...); comment (&($$), msg); label(&($$), lenp); concatenar (&($$), $6); sprintf(msg, "Fin de %s",...); comment (&($$), msg); emit (&($$), LVP); dumpcode ($$, fich_sal);
21

ENP L0 ... ; Comienzo de p L0: ... ; Fin de p LVP }


12048 - J. Neira -

4/6. Expresiones y Asignacin


x[i, j] := a*b + c*d - e*f + 10; ! De los operandos:
! Determinar su localizacin ! Efectuar conversiones implcitas

! Instrucciones generadas
! Acceso a datos ! Variables simples ! Registros ! Vectores ! Manipulacin de datos ! Conversiones ! Operaciones ! Flujo de control ! Validacin de subrangos ! Operadores complejos
22

! De los operadores:
! Respetar su precedencia ! Respetar su asociatividad ! Respetar orden de evaluacin (si definido) ! Determinar interpretacin correcta (si sobrecargado)
12048 - J. Neira -

Algunas dificultades
! Orden de evaluacin de los operandos:
push(pop() - pop()); Implementa correctamente SBT? Es relevante en el caso de PLUS?

! Mtodo de evaluacin de los operadores:


push (pop() and pop()); Implementa AND correctamente en PASCAL?

a[i] = i++;
el valor del subndice es el anterior o actual valor de i? push (pop() && pop()); Implementa AND correctamente en C?

FRAMES[pop()] = pop();
Corresponde a ASG o ASGI? En C, ni la suma ni la asignacin tienen predefinido un orden de evaluacin.
12048 - J. Neira -

En C, el operador && se evala por corto circuito y por lo tanto de izquierda a derecha.
23

Operandos: acceso a nombres (sec)


! La informacin esencial debe obtenerse de la tabla de smbolos. factor :
constante : TTRUE { generar (STC, } | TFALSE { generar (STC, } | TENTERO { generar (STC, } | TCARACTER { generar (STC, } ;
12048 - J. Neira -

1);

0);

$1);

$1); ;

TIDENT { generar (SRF, ?, ?); generar (DRF); /* parametro? */ } | TIDENT { generar (SRF, ?, ?); /* parametro? */ } '[' expresion ']' { /* ?tamano? */ generar (DRF); } | TIDENT '(' args ')' { generar (OSF, ?, ?, ?); } .....
24

Operandos: acceso a nombres (AST)


! La informacin esencial debe obtenerse de la tabla de smbolos. factor :
constante : TTRUE { $$.cod = code } | TFALSE { $$.cod = code } | TENTERO { $$.cod = code } | TCARACTER { $$.cod = code } ;
12048 - J. Neira -

TIDENT { $$.cod = code (SRF,?,?); emit (&($$.cod), DRF); (STC, 1); /* parametro? */ } | TIDENT '[' expresion ']' { $$.cod = code (SRF, ?, ?); (STC, 0); /* parametro? */ concatenar (&($$.cod), $3.cod); /* ?tamano? */ (STC, $1); emit (&($$), (DRF); } | TIDENT '(' args ')' { $$.cod = $3; (STC, $1); emit (&($$.cod),OSF,?,?,?); } ..... ;
25

Vectores
! Componentes almacenadas de forma contigua
V[1] V[2] V[3] V[4] V[5]

! Vectores de dimensin definida en compilacin, desplazamiento de V[i]: (i lim_inf) x tamao

! En C: i x tamao ! se reduce a aritmtica de punteros: v[i] es equivalente a *(v + i)

12048 - J. Neira -

26

Procesamiento de Vectores
! Dada var v : array[4..8] of integer;
v[<expresin1>] := <expresin2>; ; n y o dependen de la declaracin SRF n o ; cdigo para expresin1 ... ; lmite inferior STC 4 SBT ; tamao (en este caso sobra) STC 1 TMS PLUS ; cdigo para expresin2 ... ASG
12048 - J. Neira -

o sea que el lmite superior no sirve?

27

Procesamiento de Vectores
! Dada var v : array[-3..5] of boolean;
if v[<expresin>] then ...; ; n y o dependen de la declaracin SRF n o ; cdigo para expresin ... ?? qu hacer aqu? ?? STC -3 GTE JMF ... ; procedimiento de error STC 5 LTE JMF ... ; procedimiento de error ; lmite inferior STC -3 SBT ; tamao STC 1 TMS PLUS DRF JMF ... 12048 - J. Neira -

28

Matrices contiguas por filas, v1


entero v[2..5,3..7,1..8]; .... v[2,3,1] := ...; v[5,7,8] := ...; direccin? v[3,4,5] := ...;

0 159 4 5 8
12048 - J. Neira -

40 8 1

52

105 264 157

105 105 105


29

Formulacin alternativa, v2

entero v[2..5,3..7,1..8]; .... v[2,3,1] := ...; v[5,7,8] := ...; direccin? v[3,4,5] := ...; 2 13 105 0 5 32 264 159 3 19 157 52
30

105

4 5 8
12048 - J. Neira -

Matrices: generacin de cdigo, v2


factor : TIDENT { int nivel = ..., /* nivel sint. */ int offset = ....; /* dir en BA */ } '[' lista_indices '] { int t = ...; /* Tamao elems */ int c = ...; /* Parte constante */ generar generar generar generar generar generar (STC, c); (SBT); (STC, t); (TMS); (PLUS); (DRF); generar (SRF, nivel, offset); /* par x ref? */

cn

dn addr
; }

12048 - J. Neira -

31

Matrices: generacin de cdigo, v2


%union { ..... int i; ..... } %type <i> lista_indices %% lista_indices: expresion e1 { $$ = 1; c1 = e1 } | lista_indices ',' ci-1 { int s_i, i;

ci-1 si ci = ci-1 si + ei
;
12048 - J. Neira -

} expresion ei { generar (PLUS); $$ = $1 + 1; }

i = $1 + 1; s_i = ..., generar (STC, s_i); si generar (TMS);

32

y porqu no...?
{% int i; %} %% lista_indices: expresion e1 { c1 = e1 i = 1; } | lista_indices ',' ci-1 { int s_i, i; i = i + 1; s_i = ..., generar (STC, s_i); si generar (TMS); ci-1 si } expresion e i { ci = ci-1 si + ei generar (PLUS); } ; entero v[1..10], w[1..3, 1..4, 1..5, 1..6]; .... w[v[1], v[2], v[3], v[4]] := ...;
12048 - J. Neira 33

Ejemplo: para
; v ; e_1 ; m_1 ; e_2 ; m_2 ; e_3 ; m_3 ; fin ; c SRF n o v1 STC 3 STC 40 TMS PLUS STC 4 STC 8 TMS PLUS STC 5 STC 1 TMS PLUS de los indices STC 105 SBT

v[3,4,5]

; v ; e_1 ; s_ 2 ; e_2 ; s_3 ; e_3 ; fin ; c

SRF n o v2 STC 3 STC 5 TMS STC 4 PLUS STC 8 TMS STC 5 PLUS de los indices STC 105 SBT PLUS

cul es ms eficiente?
34

12048 - J. Neira -

Operadores
! Algoritmo recursivo: comenzando en la raz del rbol sintctico:
a*b + c*d - e*f + 10
+ + * 10

Para un operador n-ario:

1.! Generar cdigo para evaluar los operandos 1..n, almacenando los resultados en localizaciones temporales-

2.! Generar cdigo para eva* e f * luar el operador, utilizando los operandos almacenaa b c d dos en las n localizaciones temporales y almacenando a b * c d * + e f * - 10 + el resultado en otra localizacin temporal.
12048 - J. Neira 35

Operadores Aritmticos (sec)


%union { ... int instr; ... } %type <instr> op_ad op_mul %% expr_simple : termino | '+' termino | '-' termino { generar (NGI); } | expr_simple op_ad termino { generar ($2); } ; op_ad : '+' { $$ = PLUS; } | '-' { $$ = SBT; } ; termino : factor | termino op_mul factor { generar ($2); } ; op_mul : '*' { $$ = TMS; } | TDIV { $$ = DIV; } | TMOD { $$ = MOD; } ; Los operadores lgicos se tratan de forma similar, excepto.... 12048 - J. Neira -

36

Corto circuito: or else


! Implica operaciones de control de flujo: A or else B ! if A then true else B A JMF F STC 1 JMP Fin F: B Fin:
A v v f f B v f v f Instr. a+3 a+3 a+b a+b +1 +1
37

A JMT T B JMP Fin T: STC 1 Fin:


A v v f f B v f v f Instr. a+2 a+2 a+b a+b +2 +2
12048 - J. Neira -

Corto circuito: and then


A and then B ! if A then B else false A JMT T STC 0 JMP Fin T: B Fin:
f f A B Instr. v v v f f v f f

A JMF F B JMP Fin F: STC 0 Fin:


A B Instr. v v v f f v

12048 - J. Neira -

38

Siguiente problema....
! qu hacer con los resultados intermedios?
a*1b +1 c*2d - e*3f +2 10 + + * a b c * e d * f 10

! Mquinas de pila:
;variable A SRF 0 3 DRF ;variable B SRF 0 4 DRF ;*1: A * B TMS ;variable C SRF 0 5 DRF ;variable D SRF 0 6 DRF ;*2:C * D TMS ;+1:(A*B)+(C*D) PLUS ;variable E SRF 0 7 DRF ;variable F SRF 0 8 DRF ;*3:E * F TMS ;-:((A*B)+(C*D))-(E*F) SBT STC 10 ;+2:(((A*B)+(C*D))-(E*F))+10 PLUS 39

Depende del tipo de cdigo intermedio


12048 - J. Neira -

TAC: Variables temporales


! Se supone disponible una cantidad ilimitada de variables a*1b +1 c*2d - e*3f +2 10

t0 t1 t2 t3 t4 t5

:= := := := := :=

A * B; C * D; t0 + t1; E * F; t2 - t3; t4 + 10;

register allocation problem ! Al traducir este cdigo intermedio para una arquitectura destino, se utilizarn registros en lo posible, de lo contrario posiciones de memoria.
12048 - J. Neira 40

Cdigo de tres direcciones


! Se utiliza un generador de nombres temporales:
char *newtemp () { static int c = 0; char *m = malloc (5); } sprintf (m, "t%d", c++); return m;

! Las expresiones tienen como atributo el nombre de la variable en la que quedan almacenadas.
%{ extern char *newtemp(); %} %union {...char *place;...} %type <place> TIDENT expresion %type <place> expresion_simple termino factor
12048 - J. Neira 41

Cdigo de tres direcciones


expresion : simple { strcpy ($$, $1); } ; simple : termino { strcpy ($$, $1); } | '+' termino { strcpy ($$, $2);} | '-' termino { strcpy ($$, newtemp()); tac ("%s := -%s;\n",$$, $2); } | simple '+' termino { strcpy ($$, newtemp()); tac("%s := %s + %s;\n",$$, $1, $3); } | simple '-' termino { strcpy ($$, newtemp()); tac("%s := %s - %s;\n",$$, $1, $3); } ; factor : TIDENT { strcpy ($$, $1); } | '(' expresion ') { strcpy ($$, $2); } | TENTERO { sprintf ($$, "%d", $1);} ;
12048 - J. Neira 42

Reutilizacin de temporales
! Una vez que una variable temporal aparece como operando, deja de utilizarse. t0 t1 t2 t3 t4 t5 t0 t1 t0 t1 t0 t0 := := := := := := := := := := := := A * B; C * D; t0 + t1; E * F; t2 - t3; t4 + 10; A * B; C * D; t0 + t1; E * F; t0 - t1; t0 + 10; ! Al traducir el cdigo intermedio, en lo posible se utilizarn registros (habr una cantidad limitada); de lo contrario, posiciones de memoria. ! Reduccin de temporales requeridas: 1.! c = 0 0 1 2 1 2 1 1 2.! Para generar un nuevo nombre temporal, utilizar tc, e incrementar c en 1. 3.! Cuando aparezca un nombre temporal como operando, decrementar c en 1. 43

12048 - J. Neira -

5/6. Estructuras de Control


! Sin consideraciones de eficiencia, la generacin de cdigo es relativamente sencilla: INSTR: ! Ejemplo 1: repetir
<instr> hasta <exp> ; <instr> ; <exp> JMF INSTR

repetir: tREPETIR { $<instr>$ = nueva_etiqueta(); etiqueta ($<instr>$); } lista_instrucciones tHASTA_QUE expresion { generar (JMF, $<instr>2); } ;
12048 - J. Neira 44

Seleccin (sec)
si <exp> ent <instr1> si_no <instr2> fsi seleccion: tSI expresion { $<sino>$ = nueva_etiqueta(); generar (JMF, $<sino>$); } tENT lista_instrucciones { $<fin>$ = nueva_etiqueta(); generar (JMP,$<fin>$); etiqueta ($<sino>3); } resto_seleccion tFSI { etiqueta($<fin>6); } ; resto_seleccion: | tSI_NO lista_instrucciones ;
45

; <exp> JMF SINO ; <instr1> JMP FIN SINO: ; <instr2> FIN:


12048 - J. Neira -

Optimalidad
! La generacin de cdigo puede no ser ptima:
; exp SRF n o DRF STC 1 EQ JMF L0 ; l1 SRF n o SRF n o DRF STC 1 PLUS ASG JMP L1 L0: L1:
46

si i = 1 ent i := i + 1; fsi

12048 - J. Neira -

Seleccin (AST)
; <exp> JMF SINO ; <instr1> JMP FIN SINO: ; <instr2> FIN:

seleccion: tSI expresion tENT lista_instrucciones resto_seleccion tFSI { char *lsino = newlabel(), *lfin = newlabel(); $$ = $2.cod; emit (&($$), JMF, lsino); concatenar (&($$), $4); if (longitud_lista($5)) { emit (&($$), JMP, lfin); label (&($$), lsino); concatenar (&($$), $5); label (&($$), lfin); } else label (&($$), lsino);

; <exp> JMF SINO ; <instr1> SINO:

12048 - J. Neira -

} ; resto_seleccion: { $$ = newcode();} | tSI_NO lista_instrucciones 47 { $$ = $2};

Seleccin mltiple
; caso ; exp ; exp1 EQ JMF EXP2 ; instr1 JMP FIN EXP2: ... EXPn: ; expn EQ JMF DLC ; instrn JMP FIN DLC: ; dlc ; instr FIN:
48

caso <exp> <exp1> : <instr1> ; ... <expn> : <instrn> ; dlc <instr> fcaso problemas?

12048 - J. Neira -

Seleccin mltiple
; caso ; exp DUP ; exp1 EQ JMF EXP2 ; instr1 JMP FIN EXP2: ... EXPn: DUP ; expn EQ JMF DLC ; instrn JMP FIN DLC: ; dlc ; instr FIN: POP
49

equivale a: si <exp> = <exp1> ent <instr1> si_no si <exp> = <exp2> ent <instr2> .... si_no si <exp> = <expn> ent <instrn> si_no <instr> fsi ... fsi

12048 - J. Neira -

Mientras que (sec)


mq <exp> hacer <instr> fmq EXP: ; <exp> JMF FIN ; <instr> JMP EXP FIN:

mientras_que: tMQ { $<exp>$ = nueva_etiqueta(); etiqueta ($<exp>$); } expresion { $<fin>$ = nueva_etiqueta(); generar (JMF, $<fin>$); } instr tFMQ { generar (JMP, $<exp>2); etiqueta($<fin>4); } ; 12048 - J. Neira

50

Mientras que (AST)


mq <exp> hacer <bloque> fmq JMP COND BLOQUE: ; <bloque> COND: ; <exp> JMT BLOQUE

mientras_que: tMQ expresion bloque tFMQ { char *lcond = newlabel(), *lbloque = newlabel(); $$ = code (JMP, lcond); label (&($$), lbloque); concatenar( &($$), $3); label (&($$), lcond); concatenar (&($$), $2); emit (&($$), JMT, lbloque);
51

12048 - J. Neira -

6/6. Procedimientos y Funciones


Declaraciones: !Recuperar los argumentos !Generar el cdigo del procedimiento/funcin !Devolver el valor resultado (funciones) accion q (val entero i; ref booleano t); entero j; booleano f; accion r (ref entero j); entero i; principio q (i, t); r (j) fin principio q (j, f); r (i) fin
12048 - J. Neira -

Invocaciones: !Apilar los argumentos !Ejecutar la invocacin


52

Argumentos
! Los argumentos se transmiten a travs del stack
accion p(val entero i; ref booleano k; val caracter c); .......... p (a,b,d); ; recuperar C ; recuperar K ; recuperar I JMP P ... P: ; accion P ... CSF 53

; ; ; ;

apilar A apilar B apilar D invocar P OSF s l a


12048 - J. Neira -

Invocacin de Procedimientos
p (n+1, b, entacar(c+1)); ! Cuando se evalan las expresiones correspondientes a los argumentos, stos van almacenndose en la pila. ! Al crear el BA del procedimiento, debe respetarse el tamao del bloque actual ! El cambio de nivel es la diferencia entre el nivel actual y el invocado. ! La direccin del procedimiento o funcin se determina al introducir el smbolo en la tabla.
54

SRF nn on DRF STC 1 PLUS SRF nb ob DRF SRF nc oc DRF STC 1 PLUS OSF s l a
12048 - J. Neira -

Invocacin de Procedimientos
! Los parmetros ref requieren la direccin de la varia-ble referenciada; expresion genera cdigo para obtener el valor de la variable. SRF nn on n+1 DRF STC 1 PLUS SRF nb ob b DRF SRF nc oc entacar(c+1) DRF STC 1 PLUS OSF s l a
12048 - J. Neira -

! Para los parmetros ref elimino la ltima instruccin de cdigo generado por expresion

SRF nn on DRF STC 1 PLUS SRF nb ob SRF nc oc DRF STC 1 PLUS OSF s l a

55

Declaracin de procedimientos
! Evitar el posible cdigo de procedimientos y funciones locales
accion q (...); accion r (...); principio ... fin principio ... fin ; accion Q ; recuperar JMP Q ; accion R ; recuperar JMP R R: ; codigo de CSF Q: ; cdigo de CSF ; accion R ; recuperar R: ; codigo de CSF ; accion Q ; recuperar Q: ; cdigo de CSF args Q args R R Q

args R R args Q Q
56

12048 - J. Neira -

Recuperar los argumentos


! Los parmetros por valor/referencia se tratan de forma separada:
! Todos se recuperan al inicio, unos son valores y otros son direcciones ! Ninguno se devuelve al final. ; recuperar C SRF 0 5 ASGI ; recuperar K SRF 0 4 ASGI ; recuperar I SRF 0 3 ASGI
12048 - J. Neira -

! Los parmetros por copia se tratan como variables locales:


! Todos se recuperan al inicio ! Los que son S o E/S se devuelven al final

! Los argumentos de tipo vector pueden requerir que todas las componentes sean almacenadas en la pila y luego recuperadas.
57

Utilizacin de parmetros
1.! valor de un parmetro por referencia accion q(ref entero m); 2.! direccin de un parmetro principio por referencia escribir (m); 1 3.! valor de un parmetro por m := 0 2 fin valor y otro por referencia accion r(val entero k; 4.! parmetro por valor utilizaref entero l); do como argumento a principio parmetro por referencia escribir (k, l); 3 l := 0; 5.! parmetro por referencia 4 q (k); utilizado como argumento q (l); 5 a parmetro por referencia fin 6.! variables utilizadas como principio parmetros por valor y rer (i, j); 6 fin ferencia respectivamente programa p; entero i, j;
12048 - J. Neira 58

Cdigo que debe ser generado


; ENP L0 accion Q SRF 0 ASGI JMP L1 L1: SRF 0 DRF DRF WRT 1 SRF 0 DRF STC 0 ASG CSF accion R SRF 0 ASGI SRF 0 ASGI JMP L2 L2: SRF 0 DRF WRT 1
12048 - J. Neira -

3 ;rec. M 3 ; M 3 ; M

1 2 ;

4 ;rec. L 3 ;rec. K 3 ; K

SRF DRF 3 DRF WRT SRF DRF STC ASG SRF 4 OSF SRF DRF 5 OSF CSF ; ppal P L0: SRF DRF 6 SRF OSF LVP

0 1 0 0 0 5 0 5 0 0 5

4 ; L 4 ; L 3 ; K 1 1 ; Q 4 ; L 1 1 ; Q

3 ; I 4 ; J 0 13 ; R

59

Y para funciones.....
! Versin C:
funcion mcd( val entero a,b) dev entero; entero r; principio r := a mod b; mq r <> 0 a := b; b := r; r := a mod b fmq; dev (b); fin
12048 - J. Neira -

; recuperar parametros SRF 0 4 ; B ASGI SRF 0 3 ; A ASGI JMP MCD ; codigo de mcd MCD: ... ... ; dejar resultado en ; la pila SRF 0 4 DRF CSF CSF
60

Y para funciones.....
! Versin Pascal:
funcion mcd( val entero a, b) dev entero; entero r; principio r := a mod b; mq r <> 0 a := b; b := r; r := a mod b fmq; mcd := b; fin
12048 - J. Neira -

; recuperar parmetros SRF 0 5 ; B ASGI SRF 0 4 ; A ASGI JMP MCD ; cdigo de mcd MCD: ... ... SRF 0 3 ; MCD SRF 0 5 ; B DRF ASG ; dejar resultado en ; la pila SRF 0 3 ; MCD DRF CSF
61

También podría gustarte