Está en la página 1de 101

Autómatas y lenguajes

Pedro Valero y Alberto Parramón Apuntes UAM


Doble Grado Mat.Inf.
UAM - 2014/2015
14 de junio de 2016 12:49
Código en Github
Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Índice general

I Introducción 3
I.1 Lenguaje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
I.1.1 Lenguajes particulares . . . . . . . . . . . . . . . . . . . . . . 4
I.1.2 Operadores de utilidad . . . . . . . . . . . . . . . . . . . . . . 4
I.2 Expresiones regulares . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

II Gramática 7
II.1 Gramáticas independientes del contexto . . . . . . . . . . . . . . . . . 10

III Autómatas finitos: deterministas y no deterministas 14


III.1 Equivalencia entre AF y ER . . . . . . . . . . . . . . . . . . . . . . . 18

IV Autómatas a pila 19

V Gramáticas de atributos 23
V.1 Análisis semántico . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

VI Analizador morfológico 34

VIIAnalizador sintáctico 36
VII.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
VII.2 Tablas de análisis ascendente . . . . . . . . . . . . . . . . . . . . . . 38
VII.2.1 Tablas LR(0) . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
VII.2.2 Tablas SLR(1) . . . . . . . . . . . . . . . . . . . . . . . . . . 44
VII.2.3 Tablas LR(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
VII.2.4 Tablas LALR(1) . . . . . . . . . . . . . . . . . . . . . . . . . 51
VII.3 Análisis descendente . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
VII.3.1 Forma normal de Greigbach . . . . . . . . . . . . . . . . . . . 53
VII.3.2 ¿Cuándo nos interesa eliminar las transiciones λ? . . . . . . . . 56
VII.3.3 Análisis LL(1) usando la tabla . . . . . . . . . . . . . . . . . . 56
VII.3.4 Análisis LL(2) usando la tabla . . . . . . . . . . . . . . . . . . 59
VII.3.5 Análisis LL(*) . . . . . . . . . . . . . . . . . . . . . . . . . . 60

VIIIÚltimos detalles: lemas, equivalencias y reducción de automátas... 61


VIII.1Minimizar autómatas finitos . . . . . . . . . . . . . . . . . . . . . . . 61
VIII.2Equivalencia AFN - AFD . . . . . . . . . . . . . . . . . . . . . . . . . 64
VIII.3Propiedades del cierre (regulares) . . . . . . . . . . . . . . . . . . . . 65
VIII.4Lemas del Bombeo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
VIII.4.1 Lema del bombeo (Lenguajes regulares) . . . . . . . . . . . . . 66
0
Documento compilado el 14 de junio de 2016 a las 12:49

1 de 100
Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

VIII.4.2 Lema del bombeo (Lenguajes independientes del contexto) . . . 67


VIII.5Propiedades del cierre (independientes del contexto) . . . . . . . . . . 68

A Ejercicios 70
A.1 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

B Ejercicios 1a Hoja 73
B.1 Ejercicios sobre autómatas finitos y lenguajes regulares . . . . . . . . . 73
B.2 Ejercicios sobre autómatas a pila y gramáticas independientes del contexto 77

C Ejercicios 2a Hoja 79
C.1 Ejercicios sobre Gramáticas de Atributos . . . . . . . . . . . . . . . . 79

D Ejercicios 3a Hoja 86
D.1 Ejercicios de análisis . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

2 de 100
Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo I

Introducción

Vamos a trabajar con tres elementos fundamentales:

Máquinas/Autómata
• Autómatas finitos ⇒ Expresiones regulares
• Autómatas de pila ⇒ Lenguajes independientes del contexto
Problemas ¿Qué se puede computar?. Conjeturas que se creen ciertas pero cuya
veracidad, por ahora, no se ha demostrado.
Lenguajes/Gramática

Nuestro objetivo es ver qué relación existe entre estos tres elementos. Para ello,
primero debemos establecer algunas definiciones.

I.1. Lenguaje

Símbolo Definición I.1 Símbolo. “Letra", elemento de un conjunto

Alfabeto Definición I.2 Alfabeto. Conjunto finito de símbolos no vacío.

Palabra Definición I.3 Palabra (Cadena). Secuencia finita de símbolos tomados de un


(Cadena) alfabeto. La palabra vacía tiene 0 símbolos y se representa por λ.
Será conveniente acostumbrarnos a usar el término “cadena” en lugar del término
“palabra” ya que representa mejor el concepto que queremos representar.

Longitud Definición I.4 Longitud de cadena. Número de símbolos que contiene.


de cadena

Lenguaje Definición I.5 Lenguaje. Conjunto de palabras, cualquier subconjunto de Σ∗ .


Hay algunos casos particulares de lenguajes:

3 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

I.1.1. Lenguajes particulares

P P∗
Lenguaje Definición I.6 Lenguaje universal (sobre ). Denotado por representa el
universal
P conjunto de todas las palabras que se pueden formar con los símbolos de Σ, incluido
(sobre ) λ.

Lenguaje Definición I.7 Lenguaje de un autómata. Conjunto de palabras que acaban en un


de un estado final del autómata y, por tanto, son aceptadas por el mismo.
autómata

Lenguaje Definición I.8 Lenguaje vacío. Lenguaje que no contiene ningún elemento: φ.
vacío

Lenguaje Definición I.9 Lenguaje {λ}. Lenguaje que sólo contiene λ. El lenguaje {λ} es
{λ} distinto del lenguaje vacío aunque λ sea la palabra vacía. En particular |{λ}| = 1 y
|φ| = 0.

Lenguaje Definición I.10 Lenguaje Σ+ .


Σ+
Σ+ = Σ \ {λ}

Lenguajes Definición I.11 Lenguajes Regulares. Son lenguajes que pueden ser admitidos por
Regulares autómatas finitos.

I.1.2. Operadores de utilidad


Tenemos dos operadores importantes:

Cierre 1. Definición I.12 Cierre estrella (star-closure). El operador estrella se


estrella corresponde con la suma infinita:
(star-
closure) a∗ = λ + a + a2 + a3 + ...

Cierre 2. Definición I.13 Cierre positivo (positive-closure). Este operador se


positivo corresponde con la suma infinita:
(positive-
closure) a+ = a + a2 + a3 + ...

En otras palabras, estos conceptos nos sirven para entender por qué Σ∗ representa todas
las palabras posibles. Para poder entender esto debemos entender la multiplicación

4 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

como una concatenación y la suma como un OR. Así el “elemento neutro del producto”
sería la cadena vacía.
Tomemos ahora el alfabeto binario Σ = {0, 1} Entonces:

Σ∗ = (0 + 1)∗ = λ + (0 + 1) + (0 + 1)2 + (0 + 1)3 + ... =

= λ + 0 + 1 + 00 + 01 + 10 + 11 + 000 + 001 + 010 + 011 + 100 + 101 + 110 + 111 + ...


Y con esto vemos cómo se forman todas las posibles combinaciones de bits de diferente
longitud. Si en lugar de este alfabeto hubiésemos tomado nuestro alfabeto castellano,
habríamos obtenido todas las posibles combinaciones de letras.
Si cada conjunto de símbolos representa una cadena, es lógico pensar que no tiene
sentido la operación suma como la hemos conocido siempre. La forma de entenderlo es
que si yo tengo la palabra abc y también tengo la palabra cda, en total tengo abc+cda,
es decir, tengo ambas palabras (unión).

I.2. Expresiones regulares

Expresión Definición I.14 Expresión regular. Forma alternativa de representar un lenguaje


regular regular.
Dado un alfabeto Σ existen tres tipos de expresiones regulares primitivas:

1. ∅
L(∅) = ∅

2. λ
L(λ)={λ}

3. a ∈ Σ
L(a) = {a}

A partir de estas expresiones regulares primitivas podemos construir expresiones


regulares compuestas aplicando la siguiente regla:
Siendo α, β dos expresiones regulares primitivas o compuestas sobre Σ también lo
son:

1. α + β (Unión de lenguajes)
L(α + β) = L(α) ∪ L(β)

2. α.β (Concatenación de lenguajes)


L(α.β) = L(α). L(β)

3. α∗ (Cierre)
L(α∗ ) = L(α)∗

5 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

L(β ∗ ) = L(β)∗
El cierre es la repetición de cero o más veces de las expresiones regulares a las
que aplica.

Orden de precedencia de los operadores (de más a menos):

1. *

2. .

3. +

Cuando la precedencia no esté clara o se quiera alterar, se pueden (y deben) usar


paréntesis.

Ejemplo: Encontrar los lenguajes definidos por las siguientes expresiones regulares:

1. a.(b + a).b
Cadenas de tres símbolos que empiezan por ’a’ y acaban por ’b’ y el símbolo
central es una ’a’ o una ’b’: {abb,aab}

2. (a + b)
Cadenas de un solo símbolo, que es o ’a’ o ’b’: {a,b}

3. (a + b)∗
Todas las cadenas posibles formadas por los símbolos a y b (incluso la cadena
vacía)

4. (a + b).(a + b)∗
Todas las cadenas posibles formadas por los símbolos a y b. Pero no incluye la
cadena vacía ya que por (a + b) necesariamente deben contener una ’a’ o una
’b’.

5. (aa + bb)∗
Todas las cadenas posibles formadas por ’a’ y ’b’ con la condición de que siempre
aparezcan los símbolos consecutivos un número par de veces. Es decir, cadenas
del tipo ’aaaabbaabbbbbb’, (no valdría ’aaabb’) (incluyendo la cadena vacía).

6 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo II

Gramática

Gramática Definición II.1 Gramática. Hay varias definiciones para este término. No son muy
precisas pero nos dan una idea de su significado:

a. Mecanismo para formalizar matemáticamente un lenguaje.

b. Conjunto de reglas que determinan cómo formar las cadenas de un lenguaje.

Ejemplo: Tomemos las reglas:

1. ORACIÓN → SUJETO PREDICADO

2. SUJETO → ARTÍCULO NOMBRE

3. PREDICADO → VERBO

4. ARTÍCULO → el | un

5. NOMBRE → coche | perro

6. VERBO → come | corre

Estas reglas constituyen una gramática que nos permite generar un lenguaje. En este
caso el lenguaje estaría por formado todas las cadenas que se pueden construir a partir
de estas reglas. Empezando siempre por el axioma (en este caso: “ORACIÓN”).
Una gramática está compuesta por una serie de elementos que definiremos a
continuación.

Símbolos Definición II.2 Símbolos terminales (T). Conjunto de símbolos que pueden aparecer
terminales en la cadena final (o sentencia). En el ejemplo anterior serían elementos terminales
(T) aquellos escritos en minúscula. Para ellos no existe ninguna regla que indique cómo se
derivan.

7 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Símbolos Definición II.3 Símbolos no terminales (N). Conjunto de símbolos que no


no ter- pueden aparecer en la cadena final. Simplemente son usados para definir las reglas
minales de derivación.
(N)
Los conjuntos T y N deben ser disjuntos, es decir T ∩ N = ∅. Utilizaremos el símbolo
Σ para referirnos a la unión de ambos, Σ = T ∪ N .

Reglas de Definición II.4 Reglas de producción (P). Explican cómo se transforma un símbolo
producción no terminal en un conjunto de símbolos terminales y/o no terminales.
(P)

Símbolo Definición II.5 Símbolo inicial / Axioma (S). Indica dónde empieza a construirse
inicial / la cadena. En el ejemplo anterior, el axioma sería el símbolo ORACIÓN. Una gramática
Axioma sólo puede tener un único axioma.
(S)

Gramática Definición II.6 Gramática (G). Cuádrupla formada por T, N, P y S.


(G)

G = (T, N, P, S)

Una gramática permite generar cadenas para un lenguaje. Por ejemplo, para la
gramática anterior:
ORACIÓN → (derivamos ORACIÓN:)
SUJETO PREDICADO → (derivamos SUJETO:)
ARTÍCULO NOMBRE PREDICADO → (derivamos ARTÍCULO:)
el NOMBRE PREDICADO → (derivamos NOMBRE;)
el coche PREDICADO → (derivamos PREDICADO:)
el coche VERBO → (derivamos VERBO:)
el coche corre (acabamos, pues no hay más que derivar)
Este proceso se llama derivación. Cada una de las cadenas en una derivación
se denomina forma sentencial. La última de ellas es una cadena válida del lenguaje
generado por la gramática, y se denomina sentencia. Está formada únicamente por
símbolos terminales de la gramática. El lenguaje generado por una gramática, L(G),
es el conjunto de todas las sentencias posibles, es decir, el conjunto de todas las cadenas
de símbolos no terminales que pueden derivarse a partir del axioma.
Vamos a ver algunos ejemplos de gramáticas y los lenguajes que generan:

Ejemplo: Tomemos la gramática generada por las reglas:

1. S → aSb

2. S → λ

8 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

T = {a, b}
N = {S}

Y su axioma es S.
El lenguaje generado por esta gramática serían todas las palabras de la forma: ai bi
con i = 0, 1, ...∞

Ejemplo: Ahora vamos a tratar de construir la gramática que define un lenguaje


dado: L={(ab)n a, n ≥ 0}
La gramática que define este lenguaje es:

1. S → abS
2. S → a

El autómata finito asociado a este lenguaje sería:

Gramáticas Definición II.7 Gramáticas independientes del contexto. Son aquellas cuyas
indepen- reglas tienen un único símbolo no terminal en el lado izquierdo.
dientes del
contexto
Ejemplo: Gramática dependiente de contexto

aSb → abb
cSd → cdd

S puede derivarse dependiendo de lo que la rodee, es decir, de su contexto.

Ejemplo: Gramática independiente de contexto (regular)

A → aA
A→a

A la derecha tenemos únicamente símbolos terminales o bien símbolos terminales


acompañados de un único símbolo no terminal. Si el elemento no terminal está a la
izquierda se denomina gramática lineal por la izquierda. En caso contrario, gramática
lineal por la derecha.

9 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Nota a lo anterior: Una gramática es lineal por la derecha (right-linear) si todas


sus reglas de producción son de una de las dos formas siguientes:

B → aA

B→a

con A, B ∈ N y a ∈ T ∗ . Una gramática es lineal por la izquierda (left-linear) si todas


sus reglas de producción son de una de las dos formas siguientes:

B → Aa

B→a

con A, B ∈ N y a ∈ T ∗ . Una gramática es regular si es lineal por la izquierda o lineal


por la derecha. Todas las gramáticas regulares son independientes del contexto.

Equivalencia Definición II.8 Equivalencia de gramáticas. Dos gramáticas son equivalentes si


de gramá- generan el mismo lenguaje
ticas

II.1. Gramáticas independientes del contexto


Como ya vimos una gramática puede representarse como una cuádrupla
G=(N,T,S,P), es decir, consta de símbolos no terminales, símbolos terminales, un
axioma y unas reglas de producción.
En el caso de una gramática independiente del contexto las reglas de P son de la
forma:

A→x
Con A ∈ N , x ∈ Σ∗ con Σ = T ∪ N

Ejemplo: El lenguaje:

L = {wwR : w ∈ (a + b)∗ }

es independiente del contexto puesto que puede representarse por medio de una
gramática G independiente del contexto, que sería:

S → aSa

S → bSb

S→λ

10 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Para demostrar que el lenguaje generado por la gramática, L(G), es el mismo que
L, habría que hacer dos cosas:

1. Probar que cualquier palabra de L(G) está en L.

2. Probar que cualquier palabra de L está en L(G).

El punto 1 es fácil de ver, pues está claro que cualquier cadena generada por G es
simétrica (siempre que añadimos una a al principio añadimos otra al final, y lo mismo
para b).
Para demostrar el punto 2 vamos a probar que si w ∈ L entonces w ∈ L(G)
usando inducción:

Todas las cadenas de L tienen un número par de símbolos: |w| = 2n ∀w ∈ L,


n = 0, 1, 2, ...

Para n = 0 tenemos w = λ ∈ L y se cumple que w ∈ L(G). Tomamos este


caso como base de la inducción.

Supongamos que se cumple la hipótesis para n: si w ∈ L con |w| = 2n entonces


w ∈ L(G).

Demostremos que se cumple la hipótesis para n + 1:


Sea w ∈ L con |w| = 2n + 2. Entonces w debe ser de la forma ava o bvb
con v ∈ L y |v| = 2n. Por hipótesis tenemos que v ∈ L(G), es decir se puede
generar a partir del axioma S. Finalmente si w = ava podemos generarla a partir
del axioma con la regla S → aSa, y si w = bvb podemos generarla a partir del
axioma con la regla S → bSb. Por tanto también w ∈ L(G).

Derivación Definición II.9 Derivación directa. Dada una gramática independiente del contexto
directa G=(N,T,S,P) y sean v, w dos formas sentenciales, decimos que w es derivación directa
de v:
v → w ≡ v = xZy ∧ w = xαy ∧ ∃ regla en P  Z → α

con Z ∈ N y α ∈ Σ∗ .

Derivación Definición II.10 Derivación. Dada una gramática G=(N,T,S,P) y sean v, w dos
formas sentenciales, decimos que w es derivación de v, y lo escribimos v →+ w, si
existe una cadena de formas sentenciales a0 , a1 , a2 ,... an , tales que:

v = a0 → a1 → a2 → ... → an = w

11 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Lenguaje Definición II.11 Lenguaje generado por G. Dada una gramática G=(N,T,S,P)
generado definimos el lenguaje generado por ella como:
por G
L(G) = {w ∈ T ∗ : S →+ w}

Veamos algunos ejemplos:

Ejemplo: Dado el lenguaje:

L = {an bn : n ≥ 0}

La gramática que genera este lenguaje es:

S→λ

S → aSb

Ejemplo: Dado el lenguaje:

L = {w ∈ (a + b)∗  na (w) = nb (w)}

La gramática que genera este lenguaje es:

S → aSb|bSa|λ

S → SS

Para construirla nos hemos fijado en que una palabra w puede ser de 4 formas:



 aw0 b con w0 ∈ L




 bw0 a con w0 ∈ L


w=
aw0 a ⇒ w = w1 w2 con w1 , w2 ∈ L








 bw0 b ⇒ w = w1 w2 con w1 , w2 ∈ L

Una sentencia puede ser derivada de diferentes formas a partir de una misma
gramática. Para estos casos vamos a definir derivaciones “leftmost” y “rightmost”:

Leftmost Definición II.12 Leftmost. Consiste en derivar, en cada paso, el elemento no terminal
colocado más a la izquierda. Se deja para el lector el arduo trabajo de deducir que
significa una derivación “rightmost”.
Esto nos lleva a definir un nuevo concepto:

12 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ambigüedad Definición II.13 Ambigüedad. Una gramática se define como ambigua si existen dos
o más árboles de derivación distintos para la misma sentencia.
Otra forma de definirlo sería considerar ambiguas aquellas gramáticas para las que
existen dos derivaciones leftmost (o rightmost) distintas para la misma sentencia.

Ejemplo: Consideremos la gramática dada por las reglas:

E → E + E|E × E|I

I → a|b|c

Se trata de una gramática ambigua ya que la sentencia a + b × c tiene dos


derivaciones distintas leftmost.

1. E → E + E → I + E → a + E → a + E × E → a + I × E → a + b × E →
a+b×I →a+b×c

2. E → E × E → E + E × E → I + E × E → a + E × E → a + I × E →
a+b×E →a+b×I →a+b×c

Ya vimos que dos gramáticas son equivalentes si generan el mismo lenguaje pero
vamos a recalcar que hay infinitas gramáticas que generan el mismo lenguaje.
Dada una gramática G=(T,N,S P) para obtener otra equivalente basta con hacer
otra:
G0 = (T, N ∪ {Z}, Z, P ∪ {Z → E})

13 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo III

Autómatas finitos: deterministas


y no deterministas

Autómata Definición III.1 Autómata finito determinista. Se representa como:


finito de-
terminista A = (Q, Σ, δ, q0 , F )
donde:

Q = conjunto de estados
Σ = alfabeto de entrada
δ = función de transición: δ : Q × Σ → Q
q0 = estado inicial ∈ Q
F = conjunto de estados finales, F ⊂ Q

Función de Definición III.2 Función de transición extendida . Consiste en una extensión de


transición la función de transición a cadenas. Se representa como δ ∗ :
extendida
δ ∗ (q, w) = q1
Siendo w ∈ Σ∗ , q el estado en el que comenzamos y q1 el estado al que llegamos tras
procesar toda la palabra. Recordemos que Σ es el alfabeto de entrada (conjunto de
símbolos) y Σ∗ es el conjunto formado por todas las posibles cadenas de símbolos que
puedes crear con dicho alfabeto.

Lenguaje Definición III.3 Lenguaje aceptado por un AFD. El lenguaje aceptado por un
aceptado autómata finito determinista, A, es el conjunto de palabras que llevan al autómata a
por un un estado final.
AFD
L(A) = {w ∈ Σ∗ : δ ∗ (q0 , w) ∈ F }

Veamos algún ejemplo:

14 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejemplo: Queremos un autómata que reconozca el lenguaje: L={101,110}


El autómata resultado es:

Observación: : Un autómata determinista tiene que tener todas las transiciones


definidas, se sobreentiende que las transiciones que no están dibujadas van a un sexto
estado en el cual se quedan colgadas.
Este autómata es determinista y su transición de estados dada una entrada "101"
sería:

entrada: 1 0 1
q0 q1 q3 q4

Por tanto "101" forma parte del lenguaje del autómata.


Pero podríamos representar el mismo lenguaje con un autómata no determinista:

Y su transición de estados dada una entrada "101" sería:

entrada: 1 0 1
q0 q1 q4 q5
q2 - -

Como al menos uno de los caminos lleva a un estado final, la cadena "101" forma
parte del lenguaje del autómata (los guiones indican transición no definida, o a un
estado vacío).
La ventaja de un autómata no determinista es que podemos explorar varias ramas
en paralelo.

15 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Transición Definición III.4 Transición λ. Transición que puede ocurrir sin consumir ningún valor
λ de entrada. Un autómata finito que tenga transiciones de este tipo se considera no
determinista.

Autómata Definición III.5 Autómata finito no determinista. AFN . Autómata con función
finito no de transición de la forma:
deter-
δ : Q × (Σ ∪ {λ}) → 2Q
minista.
AFN Es decir, dado un estado y una entrada (posiblemente vacía) salta a un conjunto de
estados.

Función de Definición III.6 Función de transición de un AFN extendida . Consiste en una


transición extensión de la función de transición a cadenas. Se representa como δ ∗ :
de un AFN
extendida δ ∗ (q, w) = E
Siendo w ∈ Σ∗ , q el estado en el que empezamos y E el conjunto de estados a los que
llegamos tras procesar toda la palabra.

Lenguaje Definición III.7 Lenguaje aceptado por un AFN. El lenguaje aceptado por un
aceptado autómata finito no determinista, A, es el conjunto de palabras que llevan al autómata
por un a un estado final.
AFN
L(A) = {w ∈ Σ∗ : δ ∗ (q0 , w) ∩ F 6= ∅}

Ejemplo: Diseñar un autómata para el siguiente lenguaje


Tenemos el alfabeto: Σ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, −, ·} con las siguientes
restricciones:

1. Signo puede o no aparecer


2. Parte decimal puede aparecer o no
3. Parte entera puede o no aparecer
4. Debe haber al menos parte entera o decimal.

El autómata queda:

16 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Fuentes de Definición III.8 Fuentes de indeterminismo de un AF. Un autómata finito no


indetermi- determinista se caracteriza por tener alguna de las siguientes propiedades:
nismo de
un AF
a. Con la misma entrada, varias transiciones posibles para un mismo estado.

b. Hay transiciones lambda

c. Se puede transitar a ∅ (transiciones no definidas)

Ejemplo: Otro ejemplo de autómata no determinista podría ser:

Cuya transición de estados dada una entrada "101" sería:

Estados 1 0 1
q0 - - -
q1 q2 q4 q5

En este autómata, podemos avanzar al estado ’q1’ a través de la transición λ,


aunque el primer símbolo de la entrada sea un ’1’, (segunda línea de la tabla). Sin
embargo en el camino en el que nos mantenemos en el estado ’q0’ (primera línea de
la tabla), no tenemos la transición definida con entrada ’1’ y vamos al estado vacío.
Llegamos a un estado final, por tanto la palabra "101" pertenece al lenguaje de este
autómata.

Teorema III.1. Los autómatas finitos no deterministas y deterministas son


equivalentes.

Esto significa que dado un autómata finito determinista que acepta un determinado
lenguaje, existe otro no determinista que acepta el mismo lenguaje, y viceversa. Se
utilizan los AFN por comodidad, porque las demostraciones formales son más sencillas.

17 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

III.1. Equivalencia entre AF y ER


Vamos a ver cuál es la relación existente entre los autómatas finitos y las expresiones
regulares.
Como ya vimos una gramática puede expresarse como una cuádrupla G=(N,T,S,R),
es decir, consta de símbolos no terminales, símbolos terminales, un símbolo inicial o
axioma y unas reglas de producción.
Recordamos también que una gramática regular es aquella que es lineal por la
derecha o lineal por la izquierda
Hay 4 formas de representar un lenguaje regular, y en ellas reside la equivalencia
entre autómatas finitos y expresiones regulares. Las 4 formas de representar un lenguaje
regular son:

1. Describiendo todos sus componentes

2. Con una gramática regular

3. Con una expresión regular

4. Mediante un AFN/AFD

18 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo IV

Autómatas a pila

Dado el lenguaje:
L = {wwR  w ∈ (0 + 1)∗ }
que representa palabras capicúas sobre {0, 1} con un número par de símbolos, vamos
a intentar construir un autómata finito para él.
Esto no es posible ya que siempre necesito llegar hasta la mitad de la palabra
“almacenando” lo que hemos leído para después comprobar que lo leemos al revés.
Puesto que la palabra puede tener longitud arbitraria, necesitaremos una cantidad de
memoria arbitraria y esto no es viable (sería necesario un autómata con un número
infinito de estados).
Es aquí donde surgen los autómatas a pila. Estos autómatas se caracterizan por
que en cada salto indicamos una entrada, saca el símbolo de la cima de la pila y añade
una cadena a la pila.
Para el lenguaje dado, el autómata a pila que lo representa sería:

En teoría, las etiquetas de los arcos del autómata son de la forma:

Acb

donde A sería la entrada leída, b el elemento que extraemos del tope de la pila y c la
cadena que insertamos en la pila. Por tanto una transición solo se puede dar si aparte
de tener la entrada correspondiente, la cima de la pila coincide con lo que vamos a
extraer de ella. Introducir az implica que la ’a’ se queda como cima de la pila, y la ’z’
detrás.
En algunos ejercicios usaremos la notación {b, A, c} con idéntico significado.

19 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Autómata Definición IV.1 Autómata a pila. Un autómata a pila se representa como:


a pila
A = (Q, Σ, δ, q0 , F, T , A0 )

siendo:

Q: conjunto de estados

Σ: alfabeto de entrada

δ: función de transición: δ : Q × (Σ ∪ {λ}) × T → 2Q×T

q0 : estado inicial ∈ Q

F : conjunto de estados finales

T : alfabeto de la pila

A0 : símbolo inicial de la pila ∈ τ

Nota: En realidad el codominio de δ es el conjunto de subconjuntos finitos de Q × T ∗ .


Básicamente consiste en un autómata, como los vistos hasta ahora, acompañado
de una pila en la que realizaremos inserciones y extracciones en cada transición.
Vamos a ver un pequeño ejemplo que explica cómo entender la función de
transición:

Ejemplo: La evaluación de la función de transición:

δ(q, a, x) = {(p, y)}

con q, p ∈ Q, a ∈ Σ, x ∈ T y y ∈ T ∗ . Implica que, estando en el estado ’q’, ante una


entrada ’a’, habiendo en la cima de la pila un ’x’ pasamos al estado ’p’, insertando en
la pila ’y’, y sacando la ’x’.
En estos autómatas los conceptos de determinismo o no determinismo se
mantienen. Es decir, un autómata a pila será no determinista si dada una entrada
y un elemento a extraer de la cima de la pila tiene varias acciones que puede llevar
a cabo (varios pares (’estado’,’inserción en pila’)). Profundizaremos más adelante en
este concepto.

Observación: Aunque un autómata finito determinista es equivalente a uno no


determinista, con autómatas a pila no ocurre lo mismo.

Autómata Definición IV.2 Autómata a pila determinista. Un autómata a pila será


a pila de- determinista si cumple las siguientes condiciones:
terminista
No hay transiciones λ o, si las hay, no hay ninguna otra transición con un símbolo
diferente. Es decir, si desde un estado p y con a en la pila pudieras pasar a otro
q por una transición lambda, no habría otra posible transición desde el estado p
y con a en la pila.

20 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Dada una situación (estado p, símbolo de entrada x y símbolo a en la cima de


la pila) δ(p, x, a) contiene como mucho un elemento (q, b).

Descripción Definición IV.3 Descripción instantánea. Se trata de una representación de la


instantá- situación actual del autómata. (q,X,A) es una descripción instantánea donde:
nea

a. q = Nodo/estado en el que nos encontramos

b. X = Entrada que falta por leer, X ∈ Σ∗

c. A = Contenido de la pila, A ∈ T ∗

Dada una descripción instantánea podemos continuar el procesamiento de la cadena


sin perder información.

Precedencia Definición IV.4 Precedencia entre descripciones instantáneas. Decimos que una
entre des- descripción instantánea precede a otra:
cripciones
instantá- (q, xX, aA) ` (p, X, bA)
neas
si:
(p, b) ∈ δ(q, x, a)
Siendo ’p’,’q’ nodos del autómata, ’x’ el siguiente símbolo de entrada que se va a leer,
’X’ el resto de la cadena de entrada; ’a’ el carácter que hay en la cima de la pila, ’A’ el
resto del contenido de la pila y,’b’ una cadena de símbolos que insertamos en la pila.
En este transición se lee ’x’, se saca ’a’ de la cima de la pila y se introduce ’b’.
Es decir, una descripción instantánea precede a otra si hay una transición que nos
lleva de una a otra.

Precedencia Definición IV.5 Precedencia *. Decimos que hay precedencia * entre dos
* descripciones instantáneas:
(q, X, A) `∗ (p, Y, B)
cuando hay una secuencia d0 , d1 , ..., dn de descripciones instantáneas tales que:

(q, X, A) = d0 ` d1 ` ... ` dn = (p, Y, B)

con p, q ∈ Q, X, Y ∈ Σ∗ y A, B ∈ T ∗ .
Basándonos en estas definiciones, podemos representar el lenguaje aceptado por
un autómata a pila como:

L(A) = {w ∈ Σ∗  (q0 , w, A0 ) `∗ (p, λ, X)}

con p ∈ F, X ∈ T ∗

21 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejemplo: Queremos encontrar un autómata que represente el lenguaje:

L = {an bn , n ≥ 0}

El autómata de pila que representa este lenguaje es:

22 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo V

Gramáticas de atributos

Un compilador se encarga de generar el código máquina a partir de un código dado.


En primer lugar debemos saber que un compilador realiza tres tareas:

1. Análisis morfológico. A estas alturas consideramos que ya nos viene hecho y


no nos preocupamos por ello.

2. Análisis sintáctico. Consiste en construir el árbol de derivación. Es decir, se


comprueba que la sentencia obtenida sale de derivar el axioma.

3. Análisis semántico. Consiste en recorrer el árbol de derivación calculando


atributos y realizando comprobaciones semánticas.

Vamos a centrarnos ahora en análisis semántico.

V.1. Análisis semántico


Vamos a explicar brevemente la idea que hay detrás de esto:
Partiendo de una gramática independiente del contexto, y derivando el axioma
hasta obtener una sentencia, queremos obtener alguna función específica de nuestra
gramática.
Es entonces cuando surgen las gramáticas de atributos, que añaden lo siguiente a
la gramática independiente del contexto:

Incorporan atributos a los nodos no terminales.

Incorporan funciones sobre esos atributos en las reglas de derivación. (Además


veremos que estas funciones se podrán realizar en instantes concretos).

Incorporan una información global a la gramática. La información global está


formada por un conjunto de variables que son accesibles desde cualquier nodo
del árbol.

23 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Por tanto, una vez obtenido el árbol de derivación, el análisis semántico recorrerá dicho
árbol utilizando el recorrido en profundidad por la izquierda y con vuelta atrás
(lo explicamos más adelante) corroborando el buen funcionamiento de estas nuevas
funciones.
El paso de información de un nodo a otro del árbol se podrá realizar mediante tres
métodos:

Síntesis: la información se propaga del nodo inferior al nodo superior.


Herencia: la información se propaga del nodo superior al nodo inferior.
Usando la información global.

Vamos a ver un ejemplo con detalle, explicando sobre él algunos de los conceptos:
Como hemos dicho, la idea es que dada una gramática independiente del contexto,
podemos conseguir que esta realice funciones específicas. Lo conseguimos añadiendo
atributos y especificaciones a las reglas de derivación.

Ejemplo: Consideremos la gramática:


G = {{(, )}, {L, I}, L, P }
Con las reglas de derivación P:

L → (I)
I → (I)
I → II
I→λ

En primer lugar vamos a derivar el axioma y obtener una sentencia, nos queda (por
ejemplo) el siguiente árbol de derivación:

I I

I I

( ( λ ) ( ( λ ) ) )

24 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Vemos que sintácticamente es correcto ya que se obtiene de derivar el axioma L.


Queremos hacer que esta gramática nos devuelva la profundidad de una expresión,
es decir, el máximo número de paréntesis contenidos unos en otros.
Para ello, vamos a utilizar gramática de atributos, en primer lugar debemos añadir
a los elementos L e I un atributo profundidad.
Vamos a intentar hacerlo propagando el atributo profundidad hacia arriba (es decir,
usando síntesis). Por ello, un nodo terminal como sería λ debería tener profundidad 0.
Por lo que la cuarta regla queda de la forma:

I → λ{I.prof = 0}

En las dos primeras reglas, debemos realizar una propagación hacia arriba,
aumentando en uno la profundidad. Así estas dos primeras reglas quedan de la forma:

L → (I){L.prof = I.prof + 1}

I1 → (I2 ){I1 .prof = I2 .prof + 1}

Para la tercera regla, podemos ver que la profundidad que asciende será el máximo
de las profundidades de cada uno de los símbolos en los que deriva. La tercera regla
quedaría:
I1 → I2 I3 {I1 .prof = max(I2 .prof, I3 .prof )}

Si ahora analizamos los instantes en que se realizaría la función de cada regla y


agrupamos todo lo indicado anteriormente llegamos a:

G = {{(, )}, {L(prof ), I(prof )}, L, P, ∅}

Con P:

L → (I){2 : L.prof = I.prof + 1}

I1 → (I2 ){2 : I1 .prof = I2 .prof + 1}

I1 → I2 I3 {2 : I1 .prof = max(I2 .prof, I3 .prof )}

I → λ{0 : I.prof = 0}

Así, hemos conseguido una gramática de atributos que realiza una función específica
(obtener la profundidad). Lo hemos logrado a partir de una gramática independiente
del contexto añadiendo atributos y el instante en el que debo realizar cada asignación
en las reglas de derivación.
Además, una gramática de atributos contiene una información global. En este caso
no la vamos a usar por lo que la declaramos vacía (es el último símbolo que se ha
añadido a G).
También debemos saber que el árbol se recorre en profundidad por la izquierda y
con vuelta atrás. Esta técnica consiste en recorrer siempre el hijo más a la izquierda,
cuando no queden hijos a la izquierda, continuamos con el siguiente hijo más a la
izquierda. Cuando no queden hijos volvemos al nodo superior y así sucesivamente.

25 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Si suponemos un caso simple en el que un nodo raíz tiene n hijos inmediatos,


podemos ver que al aplicar este procedimiento recorremos el nodo raíz n+1 veces. Por
tanto el nodo raíz tendrá n+1 instantes.
Vamos a dejar claro a qué nos referimos con el instante en el que realizo la función
de cada regla. Para ello, debemos saber que al realizar el análisis semántico cada nodo
sabe qué regla de derivación se ha usado sobre él, y por tanto conocerá el número
de hijos inmediatos que tiene. Así, por ejemplo un nodo I al que le aplicamos la regla
I1 → I2 I3 , tiene 3 instantes:
-El instante 0, en el que se visita el nodo I1 .
-El instante 1, en el que se vuelve al nodo I1 después de haber visitado el nodo I2 .
-El instante 2, en el que se vuelve al nodo I1 después de haber visitado el nodo I3 .
Veamos ahora como queda el árbol realizando el recorrido en profundidad por la
izquierda y con vuelta atrás y aplicando las distintas funciones:
L
0:nada
p=2 en instante 2

I1
p=2 en instante 2

I2 I3
p=1 en instante 2 p=2 en instante 2

I4 I5
p=0 en instante 0 p=1 en instante 2

I6
p=0 en instante 0

( ( λ ) ( ( λ ) ) )

Hemos puesto superíndices a las I para poder referirnos ahora a ellas:


El recorrido en profundidad de esté árbol quedaría:
Empezamos en L, estamos en el instante 0 de L... bajamos a (, como es terminal no
hacemos nada... subimos a L, instante 1 de L... bajamos a I 1 , instante 0 de I 1 ...bajamos
a I 2 , instante 0 de I 2 ... bajamos a ( como es terminal no hacemos nada... subimos a
I 2 , instante 1 de I 2 ...bajamos a I 4 , instante 0 de I 4 , que como es un nodo que deriva
con la regla I → λ le aplicamos la función I.prof = 0... subimos a I 2 , instante 2 de
I 2 , que como es un nodo que deriva con la regla I1 → (I2 ), le aplicamos la función
I1 .prof = I2 .prof + 1, por tanto tenemos ahora mismo I 2 .prof = 1... bajamos a
), como es un nodo terminal no hacemos nada... subimos a I 2 , instante 3 de I 2 ...
subimos a I 1 , instante 1 de I 1 ... bajamos a I 3 , instante 0 de I 3 ... etc etc etc.

26 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejemplo: Vamos a apoyarnos en la gramática definida en el ejemplo anterior y a


modificar simplemente las acciones, con el fin de obtener un programa que cuente el
número de listas (parejas de paréntesis).
Vamos a realizarlo de tres formas distintas: con síntesis, herencia y con información
global. Estas diferentes formas dan lugar a diferentes acciones, pero el árbol de
derivación sigue siendo el mismo.
Cada una de las reglas de derivación serían:

Síntesis
G = {{(, )}, {L(n), I(n)}, L, P }

• L → (I){2 : L.n = I.n + 1}


• I1 → (I2 ){2 : I1 .n = I2 .n + 1}
• I1 → I2 I3 {2 : I1 .n = I2 .n + I3 .n)}
• I → λ{0 : I.n = 0}

Herencia
G = {{(, )}, {L(n), I(antes, despues)}, L, P }

• L → (I){0 : I.antes = 1, 2 : L.n = I.despues}


• I1 → (I2 ){0 : I2 .antes = I1 .antes + 1, 2 : I1 .despues = I2 .despues}
• I1 → I2 I3 {0 : I2 .antes = I1 .antes, 1 : I3 .antes = I2 .despues, 2 :
I1 .despues = I3 .despues}
• I → λ{0 : I.despues = I.antes}

Hemos usado alguna acción que se sale de un esquema puro de herencia por ser
imposible realizarlo de otra forma.

Información global

G = {{(, )}, {L, I}, L, P, {n}}

• L → (I){0 : n = 0; 1 : n = n + 1}
• I1 → (I2 ){0 : n = n + 1}
• I1 → I2 I3
• I→λ

Este caso es bastante más sencillo, pues en cada derivación tienes acceso al
contador global y basta con incrementarlo, sin preocuparte por los sucesores.
Usando información global es realmente importante indicar los instantes en
que se realiza cada acción puesto que de lo contrario habría lugar a confusión.
(En los casos anteriores los atributos imponían un orden sin ambigüedad).

En las transparencias podéis ver estos tres ejemplos para diferenciar la herencia, la
síntesis y la información global (llamada tabla de símbolos):

27 de 100 14 de junio de 2016 12:49


Ejemplo 1 (sı́ntesis) Ejemplo 1 (sı́ntesis)

Gramática independiente del contexto: Gramática de atributos:


G = {{+, ∗, (, ), c, i}, {E }, E , P} G = {{+, ∗, (, ), c(tipo, valor ), i}, {E (tipo, valor )}, E , P}
Conjunto de reglas de producción P: Conjunto de reglas de producción P:
E ::= E + E E1 ::= E2 + E3 {E1 .valor = E2 .valor + E3 .valor ; E1 .tipo = E2 .tipo}
E ::= E ∗ E E1 ::= E2 ∗ E3 {E1 .valor = E2 .valor ∗ E3 .valor ; E1 .tipo = E2 .tipo}
E ::= (E ) E1 ::= (E2 ) {E1 .valor = E2 .valor ; E1 .tipo = E2 .tipo}
E ::= i E ::= i
E ::= c E ::= c {E .valor = c.valor ; E .tipo = c.tipo}

AutLen () Gramáticas de atributos 7 de octubre de 2014 2 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 3 / 27

Ejemplo 1 (sı́ntesis) Ejemplo 1 (sı́ntesis)


Analizador morfológico

E E

E E

E E

E E

c c c
c c c
c.valor = 4 c.valor = 2 c.valor = 3
c.tipo = int c.tipo = int c.tipo = int

( 4 + 2 ) * 3

( 4 + 2 ) * 3

AutLen () Gramáticas de atributos 7 de octubre de 2014 4 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 5 / 27

Ejemplo 1 (sı́ntesis) Ejemplo 1 (sı́ntesis)


E ::= c E ::= E + E

E E

E E E E

E
E E.valor = 6
E.tipo = int

E E E E
E.valor = 4 E.valor = 2 E.valor = 4 E.valor = 2
E.tipo = int E.tipo = int E.tipo = int E.tipo = int

c c c c c c
c.valor = 4 c.valor = 2 c.valor = 3 c.valor = 4 c.valor = 2 c.valor = 3
c.tipo = int c.tipo = int c.tipo = int c.tipo = int c.tipo = int c.tipo = int

( 4 + 2 ) * 3 ( 4 + 2 ) * 3

AutLen () Gramáticas de atributos 7 de octubre de 2014 6 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 7 / 27

Ejemplo 1 (sı́ntesis) Ejemplo 1 (sı́ntesis)


E ::= (E ) E ::= c E ::= E ∗ E

E
E E.valor = 18
E.tipo = int

E E E E
E.valor = 6 E.valor = 3 E.valor = 6 E.valor = 3
E.tipo = int E.tipo = int E.tipo = int E.tipo = int

E E
E.valor = 6 E.valor = 6
E.tipo = int E.tipo = int

E E E E
E.valor = 4 E.valor = 2 E.valor = 4 E.valor = 2
E.tipo = int E.tipo = int E.tipo = int E.tipo = int

c c c c c c
c.valor = 4 c.valor = 2 c.valor = 3 c.valor = 4 c.valor = 2 c.valor = 3
c.tipo = int c.tipo = int c.tipo = int c.tipo = int c.tipo = int c.tipo = int

( 4 + 2 ) * 3 ( 4 + 2 ) * 3

AutLen () Gramáticas de atributos 7 de octubre de 2014 8 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 9 / 27
Ejemplo 2 (herencia) Ejemplo 2 (herencia)

Gramática independiente del contexto: Gramática de atributos:


G= {{int, float, i,00 ,00 }, {D, T , L}, D, P} G = {{int, float, i(nombre),00 ,00 }, {D(tipo), T (tipo), L(tipo)}, D, P}
Conjunto de reglas de producción P: Conjunto de reglas de producción P:
D ::= TL D ::= TL{D.tipo = T .tipo; L.tipo = T .tipo}
T ::= int T ::= int{T .tipo = int}
T ::= float T ::= float{T .tipo = float}
L ::= L, i L1 ::= L2 , i{L2 .tipo = L1 .tipo; i.tipo = L1 .tipo}
L ::= i L ::= i{i.tipo = L.tipo}

AutLen () Gramáticas de atributos 7 de octubre de 2014 10 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 11 / 27

Ejemplo 2 (herencia) Ejemplo 2 (herencia)


T := int
D
D

T
L
T L T.tipo = int

L
L

L
L

i i i
i i i
i.nombre = x i.nombre = y i.nombre = z
i.nombre = x i.nombre = y i.nombre = z

int x , y , z
int x , y , z

AutLen () Gramáticas de atributos 7 de octubre de 2014 12 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 13 / 27

Ejemplo 2 (herencia) Ejemplo 2 (herencia)


D ::= TL L ::= L, i
D D
D.tipo = int D.tipo = int

T L T L
T.tipo = int L.tipo = int T.tipo = int L.tipo = int

L L
L.tipo = int

L L

i i i i i i
i.nombre = x i.nombre = y i.nombre = z i.nombre = x i.nombre = y i.nombre = z

int x , y , z int x , y , z

AutLen () Gramáticas de atributos 7 de octubre de 2014 14 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 15 / 27

Ejemplo 2 (herencia) Ejemplo 2 (herencia)


L ::= L, i L ::= i
D D
D.tipo = int D.tipo = int

T L T L
T.tipo = int L.tipo = int T.tipo = int L.tipo = int

L L
L.tipo = int L.tipo = int

L L
L.tipo = int L.tipo = int

i i i i i i
i.nombre = x i.nombre = y i.nombre = z i.nombre = x i.nombre = y i.nombre = z

int x , y , z int x , y , z

AutLen () Gramáticas de atributos 7 de octubre de 2014 16 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 17 / 27
Ejemplo 3 (información global) Ejemplo 3 (información global)
Gramática de atributos:
Gramática independiente del contexto:
G = {{int, float, c(valor , tipo), i(nombre),00 ,00 , +, ∗, (, ), =},
G = {{int, float, c, i,00 ,00 , +, ∗, (, ), =}, {P, D, A, T , L, E }, P, R}
{P, D(tipo), A(valor , tipo), T (tipo), L(tipo), E (valor , tipo)}, P, R}
Conjunto de reglas de producción R:
Conjunto de reglas de producción R:
P ::= DA
P ::= DA
D ::= TL
D ::= TL{D.tipo = T .tipo; L.tipo = T .tipo}
T ::= int
T ::= int{T .tipo = int}
T ::= float
T ::= float{T .tipo = float}
L ::= L, i
L1 ::= L2 , i{L2 .tipo = L1.tipo; st(i.nombre, L1 .tipo)}
L ::= i
L ::= i{st(i.nombre, L.tipo)}
A ::= i = E
A ::= i = E {A.valor = E .valor ; A.tipo = E .tipo; sv (i.nombre, E .valor )}
E ::= E + E
E1 ::= E2 + E3 {E1 .valor = E2 .valor + E3 .valor ; E1 .tipo = E2 .tipo}
E ::= E ∗ E
E1 ::= E2 ∗ E3 {E1 .valor = E2 .valor ∗ E3 .valor ; E1 .tipo = E2 .tipo}
E ::= (E )
E1 ::= (E2 ){E1 .valor = E2 .valor ; E1 .tipo = E2 .tipo}
E ::= i
E ::= i{E .valor = gv (i.nombre); E .tipo = gt(i.nombre)}
E ::= c
E ::= c{E .valor = c.valor ; E .tipo = c.tipo}

AutLen () Gramáticas de atributos 7 de octubre de 2014 18 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 19 / 27

Ejemplo 3 (información global) Ejemplo 3 (información global)


T ::= int
P

D A

D A

T L E
T
L E
T.tipo = int

L E E

L E E

c c
i i i
c.valor = 3 c.valor = 5
i.nombre = x i.nombre = y i.nombre = x c c
c.tipo = int c.tipo = int i i i
c.valor = 3 c.valor = 5
i.nombre = x i.nombre = y i.nombre = x
c.tipo = int c.tipo = int

int x , y x = 3 + 5

int x , y x = 3 + 5

TS

TS

AutLen () Gramáticas de atributos 7 de octubre de 2014 20 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 21 / 27

Ejemplo 3 (información global) Ejemplo 3 (información global)


D ::= TL L ::= L, i

P P

D D
A A
D.tipo = int D.tipo = int

T L T L
E E
T.tipo = int L.tipo = int T.tipo = int L.tipo = int

L E E L
E E
L.tipo = int

c c c c
i i i i i i
c.valor = 3 c.valor = 5 c.valor = 3 c.valor = 5
i.nombre = x i.nombre = y i.nombre = x i.nombre = x i.nombre = y i.nombre = x
c.tipo = int c.tipo = int c.tipo = int c.tipo = int

int x , y x = 3 + 5 int x , y x = 3 + 5

TS TS
y(int, ?)

AutLen () Gramáticas de atributos 7 de octubre de 2014 22 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 23 / 27

Ejemplo 3 (información global) Ejemplo 3 (información global)


L ::= i E ::= c

P P

D D
A A
D.tipo = int D.tipo = int

T L T L
E E
T.tipo = int L.tipo = int T.tipo = int L.tipo = int

E E
L L
E E E.valor = 3 E.valor = 5
L.tipo = int L.tipo = int
E.tipo = int E.tipo = int

c c c c
i i i i i i
c.valor = 3 c.valor = 5 c.valor = 3 c.valor = 5
i.nombre = x i.nombre = y i.nombre = x i.nombre = x i.nombre = y i.nombre = x
c.tipo = int c.tipo = int c.tipo = int c.tipo = int

int x , y x = 3 + 5 int x , y x = 3 + 5

TS TS
y(int, ?) y(int, ?)
x(int, ?) x(int, ?)

AutLen () Gramáticas de atributos 7 de octubre de 2014 24 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 25 / 27
Ejemplo 3 (información global) Ejemplo 3 (información global)
E ::= E + E A ::= i = E

P P

A
D D
A A.valor = 8
D.tipo = int D.tipo = int
A.tipo = int

E E
T L T L
E.valor = 8 E.valor = 8
T.tipo = int L.tipo = int T.tipo = int L.tipo = int
E.tipo = int E.tipo = int

E E E E
L L
E.valor = 3 E.valor = 5 E.valor = 3 E.valor = 5
L.tipo = int L.tipo = int
E.tipo = int E.tipo = int E.tipo = int E.tipo = int

c c c c
i i i i i i
c.valor = 3 c.valor = 5 c.valor = 3 c.valor = 5
i.nombre = x i.nombre = y i.nombre = x i.nombre = x i.nombre = y i.nombre = x
c.tipo = int c.tipo = int c.tipo = int c.tipo = int

int x , y x = 3 + 5 int x , y x = 3 + 5

TS TS
y(int, ?) y(int, ?)
x(int, ?) x(int, 8)

AutLen () Gramáticas de atributos 7 de octubre de 2014 26 / 27 AutLen () Gramáticas de atributos 7 de octubre de 2014 27 / 27
Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejemplo: Para ver claramente las diferencia entre análisis semántico y sintáctico
nos podemos fijar en lo siguiente, según el ejemplo 1, el código:

int _x,_y
_x=7

es correcto semántica y sintácticamente, mientras que el código:

int _x,_y
_z=7

es sintácticamente correcto pero no semánticamente.

Ejemplo: Vamos a tomar un caso sencillo con dos reglas sacadas del último ejemplo
mostrado en las transparencias. La semántica es:

L → i{st(i.nombre, L.tipo}

A → i = E{inT S(i.nombre) == true; gt(i.nombre) ==


E.tipo; sv(i.nombre, E.valor)}

Para la primera regla, el orden en que se recorrería el árbol de derivación es:

- En el instante 0 bajamos del nodo L al nodo i,


- En el instante 1 volvemos al nodo L.

Como es lógico, la operación de setType representada en la gramática no puede


realizarse hasta conocer el tipo de L y el nombre de i, por lo que se realiza en el instante
1.
Lo representaríamos como:

L → i{1 : st(i.nombre, L.tipo}

Vamos ahora con la segunda regla. El orden en el que se recorrería el árbol de


derivación seria:

- En el instante 0 bajamos del nodo A al nodo i, en el instante 1 volvemos al A.


- En ese instante bajaríamos al nodo =, del que volveríamos en el instante 2.
- Por último bajaríamos al nodo E y volveríamos del mismo en el instante 3

Siguiendo esta secuencia y analizando en qué momento tenemos disponibles los


valores para cada operación la segunda regla de la gramática sería de la forma:

A → i = E{1 : inT S(i.nombre) == true; 3 : gt(i.nombre) == E.tipo; 3 : sv(i.nombre, E.valor)}

En este tercer ejemplo es importante añadir algunas comprobaciones más en las


reglas, que no vienen en las transparencias:

32 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

En la regla A → i = E comprobar inT S(i.nombre) == true (es decir, ¿está


en la tabla de símbolos i.nombre?)

En la regla E1 → E2 + E3 y E1 → E2 ∗ E3 comprobar que E2 .tipo = E3 .tipo

En la regla E → i comprobar inT S(i.nombre) == true y gt(i.nombre) ==


E.tipo con gt=getType (es decir, ¿es el parámetro tipo de i.nombre igual al de
E?).

33 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo VI

Analizador morfológico

Empezamos este capítulo recordando la función de un compilador.


Dado un archivo fuente, este archivo pasará a través de un analizador de código,
que realiza tres funciones, utilizando para ello una tabla de símbolos que él mismo
genera:

Análisis morfológico
Análisis sintáctico
Análisis semántico

Tras ser analizado, se genera un árbol de derivación como los vistos hasta ahora.
Nos centramos ahora en el analizador morfológico (también llamado léxico o
scanner). Este realiza principalmente la siguiente función:
Obtención de unidades sintácticas. Son los llamados tokens. Estos pueden ser
identificadores, constantes, palabras reservadas (if , them, f or,...) u otros símbolos
(simples: +, =,... o dobles: :=,...).

No obstante, el analizador morfológico también es importante en la consecución de


las siguientes tareas secundarias:

1. Eliminar delimitadores (espacios en blanco, tabuladores, saltos de línea...).


2. Eliminación de comentarios en el código.

3. Detecta errores morfológicos. (Símbolos inválidos, constantes e identificadores


mal construidos...)

4. Inicializa algunas tareas semánticas, es decir, calcula el valor de algunos atributos


de constantes o identificadores.

Lo vemos con un ejemplo: tenemos un lenguaje que admite el siguiente tipo de


objetos:

Identificadores: letra seguida de cero o más dígitos y letras.

34 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Constantes: (números enteros).

Palabras reservadas: begin, end, int, print.

Símbolos: tanto simples: ’;’ como dobles: ’:=’.

Con este lenguaje, y dado el siguiente fichero de entrada fuente.

begin
int A;
A := 100;
print A;
end

El analizador morfológico generará un fichero de salida semejante al siguiente:

<"begin",TOK_BEGIN>
<"int",TOK_INT>
<"A",TOK_ID, valor=’A’>
.
.
.
<"100",TOK_CONST, valor=100>
.
.
.

La 4a tarea secundaria, que tenía el analizador morfológico, es la que realiza la


función de crear un atributo valor e inicializarlo.

35 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo VII

Analizador sintáctico

VII.1. Introducción
Para llevar a cabo el análisis sintáctico de una entrada se emplean tablas de análisis.
Estas permiten analizar una sentencia, con el fin de saber si se trata de una sentencia
válida para una gramática dada o no.
Existen dos tipos de análisis: ascendente y descendente
Veamos un ejemplo:

Ejemplo: Dada la gramática:

1) E → E + E

2) E → E x E

3) E → -E

4) E → (E)

5) E → id

Vamos a realizar un análisis ascendente partiendo de la siguiente sentencia:

(id+id)xid

Para ello vamos a contar con la ayuda de una pila y nos basaremos en dos reglas
básicas:

1. Reducción Se aplicará siempre que sea posible. No hay elección.


Se lleva a cabo cuando los elementos de la cima de la pila coinciden con la parte
derecha de alguna regla de nuestra gramática.
En este caso se extraen los elementos de la pila y se sustituyen por la parte
izquierda de la regla indicada anteriormente.

36 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

2. Desplazamiento Se aplica cuando no puede realizarse ninguna reducción.


Consiste en introducir en la cima de la pila el siguiente elemento de la sentencia
que estamos analizando

Aplicando estas reglas a nuestra sentencia obtenemos el siguiente resultado:

Instante Entrada Pila Acción


0 (id+id)xid - Desplazamiento
1 id+id)xid ( Desplazamiento
2 +id)xid (id Reducción(5)
3 +id)xid (E Desplazamiento
4 id)xid (E+ Desplazamiento
5 )xid (E+id Reducción(5)
6 )xid (E+E Reducción(1)
7 )xid (E Desplazamiento
8 xid (E) Reducción(4)
9 xid E Desplazamiento
10 id Ex Desplazamiento
11 - Exid Reducción(5)
12 - ExE Reducción(2)
13 - E Fin

Puesto que en la pila sólo queda el axioma, concluimos que la sentencia es válida para
este lenguaje.
Tras este ejemplo podemos definir formalmente el algoritmo de análisis ascendente.

Análisis Definición VII.1 Análisis ascendente. Este algoritmo consiste de dos pasos:
ascenden-
te
Mientras queden elementos en la entrada:
desplazamos
mientras podemos reducir:
reducimos

Si en la pila sólo está el axioma:


OK.
En caso contrario:
ERROR.

Una vez visto el análisis ascendente el siguiente paso es estudiar el análisis


descendente.

Análisis Definición VII.2 Análisis descendente. Algoritmo para determinar si una entrada es
descen- válida o no para una gramática dada mediante derivaciones (partiendo del axioma)
dente
Es decir, tomamos el axioma y aplicamos derivaciones sucesivas intentando llegar
a la sentencia que queremos analizar.

37 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Si logramos generar la sentencia que estamos analizando, esta será válida. (En caso
contrario no)
Vamos a trabajar con gramáticas sencillas en las que sólo haya una derivación
posible en cada paso. En caso de no ser así deberíamos avanzar todo lo posible para
después hacer backtracking, comprobando que no dejamos caminos sin explorar.
Veámoslo con un ejemplo:

Ejemplo: Dada la gramática:

E → TB

B → +TB | λ

T → FX

X → *FX | λ

F → i | (E)

Vamos a usar un análisis descendente para comprobar si es válida la sentencia:

i*i

Para hacerlo apoyándonos en una pila, como en el ejemplo anterior, los pasos a seguir
son los siguientes:
Instante Pila Acción
1 E Derivamos
2 B|T Derivamos
3 B|X|F Derivamos
4 B|X|i Extraemos, pues i está en la sentencia dada
5 B|X Derivamos
6 B | X | F | * Extraemos, pues * está en la sentencia dada
7 B|X|F Derivamos
8 B|X|i Extraemos, pues i está en la sentencia dada
9 B|X Derivación λ
10 B Derivación λ
Si al finalizar nos queda la pila vacía concluimos que la sentencia estudiada es
correcta.
A lo largo de esta sección profundizaremos sobre el análisis ascendente y el análisis
descendente.

VII.2. Tablas de análisis ascendente


Vamos a estudiar ahora diferentes tablas de análisis (y autómatas asociados) que
se utilizan para realizar el análisis ascendente.

38 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

VII.2.1. Tablas LR(0)

Tabla Definición VII.3 Tabla LR(n). Tabla empleada para el procesamiento de entrada
LR(n) desde la izquierda (Left) mediante derivaciones Right-most con n símbolos de entrada.
Veamos un ejemplo de como funciona esta tabla de análisis

Ejemplo: Consideremos la gramática G=(T, N, E, P):

E → T | E+T

T → i | (E)

El primer paso para realizar el análisis LR(O) consiste en añadir un axioma E’ y la


regla:

E’ → E$

De forma que se obtiene la siguiente gramática extendida:

E’ → E $

E→T

E → E+T

T→i

T → (E)

Ahora lo que hacemos es añadir un ’.’ delante del símbolo que estemos analizando
en cada paso.
Para realizar el análisis por este método vamos a construir un autómata finito
determinista, que procesa una cadena de símbolos, empezando por el estado S0:

39 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Si aplicamos el algoritmo de análisis LR(0) a lo bruto, tras cada reducción todo lo


que hay en la pila (una vez aplicado el correspondiente cambio fruto de la reducción)
pasa al inicio de la cadena de entrada y saltamos al estado S0 para continuar con el
análisis.
No obstante, esta práctica implica deshacer lo andado muchas veces y alarga mucho
el desarrollo del algoritmo. Para evitar esto, en la pila guardamos, además de la última
entrada leída, el estado en que nos encontramos y tras una reducción nos desplazamos
al estado indicado en la pila justo antes de la reducción y añadimos la nueva cadena
(fruto de la reducción) al inicio de la cadena de entrada.
A continuación explicamos cómo se realiza el análisis a lo bruto.
Si el análisis de una cadena llega al estado de aceptación (Sacc ) en este autómata,
se termina el análisis concluyendo que la cadena es sintácticamente correcta.
Para construir el autómata seguimos los siguientes pasos:

Partimos en el estado S0 del axioma de la gramática extendida (E 0 ).

Situamos un ’.’ delante del símbolo que analizamos, en este caso empezamos
por el símbolo E. Ya que la regla de derivación del axioma es E 0 → E$. Por
tanto nos queda E 0 → .E$

Ahora tenemos que cerrar el símbolo que esta inmediatamente después del
punto. Si es un terminal ya estaría cerrado. Si es un no terminal lo cerramos
escribiendo las reglas de derivación del mismo, poniendo de nuevo un ’.’
delante del primer símbolo de cada una de las reglas y cerrando el símbolo
inmediatamente posterior al ’.’. Así terminamos el estado S0

Creamos los siguientes estados. La transición de un estado a otro se da a partir de


la entrada de un símbolo. Si entra un símbolo que se encuentra inmediatamente

40 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

después del ’.’, entonces se irá a un nuevo estado del autómata en el que ahora el
’.’ se encontrará en la siguiente posición dentro de la regla de derivación. Si llega
un símbolo que no está inmediatamente después del ’.’, se saltará a un estado
de error.

Si se llega a un estado en el que el ’.’ queda a la derecha de la regla de


derivación (sin ningún símbolo inmediatamente después), este estado será un
estado final. Esto implica que nada más llegar a este estado se reducirá la
regla (introduciendo en la entrada la pare izquierda de la regla )y volveremos al
estado inicial S0 .

A partir de este autómata se puede crear una tabla, denominada tabla de análisis
LR(0) que resume el funcionamiento del autómata:

En la cual vemos que se indica la acción a realizar según el estado en el que nos
encontremos y el símbolo de entrada que leamos.
Así, para realizar el análisis de una entrada nos basta con utilizar esta tabla y una
pila en la que vayamos guardando las acciones que vamos realizando.
A la hora de analizar una entrada realizamos los siguientes 5 tipos de acciones:

ERROR: si llegamos a una casilla en blanco de la tabla se deduce que la entrada


es incorrecta.

Desplazar (símbolo terminal): Avanzamos un símbolo en la entrada y lo


introducimos en la pila junto con el número del estado al que saltas. Corresponde
a las casillas dx, siendo x el estado al que saltamos.

Reducir: Sacar de la pila la parte derecha de la regla (doble de símbolos de los


que tiene la parte derecha ya que sacamos símbolo y número de estado al que
saltó). Tras la reducción se considera que volvemos al estado S0 con símbolo de
entrada el de la parte izquierda de la regla que se acaba de reducir. Corresponde
a las casillas rx, siendo x la regla de la gramática que reducimos.

41 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ir a (desplazamiento de símbolo no terminal). Saltar al estado indicando


introduciendo en la pila el no terminal y el estado al que se salta. Se aplica
justo después de realizar una reducción. No se avanza por tanto en la cadena
de entrada. Corresponde a las casillas de la tabla en la que hay solo un número
(estado al que saltamos).

Aceptar: Se acepta el símbolo e entrada si llegamos al estado de aceptación Sacc .

La siguiente tabla recoge el resultado detallado del análisis de la entrada (por


comodidad mostramos en análisis mejorado, guardando en la pila el estado en que nos
encontramos):
i + i + i$
Instante Entrada Pila2 Acción
0 i+i+i$ 0 d4: desplazar i, saltar a 4
1 +i+i$ 0i4 r3: Reducción con regla 3, T -> i
2 +i+i$ 0 7: desplazar T, ir a 7
3 +i+i$ 0T7 r1: reducción E -> T
4 +i+i$ 0 1: desplazar E, ir a 1
5 +i+i$ 0E1 d2: desplazar +, saltar a 2
6 i+i$ 0E1+2 d4: desplazar i, saltar a 4
7 +i$ 0E1+2i4 r3: reducción T -> i
8 +i$ 0E1+2 3: desplazar T, ir a 3
9 +i$ 0E1+2T3 r2: reducción E -> E+T
10 +i$ 0 1: desplazar E, ir a 1
11 +i$ 0E1 d2: desplazar +, saltar a 2
12 i$ 0E1+2 d4: desplazar i, saltar a 4
13 $ 0E1+2i4 r3: reducción T -> E
14 $ 0E1+2 3: desplazar T, ir a 3
15 $ 0E1+2T3 r2: reducción E -> E+T
16 $ 0 1: desplazar E, ir a 1
17 $ 0E1 Acepar: desplazas $ y saltas a Sacc

Ejemplo: Veamos un ejemplo del análisis de una expresión que termina en error:

42 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

VII.2.1.1. Conflictos, y herramientas para solucionarlos

Vamos a definir nuevos conceptos que pondremos en práctica en esta sección.


Las tablas LR(0) no son suficientemente potentes para representar todo tipo de
gramáticas. Podemos encontrarnos dos tipos de conflictos:

Conflicto desplazamiento/reducción: Se producen cuando te encuentras en un


estado final y además de la reducción, existe la posibilidad de desplazar.
Conflicto reducción/reducción: Se producen cuando te encuentras en un estado
final y puedes realizar una reducción utilizando dos reglas diferentes.

Para solucionar estos conflictos definimos primero(x) y siguiente(x):

Primero(A) Definición VII.4 Primero(A). El primero de A es el conjunto de terminales que pueden


aparecer al principio de una cadena derivada de A.
Veamos cómo calcular el primero de A. Para ello observamos que existen tres
diferentes casos para una regla de la forma A → α:

1. α ∈ T (Si α es un símbolo terminal): primero(A)=α


2. α ∈ N (Si α es un símbolo no terminal): primero(A)=primero(α)

Veamos un ejemplo

Ejemplo: Dada la gramática:

E → T E0
E 0 → +T E 0
E0 → λ
T → FT0
T 0 → ∗F T 0
T0 → λ
F → (E)
F →i

Vamos a calcular el primero de algunos símbolos. Por ejemplo:


primero(E’)={+, λ}
primero(T’)={∗, λ}
primero(F)={(, i}
primero(T)={(, i}
primero(E)={(, i}

43 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejemplo: Si tuviéramos la misma gramática que en el apartado anterior cambiando


la regla T 0 → λ por T 0 → λT , entonces:
primero(T’)={∗, λ, (, i}

Siguiente(A) Definición VII.5 Siguiente(A). Dada una gramática, el siguiente de un elemento,


A, es el conjunto de símbolos terminales que pueden aparecer justo después de A en
alguna forma sentencial derivada del axioma.

P∗ Para calcularlo formalmente, dada una regla : X 7−→ αA{β1 , β2 , ...}, con α, βi ∈

1. añadimos primero(β1 ) \λ a siguiente(A).

2. si λ ∈ primero(β1 ), repetimos (1) con β2 .

iteramos hasta que λ ∈


/ primero(βj ) o se acaben los símbolos a su derecha.

si se acaban los símbolos a su derecha, añadimos siguiente(X) a siguiente(A).

si el algoritmo te lleva a que en siguiente de un símbolo se debe unir siguiente


de ese mismo símbolo, se ignora.

Observación: $ ∈ Siguiente(axioma) siempre (Al formar la gramática extendida). En


este caso como el axioma es E, y ya existe un E’, habría que definir una nueva regla
del tipo E 00 → E$
Veamos un ejemplo para poner en práctica lo aprendido:

Ejemplo: Considerando la misma gramática del ejemplo anterior, tenemos:


E es el axioma, y por tanto tenemos que:
siguiente(T)=primero(E’) ∪ siguiente(E’) ∪ siguiente(E) = {+, ), $}
siguiente(E’)=siguiente(E) = {), $}
siguiente(E)={), $}
siguiente(F)=primero(T’) ∪ siguiente(T) ∪ siguiente(T’) = {+, ∗, ), $}
siguiente(T’)=siguiente(T) = {+, ), $}

VII.2.2. Tablas SLR(1)


Las tablas de análisis SLR(1) surgen para solucionar los conflictos desplazamien-
to/reducción. Lo vemos con un ejemplo:

44 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejemplo: Definimos la siguiente gramática extendida para aplicarle la tabla de


análisis LR(0):

(0) B’ → B $

(1) B → bD;Ef

(2) D → d

(3) D → D;d

(4) E → e

(5) E → e;E

Genera el siguiente autómata:

En el cual podemos observar que en el estado final S7 tenemos dos posibles acciones
si entra un ’;’, la de reducir (por ser estado final y encontrarse el ’.’ a la derecha de la
regla) o la de desplazar al estado S10
Por tanto nos quedaría la siguiente tabla de análisis LR(0):

45 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Concluimos que no es por tanto un autómata LR(0) ya que tenemos conflictos que
debemos solucionar. Para ello usaremos SLR(1).

Tabla Definición VII.6 Tabla SLR(1). Tabla que mejora la tabla de análisis LR(0)
SLR(1) modificando las transiciones de los estados finales del autómata.
En el caso de LR(0) realizaban una reducción siempre, mientras que en SLR(1) se
específica cuándo hay que realizar una reducción, cuándo un desplazamiento, y cuándo
vamos a un estado de error.
Por tanto el autómata quedará igual a simple vista (sólo que ahora habrá más
transiciones a estados de error aunque estas no aparezcan dibujadas). Los cambios los
mostraremos en la tabla de análisis.
La idea principal del análisis SLR(1) es que sólo aplicaremos las reducciones de
reglas de la forma X → algo, delante del Siguiente(X).
Vamos a calcular los elementos siguientes de los no terminales B, D y E.

siguiente(B) → $, por tanto las reducciones de B sólo se producirán delante del


símbolo $.

siguiente(D) → ;, por tanto las reducciones de B sólo se producirán delante del


símbolo $.

siguiente(E) → f, por tanto las reducciones de B sólo se producirán delante del


símbolo $.

Se eliminan así los conflictos, quedando la tabla de análisis de la siguiente manera:

Como podemos observar, en el estado S7, se reduce siguiendo la regla (4) (ver
las reglas de la gramática definidas al principio del ejemplo), pero sólo si el siguiente
elemento de la entrada es una f, ya que siguiente(E)=f.

46 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Conclusión: Para realizar una tabla de análisis SLR(1) basta con:

1. Hacer la tabla de análisis LR(0).

2. Calcular los elementos siguientes de los símbolos no terminales.

3. Modificar las filas de la tabla que correspondan a estados finales. Poniendo huecos
en blanco en todas las casillas salvo en aquellas en las que haya desplazamiento
y aquellas en las que realmente reduzcamos, es decir, en las que el siguiente
elemento del que vayamos a reducir coincida con el de la entrada.

VII.2.3. Tablas LR(1)


Las tablas LR(1) surgen para corregir los conflictos desplazamiento/reducción que
no es capaz de solventar el análisis SLR(1).
Veamos dos ejemplos en los que el análisis SLR(1) falla:

Ejemplo: Definimos la siguiente gramática extendida para aplicarle la tabla de


análisis SLR(1):

(0) E’ → E $

(1) E → E+E

(2) E → E*E

(3) E → i

Genera el siguiente autómata:

En el cual podemos observar que en el estado final S6 podríamos desplazar o reducir


para los símbolos ’+’ y ’*’. Ya que siguiente(E)={+, ∗$}.

47 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Por tanto nos quedaría la siguiente tabla de análisis:

Ejemplo: Definimos la siguiente gramática extendida para aplicarle la tabla de


análisis SLR(1):

(0) S’ → S $

(1) S → xb

(2) S → A

(3) A → aAb

(4) A → x

Genera el siguiente autómata:

48 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

En el cual vuelve a ocurrir algo parecido a lo del ejemplo anterior. En este caso
tenemos que:

siguiente(S)={$}

siguiente(A)={b, $}

Por tanto nos quedaría la siguiente tabla de análisis:

Mediante el análisis SLR(1) no añadíamos ningún estado más al autómata,


únicamente cambiábamos la tabla de análisis. Ahora, con LR(1) vamos a añadir
más estados a nuestro autómata. Así, para formar un autómata LR(1) realizamos
los siguientes pasos:

1. Ahora la gramática extendida no va a tener una regla que sea S 0 → S$ sino que
esta regla será S 0 → S{$}.

2. Vamos a formar cada estado como en LR(0), poniendo un ’.’ delante del
símbolo que estamos evaluando y cerrando ese símbolo como ya explicamos
anteriormente.

3. A cada regla que aparezca en cada estado del autómata se deberá añadir entre
corchetes lo que llamaremos el símbolo de adelanto.
Este símbolo es el siguiente(X) si tenemos X → ABC..., es decir, el siguiente
del símbolo no terminal situado a la izquierda de la regla.
Esto es algo más complicado de lo que parece.
El procedimiento a aplicar, consiste en partir únicamente de la regla que está
generando el autómata (En el estado inicial esta regla será la derivación del
axioma y en otros estados la regla que acabamos de derivar).
Para esta regla ya conocemos el símbolo de adelanto: si es un estado intermedio
conserva el símbolo de adelanto del estado anterior y si es el estado inicial su
símbolo de adelanto es $.
Una vez tenemos la regla inicial, calculamos su cierre en pequeños pasos.
Es decir, primero añadimos las reglas que se derivan del no terminal situado
inmediatamente después del punto (hasta aquí un paso), luego aplicamos

49 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

calculamos el cierre de cada una de estas nuevas reglas (por cada regla un
paso).
¿Por qué realizamos esta distinción entre pasos que antes no hacíamos? Por que
ahora será necesario realizar un pequeño trabajo entre estos pasos.
En cada paso tomamos únicamente la regla que estamos cerrando y las reglas que
acabamos de añadir y, restringiéndonos a ese subconjunto de reglas, calculamos
los símbolos de adelanto de las mismas.

Como resultado, tendremos un mayor número de estados ya que si el símbolo de


adelanto cambia, habrá que definir un nuevo estado.

Ejemplo: Usando la gramática del ejercicio anterior, generamos el siguiente


autómata usando LR(1):

Observación: En este ejemplo hay una errata. En los estados S0 , S3 y S7 la regla


A ::== .Ab{$} debería ser A ::== .Ab{b}, puesto que Siguiente(A) ={b} y la regla
A ::== .x{$} debería ser A ::== .x{b}
Como podemos observar, en este autómata se eliminan los conflictos que teníamos
antes. Nos fijamos en la clave de esto.
Nos quedaría la siguiente tabla de análisis:

50 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

VII.2.4. Tablas LALR(1)


El análisis LALR(1) supone reducir el tamaño de la tabla de análisis de LR(1), a
cambio de la posibilidad de aparición de conflictos reducción/reducción.
Debemos tener en cuenta que buena parte de la complejidad del algoritmo recae
en el coste de procesar la entrada siguiendo un autómata y que, cuando menor sea el
mismo menor será el coste.
La principal diferencia que aporta el análisis LALR(1) consiste en la agrupación de
estados finales que sólo difieran en los símbolos de adelanto.
Veamos como transformar un autómata LR(1) en un autómata LALR(1).

VII.3. Análisis descendente


Vamos a estudiar cómo se desarrollan los algoritmos de análisis descendente.
Ya los mencionamos anteriormente pero, para ver cómo funcionan, vamos a realizar
algunos ejemplos por fuerza bruta, para captar la idea del asunto.

Ejemplo: Empezaremos por una gramática sencillita:

S → aSb

S → ab

y trataremos de ver si la cadena aabb se deriva de esta gramática.


Para empezar a estudiar el ejemplo, debemos tener en cuenta dos máximas del
análisis descendente:
La cadena se lee desde la izquierda
Realizaremos siempre derivaciones Leftmost

51 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Vamos a realizar el ejercicio por fuerza bruta.

Para empezar derivamos el axioma con la primera regla (en realidad daría igual
cual coger).
Obtenemos por tanto S->aSb y vemos que es compatible con la cadena buscada.

Tomamos ahora el elemento no terminal situado más a la izquierda y lo derivamos.


Obtenemos así S->aSb->aaSbb que vemos que es compatible con la entrada.

Derivamos una vez más el siguiente elemento no terminal más a la izquierda.


En esta ocasión llegamos a S->...->aaaSbbb que ya no es compatible con la
cadena de modo que deshacemos la última operación.

Tratamos de aplicar la segunda regla.


Así obtenemos S->...->aaabbb que tampoco es compatible por lo que volvemos
a deshacer el último paso.

Nos hemos quedado sin reglas por aplicar, de modo que debemos deshacer una
acción más. Volvemos al estado S->aSb y tratamos de aplicar la segunda regla:
Llegamos a S->aSb->aabb y vemos que coincide con la cadena buscada.

Al explicar el algoritmo empleado hemos hecho alusión a la compatibilidad.


Definámosla formalmente.

Compatibilidad Definición VII.7 Compatibilidad. Para comprobar si la cadena que tenemos ahora
mismo es compatible con la cadena que estamos buscando simplemente vemos si los
primeros símbolos terminales (hasta el primer no terminal) coinciden.
Tal y como lo hemos explicado ,el algoritmo de análisis descendente presenta dos
problemas graves:

1. Es extremadamente ineficiente
2. Recursividad por la izquierda.
Si nos encontramos con una gramática del tipo
S→b
S → Sb
y buscamos la cadena abb entraríamos en un problema de recursión infinita pues
aplicar la primera regla no nos da la solución final en ningún caso y con la segunda
regla tendremos siempre al inicio de la cadena un símbolo que no es terminal.

Para clasificar las gramáticas según puedan causarnos o no este problema vamos a
definir un nuevo concepto

Gramática Definición VII.8 Gramática LL(1). Gramática en la que todas las reglas presentan
LL(1) en la parte derecha 1 símbolo no terminal seguido de un símbolo cualquiera (terminal
o no terminal).

52 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Además, dos reglas con la misma parte izquierda deben un terminal distinto al
inicio de su parte derecha.
Estas gramática son muy interesantes ya que presentan un claro determinismo, que
nos evita de hacer backtracking con lo que hacen la búsqueda muy eficiente.
Veremos dos métodos para el análisis de gramáticas de este tipo pero antes debemos
definir un nuevo concepto muy importante de cara al análisis descendente: Forma
normal de Greigbach

VII.3.1. Forma normal de Greigbach

Forma Definición VII.9 Forma normal de Greigbach. Decimos que una gramática está en
normal de forma normal de Greigbach si todas las reglas son de la forma:
Greigbach
A → aβ donde a ∈ T, β ∈ N ∗

Observación: Todas las gramáticas pueden expresarse en forma normal de Greigbach.


Una vez que una gramática está expresada de esta forma, comprobamos si es,
además, LL(1) y si es así ya lo tenemos.
Vamos a ver cómo tratar una gramática que no esté expresada en forma normal de
Greigbach. En estos casos debemos solucionar, antes de nada, los dos problemas que
nos impiden que la gramática esté en esta forma normal

1. Eliminación de reglas recursivas por la izquierda


Dada una gramática de la forma

A → Aβ
A→α

la convertimos en otra

A → αX
X → βX|λ

2. Eliminar símbolos no terminales del principio de la parte derecha de


las reglas.
Vamos a clasificar las reglas en tres tipos:

a) A → aZ
b) Ai → Aj α con Ai precediendo a Aj
c) Ai → Aj α con Aj precediendo a Ai

El algoritmo a seguir sería:

53 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

a) Dejamos las reglas de Tipo a) como están.


b) Eliminamos las reglas de Tipo c), empezando con aquellas cuyo símbolo de
la parte derecha tiene mayor precedencia
c) Eliminamos las reglas de Tipo b), empezando con aquellas cuyo símbolo de
la parte izquierda tenga menor precedencia.

3. Eliminar símbolos terminales de más.


Para ello, dada una regla
A → abX

pasamos a dos reglas:


A → aBX
B→b

4. Eliminar reglas λ

5. Eliminar indeterminismo
Dadas reglas de la forma

a) A → aZ
b) A → aB

sacamos factor común y llegamos a

a) A → aW
b) W → B
c) W → Z

Tras este paso vemos si aparecen reglas recursivas. En caso afirmativo, las
eliminamos antes de seguir.

6. Volvemos al primer paso y repetimos

Observación: Si la gramática no es LL(1) este algoritmo no converge

Veamos un ejemplo de cómo aplicar este algoritmo

Ejemplo: Tomamos la gramática:

E →E+T

E→T

T →T ∗T

T →F

F →i

54 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Primero eliminamos las reglas recursivas por la izquierda y nos quedamos en:

E → T X (tipo 2)

X → +T X|λ (tipo 1)

T → F Y (tipo 2)

Y → ∗T Y |λ (tipo 1)

F → i (tipo 1)

donde hemos indicado el tipo de cada regla, preparándonos así para el paso siguiente.
Ahora tenemos que eliminar los símbolos no terminales del principio de la parte
derecha de las reglas. Para ello aplicamos las siguientes transformaciones

T → FY =⇒ T → iY

E → T X =⇒ E → F Y X =⇒ F → iY X

en el orden exacto en que se han indicado.


El resultado por el momento es:

E → iY X

X → +T X

X→λ

T → iY

Y → ∗T Y

Y →λ

F →i

Pero a esta gramática aún le falta algo para ser de Greibach, tenemos que eliminar
las transiciones vacías, obteniendo:

E → iY X

E → iY

E → iX

E→i

X → +T X

X → +T

T → iY

55 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

T →i

Y → ∗T Y

Y → ∗T

F →i

El método seguido se basa en la duplicación de aquellas reglas que contengan Y ó X


(los no terminales que ocasionaban transiciones λ) añadiéndoles una opción sin esas
variables, que es lo que obtendríamos si empleásemos la derivación λ
El último paso llevado a cabo en el ejemplo (eliminación de reglas λ) no es siempre
necesario.
Recordemos que queríamos saber si una gramática era de forma normal de Greibach
con el fin de reconocer si era LL(1). Desde el último estado que hemos alcanzado en
la gramática, para convertirla en una gramática LL(1) deberíamos eliminar los no
terminales que aparecen repetidos en numerosas reglas.
Sin embargo, desde el paso anterior tendríamos directamente que la gramática es
LL(1).
La pregunta que surge ahora está clara:

VII.3.2. ¿Cuándo nos interesa eliminar las transiciones λ?


En general, nos interesará eliminar las transiciones λ siempre que al hacerlo
no estemos generando una gramática no LL(1). Es decir, queremos eliminar estas
transiciones sin dar lugar a gramáticas no deterministas.
En general,

primero(X) ∩ siguiente(X) = ∅ =⇒ X → λ no molesta para LL(1)

En el ejemplo anterior ninguna de las reglas λ nos molestaban de modo que


podíamos prescindir del último paso para garantizar que la gramática es LL(1)

VII.3.3. Análisis LL(1) usando la tabla


El algoritmo a seguir es el siguiente

1. Inicializamos la pila con S$

2. Inicializamos la entrada al primer elemento de la cadena

3. Comparamos la pila con la entrada

a) pila=entrada=$ FIN
b) pila contiene x∈ T
1) x = entrada =⇒ desplazamos entrada y pop

56 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

2) x 6= entrada =⇒ ERROR
c) pila contiene x ∈ N =⇒ saco x de la pila y meto β.

Veamos un pequeño ejemplo de cómo aplicar este algoritmo.

Ejemplo: Consideremos la gramática:

S → E$

E → T E0

E 0 → +T E 0

E0 → λ

T → FT0

T 0 → ∗F T 0

T0 → λ

F →i

F → (E)

Y vamos a analizar con ella la entrada

i + i ∗ i$

La tabla queda:

Símbolo + * i ( ) $
E E →TE’ E → T E0
E’ E 0 → +T E 0 E0 → λ E0 → λ
T T → FT0 T → FT0
T’ T0 → λ T 0 → ∗F T 0 T0 → λ T0 → λ
F F →i F → (E)

y el análisis resulta:

57 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

0 i+i*i$ S$ derivar E→TE’


1 i+i*i$ TE’$ derivar T → FT’
2 i+i*i$ FT’E’$ derivar F→i
3 i+i*i$ iT’E’$ desplazar entrada
4 +i*i$ T’E’$ derivar T’ → λ
5 +i*i$ E’$ derivar E’ → TE’
6 +i*i$ +TE’$ desplazar
7 i*i$ TE’$ derivar T → FT’
8 i*i$ FT’E’$ derivar F → i
9 i*i$ iT’E’$ desplazar
10 *i$ T’E’$ T’ → *FT’
11 *i$ *FT’E’$ desplazar
12 i$ FT’E’$ F→i
13 i$ iT’E’$ desplazar
14 $ T’E’$ T’ → λ
15 $ E’$ E’ → λ
16 $ $ OK

Ejemplo: Consideremos la gramática:

P → iEtP P 0 $
P →a
P 0 → eP
P0 → λ
E→b

Vamos a construir ahora la tabla de análisis asociado.


Para ello tenemos que ver cuál es el siguiente de cada elemento no terminal y dejar
claro en la tabla que sólo aplicamos la reducción delante del siguiente
La tabla de análisis asociada sería:

Símbolo a t e b i $
P P →a P → iEtP P 0
P’ P 0 → EP P0 → λ
P0 → λ
E E→b

Como podemos observar, esta gramática no es LL(1)


Vamos a hacer hincapié en la diferencia entre gramática LL(1) y lenguaje LL(1)
Definición VII.10 Gramática LL(1).
Gramática
LL(1)
Gramática cuya tabla de análisis LL(1) no presenta conflictos

Lenguaje Definición VII.11 Lenguaje LL(1).


LL(1)
58 de 100 14 de junio de 2016 12:49
Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Lenguaje para el cual existe una gramática LL(1) que lo genera

Ejemplo: La gramática

S → aSb

S → ab

no es una gramática LL(1), cosa que podemos comprobar construyendo su tabla de


análisis LL(1). Sin embargo, su lenguaje asociado si que es LL(1) ya que podemos
transformarla en

B→b

S → aW

W → aW b

W →b

que si es LL(1) (de nuevo lo comprobamos construyendo su tabla de análisis LL(1)).

VII.3.4. Análisis LL(2) usando la tabla


La principal diferencia del análisis LL(2) respecto al LL(1) radica en que ahora
vamos a tomar dos símbolos de adelanto
Veámoslo para el caso particular de la gramática

S → aSb

S → ab

En este caso sería tremendamente sencilla la tabla de símbolos:

Símbolo aa ab
S S → ab S → aSb

Pero aún quedan casos en los que no podemos resolver los conflictos ni usando
LL(2).
Por ejemplo, en la gramática

FUNCION -> TIPO ID (ARGS);

FUNCION -> TIPO ID (ARGS) {CUERPO}

ARGS -> λ

ARGS -> ARG ARGS

59 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

TIPO -> int | float

ARG -> ID

ID -> (a + ... + z)(a + ... + z)∗

A la hora de trabajar con la regla FUNCION -> TIPO ID (ARGS) no sabemos


cuántos argumentos vamos a encontrar.
La solución para este problema pasa por usar expresiones regulares, lo que nos lleva
al análisis LL(*)

VII.3.5. Análisis LL(*)


Consiste en emplear expresiones regulares en lugar de símbolos de adelanto.
Continuando con el ejemplo anterior, para resolver el problema con LL(*)
consideramos la expresión regular:

r = (int + f loat).(a − z)+ .”(”.[(a − z)+ ] ∗ .”)”

y la tabla quedaría (para la regla que causaba el problema)

Símbolo r.";" r."ε"


FUNCION FUNCION -> TIPO ID (ARGS); FUNCION -> TIPO ID (ARGS) {CUERPO}

En este caso no hay problemas pues es bastante sencilla la tabla mostrada. No obstante,
en un caso más general sería necesario cuidar que no se solapen las expresiones regulares
empleadas en el análisis.

60 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Capítulo VIII

Últimos detalles: lemas,


equivalencias y reducción de
automátas...

VIII.1. Minimizar autómatas finitos


En esta sección vamos a tratar de reducir los estados de un autómata finito. Para
ello seguimos dos pasos:

1. Eliminar estados inaccesibles.


Se realizará mediante una búsqueda en anchura dentro del árbol, se parará la
expansión de las ramas del árbol según se vayan encontrando estados repetidos.
Aquellos estados que no aparezcan en el árbol podrán ser eliminados del autómata
directamente ya que nunca podremos llegar a ellos.

2. Unir estados equivalentes. Para ello primero debemos encontrarlos, definimos la


siguiente relación de equivalencia entre estados:
Sean P, Q estados del autómata, F el conjunto de estados finales y ξ el alfabeto
del autómata.

p EQ0 q ⇐⇒ o bien p ∈ F y q ∈ F o p ∈ /Fyq∈ / F. (es decir, dos estados


son equivalentes a nivel 0 si los dos pertenecen al conjunto de los estados
finales o los dos pertenecen al conjunto de los estados NO finales)
p EQ1 ⇐⇒ p EQ1 q y ∀ a ∈ ξ se cumple que δ(p, a) EQ0 δ(q, a)
.
.
.
p EQn ⇐⇒ p EQn−1 q y ∀ a ∈ ξ se cumple que δ(p, a) EQn−1 δ(q, a)
paramos cuando lleguemos a un paso en los que tengamos las mismas clases
de equivalencia con los mismos elementos que en el paso anterior.

61 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejemplo: Vamos a reducir el siguiente autómata:

1. Vemos que no tiene ningún estado inaccesible.


2. Vamos a ir viendo los estados equivalentes
EQ0 : C1 = {A, B} (estados finales) y C2 = {C} (estados NO finales).
Ahora se revisan los grupos equivalentes del paso anterior y se comprueba
si son equivalentes en un nivel más.
Con el estado C ya no debemos hacer nada, ya que este es equivalente
consigo mismo.
Si desde A se sale con un 0 llegamos a B, que pertenece al grupo C1 de
la equivalencia anterior. Si se sale con un 1 llegamos a C que pertenece al
grupo C2 .
Si desde B se sale con un 0 llegamos a B, que pertenece al grupo C1 de
la equivalencia anterior. Si se sale con un 1 llegamos a C que pertenece al
grupo C2 .
Por tanto llegamos a estados pertenecientes al mismo grupo de equivalencia
tanto desde A como desde B. Y es por eso que A y B son también EQ1
entre ellos.
Como hemos llegado a dos pasos consecutivos en el que nuestros grupos
de equivalencia han coincidido ( C1 = {A, B} y C2 = {C}), paramos el
algoritmo y concluimos: A y B son equivalentes entre si.

Transformamos el autómata y nos queda:

Ejemplo: Dado el siguiente autómata:

62 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

1. Realizamos el árbol de búsqueda en anchura y obtenemos lo siguiente:

B F

G C

Podemos deducir de ello que el nodo D es inaccesible, y por tanto lo eliminamos


del autómata.

2. Vamos a ir viendo los estados equivalentes

EQ0 : C1 = {C} (estados finales) y C2 = {A, B, E, F, G, H} (estados NO


finales).
Ahora se revisan los grupos equivalentes del paso anterior y se comprueba
si son equivalentes en un nivel más.
Con el estado C ya no debemos hacer nada, ya que este es equivalente
consigo mismo.
Si desde A se sale con un 0 llegamos a B, que pertenece al grupo C2 de
la equivalencia anterior. Si se sale con un 1 llegamos a F que pertenece al
grupo C2 también.
Si desde B se sale con un 0 llegamos a G, que pertenece al grupo C2 de
la equivalencia anterior. Si se sale con un 1 llegamos a C que pertenece al
grupo C1 .
Por tanto llegamos a estados pertenecientes a distintos grupos de
equivalencia. Y concluimos que A y B no son equivalentes.
Repetimos el mismo procedimiento con todas las parejas de nodos.
Marcamos con X si NO son equivalentes y con V si SI son equivalentes.

A-B -> X B-E -> X E-F -> X F-G -> X G-H -> X
A-E -> V B-F -> X E-G -> V F-H -> X
A-F -> X B-G -> X E-H -> H
A-G -> V B-H -> V
A-H -> X

Por tanto las nuevas equivalencias quedarían: EQ1 : C1 = {C}, C2 =


{A, E, G}, C3 = {B, H}, C4 = {F }
Continuamos con la siguiente equivalencia. Los grupos C1 y C4 ya están
terminados. Miramos los grupos C2 y C3 .

63 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Empezamos con C2 . Si desde A se sale con un 0 llegamos a B, que pertenece


al grupo C3 de la equivalencia anterior. Si se sale con un 1 llegamos a F
que pertenece al grupo C4 .
Si desde E se sale con un 0 llegamos a H, que pertenece al grupo C3 de
la equivalencia anterior. Si se sale con un 1 llegamos a F que pertenece al
grupo C4 .
Por tanto A y E son equivalentes. Repetimos el mismo proceso con el resto
de parejas y obtenemos:
A-E -> V
G-E -> X
A-G -> X
Por tanto del grupo de equivalencia C2 obtenemos 2. C2 = {A, E} y
C5 = {G}
Ahora miramos el grupo C3 , y se observa que B y H siguen siendo
equivalentes.
Nos queda: EQ2 : C1 = {C}, C2 = {A, E}, C3 = {B, H}, C4 = {F },
C5 = {G} Como los grupos de equivalencia han cambiado, tenemos que
avanzar un nivel más.
Solo tenemos que mirar los conjuntos C2 y C3 . Observamos que no se
forman nuevos grupos de equivalencia, y tenemos:
EQ3 : C1 = {C}, C2 = {A, E}, C3 = {B, H}, C4 = {F }, C5 = {G}
Por tanto llegamos a la conclusión parada y construimos el autómata
resultante:

VIII.2. Equivalencia AFN - AFD


Vamos a ver que un autómata finito no determinista se puede transformar en un
autómata finito determinista equivalente.
Sea ∨∗ (q) el conjunto formado por los estados accesibles dado un estado ’q’ con
transiciones λ.
Sea C0 = {qo } ∪ ∨∗ (q) el conjunto de transiciones posibles desde C0 .
Vamos a transformar el siguiente AFN en un AFD:

Ejemplo:

64 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

y nos queda:

NOTA: Si tuviéramos un autómata que empezará en un estado A y pudiese pasar a


otro B a través de una transición λ, el estado inicial quedaría C0 = {A, B}.

VIII.3. Propiedades del cierre (regulares)


Sean L1 y L2 lenguajes regulares.

L1 ∪ L2 , L1 .L2 y L1 ∩ L2 son regulares


Lc1 = ξ ∗ − L es regular
L1 − L2 = L1 ∩ Lc2 es regular.

65 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

VIII.4. Lemas del Bombeo

VIII.4.1. Lema del bombeo (Lenguajes regulares)


Sea L un lenguaje regular, infinito: ∃m ≥ 0 tal que cualquier w ∈ L puede
descomponerse como w = xyz con |xy| ≤ m y |y| ≥ 1 de tal modo que xy i z ∈ L
∀i = 0, 1, 2, ....

Ejemplo: Sea el lenguaje L = {an bn , n ≥ 0} queremos ver si es un lenguaje regular.


Vamos a intentar demostrar que no es regular.

1. Elegimos un número ’m’ cualquiera.

2. Elegimos una palabra w ∈ L con |w| ≥ m. Cogemos w = am bm que tiene


|w| = 2m ≥ m

3. Manipulamos la palabra y vemos como separarla.


Tenemos: a, a, ..., a b, b, ..., b
| {z } | {z }
m m

Como |xy| ≤ m podemos escoger un xy que sean todo a’s, de manera que xy i z
tendría mas a’s que b’s y por tanto no pertenecería a L.
Hemos encontrado una palabra w que no cumple las condiciones que debería
cumplir toda palabra si el lenguaje fuese regular. Concluimos que el lenguaje no
es regular.

El truco esta en coger una palabra que no cumpla la implicación, con la cual si
tenemos un A ⇒ B y B no se cumple, se deduce que A tampoco. ¬B ⇒ ¬A
Veamos otro ejemplo:

Ejemplo: Sea el lenguaje L = {wwc , w ∈ {a, b}∗ } queremos ver si es un lenguaje


regular. Vamos a intentar demostrar que no es regular.

1. Elegimos un número ’m’ cualquiera.

2. Elegimos una palabra w ∈ L con |w| ≥ m. Cogemos w = am bm bm am que tiene


|w| = 4m ≥ m

3. Manipulamos la palabra y vemos como separarla.


Tenemos: a, a, ..., a b, b, ..., b b, b, ..., b a, a, ..., a
| {z } | {z } | {z } | {z }
m m m m

Como |xy| ≤ m podemos escoger un xy que sean todo a’s de la parte izquierda,
de manera que xy i z no sería simétrica.
Hemos encontrado una palabra w que no cumple las condiciones que debería
cumplir toda palabra si el lenguaje fuese regular. Concluimos que el lenguaje no
es regular.

66 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Demostrar que el lenguaje L = (ab)n ak |n > k, k ≥ 0 no es regular.



Ejemplo:

1. Elegimos una ‘m’ cualquiera

2. Elegimos una palabra de la forma w = (ab)m+1 am , que tiene |w| = 2(m + 1) +


m≥m

3. Tenemos: abab
| {z . . . ab} ab |aa {z
. . . a}
2m m

Ahora descomponemos w = xyz, con |xy| ≤ m y |y| ≥ 1.


De este modo xy está forzado a aparecer en la parte de las ab:

2m
z }| {
m m
z }| { z }| {
abab
| {z . . . ab} . . . ab ab aa . . . a
xy

Y por tanto y sólo puede ser igual a las siguientes cadenas:

a) a . . . a, para esta situación cogemos i = 0 y nuestra cadena ó bien empieza


por b (en caso de que |x| = 0), ó bien tendrá 2 b seguidas. Por tanto
xy 0 z ∈ / L.
b) a . . . b, para esta situación cogemos i = 0 y ya no se cumplirá la condición
n > k del lenguaje. Por tanto xy 0 z ∈ / L.
c) b . . . a, hacemos lo mismo que en el caso anterior.
d) b . . . b, otra vez tomamos i = 0 y nuestra cadena pasaría a tener 2 a
seguidas en las primeras m letras. Y por tanto xy 0 z ∈
/ L.

VIII.4.2. Lema del bombeo (Lenguajes independientes del


contexto)
Sea L un lenguaje independiente del contexto, infinito y que no contiene a λ,
entonces: ∃m ≥ 0 tal que cualquier w ∈ L con |w| ≥ m puede descomponerse como
w = uxyzv con |xyz| ≤ m y |xy| ≥ 1 de modo que uxi yz i v ∈ L ∀i = 0, 1, 2, ....

Ejemplo: Sea el lenguaje L = {an bn cn , n ≥ 0} queremos ver si es un lenguaje


independiente del contexto.

1. Elegimos un número ’m’ cualquiera.

2. Elegimos una palabra w ∈ L con |w| ≥ m. Cogemos w = am bm cm que tiene


|w| = 3m ≥ m

3. Manipulamos la palabra y vemos como separarla.


Tenemos: a, a, ..., a b, b, ..., b c, c, ..., c
| {z } | {z } | {z }
m m m

67 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Como |xyz| ≤ m tenemos que en xyz o bien no hay a’s o bien no hay c’s, y por
tanto ux0 yz 0 v ∈
/ L.
Hemos encontrado una palabra w que no cumple las condiciones que debería
cumplir toda palabra si el lenguaje fuese independiente del contexto. Concluimos
que el lenguaje no es independiente del contexto.

Veamos otro ejemplo:

Ejemplo: Sea el lenguaje L = {ww, w ∈ {a, b}∗ } queremos ver si es un lenguaje


independiente del contexto.

1. Elegimos un número ’m’ cualquiera.

2. Elegimos una palabra w ∈ L con |w| ≥ m. Cogemos w = am−1 bam−1 b que tiene
|w| = 2m ≥ m

3. Manipulamos la palabra y vemos como separarla.


Tenemos: a, a, ..., a b a, a, ..., a b
| {z } | {z }
m−1 m−1

Vemos que si escogemos xyz = a, a, ..., b, a, a, ..., a, con esta división la palabra
ux0 yz 0 v ∈ L, y por tanto no nos vale como contraejemplo.
Se deja como ejercicio para e lector comprobar que la elección correcta es coger
un w = am bm am bm . Con esta palabra conseguiremos demostrar que el lenguaje
no es independiente del contexto.

VIII.5. Propiedades del cierre (independientes del


contexto)
Sean L1 y L2 lenguajes independientes del contexto, y LR un lenguaje regular.

L1 ∪ L2 es I.C. (Podemos construir la gramática G → G1 |G2 ).

L1 .L2 es I.C. (Podemos construir la gramática G → G1 G2 ).

L∗1 es I.C. (Podemos construir la gramática G → G1 G|λ).

L1 ∩ L2 no tiene por qué ser I.C. Veamos el siguiente contraejemplo:

 n n m
Ejemplo: Tomemos el lenguaje L1 = a b c |n, m ≥ 1 generado por la
gramática:

• S → AB
• A → aAb| ab
• B → cB| c

68 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Que podemos ver que es I.C.



Ahora tomemos el lenguaje L2 = an bm cm |n, m ≥ 1 generado por la
gramática:

• S → AB
• A → aA| a
• B → bBc| bc

Que también podemos ver que es I.C.



En este caso tendremos que L1 ∩ L2 = an bn cn |n ≥ 1 . Y ya habíamos
demostrado anteriormente que este lenguaje no es I.C.

L1 ∩ LR es I.C.

L1 no tiene por qué ser I.C. Veamos por qué:

Demostración. Supongamos que L1 y L2 son lenguajes I.C., y que fuera cierto


que se cumple la propiedad.
En ese caso tendríamos que L1 ∪ L2 sería I.C., y por tanto:

L1 ∪ L2 = L1 ∩ L2 = L1 ∩ L2

Pero sin embargo acabamos de ver que L1 ∩ L2 no tiene por qué ser I.C.

L1 − L2 no es necesariamente I.C.

69 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Apéndice A

Ejercicios

A.1. Ejercicios

Ejercicio 1.1: Encontrar el lenguaje definido por la gramática:

S → abB

A → aaBb

B → bbAa

A→λ

L(G) = ab(bbaa)n bba(ba)n

Ejercicio 1.2: Dado el lenguaje Σ = {a, b} queremos encontrar las


gramáticas, las expresiones regulares y los autómatas finitos deterministas que
representen:

1. Cadenas con exactamente una ’a’

2. Cadenas con al menos una ’a’

3. Cadenas con, como mucho, 3 ’a’s

1. La expresión regular sería: b∗ ab∗


La gramática que lo representa:

S → BaB
B → Bb

70 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

B→λ

El autómata sería:

2. La expresión regular sería: (a + b)∗ a(a + b)∗


La gramática que lo representa es:

S → XaX
X → XZ|λ
Z → a|b

El autómata sería:

3. La expresión regular sería: b∗ (λ(a + b) + (a + b)2 + (a + b)3 )b∗


Otra expresión podría ser: b∗ (a + b + λ)b∗ (a + b + λ)b∗ (a + b + λ)b∗
La gramática que lo representa es:

El autómata sería:

71 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejercicio 1.3: Dados los lenguajes:

1. L = {a2n bn+1 }

2. L = {an bm  n > m ≥ 0}

3. L = {an bm ck  k = n + m}

Encontrar la gramática y los autómatas a pila que los representan:

1. Gramática

S → aaSb|b

Autómata

2. Gramática

S → aSb|aS|a

Autómata

3. Gramática

S → aSc|aAc|λ
A → bAc|λ

Autómata

72 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Apéndice B

Ejercicios 1a Hoja

B.1. Ejercicios sobre autómatas finitos y lengua-


jes regulares

Ejercicio 1.1: Diseña expresiones regulares para los siguientes lenguajes:


a) L(A) = {an bm : n + m es impar }
b) Conjunto de números binarios que contienen la subcadena 1010
c) Identificadores de un lenguaje de programación que empiezan con el símbolo
@, seguido de una letra minúscula y cualquier combinación de letras minúsculas o
números.

Apartado a)
(aa) ∗ .(a + b).(bb)∗

Apartado b)
(1 + 0) ∗ .1010.(1 + 0)∗

Apartado c)
@.(a + b + ... + z).(0 + 1 + ... + 9 + a + b + ... + z)∗

Ejercicio 1.2: Diseña un autómata finito (determinista o no determinista)


que reconozca cada uno de los siguientes lenguajes:
a) Conjunto de números binarios que contienen la subcadena 1010
b) Identificadores de un lenguaje de programación que empiezan con el símbolo
@, seguido de una letra minúscula y cualquier combinación de letras minúsculas o
números.

73 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Escojo hacer los diagramas deterministas:


Apartado a)

Apartado b)
Las transiciones no indicadas sobreentendemos que van a un nodo residuo.

Ejercicio 1.3: Indica cuál es el lenguaje aceptado por el siguiente autómata:

Expresión regular: L(A) = b∗ .a + b∗ .a.(a + b)∗ .b

74 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Aunque nos pida el lenguaje nos vale con poner la expresión regular.

Ejercicio 1.4: Construye un autómata finito determinista que acepte cadenas


sobre el alfabeto 0,1 que representen números enteros y múltiplos de 5 expresados
en representación binaria.

Explicación: Los estados representan el resto de dividir el número entre 5. Se tiene


en cuenta que si tienes un numero cualquiera (por ejemplo 101) al añadirle un 0, es
como multiplicarlo por 2, por tanto su resto es el doble, y al añadirle un 1, es como
multiplicarle por 2 y sumarle 1.

Ejercicio 1.5: Para el autómata siguiente encuentra δ ∗ (q0 , 1011) y δ ∗ (q1 , 01)

Explicación: Nos piden la salida del autómata dada un estado inicial y una palabra.

δ ∗ (q0 , 1011) = q2

Estados 1 0 1 1
q0 q1 q0 q1 q2
q2 - -
q2 - - - -

75 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

δ ∗ (q1 , 01) = q1

Estados 0 1
q1 q0 q1
q2 -

Ejercicio 1.6: Construye un autómata finito no determinista con tres estados


que acepte el lenguaje L = {ab, abc}∗ , ¿es posible hacerlo con menos de tres
estados?

76 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

B.2. Ejercicios sobre autómatas a pila y gramáti-


cas independientes del contexto

Ejercicio 2.1: Diseña una gramática independiente del contexto que


genere el lenguaje de los números capicúa formados con el alfabeto Σ =
0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Los números de una sola cifra no se consideran capicúa.

En cada regla, si aparecen dos ’X’ estas tienen que acabar en el mismo símbolo
terminal. La otra opción era poner muchas reglas más tipo X0 , ..., X9 .
S −→ XZX
Z −→ XZX|X|λ
X −→ 0|1|2|3|4|5|6|7|8|9

Ejercicio 2.2: Diseña una gramática independiente del contexto que genere
el lenguaje de los números formados con el alfabeto Σ = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 que
tengan el mismo número de dígitos pares e impares. Puede suponer por simplicidad
que los números pueden tener ceros a la izquierda.

S −→ P SI|ISP |P I|IP |SS


P −→ 0|2|4|6|8
I −→ 1|3|5|7|9

Ejercicio 2.3: Diseña un autómata a piña que reconozca el lenguaje del


ejercicio 1.

Explicación: Cuando pongo ’x’ o ’y’ quiero decir un símbolo del conjunto
{0,1,2,3,4,5,6,7,8,9}. Cuando pongo ’x’ e ’y’ en la misma transición, x 6= y.

77 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejercicio 2.4: Demuestra que la siguiente gramática es ambigua:


S −→ AB|aaB
A −→ a|Aa
B −→ b

Si derivamos usando la primera regla de S obtenemos:


S −→ AB −→ AaB −→ aaB −→ aab
Si derivamos usando la segunda regla de S obtenemos:
S −→ aaB −→ aab

Ejercicio 2.5: Encuentra una gramática independiente del contexto para el


siguiente lenguaje:
L = {an wwR bn : w ∈ {a, b}∗ , n ≥ 1}

wR , es la imagen simétrica de la cadena w. Si w es aab, wR es baa.


S −→ aSb|aXb|
X −→ aXa|bXb|λ

Ejercicio 2.6: Indica cuál es el lenguaje aceptado por el siguiente autómata


a pila:
A = ({q0 , q1 , q2 }, {a, b}, {a, b, z}, δ, q0 , z, {q2 })
δ(q0 , a, z) = {(q1 , a), (q2 , λ)}
δ(q1 , b, a) = {(q1 , b)}
δ(q1 , b, b) = {(q1 , b)}
δ(q1 , a, b) = {(q2 , λ)}

El autómata a pila sería el siguiente:

El lenguaje consiste en expresiones del tipo {a} ∪ {abn a


f oralln > 0}

78 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Apéndice C

Ejercicios 2a Hoja

C.1. Ejercicios sobre Gramáticas de Atributos


La gramática:

axioma ::= USUARIO peliculas


peliculas ::= peliculas peliculas | pelicula
pelicula ::= TITULO valoraciones
valoraciones ::= valoraciones valoracion valoracion
valoracion ::= (USUARIO:NUMERO)

genera frases que consisten en una secuencia de películas con sus respectivas
valoraciones realizadas por los usuarios.Al principio de las frases generadas por la
gramática siempre aparece el nombre de un usuario. A continuación se muestran tres
ejemplos:
jaime Star_Wars(jaime:10)(ana:10) Spiderman(ana:10)(pepe:1)
ana Kapax(pepe:100)(jaime:1) Avatar(ana:40) Pi(pepe:100)(ana:1)
mike Kapax(pepe:100)(jaime:1) Avatar(ana:40) Pi(pepe:100)(ana:1)
Se desa añadir a esta gramática un sistema de atributos que haga lo siguiente:

1. Calcular el número total de películas valoradas

2. Indicar el título y la valoración de la película mejor valoradas por el usuario


indicado al principio de la cadena. Si no hay ninguna películas valorada por dicho
usuario debe indicarse tal circunstancia.

Por ejemplo, para las tres cadenas anteriores se mostrarían respectivamente los
mensajes siguientes:
Se han valorado 2 películas. La mejor valorada por jaime es Star_Wars, con una
valoración de 10.
Se han valorado 3 películas. La mejor valorada por ana es Avatar, con una valoración
de 40.

79 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Se han valorado 3 películas. Ninguna película ha sido valorada por mike.


Notas:

Puede considerarse que existe un proceso de análisis morfológio que asigna a


los símbolos terminales los siguientes atributos semánticos: USUARIO.nombre
(nombre de usuario), TITULO.titulo (título de la película), NUMERO.valor (valor
numérico del número)

Debe comprobarse que el usuario que aparece al principio de la cadena no valora


más de una vez la misma película. No es necesario realizar esta comprobación
para el resto de usuarios.

No está permitido el uso de información global

Debe responderse a cada una de las cuestiones usando las plantillas


correspondientes

80 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejercicio 1.1: Describa explícita y brevemente el significado de cada atributo


que utilice, así como el proceso de actualización de cada uno de ellos mencionando
si se realiza herencia o síntesis en su propagación. Responde rellenando la tabla:

SÍMBOLO ATRIBUTOS DESCRIPCIÓN


USUARIO nombre Nombre del usuario.
TITULO titulo Título de la película.
NÚMERO valor Valor numérico del número.
valoración nota nota de la valoración (por síntesis)
usuario usuario que da la valoración (por síntesis)
valoraciones usuario_actual Usuario inicial (por herencia)
notaMax nota máxima (por síntesis)
nota Nota máxima de la película (por síntesis)
película titulo titulo de la película (por síntesis)
usuario_actual Usuario inicial (por herencia)
num Número de películas valoradas (por síntesis)
películas usuario_actual Usuario inicial (por herencia)
titulo titulo de la película mejor valorada (por síntesis)
nota nota de la película mejor valorada (por síntesis)

Ejercicio 1.2: Define formalmente la gramática utilizando la notación


explicada en el temario de esta asignatura. Utiliza la siguiente tabla, en la que
debes indicar, para cada regla de la gramática, las acciones semánticas asociadas
junto con el instante en que se deben ejecutar.

81 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

INSTATE ACCIÓN
axioma ::= USUARIO peliculas
1 peliculas.usuario_actual = USUARIO.nombre
2 print("Se han valorado " + peliculas.num + " películas")
print("la mejor valorada por " + USUARIO.nombre + " es " + peliculas.titulo
+ " con una valoración de " + peliculas.nota + ".")
peliculas_1 ::= peliculas_2 pelicula
0 peliculas_2.usuario_actual = peliculas_1.usuario_actual
pelicula.usuario_actual = peliculas_1.usuario_actual
2 if(peliculas_2.nota>pelicula.nota){
peliculas_1.nota=peliculas_2.nota
peliculas_1.titulo=peliculas_2.titulo}
else{peliculas_1.nota=pelicula.nota
peliculas_1.titulo=pelicula.titulo}
peliculas_1.num = peliculas_2.num+1
peliculas ::= pelicula
0 pelicula.usuario_actual = peliculas.usuario_actual
1 peliculas.titulo = pelicula.titulo
peliculas.nota = pelicula.nota
peliculas.num=1
pelicula ::= TITULO valoraciones
0 valoraciones.usuario_actual = pelicula.usuario_actual
1 pelicula.titulo = TITULO.titulo
2 pelicula.nota=valoraciones.notamax
valoraciones_1 ::= valoraciones_2 valoracion
0 valoraciones_2.usuario_actual = valoraciones_1.usuario_actual
2 if(valoraciones_1.usuario_actual==valoracion.usuario AND valoraciones_2.notamax
6= 0){
print("ERROR")
}else if(valoraciones_1.usuario_actual==valoracion.usuario)}
valoraciones_1.notamax=valoracion.nota
}else if(valoraciones_2.notamax 6=0){
valoracion_1.notamax=valoraciones_2.notamax
}else{valoraciones_1.notamax=0}
valoraciones ::= valoracion
0 valoraciones.notamax=0
1 if(valoraciones.usuario_actual==valoracion.usuario){
valoraciones.notamax=valoracion.nota}
valoracion ::= (USUARIO:NUMERO)
2 valoracion.nota = NUMERO.valor
valoracion.usuario=USUARIO.nombre

Ejercicio 1.4: Considérese la siguiente gramática independiente del contexto:

axioma ::= DINERO lista_compra


lista_compra ::= compra lista_compra | compra
compra ::= [PRODUCTO, PRECIO]

82 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Esta gramática genera sentencias que consisten en una cantidad de DINERO


seguida de una lsita de compras, cada una con un PRODUCTO y el PRECIO
del mismo. Tanto el DINERO como el PRECIO son números reales.
Se desa añadir a esta gramática un sistema de atributos que compruebe si
se puede hacer la compra con el dinero disponible. Se indicarán los productos de
la lista que se pueden comprar y el saldo disponible al final. Se supone que los
productos se adquieren en el mismo orden en el que aparecen en la lista.
Notas:

Puede considerarse que existe un proceso de análisis morfológico que


asigna a los símbolos terminales los siguientes aributos semánticos:
PRODUCTO.nombre (nombre del producto), PRECIO.valor (valor numérico
del precio) y DINERO.valor (valor numérico del dinero).

No está permitido el uso de información global

Los atributos que debemos añadir son:

lista_compra Añadimos los atributos: items, coste y saldo

compra Añadimos los atributos: item y coste

La gramática de atributos resultante sería:

axioma ::= DINERO lista_compra


{Herencia; lista_compra.saldo = DINERO}

lista_compra_1 ::= compra lista_compra_2


{Herencia;
if lista_compra_1.saldo < compra.coste:
lista_compra_2.saldo = lista_compra_1.saldo
else
lista_compra_1.saldo = lista_compra_2.saldo - compra.coste
print compra}

lista_compra ::= compra


{Herencia;
if lista_compra.saldo >= compra.coste:
print compra}

compra ::= [PRODUCTO, PRECIO]


{compra.coste = PRODUCTO}
{Síntesis; compra.item = PRODUCTO}

83 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejercicio 1.5: Considérese la siguiente gramática independiente del contexto:

romano ::= IList | I V | V IList


IList ::= IList I | λ

Esta gramática genera sentencias entre las que se encuentran los números romanos
hasta el 8.
Se pide añadir a la gramática un sistema de atributos que compruebe si la
sentencia corresponde a un número romano correcto y, en caso afirmativo, imprima
su valor numérico.
No está permitido el uso de información global

romano ::= IList


{romano.esValido = IList.esValido}

romano ::= I V
{romano.esValido = true}

romano ::= V IList


{síntesis; romano.esValido = IList.esValido}

IList_1 ::= IList_2 I


{Síntesis; if IList_2.esValido & IList_2.items < 3 , IList_1.esValido = true}
{Síntesis; IList_1.items = IList_2.items + 1}

IList ::= λ
{IList.esValido = true}
{IList.items = 0}

Ejercicio 1.6: Considérese la gramática independiente del contexto resultante


de añadir a la del ejercicio 5 el siguiente axioma:

S ::= romano = IList

Esta gramática genera sentencias formadas por dos cadenas separadas por el signo
’=’. La primera cadena es igual que las generadas por la gramática del ejercicio 5.
La segunda cadena es una lista de símbolos I.
Se pide añadir a la gramática un sistema de atributos que compruebe si, en el
caso de que la primera cadena sea un número romano correcto, el valor del mismo
coincide con el número de símbolos I en la segunda cadena.
No está permitido el uso de información global

84 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

S ::= romano = IList


{Síntesis; if (romano.esValido & romano.value == IList.items), OK}

romano ::= IList


{Síntesis; romano.esValido = IList.esValido}
{Síntesis; if (IList.esValido), romano.value=IList.items}

romano ::= I V
{Síntesis; romano.esValido = true}
{Síntesis; romano.value = 4}

romano ::= V IList


{Síntesis; romano.esValido = IList.esValido}
{Síntesis; if (Ilist.esValido) romano.value = IList.items + 5}

IList_1 ::= IList_2 I


{Síntesis; if (IList_2.esValido & IList_2.items < 3) , IList_1.esValido = true}
{Síntesis; IList_1.items = IList_2.items + 1}

IList ::= λ
{IList.esValido = true}
{IList.items = 0}

85 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Apéndice D

Ejercicios 3a Hoja

D.1. Ejercicios de análisis

Ejercicio 1.1: Sea la siguiente gramática:

S ::= A

S ::= B

A ::= cA+b

A ::= a

B ::= cB+a

B :== b

Calcula los conjuntos primero y siguiente para cada símbolo no terminal

Primeros:

Primero(A) ={c, a}

Primero(B) ={c, b}

Primero(S) ={a, c, b}

Sigueintes

siguiente(A) ={$, +}

siguiente(B) ={$, +}

siguiente(S) ={$}

86 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Ejercicio 1.2: Sea la siguiente gramática LR(0):

E ::= T

E ::= E + T

T ::= i

T ::= (E)

Calcula el cierre de la configuración inicial: E’ ::= .ES

E’ ::= .ES

E ::= .T

E ::= .E + T

T ::= .i

T ::=.(E)

Ejercicio 1.3: Sea la siguiente gramática LR(0):

E ::= (L)

E ::= i

L ::= L,E

L ::= E

a) Calcula el cierre de la configuración E ::= (.L)


b) Calcula el estado al que se llega desde el estado anterior tras conocer el
símbolo no terminal L.

a)

E ::= (.L)

L ::= .L,E

L ::= .E

E ::= .(L)

E ::= .i

87 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

b)

E ::= (L.)

puesto que el punto se encuentra delante de símbolos terminales no es necesario cerrar


la configuración.

Ejercicio 1.4: Sea la siguiente gramática

D ::= iPSn

P ::= :n

S ::= λ

S ::= n

a) Dibuja el diagrama de estados del analizador LR(0) para dicha gramática


b) Calcula la tabla de análisis para el analizador LR(0)
c) Indica justificadamente si la gramática es LR(0). Indica justificadamente si
es SLR(1)

Para trabajar con esta gramática primero añadimos la regla: D’ ::= D$, con lo que
nos queda el conjunto de reglas:

(0) D’ ::= .D$

(1) D ::= .iPSn

(2) P ::= .:n

(3) S ::= .λ

(4) S ::= .n

a)

88 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Estado i n : $ D P S
S0 d1 2
S1 d3 F3
S2 dacc F5
SF3 r3 r3/df4 r3 r3 4
b)
S3 dF2
SF4 r4 r4 r4 r4
S4 dF5
SF2 r2 r2 r2 r2
SF5 r1 r1 r1 r1
c) No se trata de una gramática LR(0) ya que hay ocasiones en las que
observamos un conflico desplazamiento-reducción. Por ejemplo, en el estado inicial
podemos reducir la S o desplazar según la entrada dada.
Para ver si se trata de una gramática SLR(1) vamos a ver si somos capaces de
solucionar los conflictos sabiendo cuales son los elementos siguientes:

siguiente(D)=$ : solo reducimos la regla 1 si después hay un ’$’.

siguiente(P)=n : solo reducimos la regla 2 si después hay una ’n’.

siguiente(S)=n : solo reducimos las reglas 3 y 4 si después hay una ’n’.

Sin embargo, tampoco se trata de una gramática SLR(1) ya que si forzamos


a que las reducciones se produzcan en presencia del siguiente elemento no evitamos
el conflicto. Como el siguiente de S es n, en presencia de esta n podremos aplicar la
reducción S ::= λ o desplazar según la regla S ::= n. Quedando la siguiente tabla
SLR(1):

89 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Estado i n : $ D P S
S0 d1 2
S1 d3 F3
S2 dacc F5
SF3 r3/df4 4
S3 dF2
SF4 r4
S4 dF5
SF2 r2
SF5 r1

Ejercicio 1.5: Sea la siguiente gramática:

S ::= bLd

L ::= E;L

L ::= λ

E ::= i=c

E ::= b

a) Dibuja el diagrama de estados del analizador LR(0) para dicha gramática


b) Calcula la tabla de análisis para el analizador LR(0)
c) Indica justificadamente si es SLR(1)

a) Extendemos la gramática para realizar el análisis LR(0):

(0) S’ ::= S $

(1) S ::= bLd

(2) L ::= E;L

(3) L ::= λ

(4) E ::= i=c

(5) E ::= b

90 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Estado i = c ; b d $ L E S
S0 dF0 1
S1 dacc
SF0 r3/d7 r3 r3 r3 r3/dF3 r3 r3 3 4
S3 dF1
SF1 r1 r1 r1 r1 r1 r1 r1
b) S4 dF4
SF4 r3 r3 r3 r3 r3 r3 r3 F5 4
SF5 r2 r2 r2 r2 r2 r2 r2
SF3 r5 r5 r5 r5 r5 r5 r5
S7 d8
S8 dF2
SF2 r4 r4 r4 r4 r4 r4 r4
c) No se trata de una gramática LR(0) ya que hay ocasiones en las que
observamos un conflicto desplazamiento-reducción.
Para ver si se trata de una gramática SLR(1) vamos a ver si somos capaces de
solucionar los conflictos sabiendo cuales son los elementos siguientes:

siguiente(L)=d : solo reducimos las reglas 2 y 3 si después hay una ’d’.

siguiente(E)=; : solo reducimos las reglas 4 y 5 si después hay un ’;’.

siguiente(S)=$ : solo reducimos la regla 1 si después hay un ’$’.

Se corrigen los dos conflictos que hay ya que en el estado SF0 solo reduciremos

91 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

si llega una ’d’, por tanto en el caso de que llegue una ’b’ o una ’i’ desplazaremos.
Quedando la tabla así:
Estado i = c ; b d $ L E S
S0 dF0 1
S1 dacc
SF0 d7 dF3 r3 3 4
S3 dF1
SF1 r1
S4 dF4
SF4 r3 F5 4
SF5 r2
SF3 r5
S7 d8
S8 dF2
SF2 r4

Ejercicio 1.6: Calcula los conjuntos primero y siguiente de todos los símbolos
no terminales de las gramáticas siguientes
a)

X ::= Ye

X ::= eYZf

Y ::= g

Y ::= Yg

Z ::= h

b)

Q ::= fXY

X ::= cQ

X ::= λ

Y ::= iQ

Y ::= λ

c)

A ::= BXB

X ::= ,

X ::= .

92 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

X ::= e

B ::= 0B

B ::= 1B

B ::= λ

Apartado a)

primero(X)={e,g}

primero(Y)={g}

primero(Z)={h}

siguiente(X)={$}

siguiente(Y)={$,e,h}

siguiente(Z)={$,f}

93 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Apartado b)

primero(Q)={f}

primero(X)={c,λ}

primero(Y)={i,λ}

siguiente(Q)={$} ∪ siguiente(X) ∪ siguiente(Y) = {$, i}

siguiente(X)={i} ∪ siguiente(Q) = {$, i}

siguiente(Y)=siguiente(Q) = {$, i}

Apartado c)

primero(X)={",",.,e}

primero(A)={0,1,",",.,e}

primero(B)={0,1,",",.,e}

siguiente(X)={$,0,1}

siguiente(A)={$,}

siguiente(B)={$,",",.,e}

Ejercicio 1.7: Cacula los símbolos de adelanto para el cierre de las siguientes
reglas y gramáticas:
a) Cierre de E’ ::= .E {$} para la siguiente gramática

E’ ::= E

E ::= T

E ::= E+T

T ::= i

T ::= (E)

b) Cierre de S’ ::= .s {$} para la siguiente gramática

S’ ::= S

S ::= L=R

94 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

S ::= R

L ::= *R

L ::= i

R ::= L

c) Cierre de E ::= (.E) {$} para la siguiente gramática

E ::= (L)

E ::= a

L ::= L,E

L ::= E

a) El cierre, con los conjuntos de adelanto, sería

E’ ::= .E {$}

E ::= .T {$}

E ::= .E+T {+, $}

T ::= .i {+, $}

T ::= .(E) {$}

b)

S’ ::= .S {$}

S ::= .L=R {$}

S ::= .R {$}

L ::= .*R {=, $}

L ::= .i {=, $}

R ::= .L {$}

c)

E ::= (.L) {$}

L ::= .L,E {”, ”, )}

L ::= .E {”, ”, )}

95 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

E ::= .a {”, ”, )}

E ::= .(L) {”, ”, )}

Ejercicio 1.8: Sea la siguiente gramática independiente del contexto:

S ::= aSb

S ::= ab

a) Dibuja el diagrama de estados del analizador LR(1) para dicha gramática


b) Calcula la tabla de análisis para el analizador LR(1)
c) Usa la tabla de análisis para analizar la sentencia aabb
d) Dibuja esquemáticamente el diagrama de estados LALR(1). Es suficiente
con indicar los nombres de los estados, especificando cuáles son la unión de otros
en LR(1).

a)

96 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

Estado S a b $
S0 S2 S1
S1 S3 S4 SF4
S2 ACC
S3 SF2
b) S4 S5 S4 SF1
S5 SF3
SF1 r3
SF2 r2
SF3 r2
SF4 r3
c) La secuencia de acciones sería la siguiente:

Cadena: .aabb / Leemos ’a’ y pasamos a S1


Cadena: a.abb / Leemos ’a’ y pasamos a S4
Cadena: aa.bb / Leemos b y pasamos a SF1
Cadena: aab.b / Como el siguiente elemento a leer es b reducimos y volvemos a S0
Cadena: .aSb / Leemos ’a’ y pasamos a S1
Cadena: a.Sb / Leemos ’S’ y pasamos a S3
Cadena: aS.b / Leemos ’b’ y pasamos a SF2
Cadena: aSb. / Como el siguiente elemento a leer es $, reducimos y volvemos a S0
Cadena: .S / Leemos S y pasamos a S2
Cadena: . / Fin de cadena. Llegados a este punto aceptamos la entrada

d) Cuando pasemos de LR(1) a LALR(1) vamos a agrupar los nodos SF4 y SF1
en uno solo así como SF2 y SF3, manteniendo las mismas reglas en cada caso y
estableciendo como símbolos de adelanto la unión de los símbolos de adelanto de las
reglas de los estados a unir.

Ejercicio 1.9: Sea la siguiente gramática independiente del contexto:

S ::= XX

X ::= aX

X ::= b

a) Dibuja el diagrama de estados del analizador LR(1) para dicha gramática


b) Calcula la tabla de análisis para el analizador LR(1)
c) Usa la tabla de análisis para analizar la sentencia aabb
d) Dibuja esquemáticamente el diagrama de estados LALR(1). Es suficiente
con indicar los nombres de los estados, especificando cuáles son la unión de otros
en LR(1).

a) Extendemos la gramática para realizar el análisis LR(1):

97 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

(0) S’ ::= S
(1) S ::= XX
(2) X ::= aX
(3) X ::= b

Estado a b X S
S0 d1 dF0 acc 2
SF0 r3 r3
S1 d1 dF3 F4
SF3 r3 r3
b) SF4 r2 r2
S2 d3 dF2 F1
SF1 r1 r1
S3 d3 dF2 F5
SF5 r2 r2
SF2 r3 r3

Ejercicio 1.10: Sea la siguiente gramática

D ::= iPSn

P ::= :n

98 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

S ::= λ

S ::= n

a) Dibuja el diagrama de estados del analizador LR(1) para dicha gramática


b) Calcula la tabla de análisis para el analizador LR(1)
c) Indica justificadamente si la gramática es LR(1). Indica justificadamente si
es SLR(1)

a) Extendemos la gramática para realizar el análisis LR(1):

(0) S’ ::= S

(1) S ::= XX

(2) X ::= aX

(3) X ::= b

Estado i n : $ D P S
S0 d1 2
S1 d3 F3
S2 dacc F5
SF3 r3 r3/df4 r3 r3 4
b)
S3 dF2
SF4 r4 r4 r4 r4
S4 dF5
SF2 r2 r2 r2 r2
SF5 r1 r1 r1 r1

99 de 100 14 de junio de 2016 12:49


Autómatas y lenguajes - 2014/2015 - UAM Pedro Valero y Alberto Parramón

c) No es LR(1) porque sigue habiendo conflictos.

100 de 100 14 de junio de 2016 12:49

También podría gustarte