2. Definición
Definición
Código Intermedio: estructura de código que
posee una complejidad comprendida entre el
código fuente y el código de máquina.
Los códigos intermedios se consideran como una
interfaz entre el generador de código y las
Teoría Lenguajes
2
interfaz entre el generador de código y las
fases previas del compilador.
Se puede pensar en el código intermedio como el
código de máquina de una computadora hipotética
3. Código Intermedio
Código Intermedio
El uso de un código intermedio tiene como
principal ventaja la de permitir que el compilador
sea independiente de la máquina destino,
haciendolo mas transportable.
Sin embargo el código que podría generarse a
Teoría Lenguajes
3
Sin embargo el código que podría generarse a
partir del código intermedio será menos
eficiente que el código de máquina generado
directamente.
4. Clases de Codigos Intermedios
Clases de Codigos Intermedios
Los códigos intermedios más usados son
Notación Posfija
Código de tres direcciones
Código de dos direcciones
Arbol de sintaxis abstracta: Cada hoja representa
Teoría Lenguajes
4
Arbol de sintaxis abstracta: Cada hoja representa
un operando y los nodos intermedios representan
los operadores.
Notación Prefija: Similar a la notación posfija
5. Clases de Códigos Intermedios
Clases de Códigos Intermedios
Código P: Uno de los códigos más destacados. Se
denomina máquina P a una máquina abstracta que
implementa este código (una computadora
hipotética de pila con cinco registros y una
memoria).
Teoría Lenguajes
5
memoria).
Código ensartado: Establece una relación entre
cada operación y una llamada a rutina. Se genera
una serie de llamadas a las diferentes rutinas.
6. Notación Posfija
Notación Posfija
La notación posfija es una notación muy simple usada
para expresiones aritméticas que coloca el operador
al extremo derecho de la expresión (después de los
operandos y no entre ellos).
Ejemplo: para la expresión A + C * D
Teoría Lenguajes
6
Su correspondiente notación posfija es: ACD*+
La notación posfija se procesa usando una pila:
Se empilan los operandos
Cuando se encuentra un operador se desempilan sus
operandos se opera y se empila el resultado
7. Notación Posfija
Notación Posfija
Suponga que A 2, C sea 4 y D es 3.
La expresión se evalúa:
Empila 2
Empila 4
Empila 3
Teoría Lenguajes
7
Empila 3
* requiere dos operandos que se desempilan (3 y 4), se
multiplican y el resultado se empila
Empila 12
+ requiere dos operandos que se desempilan (12 y 2), se
suman y el resultado se empila
Empila 14
8. Notación Posfija
Notación Posfija
La notación posfija (NPF) de una expresión E es:
Si E es una variable o constante su NPF es E
Si E es una expresión E1 op E2 con op operador binario
cualquiera, la NPF de E es E’1 E’2 op, donde E’1 y E’2 son
las NPF de E1 y E2 respectivamente.
Si E es una expresión (E ), entonces la NPF de E es la
Teoría Lenguajes
8
Si E es una expresión (E1), entonces la NPF de E1 es la
NPF de E.
La notación posfija no necesita paréntesis
Ejemplos:
(10 + 12) * 5 10 12 + 5 *
5 + (15 - 4) 5 15 4-+
9. Código de tres direcciones
Código de tres direcciones
Las proposiciones constan por lo general de tres
direcciones:
res := arg1 op arg2
Donde res, arg1 y arg2 pueden ser constantes (sólo arg1
y arg2) o identificadores declarados por el usuario o
variables de trabajo creadas por el compilador.
Teoría Lenguajes
9
variables de trabajo creadas por el compilador.
Las variables de trabajo se crean cuando se trata
de expresiones con múltiples operadores, que se
dividen en una secuencia de operaciones con un solo
operador cada una.
op arg1 arg2 res
10. Código de tres direcciones
Código de tres direcciones
Para la expresión: A + C * D
Se tiene la siguiente secuencia de instrucciones de
tres códigos:
MUL C D Var1
ADD A Var1 Var2
Teoría Lenguajes
10
ADD A Var1 Var2
STO Var2 Res
Donde MUL, ADD y STO se suponen los códigos de
las operaciones de *, + y :=.
El manejo de las variables de trabajo es importante
11. Código de dos direcciones
Código de dos direcciones
Las variables de trabajo se usan para guardar
temporalmente resultados necesarios para
operaciones siguientes.
La idea es no usar el campo resultado:
Se usan apuntadores a la tabla de símbolos para los
Teoría Lenguajes
11
Se usan apuntadores a la tabla de símbolos para los
operandos
Se usan apuntadores a la instrucción que contiene un
resultado intermedio.
La forma de un código de dos direcciones es:
op arg1 arg2
12. Código de dos direcciones
Código de dos direcciones
Para la expresión: A + C * D
Se tiene la siguiente secuencia de instrucciones de
dos códigos:
(1) MUL C D
(2) ADD A (1)
Teoría Lenguajes
12
(2) ADD A (1)
(3) STO (2) Res
El código de dos direcciones no necesita generar
variables de trabajo
13. Análisis Semántico
Análisis Semántico
El análisis semántico puede ser realizado en
paralelo al análisis sintáctico asociando reglas
semánticas a cada producción.
Estas reglas pueden generar código cada vez que
se ejecutan, por tanto se dice que la estructura
Teoría Lenguajes
13
se ejecutan, por tanto se dice que la estructura
sintáctica dirige la traducción del código lo que
es conocido como Traducción Dirigida por la
Sintaxis (TDS).
14. Regla Semántica
Regla Semántica
Una regla semántica es un fragmento de código
(método) que se ejecuta cuando el analizador
sintáctico reconoce la producción asociada a la
regla.
Ejemplo:
Teoría Lenguajes
14
Ejemplo:
E → E + T // Regla Suma
Suma es la regla asociada a la producción y será
ejecutada al reducir E + T a E (análisis
ascendente) o al derivar E a E + T (análisis
descendente).
15. Ejemplo de Reglas Semánticas
Ejemplo de Reglas Semánticas
Definición de las reglas semánticas de una
gramática generando un código de tres
direcciones.
ApuntE es el apuntador a la tabla de símbolos
para E
Teoría Lenguajes
15
para E
k lleva el control de las variables temporales
generadas para guardar los resultados
intermedios de las operaciones.
varK es una referencia a la variable temporal K
16. Ejemplo de Reglas Semánticas
Ejemplo de Reglas Semánticas
E → T (ApuntE := ApuntT)
E1 → E2 + T ( Inc K
ApuntE1 := VarK
Genera(ADD,ApuntE2,ApuntT,VarK)
E → E - T ( Inc K
Teoría Lenguajes
16
E1 → E2 - T ( Inc K
ApuntE1 := VarK
Genera(SUB,ApuntE2,ApuntT,VarK)
T → F (ApuntT := ApuntF)
17. Ejemplo de Reglas Semánticas
Ejemplo de Reglas Semánticas
T1 → T2 * F ( Inc K
ApuntT1 := VarK
Genera(MUL,ApuntT2,ApuntF,VarK)
T1 → T2 / F ( Inc K
ApuntT := VarK
Teoría Lenguajes
17
ApuntT1 := VarK
Genera(DIV,ApuntT2,ApuntF,VarK)
F → x (ApuntF := Apuntx)
F → y (ApuntF := Apunty)
F →( E ) (ApuntF := ApuntE)
18. Reglas para generar Notación Posfija
Reglas para generar Notación Posfija
Para generar la notación posfija se usan las
operaciones clásicas ADD, SUB, MUL y DIV,
adicionalmente se usa el operador LOD que
permite empilar operandos en la pila.
A seguir se presenta las reglas semánticas
Teoría Lenguajes
18
A seguir se presenta las reglas semánticas
asociadas a la gramática para generar notación
posfija.
19. Reglas para generar Notación Posfija
Reglas para generar Notación Posfija
EXPR → TERM ( T )
EXPR → EXPR + TERM ( E T ADD)
EXPR → EXPR - TERM ( E T SUB)
TERM → FACTOR ( T )
TERM → TERM * FACTOR ( T F MUL)
Teoría Lenguajes
19
TERM → TERM * FACTOR ( T F MUL)
TERM → TERM / FACTOR ( T F DIV)
F → x (LOD x)
F → y (LOD y)
F →( EXPR ) ( E )
20. Generación de Notación Posfija
Generación de Notación Posfija
Para la frase x + y - x * y se realizará la traducción a
notación posfija.
EXPR →
→
→
→ EXPR - TERM ( E T SUB)
EXPR →
→
→
→ EXPR + TERM - TERM ( E T ADD T SUB)
Teoría Lenguajes
20
EXPR →
→
→
→ EXPR + TERM1 - TERM2 ( E T1 ADD T2 SUB)
EXPR →
→
→
→ TERM3 + TERM1 - TERM2 (T3 T1 ADD T2 SUB)
EXPR →
→
→
→ FACTOR + TERM1 - TERM2 ( F T1 ADD T2 SUB)
EXPR →
→
→
→ x + TERM1 - TERM2 ( LOD x T1 ADD T2 SUB)
EXPR →
→
→
→ x + FACTOR - TERM ( LOD x F ADD T SUB)
EXPR →
→
→
→ x + y - TERM ( LOD x LOD y ADD T SUB)
21. Generación de Notación Posfija
Generación de Notación Posfija
EXPR →
→
→
→ x + y - TERM * FACTOR
( LOD x LOD y ADD T F MUL SUB)
EXPR →
→
→
→ x + y - FACTOR1 * FACTOR2
( LOD x LOD y ADD F1 F2 MUL SUB)
EXPR →
→
→
→ x + y - x * FACTOR
Teoría Lenguajes
21
EXPR →
→
→
→ x + y - x1 * FACTOR2
( LOD x LOD y ADD LOD x F2 MUL SUB)
EXPR →
→
→
→ x + y - x1 * y
( LOD x LOD y ADD LOD x F2 MUL SUB)
22. Atributos Sintetizados
Atributos Sintetizados
El siguiente ejemplo muestra una definición dirigida
por la sintaxis para especificar una calculadora de
escritorio.
Producción Reglas Semánticas
L → E n Imprimir (E.val)
Teoría Lenguajes
22
L → E n Imprimir (E.val)
E → E1 + T E.val := E1.val + T.val
E → T E := T.val
T → T1 * F T.val := T1 .val * F.val
T → F T.val := F.val
F → ( E ) F.val := E.val
F → digito F.val := digito.valex
23. Definición con Atributos Sintetizados
Definición con Atributos Sintetizados
Se asocia un atributo sintetizado llamado val a cada
no terminal.
En cada regla se calcula el valor de val para el no
terminal del lado izquierdo a partir de los valores de
los no terminales del lado derecho.
Teoría Lenguajes
23
Se considera que valex es un valor proporcionado por
el léxico como parte del token digito.
La regla asociada al no terminal L simplemente
imprime el valor generado por la expresión E.
El árbol sintáctico con atributos sintetizados para la
expresión 3*5+4n, se muestra a seguir:
25. Generación de Proposiciones
Generación de Proposiciones
En el caso de proposiciones condicionales o
iterativas hay que tener especial cuidado con los
saltos.
Generalmente se tiene que realizar una segunda
pasada para generar la dirección de la
Teoría Lenguajes
25
pasada para generar la dirección de la
instrucción que repite la iteración (direcciones
abiertas)
Para generar código usará
JPC (salto condicional)
JMP (salto incondicional)
26. Ejemplo
Ejemplo
Generar código para el comando
MIENTRAS Condición HACER proposición
E1: Instrucciones para evaluar Condicion
JPC E2
Teoría Lenguajes
26
JPC E2
Instrucciones para proposición
JMP E1
E2: Siguiente instrucción
27. Ejemplo
Ejemplo
Generar código para :
IF Condicion THEN Proposicion
Instrucciones para evaluar Condición
JPC E1
Teoría Lenguajes
27
JPC E1
Instrucciones para ejecutar Proposicion
E1: Siguiente instrucción