Sei sulla pagina 1di 39

Anlisis Sintctico

Descendente
Clase 9
Intro. a A. S. Descendente
Los terminales se
examinan en el orden en
que aparecen en la
cadena de tokens:
t
1
t
2
t
3
t
4
t
5

El rbol de derivacin se
construye
Desde la raz
De izquierda a derecha
A
t
1
B t
5

C D
t
4

t
2
t
3

Anlisis Sintctico
descendente recursivo
Considere la gramtica
E T+E| T
T (E) |int|int*int
Una cadena de tokens es: int *int
Iniciar con el no terminal E ms arriba
Intentar aplicar las reglas para E en orden

Anlisis Descendente
Recursivo
Parsing: dada una cadena de tokens, t
1
t
2
t
n
,
encontrar su rbol de derivacin.
El Anlisis descendente recursivo: trata todas
las producciones de manera exhaustiva.
En un momento dado el estado del rbol
sintctico es: t
1
t
2
t
k
A
Intentar todas las producciones para A: si ABC
es una nueva produccin el nuevo estado es
t
1
t
2
t
k
BC
Hacer backtracking cuando la cadena no empata
Detener cuando no hay ms no terminales
Cundo el A. Descendente
recursivo no funciona?
Considere una produccin SSa: :
En el proceso de reducir S tratamos la regla
anterior.
Qu pasa?
Una gramtica recursiva por la izquierda
tiene un no terminal S
S * S o para algn o
El anlisis descendente recursivo no funciona
en estos casos
Ya que se tienen ciclos infinitos.

Solucin


Eliminacin de recursin por la izquierda
Eliminacin de recursin
por la izquierda inmediata
Considere la gramtica recursiva por la
izquierda
S So||
S genera todas las cadenas comenzando con
| seguido de un nmero de os
Podemos reescribirla empleando recursin
por la derecha.
S |S
S oS|c
Eliminacin de recursin
por la izquierda inmediata.
Ejemplo
Considere la gramtica
S 1| S0 (|=1 y o=0)
Podemos reescribir como:
S 1S
S 0S|c

Eliminacin de recursin
por la izquierda inmediata
En general
S So
1
||So
n
||
1
|||
m
Todas las cadenas derivadas a partir de S
comienzan con uno de los |
1
|
m
y continan
con varias instancias de o
1
o
n

Reescribir como
S |
1
S||
m
S
S o
1
S||o
n
S|c

Forma general de recursin
izquierda inmediata
La gramtica
S Ao|o
A S|
Tambin es recursiva por la izquierda por que
S
+
S|o

Esta recursin por la izquierda tambin se puede
eliminar



Eliminacin de recursin
por la izquierda general
Algoritmo
Entrada: Una gramtica G sin ciclos
(derivaciones de la forma A
+
A) o
producciones epsilon (producciones de la
forma A c)

Salida: Una gramtica equivalente sin
recursin por la izquierda
Eliminacin de recursin
por la izquierda general
Acomoda los no terminales en algn orden A
1
,A
2
,, A
n

Para (cada i desde 1 a n) {
para (cada j de 1 a i-1) {
reemplazar cada produccin de la forma A
i
A
j

por las producciones A
i
o
1
|o
2
| | o
k

donde A
j
o
1
|o
2
| | o
k
son las A
j

producciones
}
eliminar la recursin por la izquierda inmediata de las
producciones A
i
}


Resumen de la recursin
Descendente
Es una estrategia general y simple
La recursin por la izquierda se debe eliminar
primero.
pero esto se puede hacer de manera
automtica
No es popular debido al backtracking
Ya que puede ser demasiado ineficiente
La mayora de las veces podemos evitar el
backtracking
Anlisis Sintctico
Predictivo
Anlisis Sintctico
Predictivo
Similar al descendente-recursivo pero puede predecir
que produccin emplear
Observando en los siguientes tokens
No efectuando backtracking
El anlisis predictivo acepta gramticas LL(k)
L significa explorar la entrada de izquierda-a-derecha.
L significa derivacin mas a la izquierda
K significa prediccin basada en k tokens buscando
adelante.
En la prctica se emplea LL(1).
Lenguajes LL(1)
En descendente recursivo, para cada no terminal y
token de entrada puede haber ms de una eleccin
de produccin.
LL(1) significa que para cada no terminal y tokens
hay solo una produccin que puede conducir al xito.
Se puede especificar en una tabla 2D
Una dimensin para no terminales
Una dimensin para el prximo token
Entradas a la tabla que contienen una produccin.
Anlisis Predictivo y
Factorizacin por la
izquierda
Sea la gramtica
E T+E | T
T int | int * T | ( E )
Es imposible predecir por que
Para T hay dos producciones que empiezan con int
Para E no esta claro como predecir
Una gramtica debe ser factorizada por la izquierda
antes de utilizarse para anlisis predictivo.
Ejemplo de factorizacin
por la izquierda
Regresemos a la gramtica
E T+E | T
T int | int * T | ( E )
Factorizamos los prefijos comunes de las
producciones
E TX
X +E |c
T ( E ) | int Y
Y * T |c

Ejemplo de tabla de anlisis
sintctico LL(1)
Grmtica factorizada por la izquierda
E TX X +E |c
T ( E ) | int Y Y * T |c
La tabla LL(1) (donde $ es un carcter especial de fin de
cadena)

Ejemplo de tabla de anlisis
sintctico LL(1) (Cont.)
Considere la entrada [E,int]
Cuando el no terminal actual es E y el siguiente
smbolo de entrada es int, emplear la produccin
E TX
Esta produccin puede generar int en primera
instancia
Considere la entrada [Y,+]
Cuando el no terminal actual es Y y el smbolo
de entrada es + eliminar Y
Veremos despus por que ocurre esto
Errores en la tabla de
anlisis sintctico LL(1)
Las entradas vacias indican situaciones
de error
Considere la entrada [E,*]
No hay manera de derivar una cadena que
comience con * desde el no terminal E
Manejo de la tabla de
anlisis sintctico
El mtodo es similar al descendente recursivo,
excepto
Para cada no terminal S
Buscamos el prximo token a
Escogemos la produccin mostrada en [S,a]
Empleamos una pila para dar seguimiento de los
smbolos no terminales.
Rechazamos cuando encontramos un estado de
error
Aceptamos cuando encontramos el fin de la cadena
y la pila vacia.
Algoritmo de anlisis
sintctico LL(1)
Ejemplo de anlisis
sintctico LL(1)
Construccin de la tabla de
anlisis sintctico
Los lenguajes LL(1) son aquellos definidos por una
tabla de anlisis sintctico por el algoritmo LL(1).
No puede haber entradas en la tabla con ms de una
definicin
Una vez que tenemos la tabla
El algoritmo es simple y rpido
No se necesita backtraking
Por lo tanto queremos generar tablas de anlisis
sintctico para GLC.
Anlisis Descendente.
Resumen
El anlisis descendente expande un rbol de
derivacin desde el smbolo inicial hasta las
hojas.
Siempre expandir el no terminal ms a la
izquierda.
Anlisis Descendente.
Resumen
Las hojas en cualquier
momento desde una cadena
|A
| tiene slo terminales
La cadena de entrada es
|bo
El prefijo | empata
El siguiente token es b.

Anlisis Descendente.
Resumen
Las hojas en cualquier
momento desde una cadena
|A
| tiene slo terminales
La cadena de entrada es
|bo
El prefijo | empata
El siguiente token es b.
Anlisis Descendente.
Resumen
Las hojas en cualquier
momento desde una cadena
|A
| tiene slo terminales
La cadena de entrada es
|bo
El prefijo | empata
El siguiente token es b.
Construccin de la tabla de
anlisis sintctico
predictivo
Considere el estado E * |A
Con b el siguiente token
Tratando de empatar |bo
Hay dos posibilidades
1. b pertenece a una expresin A
Cualquier Ao puede usarse si b empieza una
cadena derivada desde o
En este caso decimos que b e Primero(o)

Construccin de la tabla de
anlisis sintctico predictivo
(Cont)
1. b no pertenece a una expansin de A
La expansin de A es vaca y b pertenece a una
expansin de (e.d be)
Significa que b puede aparecer despus de A en una
derivacin de la forma S* |Abe
En este caso decimos que be Siguiente(A)
Que producciones se pueden usar en este caso?
Cualquier So se usa si o expande a c
Decimos que c e Primero(A) en este caso
Clculo del conjunto
primero
Definicin Primero(X)={b|Xbo} {c|X* c}
1. Primero(b)= {b}
2. Para toda las producciones XA
1
A
n
Agrega Primero(A
1
)- {c} a Primero(X). Detener si c e
Primero(A
1
)
Agrega Primero(A
2
)- {c} a Primero(X). Detener si c e
Primero(A
2
)

Agrega Primero(A
n
)- {c} a Primero(X). Detener si c e
Primero(A
n
)
Agrega c a Primero(X)
Conjunto primero Ejemplo
Considere la gramtica
E TX X +E |c
T ( E ) | int Y Y * T |c
Conjunto primero
Primero(()={(} Primero(T)={int,(}
Primero())={)} Primero(E)={int,(}
Primero(int)={int} Primero(X)={+, c}
Primero(+)={+} Primero(Y)={*, c}
Primero(*)={*}
Clculo del conjunto
Siguiente
Definicin Siguiente(X)={b|S|Xbe}
1. Calcular el conjunto primero para todos los no terminales.
2. Agregar $ a Siguiente(S) (Si S es el no terminal inicial)
3. Para toda produccin YXA
1
A
n
Agregar Primero(A
1
)- {c} a Siguiente(X). Detener si c e
Primero(A
1
)
Agregar Primero(A
2
)- {c} a Siguiente(X). Detener si c e
Primero(A
2
)

Agregar Primero(A
n
)- {c} a Siguiente(X). Detener si c e
Primero(A
n
)
Agregar Siguiente(Y) a Siguiente(X).

Conjunto Siguiente Ejemplo
Considere la gramtica
E TX X +E |c
T ( E ) | int Y Y * T |c
Conjunto Siguiente
Siguiente(E)={),$}
Siguiente(X)={$,)}
Siguiente(Y)={+,),$}
Siguiente(T)={+,),$}
Construccin de la tabla de
anlisis sintctico LL(1)
Construir una tabla de anlisis
sintctico T para la GLC G
Para cada produccin Ao en G hacer:
Para cada terminal bePrimero(o) hacer:
T|A,b|= o
Si o*c, para cada beSiguiente(A) hacer
T|A,b|= o

Construccin de la tabla
LL(1). Ejemplo
Considere la gramtica
E TX X +E |c
T ( E ) | int Y Y * T |c
Dnde en la lnea de Y pusimos Y *
T?
Dnde en la lnea de Y pusimos Y c
?
En la lnea de Siguiente(Y)={$,+,)}
Notas sobre tablas de
anlisis sintctico LL(1)
Si cualquier celda de la tabla tiene ms de una
produccin, entonces la gramtica G no es LL(1)
Si G es ambigua
Si G es recursiva por la izquierda
Si G no esta factorizada por la izquierda
Y otros casos tambin
La mayora de las gramticas de lenguajes de
programacin no son LL(1)
Existen herramientas que construyen tablas LL(1).
Resumen
Para algunas gramticas hay una estrategia simple
de anlisis sintctico
Anlisis sintctico predictivo (LL(1))
Una vez que se construye la tabla LL(1), se puede escribir el
rbol sintctico a mano

Siguiente clase: una estrategia ms poderosa de
anlisis sintctico para gramticas que no son LL(1)

Potrebbero piacerti anche