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 D S 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.

COMPILADORES - €¦ · COMPILADORES Examen final. 2 de febrero de 2011 Observaciones: 1. Las calificaciones se publicarán hacia el 18 de febrero. 2. …

Embed Size (px)

Citation preview

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 D S 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

Var Array [1..5] of Integer: Resumen

Integer: x

Procedure C (REF p2: Integer) /* por referencia

Function D (pb2: Integer): Integer /* por valor

BEGIN /* D

pb2:= pb2 + 111

Return pb2

END /* D

BEGIN /* C

If (p2 <= 3) Then p2:= D(p2)

Else C(p2 - 2)

END /* C

Function A (p1: Integer): Integer /* por valor

Var var1: Integer

Procedure B (REF pb1: Integer) /* por referencia

Var var2: Integer

BEGIN /* B

var1:= pb1 + 3

var2:= var1 + 1

pb1:= var2 * var2

If (var2 < 6) Then Resumen[var2]:= var2

END /* B

BEGIN /* A

var1:= 10 + p1

If (p1 <= 1) Then B(p1)

Else C(p1)

Return p1

END /* A

BEGIN /* Junio

Resumen:= [0,0,0,0,0]

x:= 1

Print A(x)

Print A(Resumen[5])

END /* Junio

El compilador y el lenguaje tienen las

siguientes características:

Las expresiones lógicas se evalúan

mediante control de flujo

El lenguaje tiene estructura de bloques

Los enteros ocupan 2 bytes; las

direcciones ocupan 4 bytes

Los parámetros se pasan por valor,

salvo que se indique la palabra REF, en

cuyo caso se pasan por referencia.

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 las sentencias “Print”.

c. Describir brevemente cómo se establece

el Puntero de Acceso en un Registro de

Activación. Aplicarlo al caso concreto

del Puntero de Acceso del Registro de

Activación correspondiente a la primera

activación del procedimiento “C”.

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 Septiembre de 2011

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 do i = 1, 6 k = k * i

k = 1 do i = 1, 6, 2 k = k * i

i valdrá 1, 2, 3, 4, 5, 6 al final k valdrá 720

i valdrá 1, 3, 5 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”.

GGEENNEERRAADDOORR DDEE CCÓÓDDIIGGOO IINNTTEERRMMEEDDIIOO 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.

CCOOMMPPIILLAADDOORREESS YY TTRRAADDUUCCTTOORREESS DDEE LLEENNGGUUAAJJEESS 1155 ddee jjuunniioo ddee 22001122

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 n: entero f: real

b: lógico s: cadena 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 B C | x D B y B | λ C z B | x D D B D | C A

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.

• La expresión PotMul (E1, E2, E3) es equivalente a E1 * E2 E3. 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 D S

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 A G W G E n F E n c │ λ A a W │ b W │ a b W 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 for i = 1, 6 k = k * i

k = 1 for i = k, 6, 2 k = k * i

i valdrá 1, 2, 3, 4, 5, 6 al final k valdrá 720

i valdrá 1, 3, 5 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 D S 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 S P | λ 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:

• 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

C Lfalso

verdad

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 S P | λ 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:

• 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

C Lfalso

verdad

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):

loop i:= 1, 6 k:= k + i i valdrá 1, 2, 3, 4, 5, 6 k valdrá al final 16

loop i:= 1, 6, 2 k:= k + i i valdrá 1, 3, 5, 7 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 S1 E id | E1 between E2 and E3

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 E1 se encuentra entre los valores de E2 y E3, 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 A B A B C A k C B C D B λ C + A D k B

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

CCOOMMPPIILLAADDOORREESS // TTRRAADDUUCCTTOORREESS DDEE LLEENNGGUUAAJJEESS 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 .