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:
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.
Inicio Tercetos
a:= 2;
b.a1:= 10;
b.a2:= 20;
b.a3:= 30;
Ejecuta Tratar (a, b);
Imprime (a);
Imprime (b);
Fin Tercetos;
S do id = E, E Inc S | id = E
Inc , E | λ
E E * E | id
Se pide diseñar una Definición Dirigida por la Sintaxis para realizar la Generación de
Código de Tres Direcciones sobre estas reglas, explicando concisamente los atributos y
funciones empleadas, y detallando todos los accesos a la Tabla de Símbolos. La sentencia
del bucle do funciona como sigue: primero se evalúan (una sola vez) las tres expresiones,
asignándose al identificador (id) el resultado de la primera (E); mientras el identificador no
sea mayor que la segunda expresión (E), se ejecuta la sentencia (S) y, posteriormente, se
incrementa el valor del identificador en el valor de la tercera expresión (Inc) (si ésta se
omite en la sentencia del bucle do, el identificador se incrementará en una unidad).
Ejemplos:
k=1 k=1
do i = 1, 6 k = k * i do i = 1, 6, 2 k = k * i
i valdrá 1, 2, 3, 4, 5, 6 i valdrá 1, 3, 5
al final k valdrá 720 al final k valdrá 15
2. Sea el siguiente programa correcto:
Program Preparar-viaje;
Integer: kms; /* Distancia al destino
Integer: n-h; /* Número de hijos
Integer: Cansancio, tarea;
String: Medio-Transp;
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:
1. La notación húngara para nombrar identificadores utiliza el primer carácter del nombre para indicar el tipo
de la variable. Considérense únicamente los siguientes tipos:
c: carácter b: lógico
n: entero s: cadena
f: real l: entero gran precisión
Se tiene un lenguaje con las siguientes características:
• Dispone de cadenas de caracteres encerradas entre comillas. La cadena puede estar vacía.
• Los elementos léxicos del lenguaje se encuentran separados entre sí por blancos o saltos de línea.
• Los identificadores tienen que ir en notación húngara, y pueden estar formados por letras, dígitos o
subrayados, aunque no puede terminar por el carácter de subrayado. Los nombres de identificadores
deben tener en total un mínimo de un carácter y un máximo de 64.
• Se diferencian las mayúsculas de las minúsculas.
• Un identificador puede aparecer en cualquier parte del programa y la primera aparición constituye su
declaración. El primer carácter tiene que corresponder obligatoriamente con uno de los tipos válidos.
Se pide construir un Analizador Léxico (gramática regular, tokens, autómata, acciones semánticas y
errores) que reconozca este lenguaje y rellene toda la información posible en la Tabla de Símbolos.
(3 puntos)
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)
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.
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;
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:
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.
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)
Se pide:
a. Realizar una traza de la ejecución, representado el contenido completo de la pila.
b. Explicar cómo se establece el puntero de acceso cuando se produce una llamada a una función.
c. ¿Cuál es la traducción a código objeto de la instrucción de tres direcciones “ti:= call suma”
correspondiente a la primera vez que la función suma llama a la función suma?
(3 puntos)
COMPILADORES
Segundo parcial, 10 de enero de 2014
Observaciones: 1. La fecha estimada de publicación de las calificaciones es el 21 de enero.
2. La fecha estimada de la revisión es el 23 de enero.
3. La duración de este examen será de 1¾ hora.
4. Cada ejercicio deberá entregarse en hojas separadas.
5. Todos los ejercicios tienen la misma puntuación
1. De un lenguaje que exige declaración de variables previa a su uso, se han entresacado las siguientes reglas de la
gramática:
S id = E | for id = E, E I S
I ,E |
E E * E | id
Se pide diseñar un Esquema de Traducción para realizar la Generación de Código de Tres Direcciones sobre estas
reglas, explicando concisamente los atributos y funciones empleadas. La sentencia del bucle for funciona como sigue:
primero se evalúan (una sola vez) las tres expresiones (E, E, I), asignándose al identificador (id) el resultado de la
primera expresión (E); mientras el identificador no sea mayor que la segunda expresión (E), se ejecuta la sentencia (S)
y, posteriormente, se incrementa el valor del identificador en el valor de la tercera expresión (I) (si ésta se omite en la
sentencia del bucle for, el identificador se incrementará en una unidad).
Ejemplos:
k=1 k=1
for i = 1, 6 k = k * i for i = k, 6, 2 k = k * i
i valdrá 1, 2, 3, 4, 5, 6 i valdrá 1, 3, 5
al final k valdrá 720 al final k valdrá 15
2.Se tiene un lenguaje con las siguientes características: las variables tienen que estar declaradas previamente y son
siempre enteras; todas las variables temporales se almacenan en la tabla de símbolos; todos los campos del registro de
activación se almacenan en la pila. El compilador no realiza ningún tipo de optimización.
Se pide representar la pila de registros de activación completa, detallándola al máximo, durante la ejecución del
siguiente fragmento de programa:
Procedure prueba;
x, y: Integer;
Function resultado(Val y: Integer): Integer;
{ Case y of
1: x:= x * y - x;
2: x:= x * y;
3: x:= x - y;
default: Return x – y - y;
End;
Return x;
}
Function calcula(Ref y: Integer): Integer;
x, z: Integer;
{ z:= 3;
x:= y – z;
y:= y – 1;
x:= resultado(x); // x se pasa por valor
Return x;
}
{ y:= 5;
x:= y;
y:= calcula(x); // x se pasa por referencia
Print y;
}
EXAMEN DE GENERACIÓN DE CÓDIGO INTERMEDIO
4 de abril de 2014
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:
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 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:
PDS
D var L T = I D |
L id | id , L
T int
IE | E,I
S if B < B then S | A
BE | 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:
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.
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;
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
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.
Se pide diseñar un esquema de traducción que genere código de tres direcciones. Explicar
brevemente los atributos y funciones empleadas.
Notas:
• la sentencia loop tiene el siguiente significado:
falso
C L
verdad
A B A NOR B
V V F
V F F
F V F
F F V
2. Sea el siguiente programa:
PROCEDURE ppal
VAR a, b: INTEGER { variables locales de ppal }
PROCEDURE p (REF h: INTEGER)
VAR c: INTEGER
PROCEDURE r ()
VAR d: INTEGER
BEGIN {r}
c:= -b / 6 {1}
a:= a + c
d:= a
IF d > 0 THEN p(d)
END {r}
BEGIN {p}
h:= h – 2
r()
END {p}
PROCEDURE q (REF i: INTEGER, VAL j: INTEGER)
BEGIN {q}
i:= i – 1
WHILE i > 0 DO p(j)
END {q}
BEGIN {ppal}
a:= 3
b:= 6 {2}
q(a, b)
print(a, b)
END {ppal}
Se pide:
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:
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.
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;
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
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.
Se pide diseñar un esquema de traducción que genere código de tres direcciones. Explicar
brevemente los atributos y funciones empleadas.
Notas:
• la sentencia loop tiene el siguiente significado:
falso
C L
verdad
A B A NOR B
V V F
V F F
F V F
F F V
2. Sea el siguiente programa:
PROCEDURE ppal
VAR a, b: INTEGER { variables locales de ppal }
PROCEDURE p (REF h: INTEGER)
VAR c: INTEGER
PROCEDURE r ()
VAR d: INTEGER
BEGIN {r}
c:= -b / 6 {1}
a:= a + c
d:= a
IF d > 0 THEN p(d)
END {r}
BEGIN {p}
h:= h – 2
r()
END {p}
PROCEDURE q (REF i: INTEGER, VAL j: INTEGER)
BEGIN {q}
i:= i – 1
WHILE i > 0 DO p(j)
END {q}
BEGIN {ppal}
a:= 3
b:= 6 {2}
q(a, b)
print(a, b)
END {ppal}
Se pide:
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
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
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;
Se pide:
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
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.
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
Se pide:
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 .