Anda di halaman 1dari 40

COMPILADORES

Examen final. 2 de febrero de 2011


Observaciones: 1. Las calificaciones se publicarán hacia el 18 de febrero.
2. La revisión será hacia el 22 de noviembre.
3. En la web se avisará de las fechas exactas.
4. La duración de este examen será de 1½ horas.
5. Todos los ejercicios tienen la misma puntuación.

1. Sea el siguiente fragmento de una gramática de un lenguaje de programación:


P  DS
D  T:L | D;D
T  integer | boolean | real | array
L  id | id [ cte_entera ] of T | L ; L
S  for id := E to E do S | repeat S until E | id := E | S ; S
E  E + E | id | cte_entera | true | id [ E ]

Se tienen las siguientes características:

 El lenguaje realiza conversión implícita de enteros a reales. Para el resto, no hay


conversión implícita de tipos.
 El operador aritmético ‘+’ permite realizar una suma de dos enteros o una operación or
de dos lógicos.
 Las expresiones y el identificador de la instrucción for tienen que ser enteros.

Se pide diseñar una Definición Dirigida por la Sintaxis para realizar el Generador de
Código Intermedio, explicando brevemente las funciones y atributos utilizados.
2. Sea el siguiente programa correcto:
Program Febrero
Type Uno-Dos: Record= Uno: Integer, Dos: Integer;
Global Var0: Uno-Dos
Procedure Cuerpo
Var var1, var2: Integer;
Procedure A;
Var var2: Integer;
Function C (REF var2: Integer): Integer; /* parámetro por referencia
BEGIN /* C
var2:= var2 + 111;
Return var2;
END; /* C
BEGIN /* A
var1:= var1 + 3;
var2:= var1 + 1;
If (var2 < 7)
Then B(var1);
Else var1:= var1 + C(Var2);
END; /* A
Procedure B (var2: Integer); /* parámetro por valor
BEGIN /* B
var2:= var2 + var1;
A;
END; /* B
BEGIN /* Cuerpo
var1:= 1;
var2:= 2
A;
Var0.uno:= var1;
Var0.dos:= var2;
END; /* Cuerpo
BEGIN /* Febrero
Cuerpo;
Print (Var0)
END. /* Febrero

Teniendo en cuenta que se trata de un compilador de dos pasadas, que el lenguaje tiene
estructura de bloques y que los enteros y las direcciones ocupan 2 bytes, se pide:

a. Diseñar razonadamente el Registro de Activación general para este lenguaje.


b. Realizar una traza de ejecución del programa representando el contenido completo de
la memoria, e indicando el resultado de la sentencia “Print”.
COMPILADORES
Segundo parcial, 20 de junio de 2011
Observaciones: 1. Fecha estimada de publicación de las calificaciones: 4 de julio.
2. Fecha estimada de la revisión: 6 de julio.
3. En http://www-lt.ls.fi.upm.es/compiladores se avisará la fecha exacta de
publicación de las calificaciones y la fecha y hora definitiva de la revisión.
4. La duración de este examen será de 2¼ horas.
5. Cada ejercicio deberá entregarse en hojas separadas.
6. Los dos ejercicios tienen la misma puntuación.

1. De un lenguaje de programación se ha extraído el siguiente fragmento de gramática:


S → for ( I ; C ; A ) S | I
I → id = E
C → E oprel E | C oplog C
A → id ++ | I
E → id | núm | E + E

Se pide diseñar el Generador de Código Intermedio mediante una Definición Dirigida por la Sintaxis (explicando
el significado de todos los atributos y funciones utilizadas) sabiendo que:
 El lenguaje sólo dispone de variables de tipo entero; las expresiones lógicas se evalúan numéricamente.
 Todas las variables tienen que declararse previamente a su uso.
 La expresión id++ incrementa el valor de la variable en una unidad.
 El funcionamiento del for es el siguiente: se ejecuta I, se comprueba la condición C y, si es cierta, se ejecuta el
cuerpo S del for; seguidamente, se hace la actualización indicada en A y se vuelve a comprobar la condición C.
El bucle termina cuando la condición C es falsa.

2. Sea el siguiente fragmento de un programa:


Program Junio El compilador y el lenguaje tienen las
Var Array [1..5] of Integer: Resumen
Integer: x siguientes características:
Procedure C (REF p2: Integer) /* por referencia  Las expresiones lógicas se evalúan
Function D (pb2: Integer): Integer /* por valor mediante control de flujo
BEGIN /* D
pb2:= pb2 + 111  El lenguaje tiene estructura de bloques
Return pb2  Los enteros ocupan 2 bytes; las
END /* D direcciones ocupan 4 bytes
BEGIN /* C
If (p2 <= 3) Then p2:= D(p2)  Los parámetros se pasan por valor,
Else C(p2 - 2) salvo que se indique la palabra REF, en
END /* C cuyo caso se pasan por referencia.
Function A (p1: Integer): Integer /* por valor
Var var1: Integer
Procedure B (REF pb1: Integer) /* por referencia Se pide:
Var var2: Integer
BEGIN /* B a. Diseñar y describir brevemente el
var1:= pb1 + 3
var2:= var1 + 1
Registro de Activación general para
pb1:= var2 * var2 este lenguaje.
If (var2 < 6) Then Resumen[var2]:= var2 b. Realizar una traza de ejecución del
END /* B
BEGIN /* A
programa representando el contenido
var1:= 10 + p1 completo de la memoria, e indicando el
If (p1 <= 1) Then B(p1) resultado de las sentencias “Print”.
Else C(p1)
c. Describir brevemente cómo se establece
Return p1
END /* A el Puntero de Acceso en un Registro de
BEGIN /* Junio Activación. Aplicarlo al caso concreto
Resumen:= [0,0,0,0,0]
del Puntero de Acceso del Registro de
x:= 1
Print A(x) Activación correspondiente a la primera
Print A(Resumen[5]) activación del procedimiento “C”.
END /* Junio
COMPILADORES
SHSWLHPEUH de 2011
3. Sea el siguiente programa fuente:
Global a: entero;
Programa Tercetos;
Tipo Registro Terceto= a1: entero; a2: entero; a3: entero; FinRegistro;
Local b: Terceto;
Procedimiento Decide (Ref x: entero; y: real; Ref ter: Terceto);
Inicio Decide
Si ((x – y) < 1)
Entonces a:= a + 1;
Caso x:
1: ter.a1:= ter.a1 + a;
2: ter.a2:= ter.a2 + a;
3: ter.a3:= ter.a3 + a;
FinCaso;
Fin Decide;

Procedimiento Tratar (Ref x: entero; y: Terceto);


Local i: entero;
Procedimiento Aux (b: entero);
Local c: real;
Inicio Aux
c:= b / 2,0;
Ejecuta Decide (b, c, y);
Fin Aux;
Inicio Tratar
Desde i:= 1 Hasta 3 Hacer
Ejecuta Aux (i);
x:= y.a2 + y.a3;
Fin Tratar;

Inicio Tercetos
a:= 2;
b.a1:= 10;
b.a2:= 20;
b.a3:= 30;
Ejecuta Tratar (a, b);
Imprime (a);
Imprime (b);
Fin Tercetos;

Ténganse en cuenta las siguientes características:


 El compilador no realiza ningún tipo de optimización
 El lenguaje no distingue las mayúsculas de las minúsculas
 Los enteros ocupan 2 bytes y los reales 6 bytes; las direcciones ocupan 4 bytes
 El lenguaje tiene conversión automática de tipos.
 Si un parámetro va precedido por la palabra Ref, se pasa por referencia. En caso contrario, se pasa
por valor.
 El lenguaje tiene estructura de bloques.
Se pide:
a. Diseñar un Registro de Activación para este lenguaje, teniendo en cuenta exclusivamente la estructura
del programa Tercetos.
b. Realizar la traza de ejecución del programa. Indicar el resultado de las sentencias Imprime.
COMPILADORES
Examen final. 24 de enero de 2012
Observaciones: 1. Las calificaciones se publicarán hacia el 10 de febrero.
2. La revisión será hacia el 14 de febrero.
3. En la web se avisará de las fechas exactas.
4. La duración de este examen será de 2 horas.
5. Ambos ejercicios tienen la misma puntuación.

1. De la gramática de un lenguaje se han entresacado las siguientes reglas:

S  do id = E, E Inc S | id = E
Inc  , E | λ
E  E * E | id

Se pide diseñar una Definición Dirigida por la Sintaxis para realizar la Generación de
Código de Tres Direcciones sobre estas reglas, explicando concisamente los atributos y
funciones empleadas, y detallando todos los accesos a la Tabla de Símbolos. La sentencia
del bucle do funciona como sigue: primero se evalúan (una sola vez) las tres expresiones,
asignándose al identificador (id) el resultado de la primera (E); mientras el identificador no
sea mayor que la segunda expresión (E), se ejecuta la sentencia (S) y, posteriormente, se
incrementa el valor del identificador en el valor de la tercera expresión (Inc) (si ésta se
omite en la sentencia del bucle do, el identificador se incrementará en una unidad).

Ejemplos:
k=1 k=1
do i = 1, 6 k = k * i do i = 1, 6, 2 k = k * i
i valdrá 1, 2, 3, 4, 5, 6 i valdrá 1, 3, 5
al final k valdrá 720 al final k valdrá 15
2. Sea el siguiente programa correcto:

Program Preparar-viaje;
Integer: kms; /* Distancia al destino
Integer: n-h; /* Número de hijos
Integer: Cansancio, tarea;
String: Medio-Transp;

Procedure Preparar-maleta (n-h: Integer, REF c: Integer);


/* REF indica parámetro por referencia
Integer: aux;
Function Preparar-maleta-hijo (): Integer;
BEGIN /* Preparar-maleta-hijo
c:= c + 1;
Return 3;
END; /* Preparar-maleta-hijo
BEGIN /* Preparar-maleta
tarea:= tarea + 3 * n-h;
aux:= 1;
While aux < n-h Do
Begin
aux:= aux + 1;
tarea:= tarea - Preparar-maleta-hijo ();
End;
END; /* Preparar-maleta

Procedure Transporte (kms: Integer); /* parámetro por valor


BEGIN /* Transporte
If kms >= 800 Then Medio-Transp:= "avión";
Else Medio-Transp:= "coche";
tarea:= tarea - 5;
END; /* Transporte

BEGIN /* Preparar-viaje
Cansancio:= 1;
n-h:= 3;
Print ("Introduzca la distancia al destino [1-10000]:");
Read (kms); /* lee un número del teclado
tarea:= 5;
Preparar-maleta (n-h, Cansancio);
Transporte (kms);
If tarea = 0 Then Print ("Viaje Preparado") Else Print ("Viaje No Preparado");
END. /* Preparar-viaje

Teniendo en cuenta que el lenguaje posee recursividad y tiene estructura de bloques con
reglas de ámbito léxico, se pide:

a. Diseñar y describir brevemente el Registro de Activación general para este lenguaje.


b. Realizar una traza de ejecución del programa representando el contenido completo de
la memoria en la plantilla adjunta, e indicando el resultado de las sentencias “Print”.
GENERADOR DE CÓDIGO INTERMEDIO
11 de abril de 2012

Observaciones: 1. Las calificaciones se publicarán aproximadamente el 24 de abril.


2. La revisión será aproximadamente el 26 de abril.
3. En la web se dará información sobre la publicación de notas y la revisión.
4. La duración de este examen será de 40 minutos.

De un lenguaje se ha extraído el siguiente fragmento de gramática:

S  for id in range (P) do S | A


P  E, E, E | E
A  id := E
E  cte_ent | id | E op_arit E

Se pide diseñar, mediante un Esquema de Traducción, un Generador de Código


Intermedio que proporcione como salida código de tres direcciones teniendo en cuenta
que:

• Todas las expresiones y variables son siempre enteras.


• No existen conversiones de tipos.
• La función range devuelve, cada vez, un número perteneciente a una secuencia de
números enteros (sobre la que iterará el for) de la siguiente manera:
o Si sólo contiene un argumento (range(Y)), comienza en 0 y termina en el mayor
número posible inferior a Y, siendo 1 el incremento (o paso) para la secuencia.
Por ejemplo, range(10) genera los números: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
o Si recibe tres argumentos (range(X,Y,Z)), comienza en X y termina en el mayor
número posible inferior a Y, siendo Z el incremento (o paso) para la secuencia.
Por ejemplo, range(2,15,3) genera los números: [2, 5, 8, 11, 14].
• Deben explicarse brevemente los atributos y funciones utilizadas.
COMPILADORES Y TRADUCTORES DE LENGUAJES
1 5 d e j unio d e 2 0 1 2
Observaciones: 1. Fecha aproximada de publicación de las calificaciones: 21-junio (Traductores de Lenguajes) y 27-
junio (Compiladores).
2. Fecha aproximada de la revisión: 25-junio (Traductores de Lenguajes) y 29-junio (Compiladores).
3. Cada ejercicio debe entregarse en hojas separadas. Cada ejercicio tiene la misma puntuación.
4. Los alumnos de “Compiladores” deben realizar los ejercicios 1 y 2 y disponen de 2 horas.
5. Los alumnos de “Compiladores” que ya se examinaron de Generación de Código Intermedio y los
alumnos de “Traductores de Lenguajes” deben realizar sólo el ejercicio 2 y disponen de 1 hora.

1.Sea el siguiente fragmento de una gramática de un lenguaje de programación:


S  repeat S until E | id := E
E  E oplog E | E ↑ E | id | E oprel E
oprel  > | <
oplog  and | or
Se pide, explicando el significado de las funciones y atributos empleados, diseñar el Generador de Código
de tres direcciones mediante un Esquema de Traducción. La representación de las expresiones lógicas
debe hacerse numéricamente. Supóngase que el Análisis Semántico ya está realizado y que, por tanto,
todos los tipos son correctos. Téngase en cuenta que el lenguaje tiene las siguientes características:
• Las variables deben haber sido declaradas con anterioridad a su uso.
• Sólo existen los tipos entero y lógico.
• En los tipos lógicos, cero representa falso y distinto de cero representa verdadero.
• El lenguaje realiza conversión automática de tipos.
• La expresión E1↑E2 refleja la operación de potencia entre enteros, y debe tenerse en cuenta que en el
código intermedio no existe el operador de potencia. Si el exponente (E2) es un valor inferior a uno, el
resultado de la potencia (E1↑E2) será el valor de la base (E1).
• La sentencia repeat ejecuta las sentencias S hasta que la expresión E sea verdadera.

2.Sea el siguiente programa correcto:


Program Ejercicio-junio
Integer: a;
Integer: z:= 0;
Function Fun (REF x: Integer): Integer; /* REF indica parámetro por referencia
Integer: z:= 10;
Procedure Proc (REF x: Integer; REF y: Integer);
BEGIN /* Proc
z:= z + x;
z:= z * y;
END; /* Proc
BEGIN /* Fun
Proc (x, 5);
Return z;
END; /* Fun
Function Fun2 (z: Integer): Integer; /* parámetro por valor
BEGIN /* Fun2
If z < 0 Then z:= 100;
Else z:= fun2 (z - 50) + 10;
Return z;
END; /* Fun2
BEGIN /* Ejercicio-junio
a:= 3;
z:= fun2 (fun (a));
Print (a, z);
END. /* Ejercicio-junio

a. Diseñar y describir brevemente el Registro de Activación general para este lenguaje.


b. Realizar una traza de ejecución del programa representando el contenido completo de la memoria en la
plantilla adjunta, e indicando el resultado de las sentencias “Print”.
COMPILADORES
Examen Final, 10 de septiembre de 2012
Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 19 de septiembre.
2. La fecha estimada de la revisión es el 21 de septiembre.
3. La duración de este examen es de 2½ horas.
4. Cada ejercicio deberá entregarse en hojas separadas.

1. La notación húngara para nombrar identificadores utiliza el primer carácter del nombre para indicar el tipo
de la variable. Considérense únicamente los siguientes tipos:
c: carácter b: lógico
n: entero s: cadena
f: real l: entero gran precisión
Se tiene un lenguaje con las siguientes características:
• Dispone de cadenas de caracteres encerradas entre comillas. La cadena puede estar vacía.
• Los elementos léxicos del lenguaje se encuentran separados entre sí por blancos o saltos de línea.
• Los identificadores tienen que ir en notación húngara, y pueden estar formados por letras, dígitos o
subrayados, aunque no puede terminar por el carácter de subrayado. Los nombres de identificadores
deben tener en total un mínimo de un carácter y un máximo de 64.
• Se diferencian las mayúsculas de las minúsculas.
• Un identificador puede aparecer en cualquier parte del programa y la primera aparición constituye su
declaración. El primer carácter tiene que corresponder obligatoriamente con uno de los tipos válidos.

Se pide construir un Analizador Léxico (gramática regular, tokens, autómata, acciones semánticas y
errores) que reconozca este lenguaje y rellene toda la información posible en la Tabla de Símbolos.
(3 puntos)

2. Sea la siguiente gramática, cuyo axioma es A:


A  BC | xD
B  yB | λ
C  zB | xD
D  BD | CA

Se pide:
a. Calcular los conjuntos First y Follow para todos los símbolos no terminales de la gramática.
b. Comprobar si se cumple la condición LL(1) para esta gramática.
c. Obtener la tabla correspondiente al Analizador Sintáctico Descendente por Tablas o LL(1) sin
cambiar la gramática. Si la gramática no es LL(1), resaltar las celdas que demuestran que no es LL(1).
d. Escribir el procedimiento para el símbolo B correspondiente al método de Análisis Sintáctico
Descendente Recursivo.
e. Calcular el estado del Autómata Reconocedor de Prefijos Viables (método Análisis Sintáctico
Ascendente LR) que se genera a partir del ítem C  x • D.
(3 puntos)

3. Sea el siguiente fragmento de una gramática:


S  while E do S | exit E | id := E | S ; S
E  E nand E | id

Se pide diseñar el Analizador Semántico y el Generador de Código Intermedio (para obtener código de 3
direcciones) mediante una Definición Dirigida por Sintaxis, representando los lógicos por control de flujo
y teniendo en cuenta que:
• Los identificadores pueden ser enteros o lógicos
• El lenguaje no realiza conversión de tipos
• Una expresión lógica nand es falsa si ambos operandos son ciertos
• Cuando la expresión de la instrucción exit E es cierta, se sale del bucle
(4 puntos)
COMPILADORES
Final. Examen del segundo parcial. 22 de enero de 2013
Observaciones: 1. Las calificaciones del final se publicarán hacia el 6 de febrero.
2. La revisión será hacia el 8 de febrero.
3. En la web se avisará de las fechas exactas.
4. La duración de este examen será de 2 horas.
5. Todos los ejercicios tienen la misma puntuación.

1. Sea el siguiente fragmento de gramática:


S  for ( A ; E ; P ) { S } | if ( E ) { S } | A ; | continue ; | S S
A  id = E
E  cte_entera | cte_lógica | E Op_rel E | E * E | P | id
P  ++id
Op_rel  == | >= | ≠

Se pide el diseño del Generador de Código Intermedio, mediante una Definición Dirigida por
Sintaxis, representando los lógicos mediante representación numérica y explicando brevemente los
atributos y funciones utilizadas, teniendo en cuenta que:
• El lenguaje exige declaración previa de variables
• Los tipos del lenguaje son entero y lógico
• La sentencia for funciona de la siguiente manera: se inicializa la variable índice mediante la
asignación A y, si la condición E se evalúa como cierta, se ejecuta el cuerpo del for (S); luego, se
actualiza dicha variable índice (P) y se vuelve a comprobar la condición para ver si hay que volver
a ejecutar el cuerpo del for; el bucle termina cuando la condición sea falsa
• La sentencia continue hace que se termine la iteración en curso del for y se pase, automáticamente,
a la siguiente iteración (que se ejecuta, como siempre, si la condición E se evalúa como cierta). Una
sentencia continue no puede estar fuera del cuerpo de un for
• Los valores lógicos se representan numéricamente, de tal manera que 0 es falso y distinto de cero
es cierto
• No existe conversión automática de tipos, excepto entre enteros y lógicos y viceversa
• El operador * representa la multiplicación entera o el and lógico
• El operador de preincremento aumenta en una unidad el valor de una variable, devolviendo
como resultado el valor de la variable antes de ser incrementado
2. Sea el siguiente programa correcto escrito en un lenguaje en el que existen conversiones automáticas
de tipos:
Program CentroVariable;
datos: vector [1..3] of integer;
cambio: boolean;
centro: real;
iter: integer;

Procedure CalcularCentro (iter: integer; REF cent: real);


ViejoCentro: real; /* REF indica parámetro por referencia

Procedure HaCambiado (REF camb: boolean);


BEGIN
If ((ViejoCentro – cent) / ViejoCentro) > 0,15
Then camb:= true;
Else camb:= false;
END;

BEGIN /* CalcularCentro
ViejoCentro:= cent;
cent:= cent / (5 + iter);
iter:= iter + 1;
HaCambiado (cambio);
If (cambio) Then CalcularCentro (iter, cent);
END;

BEGIN /* CentroVariable
datos:= (800, 200, 680);
centro:= datos[1] + datos[2] + datos[3];
iter:= 0;
cambio:= true;
CalcularCentro (iter, centro);
Print (centro);
END.

Se pide:

a. Diseñar y describir brevemente el Registro de Activación general para este lenguaje.


b. Realizar una traza de ejecución del programa representando el contenido completo de la
memoria e indicando el resultado de la sentencia “Print”.
EXAMEN DE GENERACIÓN DE CÓDIGO INTERMEDIO
8 de abril de 2013

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 23 de abril.


2. Fecha estimada de la revisión: 26 de abril.
3. La duración de este examen será de 50 minutos.

Sea el siguiente fragmento de una gramática:


S  id := E
E  id
E  May (E, E, E)
E  PotMul (E, E, E)

Se pide diseñar el Generador de Código Intermedio (para obtener código de 3


direcciones) mediante una Definición Dirigida por Sintaxis, usando representación
numérica para los valores lógicos (0 para falso y 1 para verdadero) y teniendo en cuenta
que:
• Hay identificadores lógicos y naturales (0, 1, 2, 3, …)
• La expresión lógica May es verdadera solo si exactamente dos de sus
expresiones son verdaderas y la otra es falsa. Solo se aplica a expresiones
lógicas.
E
• La expresión PotMul (E1, E2, E3) es equivalente a E1 * E2 3. Se aplica a
expresiones naturales o lógicas.
• No existen operadores lógicos en el código de 3 direcciones.
• Las operaciones aritméticas disponibles en el código intermedio son la suma,
resta, multiplicación y división.
• No hay conversión automática de tipos.
• Se asumirá que el Analizador Semántico ya se ha encargado de todas las
comprobaciones necesarias.
COMPILADORES Y TRADUCTORES DE LENGUAJES
11 de junio de 2013
Observaciones: 1. Fecha aproximada de publicación de las calificaciones: 17-junio (Traductores de Lenguajes) y 27-
junio (Compiladores).
2. Fecha aproximada de la revisión: 19-junio (Traductores de Lenguajes) y 2-julio (Compiladores).
3. Cada ejercicio debe entregarse en hojas separadas. Cada ejercicio tiene la misma puntuación.
4. Los alumnos de “Compiladores” que ya se examinaron de Generación de Código Intermedio y los
alumnos de “Traductores de Lenguajes” deben realizar sólo el ejercicio 2 y disponen de 1 hora.
5. El resto de alumnos de “Compiladores” deben realizar los ejercicios 1 y 2 y disponen de 2 horas.

1. Sea el siguiente fragmento de una gramática:


PDS
D  id : T D | λ
T  real | int | array [ cte-ent ] of T
S  id := E | id [ E ] := E | ForEach ( id in id ) { S } | S S
E  A | id | id [ E ]
A  cte-ent | cte-real

Se pide diseñar el Generador de Código Intermedio mediante una Traducción Dirigida por la Sintaxis
para esta grámatica, teniendo en cuenta que:
 El Análisis Semántico ya está correctamente realizado.
 Los elemento del vector sólo pueden ser enteros o reales, nunca otros vectores.
 Todos los elementos de un vector han de ser del mismo tipo.
 No hay conversiones automáticas de tipos.
 El Analizador Léxico inserta los lexemas de los identificadores en la Tabla de Símbolos.
 Se debe asumir que el índice de los vectores va desde 1 hasta el valor cte-ent indicado en la
declaración, y siempre es entero.
 El lenguaje tiene declaración de variables (D).
 El primer identificador de la sentencia ForEach debe ser del mismo tipo que los elementos del vector
(segundo identificador de la sentencia).
 La sentencia ForEach realiza tantas iteraciones como elementos tenga el vector (segundo identificador
de la sentencia) y, en cada iteración, asigna el elemento i-ésimo del vector al primer identificador de la
sentencia y ejecuta el conjunto de sentencias (S) del cuerpo.
 Seguidamente se muestran, a modo de ejemplo, algunas sentencias válidas de este lenguaje:
a: int // declaración de una variable entera
b: real // declaración de una variable real
u: array [3] of int // declaración de una variable vector de 3 enteros
v: array [3] of int
a:= 2
v[1]:= 3
v[a]:= a
v[3]:= 1
u:= v // copia una variable vector a otra variable vector
ForEach (a in v) {u[a]:= a} // hace: u[3]:=3; u[2]:=2; u[1]:=1
a:= u[v[1]]
2. Sea el siguiente fragmento correcto de un programa:

procedure calculo
{
i, a: integer // declaración de variables locales al procedimiento
function F (val x): integer
{ // función con un párametro entero por valor y que devuelve un entero
return x3 + 1
}
function suma (val x, ref y): integer
{ // función con un párametro entero por valor y otro entero por referencia y que devuelve un entero
a: integer
function varía (): integer
{ // función sin parámetros que devuelve un entero
a:= i * y
return a
}
i:= x + y
if (i < 10) then varía ()
y:= y + 1
return x + y
}
for i:= 1 to 3 do
a:= suma (F(i), i + i) // 
Print (i + i)
}

Se pide:
a. Realizar la traza de ejecución de este programa, indicando el resultado de la instrucción Print.
b. Escribir el código intermedio de tres direcciones correspondiente a la sentencia  (tener en cuenta que
un entero ocupa 2 bytes y una dirección ocupa 4).
c. Escribir el código objeto (ensamblador simbólico explicando el significado de cada instrucción)
correspondiente a la instrucción de código intermedio obtenida en el apartado b) t3:=call suma.
COMPILADORES
Examen Final, 11 de septiembre de 2013
Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 19 de septiembre.
2. La fecha estimada de la revisión es el 24 de septiembre.
3. La duración de este examen es de 2½ horas.
4. Cada ejercicio deberá entregarse en hojas separadas.

1.Sea la siguiente gramática:


MAGW
GEnF
Enc│λ
AaW│bW│abW
Wb│λ
Fc│λ

Se pide:
a. Construir el Autómata Reconocedor de Prefijos Viables (método Análisis Sintáctico Ascendente LR)
sobre la plantilla adjunta, que puede contener errores u omisiones.
b. Calcular los conjuntos First y Follow para cada símbolo no terminal y analizar sobre el autómata todos
los conflictos que pudieran existir.
c. Enumerar los estados por los que transitaría el Analizador LR para analizar la cadena abbncn. En el
caso de que en algún estado usado se presente algún conflicto, deberán seguirse todas las alternativas
posibles.
(3,5 puntos)

2. De un lenguaje se ha extraído el siguiente fragmento de gramática:


S  id := E | if E = false then S1
E  id | E1 ≤ E2 ≤ E3

Se pide diseñar un Esquema de Traducción con el Analizador Semántico y el Generador de Código


Intermedio teniendo en cuenta que:
 El lenguaje tiene variables enteras, reales y lógicas y se exige su declaración.
 La expresión de comparación múltiple se evalúa como cierta si el valor de E2 se encuentra entre los
valores de E1 y E3, ambos inclusive. La operación puede realizarse entre expresiones de cualquiera de los
tres tipos disponibles, siempre que las tres expresiones sean del mismo tipo.
 El lenguaje realiza conversiones automáticas de tipos en todos los casos excepto en la expresión de
comparación múltiple.
 Los valores lógicos tienen que representarse numéricamente (0 es falso y cualquier otro valor es
verdadero).
 Deben explicarse brevemente los atributos y funciones utilizadas.
(3,5 puntos)
3. Sea el siguiente fragmento correcto de un programa:
void main ()
int a, b, c
int producto (int a, int REF b) // parámetro a por valor y b por referencia
{
c:= a * b * c
if a = b then return b * producto (a, b - 1)
else return c
}
int suma (int a, int b) // parámetros por valor
int c
{
c = a – b * 2
if a = b then return producto (a, b + 1)
else
{
a:= a – 1
return b + suma (a, b + 1)
}
}
{
a:= 9
b:= 5
c:= a - b
if a > b then c:= suma (a, b)
else c:= producto (a, b)
}

Se pide:
a. Realizar una traza de la ejecución, representado el contenido completo de la pila.
b. Explicar cómo se establece el puntero de acceso cuando se produce una llamada a una función.
c. ¿Cuál es la traducción a código objeto de la instrucción de tres direcciones “ti:= call suma”
correspondiente a la primera vez que la función suma llama a la función suma?
(3 puntos)
COMPILADORES
Segundo parcial, 10 de enero de 2014
Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 21 de enero.
2. La fecha estimada de la revisión es el 23 de enero.
3. La duración de este examen será de 1¾ hora.
4. Cada ejercicio deberá entregarse en hojas separadas.
5. Todos los ejercicios tienen la misma puntuación

1. De un lenguaje que exige declaración de variables previa a su uso, se han entresacado las siguientes reglas de la
gramática:
S  id = E | for id = E, E I S
I  ,E | 
E  E * E | id
Se pide diseñar un Esquema de Traducción para realizar la Generación de Código de Tres Direcciones sobre estas
reglas, explicando concisamente los atributos y funciones empleadas. La sentencia del bucle for funciona como sigue:
primero se evalúan (una sola vez) las tres expresiones (E, E, I), asignándose al identificador (id) el resultado de la
primera expresión (E); mientras el identificador no sea mayor que la segunda expresión (E), se ejecuta la sentencia (S)
y, posteriormente, se incrementa el valor del identificador en el valor de la tercera expresión (I) (si ésta se omite en la
sentencia del bucle for, el identificador se incrementará en una unidad).

Ejemplos:
k=1 k=1
for i = 1, 6 k = k * i for i = k, 6, 2 k = k * i
i valdrá 1, 2, 3, 4, 5, 6 i valdrá 1, 3, 5
al final k valdrá 720 al final k valdrá 15

2.Se tiene un lenguaje con las siguientes características: las variables tienen que estar declaradas previamente y son
siempre enteras; todas las variables temporales se almacenan en la tabla de símbolos; todos los campos del registro de
activación se almacenan en la pila. El compilador no realiza ningún tipo de optimización.

Se pide representar la pila de registros de activación completa, detallándola al máximo, durante la ejecución del
siguiente fragmento de programa:
Procedure prueba;
x, y: Integer;
Function resultado(Val y: Integer): Integer;
{ Case y of
1: x:= x * y - x;
2: x:= x * y;
3: x:= x - y;
default: Return x – y - y;
End;
Return x;
}
Function calcula(Ref y: Integer): Integer;
x, z: Integer;
{ z:= 3;
x:= y – z;
y:= y – 1;
x:= resultado(x); // x se pasa por valor
Return x;
}
{ y:= 5;
x:= y;
y:= calcula(x); // x se pasa por referencia
Print y;
}
EXAMEN DE GENERACIÓN DE CÓDIGO INTERMEDIO
4 de abril de 2014

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 22 de abril.


2. Fecha estimada de la revisión: 24de abril.
3. Las fechas exactas se publicarán en: http://www-lt.ls.fi.upm.es/traductores
4. La duración de este examen será de 50 minutos.

a. De un lenguaje que exige declaración de variables previa a su uso, se ha entresacado el siguiente subconjunto
de reglas de su gramática:

S  DoIf E1 Times E2 S1 EndDo | S1 ; S2 | Return


E  id

Se pide diseñar un Esquema de Traducción, usando representación numérica para las expresiones
lógicas, para realizar la Generación de Código de Tres Direcciones sobre estas reglas, explicando
concisamente los atributos y funciones empleadas.

La sentencia del bucle DoIf-Times funciona como sigue:

• Primero, se evalúa la expresión E1


• Si es falsa, termina el bucle
• Si es verdadera, se evalúa E2 y se ejecuta S1 tantas veces como indica E2

La sentencia Return solamente se puede utilizar dentro del bucle DoIf-Times e implica abandonar
inmediatamente el bucle.

Ejemplo:
DoIf idlog Times Cont
S;
Return
EndDo

b. De un lenguaje que exige declaración de variables previa a su uso, se ha entresacado el siguiente subconjunto
de reglas de su gramática:

E  E1 AND E2 | M-OR ( L )
L  E , L1 | E

Se pide diseñar una Definición Dirigida por la Sintaxis, usando representación por control de flujo para
las expresiones lógicas, para realizar la Generación de Código de Tres Direcciones sobre estas reglas,
explicando concisamente los atributos y funciones empleadas.

El operador M-OR funciona como un or múltiple, es decir, recibe una lista de operandos y devuelve
verdadero si al menos uno de ellos es verdadero.

Ejemplos:
M-OR (T)  T
M-OR (F,F,F,F)  F
M-OR (F,F,T)  T
M-OR (T,T,F,F,T,T)  T
COMPILADORES
Segundo parcial, 11 de junio de 2014
Observaciones: 1. Fecha aproximada de publicación de las calificaciones: 23‐junio. 
  2. Fecha aproximada de la revisión: 25‐junio. 
  3. Cada ejercicio debe entregarse en hojas separadas. Cada ejercicio tiene la misma puntuación. 
  4. Los alumnos de “Compiladores” que ya se examinaron de Generación de Código Intermedio han de 
realizar sólo el ejercicio 2 y disponen de 1 hora. 
  5. El resto de alumnos de “Compiladores” deben realizar los ejercicios 1 y 2 y disponen de 2 horas. 

1. Dado el siguiente fragmento de gramática de un lenguaje de programación: 
PDS
D  var L T = I D | 
L  id | id , L
T  int
IE | E,I
S  if B < B then S | A
BE | A
A  id := E
E  id | cte_ent | E + E

Se  pide  diseñar  el  Generador  de  Código  Intermedio  mediante  una  Definición  Dirigida  por  la 
Sintaxis para esta grámatica, teniendo en cuenta que: 
 El  análisis  semántico  ya  ha  sido  realizado  y  no  hay  errores  (entre  otras  cosas,  se  ha 
comprobado ya que todas las variables se han declarado previamente a su uso y que la lista de 
valores en una declaración con inicialización tiene la longitud correcta). 
 En una declaración múltiple, el tipo se indica al final y se aplica a toda la lista. 
 Si  la  condición  de  la  sentencia  if  contiene  alguna  instrucción  de  inicialización  (A),  dichas 
inicializaciones  se  ejecutarán,  por  orden,  siempre  antes  de  evaluar  la  condición.  Después  de 
ello se evalúa la condición del if; en caso de que se haya usado la asignación, la condición del if 
usa el valor de las variables de la parte izquierda de la asignación. 
 Un ejemplo de un programa válido sería: 
var x, y, z int
var h int = 7
var f, g int = h, 8
if g < x:=5 then y:= f // se asigna un 5 a x y se comprueba si g es menor que x
if x:=h < z:=7 then y:= g // se asigna h a x, un 7 a z, y se comprueba si x es menor que z 
 
2. Sea el siguiente fragmento correcto de un programa: 

Procedure prueba;
x, y: Integer;
Function resultado(Val y: Integer): Integer;
{
Case y of
1: x:= x * y - x;
2: x:= x * y;
3: x:= x – y + resultado (x);
default: Return x – y - y;
End;
Return x;
}
Function calcula(Ref y: Integer): Integer;
x, z: Integer;
{
z:= 3;
x:= y – z;
y:= y – 1;
x:= resultado(x); // x se pasa por valor
Return x;
}
{
y:= 5;
x:= y;
y:= calcula(x); // x se pasa por referencia
Print y;
}

Se pide: 
a. Realizar  la  traza  de  ejecución  de  este  programa,  indicando  el  resultado  de  la  instrucción 
Print. 

b. Escribir  el  código  intermedio  (tres  direcciones)  y  el  código  objeto  (ensamblador  simbólico 
explicando el significado de cada instrucción) obtenido para la sentencia Return x – y - y; 
(tener en cuenta que un entero ocupa 2 bytes y una dirección ocupa 4). 
COMPILADORES
Examen Final, 10 de septiembre de 2014
Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 24 de septiembre y
la fecha estimada de la revisión es el 26 de septiembre (en la web se avisarán de
las fechas exactas).
3. La duración de este examen es de 2½ horas.
4. Cada ejercicio deberá entregarse en hojas separadas.

1. Un lenguaje contiene, entre otros elementos, operadores aritméticos (+, –, *, /), operadores relacionales (>,
<, <=, >=, ==, !=), operadores de E/S (>>, <<), palabras reservadas, números enteros e identificadores
(comienzan por subrayado o letra y pueden ir seguidos por cualquier cantidad de subrayados, letras o
dígitos). El lenguaje dispone, además, de los elementos que se pueden ver en el siguiente ejemplo:

if (a_b_c > –77) then cin >> contador;


else cout << contador – 88;

Se pide

a. Diseñar un Analizador Léxico para este fragmento de lenguaje (indicando la gramática regular, los
tokens completos, el autómata finito determinista y las acciones semánticas), introduciendo toda la
información posible en la Tabla de Símbolos.

b. Aplicar este Analizador Léxico al fragmento de programa dado, proporcionando la lista de tokens
generados y el estado en que quedaría la Tabla de Símbolos.

2. Sea el fragmento de un lenguaje de programación generado por la siguiente gramática:


PSP| λ
S  if A < A then S | A
A  id := E
E  id | cte_ent | cte_real | E + E

Se pide diseñar el Analizador Semántico y la Generación de Código Intermedio mediante una Definición
Dirigida por la Sintaxis para esta grámatica, teniendo en cuenta que:
• El lenguaje tiene los tipos entero, real y lógico.
• El lenguaje no tiene conversión de tipos.
• Para evaluar la condición de la sentencia ‘if’, se evalúan ambas asignaciones y después se compara el
valor asignado a las variables de la parte izquierda de la asignación.
• El operador ‘<’ solo es aplicable entre números (del mismo tipo).
• El operador ‘+’ repesenta tanto la suma aritmética entre números (del mismo tipo) como el OR lógico, y
el operado OR lógico no existe en el lenguaje intermedio.
• Un ejemplo de un programa válido sería:
p:= a + 3,3 + b
if g:=3+2 < x:=5 then y:=f // se asigna un 5 a g, un 5 a x y se comprueba si g es menor que x
if y:=x < z:=7+g then y:=g // se asigna x a y, un 12 a z, y se comprueba si y es menor que z
3. Dado el siguiente programa fuente:
Programa Coordenadas
Var real: desvio; //desviación del norte magnético según la longitud
int: hora; //huso horario [12, -12]
int: aux;

Procedimiento Latitud (x: real; y: real; REF hemif: string)


//Los parámetros x e y se pasan por valor
//El parámetro hemif se pasa por referencia (REF)

Procedimiento ZonaPolar (x: real)


Begin ZonaPolar
If x >= 66 then hemif= ”ZonaPolar”
End ZonaPolar

Begin Latitud
Switch (x - desvio)
Case > 0 then hemif= ”Norte”;
Case < 0 then hemif= ”Sur”;
Case = 0 then hemif= ”Ecuador”;
Call ZonaPolar (x);
End Latitud

Procedimiento Longitud (x: real; y: real; REF husohora: real)


//Los dos primeros parámetros son por valor, y el último por referencia
Var string: hemisferio;
Begin Longitud
aux++;
desvio= x / 50;
husohora= truncate (y / 15);
Call Latitud (x, y, hemisferio);
Print (“Hemisferio”, aux, hemisferio, “Huso horario:”, husohora);
End Longitud

Begin Coordenadas
aux= 0;
Call Longitud (100, 22, hora);
End Coordenadas

Se pide:
a. Diseñar el Registro de Activación general para este lenguaje explicando brevemente (1 o 2 líneas) cada
uno de los campos.
b. Calcular el tamaño de los Registros de Activación de los procedimientos Latitud y ZonaPolar,
teniendo en cuenta (además de lo que se deduce del programa) que los enteros ocupan 2 bytes y los
reales 4 y que la memoria direccionable es de 232 bytes.
c. Realizar la traza de ejecución del programa. Indicar cuál sería el resultado impreso por el programa.

Nota: Las operaciones truncate (parte entera) y Print (imprimir por pantalla) se tratarán como
operaciones del lenguaje y no como llamadas a funciones.
COMPILADORES
Segundo parcial. 19 de enero de 2015
Observaciones: 1. Las calificaciones se publicarán hacia el 5 de febrero.
2. La revisión será hacia el 9 de febrero.
3. En la web se avisará de las fechas exactas.
4. La duración de este examen es de 2 horas.
5. Los dos ejercicios tienen la misma puntuación.

1. Sea el siguiente fragmento de una gramática de un lenguaje de programación que considera


únicamente identificadores enteros:

S  S; S | id:= E | loop C do S endloop


C  C NOR C | E ≠ E
E  id | cte_entera | (E)

Se pide diseñar un esquema de traducción que genere código de tres direcciones. Explicar
brevemente los atributos y funciones empleadas.

Notas:
• la sentencia loop tiene el siguiente significado:

falso
C L
verdad

• la operación NOR se rige por la siguiente tabla de verdad:

A B A NOR B
V V F
V F F
F V F
F F V
2. Sea el siguiente programa:
PROCEDURE ppal
VAR a, b: INTEGER { variables locales de ppal }
PROCEDURE p (REF h: INTEGER)
VAR c: INTEGER
PROCEDURE r ()
VAR d: INTEGER
BEGIN {r}
c:= -b / 6 {1}
a:= a + c
d:= a
IF d > 0 THEN p(d)
END {r}
BEGIN {p}
h:= h – 2
r()
END {p}
PROCEDURE q (REF i: INTEGER, VAL j: INTEGER)
BEGIN {q}
i:= i – 1
WHILE i > 0 DO p(j)
END {q}
BEGIN {ppal}
a:= 3
b:= 6 {2}
q(a, b)
print(a, b)
END {ppal}

El lenguaje tiene las siguientes características:

1. Se exige declaración previa de identificadores


2. Las variables pueden ser enteras, reales o lógicas y no hay conversión de tipos
3. Los parámetros se pueden pasar por referencia (REF) o por valor (VAL)
4. El lenguaje tiene anidamiento de procedimientos y estructura de bloques
5. El alcance de los identificadores sigue las leyes de ámbito léxico

Se pide:

a. Justificar un diseño general del Registro de Activación para este lenguaje.

b. Realizar una traza de la ejecución de este programa, indicando el resultado que se imprimirá.

c. En el programa del enunciado se han marcado dos sentencias ({1} y {2}) en las que se usa la
variable b.
c.1. ¿Dónde estará almacenada la información sobre b cuando se compile cada una de dichas
sentencias? ¿Qué información estará guardada?
c.2. ¿Dónde estará almacenada la información sobre b cuando se ejecute cada una de dichas
sentencias? ¿Qué información estará guardada?
c.3. ¿Cuál será el código intermedio y código final generado para cada una de esas sentencias?
COMPILADORES
Examen Final, 10 de septiembre de 2014
Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 24 de septiembre y
la fecha estimada de la revisión es el 26 de septiembre (en la web se avisarán de
las fechas exactas).
3. La duración de este examen es de 2½ horas.
4. Cada ejercicio deberá entregarse en hojas separadas.

1. Un lenguaje contiene, entre otros elementos, operadores aritméticos (+, –, *, /), operadores relacionales (>,
<, <=, >=, ==, !=), operadores de E/S (>>, <<), palabras reservadas, números enteros e identificadores
(comienzan por subrayado o letra y pueden ir seguidos por cualquier cantidad de subrayados, letras o
dígitos). El lenguaje dispone, además, de los elementos que se pueden ver en el siguiente ejemplo:

if (a_b_c > –77) then cin >> contador;


else cout << contador – 88;

Se pide

a. Diseñar un Analizador Léxico para este fragmento de lenguaje (indicando la gramática regular, los
tokens completos, el autómata finito determinista y las acciones semánticas), introduciendo toda la
información posible en la Tabla de Símbolos.

b. Aplicar este Analizador Léxico al fragmento de programa dado, proporcionando la lista de tokens
generados y el estado en que quedaría la Tabla de Símbolos.

2. Sea el fragmento de un lenguaje de programación generado por la siguiente gramática:


PSP| λ
S  if A < A then S | A
A  id := E
E  id | cte_ent | cte_real | E + E

Se pide diseñar el Analizador Semántico y la Generación de Código Intermedio mediante una Definición
Dirigida por la Sintaxis para esta grámatica, teniendo en cuenta que:
• El lenguaje tiene los tipos entero, real y lógico.
• El lenguaje no tiene conversión de tipos.
• Para evaluar la condición de la sentencia ‘if’, se evalúan ambas asignaciones y después se compara el
valor asignado a las variables de la parte izquierda de la asignación.
• El operador ‘<’ solo es aplicable entre números (del mismo tipo).
• El operador ‘+’ repesenta tanto la suma aritmética entre números (del mismo tipo) como el OR lógico, y
el operado OR lógico no existe en el lenguaje intermedio.
• Un ejemplo de un programa válido sería:
p:= a + 3,3 + b
if g:=3+2 < x:=5 then y:=f // se asigna un 5 a g, un 5 a x y se comprueba si g es menor que x
if y:=x < z:=7+g then y:=g // se asigna x a y, un 12 a z, y se comprueba si y es menor que z
3. Dado el siguiente programa fuente:
Programa Coordenadas
Var real: desvio; //desviación del norte magnético según la longitud
int: hora; //huso horario [12, -12]
int: aux;

Procedimiento Latitud (x: real; y: real; REF hemif: string)


//Los parámetros x e y se pasan por valor
//El parámetro hemif se pasa por referencia (REF)

Procedimiento ZonaPolar (x: real)


Begin ZonaPolar
If x >= 66 then hemif= ”ZonaPolar”
End ZonaPolar

Begin Latitud
Switch (x - desvio)
Case > 0 then hemif= ”Norte”;
Case < 0 then hemif= ”Sur”;
Case = 0 then hemif= ”Ecuador”;
Call ZonaPolar (x);
End Latitud

Procedimiento Longitud (x: real; y: real; REF husohora: real)


//Los dos primeros parámetros son por valor, y el último por referencia
Var string: hemisferio;
Begin Longitud
aux++;
desvio= x / 50;
husohora= truncate (y / 15);
Call Latitud (x, y, hemisferio);
Print (“Hemisferio”, aux, hemisferio, “Huso horario:”, husohora);
End Longitud

Begin Coordenadas
aux= 0;
Call Longitud (100, 22, hora);
End Coordenadas

Se pide:
a. Diseñar el Registro de Activación general para este lenguaje explicando brevemente (1 o 2 líneas) cada
uno de los campos.
b. Calcular el tamaño de los Registros de Activación de los procedimientos Latitud y ZonaPolar,
teniendo en cuenta (además de lo que se deduce del programa) que los enteros ocupan 2 bytes y los
reales 4 y que la memoria direccionable es de 232 bytes.
c. Realizar la traza de ejecución del programa. Indicar cuál sería el resultado impreso por el programa.

Nota: Las operaciones truncate (parte entera) y Print (imprimir por pantalla) se tratarán como
operaciones del lenguaje y no como llamadas a funciones.
COMPILADORES
Segundo parcial. 19 de enero de 2015
Observaciones: 1. Las calificaciones se publicarán hacia el 5 de febrero.
2. La revisión será hacia el 9 de febrero.
3. En la web se avisará de las fechas exactas.
4. La duración de este examen es de 2 horas.
5. Los dos ejercicios tienen la misma puntuación.

1. Sea el siguiente fragmento de una gramática de un lenguaje de programación que considera


únicamente identificadores enteros:

S  S; S | id:= E | loop C do S endloop


C  C NOR C | E ≠ E
E  id | cte_entera | (E)

Se pide diseñar un esquema de traducción que genere código de tres direcciones. Explicar
brevemente los atributos y funciones empleadas.

Notas:
• la sentencia loop tiene el siguiente significado:

falso
C L
verdad

• la operación NOR se rige por la siguiente tabla de verdad:

A B A NOR B
V V F
V F F
F V F
F F V
2. Sea el siguiente programa:
PROCEDURE ppal
VAR a, b: INTEGER { variables locales de ppal }
PROCEDURE p (REF h: INTEGER)
VAR c: INTEGER
PROCEDURE r ()
VAR d: INTEGER
BEGIN {r}
c:= -b / 6 {1}
a:= a + c
d:= a
IF d > 0 THEN p(d)
END {r}
BEGIN {p}
h:= h – 2
r()
END {p}
PROCEDURE q (REF i: INTEGER, VAL j: INTEGER)
BEGIN {q}
i:= i – 1
WHILE i > 0 DO p(j)
END {q}
BEGIN {ppal}
a:= 3
b:= 6 {2}
q(a, b)
print(a, b)
END {ppal}

El lenguaje tiene las siguientes características:

1. Se exige declaración previa de identificadores


2. Las variables pueden ser enteras, reales o lógicas y no hay conversión de tipos
3. Los parámetros se pueden pasar por referencia (REF) o por valor (VAL)
4. El lenguaje tiene anidamiento de procedimientos y estructura de bloques
5. El alcance de los identificadores sigue las leyes de ámbito léxico

Se pide:

a. Justificar un diseño general del Registro de Activación para este lenguaje.

b. Realizar una traza de la ejecución de este programa, indicando el resultado que se imprimirá.

c. En el programa del enunciado se han marcado dos sentencias ({1} y {2}) en las que se usa la
variable b.
c.1. ¿Dónde estará almacenada la información sobre b cuando se compile cada una de dichas
sentencias? ¿Qué información estará guardada?
c.2. ¿Dónde estará almacenada la información sobre b cuando se ejecute cada una de dichas
sentencias? ¿Qué información estará guardada?
c.3. ¿Cuál será el código intermedio y código final generado para cada una de esas sentencias?
EXAMEN DE GENERACIÓN DE CÓDIGO INTERMEDIO
27 de marzo de 2015

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 14 de abril


2. Fecha estimada de la revisión: 16 de abril
3. Las fechas exactas se publicarán en: http://www-lt.ls.fi.upm.es/traductores
4. Duración del examen: 60 minutos

Dado el siguiente fragmento de gramática de un lenguaje de programación:


S  for id := E X E do begin S end | A | S ; S
X  to | downto
A  L := I
L  id | id , L
IE | E,I
E  id | cte_ent | E + E

Se pide diseñar el Generador de Código Intermedio mediante una Definición


Dirigida por la Sintaxis para esta grámatica, teniendo en cuenta que:
• En una asignación múltiple (A), se tienen dos listas de igual longitud: en el
lado izquierdo se tiene una lista de variables (L) y en el lado derecho una
lista de expresiones (I). Al identificador i-ésimo se le asigna la expresión i-
ésima.
• El índice (id) del for varía unidad a unidad. Se puede ir aumentando (to) o
disminuyendo (downto).
• El bucle for funciona de la siguiente manera: el índice se inicializa con la
primera expresión (E); el bucle for ejecuta su cuerpo (S) siempre que el
índice tenga un valor distinto al valor de la segunda expresión (E). Hay que
tener en cuenta que esta segunda expresión se evalúa en cada iteración del
bucle.
• Se debe asumir que todos los identificadores son enteros.
• Un ejemplo de un programa válido es:
h:= 7;
x, y, z:= 3, 2 + h, 9;
x, z:= z, x;
for x:= x + 5 downto h do
begin
y, z:= 3 + 5 + x, y + y
end
COMPILADORES
Segundo parcial, 8 de junio de 2015

Observaciones: 1. Fecha aproximada de publicación de las calificaciones: 18-junio.


2. Fecha aproximada de la revisión: 22-junio.
3. Cada ejercicio debe entregarse en hojas separadas.
4. Cada ejercicio tiene la misma puntuación.
5. La duración del examen es de 1¾ horas.

1. De un lenguaje, se han entresacado las siguientes reglas de la gramática:


S  loop id := E , E I S
S  id := E
I ,E
I λ
E E+E
E  id

Se pide diseñar una Definición Dirigida por la Sintaxis para realizar la Generación de Código de
Tres Direcciones sobre estas reglas, explicando concisamente los atributos y funciones empleadas.
La sentencia del bucle loop funciona según se indica en los siguientes pasos:
1. Se evalúa la primera expresión (E) y se asigna al identificador (id) su resultado
2. Se evalúa la segunda expresión (E) y si el identificador es menor que el resultado de esta
evaluación, se ejecuta la sentencia (S); en caso contrario, finaliza el bucle
3. Se evalúa la tercera expresión (I) y se incrementa el valor del identificador en el valor de
ésta (si se omite esta tercera expresión (I), el identificador se incrementará en una unidad)
4. Se vuelve al paso 2

Ejemplos (suponiendo que k vale 1 al principio de cada ejemplo):


i valdrá 1, 2, 3, 4, 5, 6
loop i:= 1, 6 k:= k + i
k valdrá al final 16
i valdrá 1, 3, 5, 7
loop i:= 1, 6, 2 k:= k + i
k valdrá al final 10
2. Dado el siguiente programa:
Program Main;
Var a= 3: integer; // variable local de Main
Function A1 (Ref x: integer; y: integer): integer; // x por referencia, y por valor
Var a: integer; // variable local
Begin A1
a:= x2 + y;
Return a;
End A1;
Function A2 (): integer;
Var b: integer; // variable local
Function A21 (x: integer): integer; // x por valor
Begin A21
Return 2 * x;
End A21;
Begin A2
b:=A1 (A21(1), a); // Φ
a:= b;
Return a;
End A2;
Begin Main
a:= A2();
Print (a);
End Main;

Considerando el siguiente diseño general para el registro de activación de los procedimientos y


funciones: [Valor devuelto, Estado de la Maquina (dirección de retorno), Puntero Acceso, Parámetros,
Variables Locales, Datos Temporales], se pide:

a. Realizar la Traza de Ejecución de este programa, detallando el contenido de la pila de


Registros de Activación. Se considera que los enteros ocupan 2 bytes y las direcciones de
memoria 4 bytes. Indicar el tamaño de cada Registros de Activación.

b. Escribir el Código Objeto (ensamblador) correspondiente a la llamada A21(1) que aparece


dentro de la sentencia marcada con Φ, escribiendo previamente el código intermedio, y
explicando brevemente cada instrucción del código objeto resultante.
TRADUCTORES DE LENGUAJES
Examen de Entorno de Ejecución y GCO. 8 de junio de 2015

Observaciones: 1. Fecha aproximada de publicación de las calificaciones: 18-junio.


2. Fecha aproximada de la revisión: 22-junio.
3. La duración del examen es de 1 hora.

Dado el siguiente programa:

Program Main;
Var a= 3: integer; // variable local de Main
Function A1 (Ref x: integer; y: integer): integer; // x por referencia, y por valor
Var a: integer; // variable local
Begin A1
a:= x2 + y;
Return a;
End A1;
Function A2 (): integer;
Var b: integer; // variable local
Function A21 (x: integer): integer; // x por valor
Begin A21
Return 2 * x;
End A21;
Begin A2
b:=A1 (A21(1), a); // Φ
a:= b;
Return a;
End A2;
Begin Main
a:= A2();
Print (a);
End Main;

Considerando el siguiente diseño general para el registro de activación de los procedimientos y


funciones: [Valor devuelto, Estado de la Maquina (dirección de retorno), Puntero Acceso, Parámetros,
Variables Locales, Datos Temporales], se pide:

a. Realizar la Traza de Ejecución de este programa, detallando el contenido de la pila de


Registros de Activación. Se considera que los enteros ocupan 2 bytes y las direcciones de
memoria 4 bytes. Indicar el tamaño de todos los Registros de Activación.

b. Escribir el Código Objeto (ensamblador) correspondiente a la llamada A21(1) que aparece


dentro de la sentencia marcada con Φ (se recomienda escribir previamente el código
intermedio) y explicando brevemente cada instrucción del código objeto resultante.
TRADUCTORES DE LENGUAJES
30 de junio de 2015
Observaciones: 1. Fecha aproximada de publicación de las calificaciones: 8 de julio.
2. Fecha aproximada de la revisión: 10 de julio.
3. Las fechas exactas de publicación y revisión se avisarán en la web:
http://www-lt.ls.fi.upm.es/traductores/
4. Cada ejercicio debe entregarse en hojas separadas.
5. Cada ejercicio tiene la misma puntuación.
6. La duración de este examen es de 2 horas

1. De un lenguaje se ha extraído el siguiente fragmento de gramática:


S  id := E | if not E then S 1
E  id | E 1 between E 2 and E 3

Se pide diseñar un Esquema de Traducción con el Generador de Código Intermedio teniendo en


cuenta que:
• La expresión between se evalúa como cierta si el valor numérico de E 1 se encuentra entre los
valores de E 2 y E 3 , ambos inclusive.
• El lenguaje tiene variables enteras y lógicas.
• El lenguaje no realiza conversiones automáticas de tipos.
• Los valores lógicos tienen que representarse por control de flujo.
• Se supone que el análisis semántico ya está realizado
• Deben explicarse brevemente los atributos y funciones utilizadas.

2. Sea el siguiente fragmento de programa:


Global y= 5
Procedure main ()
Var x, z
Procedure tabla (REF x, REF y, VAL z) // x, y por referencia; z por valor
Begin tabla
y= 8
End tabla
Procedure hoja (VAL y)
Var x= 2
Begin hoja
Call tabla (x, y, z) 
End hoja
Begin main
x= y * 2;
z= x - 3
Call hoja (x)
End main
Teniendo en cuenta que un entero ocupa 4 bytes y una dirección 2, se pide indicar, para la
instrucción marcada con “”:
a. El código de tres direcciones que produciría el generador de código intermedio.
b. La salida que produciría el generador de código final.
c. Detallar el contenido de la memoria desde que se inicia la ejecución hasta el instante en que se
ejecute la sentencia y= 8.
COMPILADORES
Examen final. 14 de septiembre de 2015
Observaciones: 1. Fecha estimada de publicación de las notas: 21-septiembre.
2. Fecha estimada de revisión: 23-septiembre.
3. Las fechas exactas se avisarán en http://www-lt.ls.fi.upm.es/compiladores
4. La duración de este examen será de 2¼ horas.
5. Cada ejercicio deberá entregarse en hojas separadas.
6. Las tres preguntas tienen la misma puntuación.

1. Dada la siguiente gramática:


SAB
ABC
AkC
BCD
Bλ
C+A
DkB
Se pide:
a. Realizar el Autómata Reconocedor de Prefijos Viables (correspondiente al método
LR).
b. Estudiar y explicar los posibles conflictos en el autómata.
c. Comprobar la condición LL(1) (Análisis Descendente).
d. Independientemente de las respuestas a las dos cuestiones anteriores, ¿presenta la
gramática algún problema adicional para la construcción de un Analizador Sintáctico?

2. De una gramática se han entresacado las siguientes reglas:


S  id := E
E  E and E | id | true | false
Teniendo en cuenta que las variables pueden ser enteras, reales y lógicas y que no existe
conversión automática de tipos, se pide:
a. Construir una Definición Dirigida por la Sintaxis para realizar el Análisis Semántico
y la Generación de Código Intermedio, realizando una representación de los valores
lógicos mediante control de flujo.
b. Construir una Definición Dirigida por la Sintaxis para realizar la Generación de
Código Intermedio, realizando una representación numérica de los valores lógicos.
c. Explicar brevemente los atributos y las funciones utilizadas en ambas Definiciones.
3. Sea el siguiente fragmento de un programa escrito en un determinado lenguaje:
procedure dos
var a, x, c
procedure uno (z ref)
var b, c
procedure cuatro (c val)
begin cuatro
a:= b + c
Call uno (1)
end cuatro
begin uno
c:= 2
b:= c
if z>b then Call cuatro (c)
end uno
procedure tres
begin tres
Call uno (c)
c:= 5
end tres
begin dos
c:= 1
Call tres
Call uno (c)
end dos

El compilador y el lenguaje tienen las siguientes características:

• El compilador no realiza ninguna optimización, lo cual implica que todos los


temporales se han de almacenar en memoria
• El lenguaje tiene estructura de bloques con reglas de ámbito léxico y anidamiento
• Las direcciones ocupan 2 bytes
• Los enteros ocupan 4 bytes
• Los parámetros se pueden pasar por valor (val) o por referencia (ref)
• Todas las variables son de tipo entero.

Se pide:

a. Diseñar un Registro de Activación general para este lenguaje.

b. Realizar una traza de ejecución detallada del fragmento de programa, representando


todo el contenido de la memoria.

c. Escribir el código intermedio de 3 direcciones y el código ensamblador (comentado y


detallando las direcciones de todas las variables) que se generaría para la sentencia
“a:= b + c” que aparece en el fragmento de programa.
EXAMEN DE GENERACIÓN DE CÓDIGO INTERMEDIO
5 de abril de 2016

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 13 de abril.


2. Fecha estimada de la revisión: 15 de abril.
3. La duración de este examen es de 55 minutos.

Sea el siguiente fragmento de una gramática:

S → do S while E
S→S;S
S → skip E
S → exit
E→E#T
E→T
T→T*F
T→F
F → id
F → true
F → false

correspondiente a un lenguaje con las siguientes características:

• Tiene los tipos entero y lógico. No tiene conversión automática de tipos.


• El do-while es un bucle que funciona como sigue: se ejecutan las sentencias S de su
cuerpo; a continuación se comprueba la expresión E y se vuelven a ejecutar las
sentencias S del cuerpo del bucle mientras que la expresión E se evalúe como cierta.
• La sentencia skip, si la expresión E es cierta, termina la iteración en curso del bucle
do-while y se continúa con la evaluación de la condición del do-while. Por el
contrario, si la expresión E es falsa, el skip no hace nada.
• La sentencia exit termina la ejecución de ese bucle do-while.
• El operador * es la multiplicación entre enteros o el AND entre lógicos.
• El operador lógico # tiene la siguiente tabla de verdad:
E T #
0 0 1
0 1 1
1 0 1
1 1 0

Se pide diseñar el Generador de Código Intermedio (para obtener código de 3


direcciones) mediante un Esquema de Traducción, teniendo en cuenta que:
• Deberá usarse representación numérica para los valores lógicos (0 para falso y 1 para
verdadero)
• No existen operadores lógicos en el código de 3 direcciones
• Se asume que el Analizador Semántico ya ha realizado todas las comprobaciones
necesarias
• Se deben explicar brevemente todos los atributos y funciones que se utilicen en la
solución
COMPILADORES / TRADUCTORES DE LENGUAJES
Segundo parcial / final, 6 de junio de 2016

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 14 de junio.


2. Fecha estimada de la revisión: 16 de junio.
3. En la web de la asignatura se avisará la fecha exacta de publicación de las
calificaciones y la fecha y hora definitiva de la revisión.
4. La duración de este examen será de 2 horas.
5. Cada ejercicio deberá entregarse en hojas separadas.
6. Todos los ejercicios tienen la misma puntuación.

1. Dado el siguiente fragmento de gramática de un lenguaje:


D  function id T ( id : T L ) begin S end
L  , id : T L | λ
T  integer | boolean | real
S  if E do S | S ; S | return E | id := E
E  id ( K ) | id | avg ( M )
K E | E , K
M E | E , M
Teniendo en cuenta que:
- El lenguaje no tiene anidamiento de procedimientos
- El lenguaje exige declaración previa de variables
- Se considera que en la máquina un lógico ocupa 1 byte, un entero 2, un real 4 y una dirección 3
- id(K) es la llamada a la función id con una lista de argumentos K. Los argumentos se pasan por valor
- avg(M) calcula la media aritmética de todos los valores M que recibe como parámetro
- El lenguaje intermedio que se desea obtener es código de 3 direcciones
Se pide diseñar el Generador de Código Intermedio para este fragmento del lenguaje con un Esquema
de Traducción, realizándolo mediante una representación numérica de los valores lógicos. Explicar
brevemente los atributos y funciones utilizadas.

2. Sea el siguiente fragmento de programa correcto:


Procedure prueba;
x, y: Integer;
Function resultado (Val y: Integer): Integer; // parámetro por valor
{ Case y of
1: x:= x * y - x;
2: x:= x * y;
3: x:= x - y;
default: Return x – y - y;
End;
Return x;
}
Function calcula (Ref y: Integer): Integer; // parámetro por referencia
x, z: Integer;
{ z:= 3;
x:= y – z;
y:= y – 1;
Return resultado (x); // ◄
}
{ y:= 5;
x:= y;
y:= calcula (resultado (x));
}

a. Representar la pila de registros de activación completa, detallándola al máximo, durante la ejecución del
fragmento de programa.

b. Indicar cuál sería el código intermedio y el código ensamblador que se generaría para la sentencia marcada
con ◄.
TRADUCTORES DE LENGUAJES
Examen Final, 27 de junio de 2016
Observaciones: 1. Fecha estimada de publicación de las calificaciones: 11 de julio.
2. Fecha estimada de la revisión: 13 de julio.
3. La duración de este examen será de 2 horas.
4. Cada ejercicio deberá entregarse en hojas separadas.
5. Todos los ejercicios tienen la misma puntuación.

1. Dado el siguiente fragmento de la gramática de un lenguaje:


E  pot_If ( E, E, E )
E  average_If ( L, E )
L  E, L | E
E  id ( L )
Y teniendo en cuenta que:
• El lenguaje exige declaración previa de identificadores.
• El operador pot_If calcula la potencia que tiene como base la primera expresión y como exponente la segunda,
siempre y cuando la tercera expresión se evalúe como cierta; en caso contrario, el operador devolvería el valor -1.
• El operador average_If recibe una lista de expresiones L y devuelve su media aritmética si la expresión E se evalúa
como cierta; en caso contrario, el operador devolvería el valor -1.
• La expresión id (L) representa una llamada a función.
• Los únicos operadores aritméticos disponibles en el lenguaje intermedio son: +, -, * y /.
• Ejemplos de uso correcto: pot_If (5*8, 2+9, x>6), pot_If (5.7, 2+9, x>6), average_If (5, 6, 42, 58, true),
pot_If (average (5.0, 6.0, 4.2, 5.8, true), 2, fin (8, 'a'))
• Ejemplos de uso incorrecto: pot_If (5, 8.2, x=5), average_If (5, 2, 9)

Se pide diseñar, mediante una Definición Dirigida por la Sintaxis, el Generador de Código Intermedio para el
fragmento recogido en las reglas indicadas.

2. Sea el siguiente programa correcto escrito en un lenguaje en el que los enteros ocupan 2 bytes y las direcciones 4:
Program EJ
Integer: a;
Integer: z:= 0;
Function F1 (Ref x: Integer): Integer; /* Ref indica parámetro por referencia
Integer: z:= 10;
Procedure P (Ref x: Integer; Ref y: Integer);
Begin /* P
z:= z + x;
a:= z + x; /* ♣
z:= z * y;
End; /* P
Begin /* F1
P (x, 3);
Return z;
End; /* F1
Function F2 (z: Integer): Integer; /* parámetro por valor
Begin /* F2
If z < 0 Then Return 100;
Else Begin z:= F2 (z - 50) + 10; Return z; End;
End; /* F2
Begin /* EJ
a:= 3;
z:= F2 (F1 (a));
Print (a, z);
End; /* EJ

a. Diseñar y describir brevemente el Registro de Activación general para este lenguaje.


b. Realizar una traza de ejecución del programa representando el contenido completo de la memoria en la plantilla
adjunta, e indicando el resultado de las sentencias “Print”.
c. Indicar el Código Intermedio y el Código Objeto que se generaría para la sentencia ♣.
3. Se tiene el siguiente fragmento de un programa fuente en un lenguaje en el que todas
las variables son enteras y tienen que estar declaradas. En la máquina destino, tanto
las direcciones como los valores enteros ocupan 4 bytes.
Procedure uno ();
Var a;
Procedure dos (x); // x por valor
Var b;
Procedure tres (y, ref z); // y por valor, z por referencia
Var c;
Begin // tres
c:= 9;
y:= c + y;
z:= c + b; //
End;
Procedure cuatro (x); // x por valor
Var d;
Begin // cuatro
b:= x;
If x <= 4 Then d:= a;
Else cuatro (x – 1);
End;
Begin // dos
b:= 7;
x:= x + b;
cuatro (a);
tres (x, a);
End;
Begin // uno
a:=5;
dos (a);
End;

Se pide:

a. Realizar una traza de ejecución de este fragmento de programa, dando el diseño


del Registro de Activación y la pila detallada.

b. Para la sentencia marcada con , detallar el código intermedio y el código objeto


que se generaría.
COMPILADORES
12 de enero de 2017
Observaciones: 1. Las calificaciones se publicarán hacia el 23 de enero.
2. La revisión será hacia el 25 de enero.
3. En la web se avisará de las fechas exactas.
4. La duración de este examen será de 2 horas.
5. Todos los ejercicios tienen la misma puntuación.

1. De una gramática se han entresacado las siguientes reglas:


S  Whenot E Then S
E  id | E & E | E $ E
Se pide, teniendo en cuenta que en el lenguaje intermedio no hay operadores lógicos:
a. Escribir un Esquema de Traducción que genere código de tres direcciones utilizando representación
numérica de los valores lógicos.
b. Escribir una Definición Dirigida por la Sintaxis que genere código de tres direcciones utilizando control
de flujo para representar los valores lógicos.
c. Explicar brevemente los atributos y funciones utilizadas.

Nota: La sentencia Whenot es un bucle que repite la ejecución de su cuerpo (S) mientras que la expresión (E)
se evalúe como falsa. La tabla de verdad de los operadores es:
F F V V
F V F V
& F F F V
$ F V F F

2. Se tiene el siguiente fragmento de un programa fuente en un lenguaje en el que todas las variables son enteras
y tienen que estar declaradas. Las direcciones y los valores enteros ocupan 4 bytes en la máquina destino.
Procedure p1 ();
Var a;
Procedure p2 (x); // x por valor
Var b;
Procedure p3 (y, ref z); // y por valor, z por referencia
Var c;
Begin // p3
c:= 9;
y:= c + y;
z:= c + b; //
End;
Procedure p4 (x); // x por valor
Var d;
Begin // p4
b:= x;
If x <= 4 Then d:= a; Else p4 (x – 1);
End;
Begin // p2
b:= 7;
x:= x + b;
p4 (a);
p3 (x, a);
End;
Begin // p1
a:=5;
p2 (a);
End;

Se pide:

a. Realizar una traza de ejecución de este fragmento de programa, dando el diseño del Registro de
Activación y la pila detallada. Supóngase que todos los temporales van en el Registro de Activación.
b. Detallar el código objeto que se generaría para la sentencia marcada con .

Anda mungkin juga menyukai