COMPILADORES - UPM · 4. Los alumnos de “Compiladores” que ya se examinaron de Generación de...

43
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

Transcript of COMPILADORES - UPM · 4. Los alumnos de “Compiladores” que ya se examinaron de Generación de...

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?

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 .

GENERACIÓN DE CÓDIGO INTERMEDIO 30 de marzo de 2017

Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 20 de abril. 2. La fecha estimada de la revisión es el 24 de abril. 3. En la web se anunciarán las fechas exactas. 4. La duración de este examen es de 1 hora.

De una gramática de un lenguaje de programación se han entresacado las siguientes reglas:

E → id | id ( L ) | E ∨ E | E ⇒ E L → E | E , L

Teniendo en cuenta que:

• en el lenguaje intermedio no hay operadores lógicos • todas las variables son lógicas • todas las funciones (id (L)) devuelven un valor lógico • la tabla de verdad de los operadores es:

∨ ⇒ F F F V F V V V V F V F V V V V

Se pide:

a. Diseñar un Esquema de Traducción que genere código de tres direcciones utilizando representación numérica de los valores lógicos.

b. Diseñar 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.

TRADUCTORES DE LENGUAJES GENERACIÓN DE CÓDIGO INTERMEDIO

7 de junio de 2017 Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 14 de junio. 2. La fecha estimada de la revisión es el 16 de junio. 3. En la web se anunciarán las fechas exactas. 4. La duración de este examen es de 1 hora.

De una gramática de un lenguaje de programación se han entresacado las siguientes reglas:

E → id | id ( L ) | E NOR E | E $ E L → E | E , L

Teniendo en cuenta que:

• en el lenguaje intermedio no hay operadores lógicos • todas las variables son lógicas • todas las funciones (id (L)) devuelven un valor lógico • los parámetros se pasan por referencia • la tabla de verdad de los operadores es:

NOR $ F F V F F V F F V F F V V V F F

Se pide:

a. Diseñar un Esquema de Traducción que genere código de tres direcciones utilizando representación numérica de los valores lógicos.

b. Diseñar 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 todos los atributos y funciones utilizadas.

TRADUCTORES DE LENGUAJES ENTORNO DE EJECUCIÓN Y GENERACIÓN DE CÓDIGO

7 de junio de 2017 Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 14 de junio. 2. La fecha estimada de la revisión es el 16 de junio. 3. En la web se anunciarán las fechas exactas. 4. La duración de este examen es de 1 hora.

Dado el siguiente fragmento de programa, escrito en un lenguaje recursivo con funciones anidadas, con paso de parámetros por valor, con enteros de 2 bytes y direcciones de 4 bytes:

Procedure a Var i Function c (q) { // c i:= q Return i } Function b (p) Var i Function d (i) { // d i:= i +5 i:= c (i) + 1 Return i } { // b i:= p + 1 While i > 0 do { i:= i – 1 p:= i } p:= d (p) Return p + i * 2 } { // a i:= 4 i:= b (i - 3) }

Se pide:

a. Realizar la traza de ejecución detallando el contenido completo de la memoria, sin que se haya realizado ninguna optimización.

b. Escribir el código objeto (en ensamblador) correspondiente a la instrucción i:= c (i) + 1.

TRADUCTORES DE LENGUAJES Y COMPILADORES 30 de junio de 2017

Observaciones: 1. Las calificaciones del primer parcial se publicarán hacia el 13 de julio y la revisión será hacia el 17 de julio Las fechas exactas se avisarán en la web de la asignatura.

2. La duración de este examen es de 2 horas. 3. Cada ejercicio debe entregarse en hojas separadas.

1. Dado el siguiente fragmento de gramática:

E → E1 out { E2 , E3 } | E1 + E2 S → if E then S1 | loop E S1 endloop | S1 ; S2

Teniendo en cuenta:

• Que el lenguaje tiene tipos enteros y lógicos. • El operador lógico out devuelve falso si E1 es mayor que E2 y menor que E3 y cierto en caso

contrario (debe asumirse que estas tres expresiones son enteras). • El operador + realiza una suma entre enteros (debe asumirse que los dos operandos son enteros). • La sentencia loop funciona de la siguiente manera: se evalúa la expresión E (debe asumirse que esta

expresión es entera); si es un número mayor que cero, se ejecuta el cuerpo del loop y se vuelve a evaluar la expresión E; si es menor o igual a cero, se sale del loop.

• La sentencia if se ejecuta si la expresión E es cierta (debe asumirse que E es de tipo lógico).

Explicando brevemente las funciones y atributos utilizados, se pide:

a. Diseñar el Generador de Código Intermedio mediante un Esquema de Traducción asumiendo una representación numérica de los valores lógicos.

b. Diseñar el Generador de Código Intermedio mediante una Definición Dirigida por la Sintaxis asumiendo una representación por control de flujo de los valores lógicos.

2. Sea el siguiente programa correcto, en el que los enteros y las direcciones ocupan 2 bytes: Program Julio; Type Uno-Dos: Record= Uno: integer, Dos: integer; // estructura con 2 campos Global Var0: Uno-Dos; Procedure Principal; Var var1, var2: integer; Procedure A; Var var2: integer; Function C (REF var2: integer): integer; // paso de parámetro por referencia BEGIN var2:= var2 + 333; Return var2; END; BEGIN var1:= var1 + 3; var2:= var1 + 1; If (var2 < 7) Then B(var1) Else var1:= var1 + C(Var2); END; Procedure B (var2: integer); // paso de parámetro por valor BEGIN var2:= var2 + var1; A(); END; BEGIN var1:= 1; var2:= 2; A(); Var0.uno:= var1; Var0.dos:= var2; END; BEGIN Principal; Print (Var0); END;

Teniendo en cuenta que se trata de un compilador de dos pasadas, 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 pila

indicando el resultado de la sentencia “Print”. c. Traducir a Código Intermedio y a Código Final la sentencia Return var2;.

3. Dado el siguiente programa:

Programa Main Var a:=3 : integer; Function QUAD (REF x: integer; y: integer): integer; //x se pasa por referencia (REF) //y se pasa por valor Var a; Begin QUAD a:= x2 + y; Return a End QUAD Function DOBLA (): integer; Var b; Function ARGF (x:integer): integer Begin ARGF Return 2 * x End ARGF Begin DOBLA b:= QUAD (ARGF(1), a); // Φ a:= b Return a End DOBLA Begin Main a:= DOBLA(); 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, Var. Locales, Datos Temporales], se pide:

a. Traza de Ejecución de este programa, detallando el contenido de la pila de control y los registros de activación. Se considerará que los enteros ocupan 2 bytes y las direcciones de memoria 4 bytes.

b. Código objeto correspondiente a la llamada a ARGF(1) que aparece dentro de la sentencia Φ. Se recomienda escribir antes el código intermedio y explicar brevemente cada instrucción del código objeto resultante.

2. Dado el siguiente fragmento de gramática:

E E1 in { E2 , E3 } | E1 + E2 | id S loop E S1 endloop | S1 ; S2

Y teniendo en cuenta que: • El lenguaje tiene los tipos entero y lógico • Todas las variables se han tenido que declarar antes de ser usadas • El operador lógico out recibe tres expresiones enteras y devuelve cierto si E1 es mayor que E2 y

menor que E3 • El operador + realiza una suma entre enteros y un OR entre lógicos • La sentencia loop funciona de la siguiente manera: se evalúa la expresión E; si es cierta, se

ejecuta el cuerpo del loop y se vuelve a evaluar la expresión E; si es falsa, se sale del loop • El lenguaje no tiene conversión automática de tipos

Se pide diseñar el Analizador Semántico y el Generador de Código Intermedio mediante una Definición Dirigida por la Sintaxis, asumiendo una representación numérica de los valores lógicos.

3. Se tiene el siguiente programa:

program principal; var a, b: integer;

procedure p (x, y, z: integer); begin

b:= 9; {*} y:= y + 1; z:= z + x; x:= 10

end; begin

a:= 3; b:= 2; p (a + b, a, b); print a; print b

end.

Se pide, considerando que el paso de parámetros se hace por referencia:

a. Mostrar, para la sentencia marcada con asterisco, cómo sería el código objeto generado.

b. Realizar una traza detallada de la ejecución del programa mediante un gráfico en el que se vaya observando la pila de ejecución.

TRADUCTORES DE LENGUAJES 19 de abril de 2018

Observaciones: 1. Las calificaciones del primer parcial se publicarán hacia el 25 de abril y la revisión será hacia el 27 de abril. Las fechas exactas se avisarán en la web de la asignatura.

2. La duración de este examen es de 1 hora.

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

E → E1 # E2 | id S → repeat S1 while E | S1 ; S2 | exit | call id ( P ) P → E | E , P1

Teniendo en cuenta que:

• Los identificadores son lógicos. • La entrada recibida es léxica, sintáctica y semánticamente correcta. • El operador lógico # devuelve falso si el primer operando es falso y el segundo es

cierto; en caso contrario devuelve cierto. Hay que tener en cuenta que este operador no existe en el lenguaje intermedio.

• La sentencia repeat funciona de la siguiente manera. Se ejecuta el cuerpo del repeat.

Se evalúa la expresión E. Si es cierta, se vuelve a ejecutar el cuerpo del repeat; si es falsa, se sale del repeat.

• La sentencia exit detiene la iteración en curso del repeat y temina el repeat. • La sentencia call llama a la función id que recibe parámetros y no devuelve nada.

Explicando brevemente las funciones y atributos utilizados, se pide diseñar el Generador de Código Intermedio mediante un Esquema de Traducción, asumiendo una representación numérica de los valores lógicos.

TRADUCTORES DE LENGUAJES 4 de junio de 2018

Observaciones: 1. Las calificaciones se publicarán hacia el 25 de junio y la revisión será hacia el 27 de junio. Las fechas exactas se avisarán en la web de la asignatura.

2. La duración de este examen es de 1 hora.

1. Dado el siguiente fragmento de la gramática de un lenguaje de programación: E → E1 % E2 | id S → do S1 until E | S1 ; S2 | continue | call id ( P ) P → E | E , P1

Teniendo en cuenta que:

• Los identificadores son lógicos. • La entrada recibida es léxica, sintáctica y semánticamente correcta. • El operador lógico % devuelve cierto si el primer operando es falso y el segundo es cierto;

en caso contrario devuelve falso. Hay que tener en cuenta que este operador no existe en el lenguaje intermedio.

• La sentencia do-until funciona de la siguiente manera. Se ejecuta el cuerpo de la sentencia.

Se evalúa la expresión E. Si es falsa, se vuelve a ejecutar el cuerpo del do-until; si es cierta, se sale del do-until.

• La sentencia continue detiene la iteración en curso del do-until y vuelve a evaluar la expresión E (esta sentencia no termina la ejecución del do-until).

• La sentencia call llama a la función id que recibe parámetros y no devuelve nada.

Explicando brevemente las funciones y atributos utilizados, se pide diseñar el Generador de Código Intermedio mediante una Definición Dirigida por Sintaxis, asumiendo una representación numérica de los valores lógicos.

TRADUCTORES DE LENGUAJES 4 de junio de 2018

Observaciones: 1. Las calificaciones se publicarán hacia el 25 de junio y la revisión será hacia el 27 de junio. Las fechas exactas se avisarán en la web de la asignatura.

2. La duración de este examen es de 1 hora.

2. Dado el siguiente programa fuente correcto: Programa Junio18 Global a: entero b: real Procedimiento INSTRUCTOR (Ref x: entero, y: real, Ref z: real) // x, z por referencia, y por valor Procedimiento DECISOR (z: real) // z por valor Local f: real Begin DECISOR f:= z / 2.0 z:= z * y // c. Traducir a CI y CO End DECISOR Begin INSTRUCTOR If (y - z < 1) Then DECISOR (a) Else a:= a + 2 End INSTRUCTOR

Procedimiento SELECTOR (Ref x: entero; y: real) // x por referencia, y por valor Begin SELECTOR En caso que y: > 5.0 ⇒ INSTRUCTOR (x, y, 3.0) <= 1.0 ⇒ INSTRUCTOR (x, 3.0, y) En otro caso ⇒ INSTRUCTOR (2, 3.0, 4.0) x:= x * 2 End SELECTOR

Begin Junio18 a:= 2 b:= 6.0 Mientras (a <= 8) SELECTOR (a, b) b:= b - 1 End Mientras Print (a, b) // b. Resultado End Junio18 Se pide: a. Diseñar el Registro de Activación para este lenguaje, teniendo en cuenta (además de lo que

se deduce del programa) que los enteros ocupan 2 bytes, los reales 4 y las direcciones 6. El lenguaje tiene conversión automática de tipos.

b. Realizar la traza de ejecución del programa mostrando la pila de Registros de Activación. Indicar el resultado de la última sentencia del programa: “Print (a, b)”.

c. Traducir a Código Intermedio y a Código Objeto la instrucción marcada con , explicando muy brevemente el objetivo de cada instrucción de Código Ensamblador.

TRADUCTORES DE LENGUAJES Examen Final, 27 de junio de 2018

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 2 de julio. 2. Fecha estimada de la revisión: 4 de julio. 3. La duración de este examen será de 2 horas. 4. Cada ejercicio tiene la misma puntuación. 5. Cada ejercicio deberá entregarse en hojas separadas.

Un fragmento de un lenguaje tiene la siguiente sintaxis:

S id:= E | return E | id ( E ) | C C case id of L end L cte_ent: S; L | D D default: S | λ E E * E | E - E | id | cte_ent

El lenguaje tiene las siguientes características:

• Las variables (id) 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. • Todas las funciones del lenguaje tienen un parámetro entero (que puede pasarse por valor o por

referencia según su declaración) y devuelven un entero. • El compilador no realiza ningún tipo de optimización. • La sentencia case es una sentencia de selección múltiple que permite ejecutar la sentencia S asociada

a un determinado valor (cte_ent) o, si existe, la sentencia S por defecto (default), en función del valor de una variable (id).

1. Construir una Definición Dirigida por la Sintaxis para generar código intermedio de tres direcciones para la gramática dada, indicando todos los accesos a la Tabla de Símbolos.

2. Representar la pila de registros de activación completa, detallándola al máximo, durante la ejecución del siguiente fragmento de programa e indicar el código intermedio y final de la instrucción marcada con (*):

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; }

TRADUCTORES DE LENGUAJES 3 de abril de 2019

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 24 de abril. 2. Fecha estimada de la revisión: 26 de abril. 3. En la web 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 1 hora.

De un lenguaje de programación se ha extraído el siguiente fragmento de

gramática:

S → For id:= E To E Step E Do S Next ; | id := E ; | S S E → id | núm | E + E | id ( L ) L → E | E , L

Se pide diseñar para este lenguaje el Generador de Código Intermedio de tres direcciones mediante un Esquema de Traducción, teniendo en cuenta que:

• El lenguaje solo tiene variables y datos de tipo entero y se asume que el Análisis Semántico está realizado y es correcto

• Las variables y funciones exigen haber sido declaradas previamente a su uso

• La expresión puede ser una variable, una constante entera, una suma entera o una llamada a una función (siendo L los parámetros actuales de la función)

• El funcionamiento del bucle For es como sigue: 1. Se evalúan las tres expresiones 2. Se inicializa la variable entera índice (id) con el valor de la primera

expresión 3. Si la variable índice es mayor al valor obtenido al evaluar la segunda

expresión en el paso 1, se abandona la ejecución del bucle 4. Se ejecutan las sentencias S 5. Se incrementa el valor de la variable índice en tantas unidades como

indique el valor obtenido al evaluar la tercera expresión en el paso 1 y se vuelve al paso 3

• Se deben explicar brevemente cada uno de los atributos y funciones utilizadas en el Esquema de Traducción.

TRADUCTORES DE LENGUAJES Examen GCI. 12 de junio de 2019

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 18 de junio. 2. Fecha estimada de la revisión: 20 de junio. 3. En la web 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 1 hora.

De un lenguaje de programación se ha extraído el siguiente fragmento de

gramática:

S → For E To E Do S Next ; | id := E ; | S S E → id | cte | E Or E | id ( L ) L → E | L , E

Se pide diseñar para este lenguaje el Generador de Código Intermedio de tres direcciones mediante una Definición Dirigida por la Sintaxis, teniendo en cuenta que:

• El lenguaje solo tiene variables y datos de tipo lógico y se asume que el Análisis Semántico está realizado y es correcto

• Debe utilizarse representación numérica para los valores lógicos

• Las variables y funciones exigen haber sido declaradas previamente a su uso

• La expresión puede ser una variable, una constante lógica, un or lógico, o una llamada a una función (siendo L los parámetros actuales de la función)

• El funcionamiento del bucle For es como sigue: 1. Se evalúa las primera expresión 2. Si la primera expresión se evalúa como falsa, se abandona la ejecución del

bucle 3. Se ejecutan las sentencias S 4. Se evalúa la segunda expresión 5. Si la segunda expresión se evalúa como verdadera, se vuelve al paso 3; en

caso contrario, finaliza el bucle.

• Asúmase que en el código intermedio no se dispone de operadores lógicos,

• Se deben explicar brevemente cada uno de los atributos y funciones utilizadas en el Esquema de Traducción.

TRADUCTORES DE LENGUAJES Examen EE+GC. 12 de junio de 2019

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 18 de junio. 2. Fecha estimada de la revisión: 20 de junio. 3. En la web 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 1 hora.

Sea el siguiente fragmento de un programa correcto:

Global p, x Function uno (ref a, copyres b, val c) { b:= c x:= 1 } Function dos (ref n, ref z) { p:= p – n If (p ≠ 0) Then uno (5 + x, x, 3) Else dos (z, n) n:= x } Function main () { Local n n:= 200 p:= 4 x:= p dos (p, n) }

Teniendo en cuenta que el lenguaje tiene las siguientes características:

• Todas las variables son enteras • Las direcciones y los enteros ocupan 1 palabra • Las funciones no se pueden anidar • Hay tres modos de paso de parámetros:

o Por valor (val) o Por referencia (ref) o Por copia y restauración (copyres). Este modo es un híbrido de los

dos anteriores y funciona de la siguiente manera: En la llamada, se evalúa el parámetro actual. Tanto su valor

como su dirección se guardan en el parámetro formal Durante la ejecución de la función, se trabaja únicamente con

el valor del parámetro formal (igual que si hubiera sido un parámetro por valor)

Al regresar, se restaura, es decir, se copia el valor del parámetro formal en la dirección guardada en la llamada

Se pide: a. La traza de ejecución de este programa, detallando todo el contenido de la

memoria. b. La traducción a código intermedio y a código ensamblador de la instrucción

“p:= p – n” que aparece en la función dos.

TRADUCTORES DE LENGUAJES 12 de julio de 2019

Observaciones: 1. Fecha estimada de publicación de las calificaciones: 22 de julio. 2. Fecha estimada de la revisión: 24 de julio. 3. En la web 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.

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

S → For E To E Do S ; | id := E ; | S S E → id | cte | E And E | id ( L ) L → E | L , E

Se pide diseñar para este lenguaje el Generador de Código Intermedio de tres direcciones mediante un Esquema de Traducción, teniendo en cuenta que:

• El lenguaje solo tiene variables y datos de tipo lógico y entero y existe conversión automática de tipos; se asume que el Análisis Semántico está realizado y es correcto

• Debe utilizarse representación numérica para los valores lógicos (0 es falso, distinto de 0 es verdadero)

• Las variables y funciones exigen haber sido declaradas previamente a su uso

• La expresión puede ser una variable, una constante entera, un and lógico, o una llamada a una función (siendo L los parámetros actuales de la función)

• El funcionamiento del bucle For es como sigue: 1. Se evalúa las primera expresión 2. Si la primera expresión se evalúa como verdadera, se abandona la ejecución

del bucle 3. Se ejecutan las sentencias S 4. Se evalúa la segunda expresión 5. Si la segunda expresión se evalúa como falsa, se vuelve al paso 3; en caso

contrario, finaliza el bucle.

• Asúmase que en el código intermedio no se dispone de operadores lógicos.

• Se deben explicar brevemente cada uno de los atributos y funciones utilizadas en el Esquema de Traducción.

2. Sea el siguiente fragmento de un programa correcto:

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 (cada palabra son

2 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.

c. Indicar el código intermedio generado para la instrucción marcada con . Indicar la traducción de ese código intermedio a código ensamblador.

TRADUCTORES DE LENGUAJES 6 de marzo de 2020

Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 17 de marzo. 2. La fecha estimada de la revisión es el 19 de marzo. 3. En la web se anunciarán las fechas exactas. 4. La duración de este examen es de 1 hora.

Se dispone del siguiente fragmento de gramática de un lenguaje de programación:

S → do S while E | id += E | S S E → id | E between E and E | id ( L ) L → E | L , E

El lenguaje tiene las siguientes características:

• Dispone únicamente de los tipos entero y lógico. • La sentencia do while ejecuta el cuerpo S, comprueba la condición E, y repite la ejecución

del cuerpo mientras que la condición sea cierta. • Cuando el operador += tiene como operandos dos enteros, se realiza la suma de ambos

operandos y su resultado se guarda en el id. Cuando el operador += tiene como operandos dos lógicos, se realiza la operación or entre ambos operandos y su resultado se guarda en el id.

• En la expresión E1 between E2 and E3, el operador devuelve cierto si el valor de la expresión E1 está entre los valores de E2 y E3, ambos inclusive, y devuelve falso en caso contrario. Las tres expresiones son siempre enteras (se asume que el valor de E2 no es nunca mayor que el valor de E3).

• id ( L ) es una llamada a una función que devuelve un valor. • En la llamada a una función, el primer parámetro siempre se pasa por referencia, y todos

los demás se pasan por valor.

Se pide, diseñar el Generador de Código Intermedio de tres direcciones, mediante un Esquema de Traducción, manejando los lógicos por representación numérica (0 para falso y 1 para verdadero), teniendo en cuenta que el análisis semántico está ya realizado y el programa que se recibe es correcto.