Subido por Miguel

ejercicios resueltos compiladores USC

Anuncio
Compiladores e Intérpretes: Ejercicios resueltos
(curso 14/15)
Ejercicio 1:
Para cada una de las plataformas de ejecución seleccionadas, disponemos de un
compilador de C a código objeto y de un enlazador de código objeto a lenguaje
máquina, que podemos ver representados en la siguiente figura:
C
OBJ
C
OBJ
P1
C
OBJ
P2
OBJ
P4
OBJ
P2
P1
OBJ
P3
OBJ
P1
C
P3
P2
OBJ
P4
P3
P4
Necesitamos disponer de al menos un compilador para cada uno de los
lenguajes soportados. Los escribimos en lenguaje C y con salida en código
objeto:
Fortran
OBJ
Ada
C
OBJ
Modula
C
OBJ
C
Cada uno de estos compiladores, los compilamos y enlazamos para cada una
de las plataformas (en la siguiente figura se muestra el ejemplo de obtención de
un compilador Fortran para la plataforma P1):
Fortran
C
OBJ
Fortran
C
OBJ
OBJ
OBJ
Fortran
OBJ
P1
P1
OBJ
P1
P1
Finalmente, el siguiente diagrama muestra un ejemplo de proceso de compilado y enlazado de un programa P escrito en Fortran para la plataforma objetivo
P2:
P
P
Fortran Fortran
OBJ
OBJ
P
OBJ
P2
P2
P2
P2
P2
1
P2
Ejercicio 2:
En el fragmento de código fuente se pueden identificar los siguientes componentes léxicos:
’function’ → Palabra reservada.
’maximo’ → Identificador.
’(’ → Paréntesis izquierdo.
’num1’ → Identificador.
’,’ → Coma.
’num2’ → Identificador.
’:’ → Dos puntos.
’integer’ → Identificador.
’;’ → Punto y coma.
’(* devuelve el maximo de dos numeros *)’ → Comentario.
’begin’ → Palabra reservada.
’if’ → Palabra reservada.
’num1’ → Identificador.
’<’ → Operador.
’num2’ → Identificador.
’then’ → Palabra reservada.
’maximo’ → Identificador.
’:=’ → Operador.
’num2’ → Identificador.
’else’ → Palabra reservada.
’maximo’ → Identificador.
’:=’ → Operador
’num1’ → Identificador.
’end’ → Palabra reservada.
’;’ → Punto y coma.
’(* maximo *)’ → Comentario.
Ejercicio 3
Las siguientes expresiones regulares permiten reconocer el lenguaje propuesto:
alfanum: [a-zA-Z0-9]
barra:
[\\]
comilla: [\”]
cadena:
“({alfanum}|{barra}|{comilla})*”
2
Ejercicio 4
1) Diseño de un AFN que reconozca el lenguaje propuesto:
q2
q0
a
q3
q1
q12
q6
q4
b
q7
a
q8
b
q9
b
q10
q13
q11
q16
q14
q5
a
b
q17
q15
2) Conversión del AFN anterior a un AFD equivalente:
1. El estado inicial del AFD equivalente será cierre-ε(q0 ):
qd0 = {q0 , q1 , q2 , q4 , q7 }
2. Calculamos las transiciones desde cualquier estado del autómata determinista para cada uno de los sı́mbolos de entrada {a,b} con las operaciones
cierre-ε(mueve()):
cierre-ε(mueve(qd0 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 }
=qd1
cierre-ε(mueve(qd0 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 }
=qd2
cierre-ε(mueve(qd1 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 }
=qd1
cierre-ε(mueve(qd1 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 , q9 }
=qd3
cierre-ε(mueve(qd2 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 }
=qd1
cierre-ε(mueve(qd2 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 }
=qd2
cierre-ε(mueve(qd3 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 }
=qd1
cierre-ε(mueve(qd3 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 , q10 , q11 , q12 , q14 , q17 }
=qd4
cierre-ε(mueve(qd4 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 , q11 , q12 , q13 , q14 , q16 , q17 }
=qd5
cierre-ε(mueve(qd4 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 , q11 , q12 , q14 , q15 , q16 , q17 }
=qd6
cierre-ε(mueve(qd5 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 , q11 , q12 , q13 , q14 , q16 , q17 }
=qd5
cierre-ε(mueve(qd5 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 , q9 , q11 , q12 , q14 , q15 , q16 , q17 }
=qd7
cierre-ε(mueve(qd6 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 , q11 , q12 , q13 , q14 , q16 , q17 }
=qd5
cierre-ε(mueve(qd6 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 , q11 , q12 , q14 , q15 , q16 , q17 }
=qd6
cierre-ε(mueve(qd7 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 , q11 , q12 , q13 , q14 , q16 , q17 }
=qd5
cierre-ε(mueve(qd7 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 , q10 , q11 , q12 , q14 , q15 , q16 , q17 }
=qd8
cierre-ε(mueve(qd8 , a)) = {q1 , q2 , q3 , q4 , q6 , q7 , q8 , q11 , q12 , q13 , q14 , q16 , q17 }
=qd5
cierre-ε(mueve(qd8 , b)) = {q1 , q2 , q4 , q5 , q6 , q7 , q11 , q12 , q14 , q15 , q16 , q17 }
=qd6
El autómata finito determinista equivalente queda por tanto de la siguiente
forma:
3
b
qd0
0,1,7,2,4
a
a
b
b
qd1
8,3,6,1,7,2,4
a
qd3
2,6,5,4,1,9,7
b
b
qd4
5,6,1,7,2,4,10,17,11,12,14
qd6
2,12,6,5,14,16,4,17,15,1,11,10,7
a
a
qd8
b
5,6,1,7,2,4,15,16,11,17,12,14
b
qd2
b 5,6,1,7,2,4 a
a
a
b
qd5
8,3,6,1,7,2,4,13,16,11,17,12,14
a
qd7
2,12,6,5,14,16,4,17,15,1,11,9,7
3) Secuencia de cómputo en ambos autómatas:
La secuencia de cómputo en cada uno de los autómatas para la entrada ’bbabbab’
es la siguiente:
• AFN: {q0 } →ε {q1 , q7 } →ε {q2 , q4 } →b {q5 } →ε {q6 } →ε {q1 , q7 } →ε
{q2 , q4 } →b {q5 } →ε {q6 } →ε {q1 , q7 } →a {q8 } →b {q9 } →b {q10 } →ε
{q11 , q17 } →ε {q12 , q14 } →a {q13 } →ε {q16 } →ε {q11 , q17 } →ε {q12 , q14 } →b
{q15 } →ε {q16 } →ε {q11 , q17 }
• AFD: qd0 →b qd2 →b qd2 →a qd1 →b qd3 →b qd4 →a qd5 →b qd7
Ejercicio 5
Tabla de sı́mbolos no ordenada:
(2)
(1)
Tabla de sı́mbolos
uno
dos
tres
cinco
uno
dos
seis
cuatro
uno
dos
Índices
Tabla de sı́mbolos
uno
dos
tres
cinco
cuatro
uno
dos
1
2
4
4
Índices
1
5
Tabla de sı́mbolos con estructura de árbol
(1)
uno
dos
cinco
uno
4
dos
4
dos
3
tres
2
cuatro 3
seis
2
3
(2)
uno
dos
cinco
3
uno
3
dos
cuatro 2
5
1
2
tres
2
uno
3
2
2
1
Tabla de sı́mbolos con estructura de bosque
(1)
1
2
uno
dos
3
uno
tres
cinco
dos
cuatro
(2)
1
2
uno
dos
cinco
4
3
uno
tres
dos
cuatro
6
uno
dos
seis
Tabla de sı́mbolos con estructura de tabla hash
(1)
(2)
tres 2
tres 2
seis 3
cinco 2
cinco 2
cuatro 3
uno 4
uno 3
uno 1
dos 4
dos 3
dos 2
cuatro 2
uno 3
uno 1
dos 3
dos 2
Ejercicio 6
Existe un pequeño error en la definición de la gramática que provoca una recursión infinita en la definición de estructuras “if-then”. La definición de la
gramática deberı́a ser la siguiente:
<proposicion> → if <expresion> then <proposicion> <else> | <expresion>
<else> → else <proposicion> | ε
<expresion> → expr
Para demostrar la ambigüedad de esta gramática, construiremos dos árboles
de derivación diferentes para la siguiente cadena:
if expr then if expr then expr else expr
a)
<proposicion>
if <expresion> then <proposicion> <else>
ε
if <expresion> then <proposicion> <else>
<expresion>
else <proposicion>
<expresion>
if expr then if expr then expr else expr
7
b)
<proposicion>
if <expresion> then <proposicion>
<else>
if <expresion> then <proposicion> <else>
ε
<expresion>
else <proposicion>
<expresion>
if expr then if expr then expr else expr
Como podemos ver, la ambigüedad radica en la asignación de la estructura
<else> al if correspondiente.
Ejercicio 7
Para simplificar la representación, asumiremos E = <expresion>, M = <expr mult>,
X = <expr exp>, V = <valor>.
a) 2+(2–2)/2*(2-2)/(2–2)
E
E
+
M
M
M
X
M
/
*
V
M
/
2
X
V
V
2
X
X
X
V
V
(
(
E
−
M
M
X
M
X
X
V
M
X
V
V
2
M
X
V
2
2
X
V
2
V
2
E
E
−
)
2
8
−
E
)
M
(
E
)
E
b) 2+2–2/2*2–2/2–2
E
E
−
E
E
E
+
−
−
M
M
M
M
*
/
X
X
V
2
X
X
V
X
V
V
2
2
2
M
X
M
X
V
X
V
V
2
V
2
2
/
M
M
2
Ejercicio 8
Debemos eliminar la recursividad por la izquierda que afecta a los no terminales
<expresion>, <termino> y <factor> del siguiente modo:
<expresion> → <termino> <expresion’>
<expresion’> → + <termino><expresion’> | ε
<termino> → <factor><termino’>
<termino’> → <factor><termino’> | ε
<factor> → <valor><factor’>
<factor’> → *<factor’> | ε
Ejercicio 9
a): Cálculo de los conjuntos PRIMEROS y SIGUIENTES:
• PRIMEROS(<expresion>) = {PRIMEROS(<izquierda>), ε} = {PRIMEROS(<factor>),
ε} = {(, id, ε}
• PRIMEROS(<izquierda>) = PRIMEROS(<factor>) = {(, id}
• PRIMEROS(<derecha>) = {+, ε}
• PRIMEROS(<factor>) = {(, id}
9
• SIGUIENTES(<expresion>) = {), $}
• SIGUIENTES(<derecha>) = SIGUIENTES(<expresion>) = {), $}
• SIGUIENTES(<izquierda>) = PRIMEROS(<derecha>) - ε ∪ SIGUIENTES(<derecha>)
= {+,),$}
• SIGUIENTES(<termino>) = SIGUIENTES(<izquierda>) = {+,),$}
• SIGUIENTES(<factor>) = PRIMEROS(<termino>) - ε ∪ SIGUIENTES(<termino>)
= {*,+,),$}
b): Tabla de análisis sintáctico descendente
<e>
<i>
<d>
<t>
<f>
+
*
(
<e> → <i><d>
<i> → <f><t>
<d> → +<i><d>
<t> → ε
<t> → *<f><t>
)
<e> → ε
id
<e> → <i><d>
<i> → <f><t>
<d> → ε
<t> → ε
<f> → (<e>)
<d> → ε
<t> → ε
<f> → id
A la vista de la tabla de análisis sintáctico, podemos comprobar que efectivamente se trata de una gramática LL(1), pues en cada celda de la tabla aparece
como máximo una regla.
c): Análisis de la cadena id*id+id
Pila
$<e>
$<d><i>
$<d><t><f>
$<d><t>id
$<d><t>
$<d><t><f>*
$<d><t><f>
$<d><t>id
$<d><t>
$<d>
$<d><i>+
$<d><i>
$<d><t><f>
$<d><t>id
$<d><t>
$<d>
$
Entrada
id*id+id$
id*id+id$
id*id+id$
id*id+id$
*id+id$
*id+id$
id+id$
id+id$
+id$
+id$
+id$
id$
id$
id$
$
$
$
Acción
<e> → <i><d>
<i> → <f><t>
<f> → id
Avanzar
<t> → *<f><t>
Avanzar
<f> → id
Avanzar
<t> → ε
<d> → +<i><d>
Avanzar
<i> → <f><t>
<f> → id
Avanzar
<t> → ε
<d> → ε
Aceptación
Ejercicio 10:
a): Obtención de la colección canónica de conjuntos de elementos
LR(0):
En primer lugar, aumentamos la gramática añadiendo la siguiente regla:
10
$
<e> → ε
<sentencia’> → <sentencia>$
A continuación, construimos la colección canónica LR(0) de la gramática,
obteniendo los siguientes conjuntos:
I0 = clausura(<sentencia’> → • <sentencia>$) =
{
<sentencia’> → • <sentencia> $
<sentencia> → • = <valorizq> [<corchete>]
}
I1 = Ir a(I0 , <sentencia>) =
{
<sentencia’> → <sentencia> •$
}
I2 = Ir a(I0 , =) =
{
<sentencia> → = • <valorizq> [<corchete>]
<valorizq> → • id1
<valorizq> → • id2
}
I3 = Ir a(I2 , <valorizq>) =
{
<sentencia> → = <valorizq> • [<corchete>]
}
I4 = Ir a(I2 , id1) =
{
<valorizq> → id1 •
}
I5 = Ir a(I2 , id2) =
{
<valorizq> → id2 •
}
I6 = Ir a(I3 , [) =
{
<sentencia> → = <valorizq> [• <corchete>]
<corchete> → • <corchete> + <valorizq>
<corchete> → • <valorizq>
<valorizq> → • id1
<valorizq> → • id2
}
I7 = Ir a(I6 , <corchete>) =
{
<sentencia> → = <valorizq> [<corchete> •]
11
<corchete> → <corchete> • + <valorizq>
}
I8 = Ir a(I6 , <valorizq>) =
{
<corchete> → <valorizq> •
}
I9 = Ir a(I7 , ]) =
{
<sentencia> → = <valorizq> [<corchete>] •
}
I10 = Ir a(I7 , +) =
{
<corchete> → <corchete> + • <valorizq>
<valorizq> → • id1
<valorizq> → • id2
}
I11 = Ir a(I10 , <valorizq>) =
{
<corchete> → <corchete> + <valorizq> •
}
b) Generación de la tabla de transiciones
Estado
0
1
2
3
4
5
6
7
8
9
10
11
id1
id2
4
5
=
2
+
[
]
$
<sentencia>
1
<valorizq>
<corchete>
3
6
4
5
8
10
4
9
5
11
Para simplificar la descripción de la tabla de acciones, numeramos las reglas de
la gramática de la siguiente forma:
0
1
2
3
4
:
:
:
:
:
<sentencia> → = <valorizq> [<corchete>]
<valorizq> → id1
<valorizq> → id2
<corchete> → <corchete> + <valorizq>
<corchete> → <valorizq>
12
7
A continuación se muestra la tabla de acciones para esta gramática. Las entradas
correspondientes a sı́mbolos terminales se refieren a las acciones a tomar durante
el análisis, mientras que las entradas correspondientes a sı́mbolos no terminales
se refieren al estado a transitar mediante la función Ir a().
Estado
0
1
2
3
4
5
6
7
8
9
10
11
id1
id2
d4
d5
=
d2
+
[
]
$
<sentencia>
1
<valorizq>
OK
3
r1
r2
d4
d6
r1
r2
r1
r2
d5
8
d10
r4
d9
r4
r0
d4
d5
11
r3
r3
A la vista de la tabla de acciones podemos afirmar que efectivamente esta es
una gramática SLR(1), ya que en cada celda aparece como mucho una acción.
c) Analizar la siguiente cadena: =id1[id1+id2]
Estados
0
0,2
0,2,4
0,2,3
0,2,3,6
0,2,3,6,4
0,2,3,6,8
0,2,3,6,7
0,2,3,6,7,10
0,2,3,6,7,10,5
0,2,3,6,7,10,11
0,2,3,6,7
0,2,3,6,7,9
0,1
Sı́mbolos
=
=id1
=<vi>
=<vi>[
=<vi>[id1
=<vi>[<vi>
=<vi>[<c>
=<vi>[<c>+
=<vi>[<c>+id2
=<vi>[<c>+<vi>
=<vi>[<c>
=<vi>[<c>]
S
Entrada
=id1[id1+id2]$
id1[id1+id2]$
[id1+id2]$
[id1+id2]$
id1+id2]$
+id2]$
+id2]$
+id2]$
id2]$
]$
]$
]$
$
$
Acción
d2
d4
r1
d6
d4
r1
r4
d10
d5
r2
r3
d9
r0
OK
Ejercicio 11
a) Ampliación de la gramática para el cálculo del valor mediante
atributos sintetizados.
F
L
L
B
B
→
→
→
→
→
<corchete>
.L { F.valor = L.valor }
LB { L.exp = L.exp − 1; L.valor = L.valor + B.valor · 2L.exp }
B { L.exp = −1; L.valor = B.valor/2}
0 { B.valor = 0}
1 { B.valor = 1}
13
7
b) Mostrar el árbol de análisis aumentado para la cadena .101
F
valor = 0.625
L
valor = 0.625
exp = -3
L
valor = 0.5
exp = -2
L
valor = 0.5
exp = -1
B
.
B
B
valor = 1
valor = 0
valor = 1
1
0
1
14
Descargar