Está en la página 1de 47

LENGUAJES Y COMPILADORES

Analisis Ascendente O Bottom-up

Profesor: Carlos A. Ruiz De La Cruz Melo


Correo: zorroculto69@hotmail.com
TIPOS DE BOTTOM-UP
 Desplazamiento o reducción(shift-reduce) con una pila.
 Analizadores LR(k)
 LR sencillo
 LR canónico
 LALR
 Precedencia de operadores
S
 LR x autómata con pila

id + id* id
ANALISIS BOTTOM-UP
Consiste en construir el árbol de análisis
sintáctico de una frase dada, partiendo de los
VT del mismo, hasta llegar al símbolo inicial o
raíz.

MANGO

Es una subcadena que concuerda con el


lado derecho de una producción y se
reduce al VN del lado izquierdo de la
producción, siendo esta sustitución
parte del árbol de análisis sintáctico.
MANGO
S
Ejemplo 1:
Considérese la siguiente aSa
gramática:

aaSaa
G=( VN , VT , P, E )
VN ={ B, S } VT = { a, b}
P= { S  aBa / aSa
aaaBaaa
B bb / bBb }
aaabBbaaa

aaabbbbaaa
MANGO
G=( VN , VT , P, E )
VN ={ B, S } VT = { a, b}
P= { S  aBa / aSa
Pero no toda cadena que concuerde con el
lado derecho de una producción es un mango B bb / bBb }
como se observa a continuación:

ES IMPOSIBLE CONTINUAR

NO SON aaaBBaaa
MANGOS

aaaBbbaaa

aaabbbbaaa
REDUCIR / DESPLAZAR
REDUCIR ( reduce)
Sustitución de una subcadena que se iguala
con el lado derecho de una producción por el
VN situado al lado izquierdo

DESPLAZAR ( shift )
Lectura de los símbolos de la cadena de
entrada
ANALIZADOR SHIFT-REDUCE
 Se utiliza un buffer para almacenar la
cadena de entrada w  VT*, añadiendole a
w un símbolo $ para marcar el final
 Los tokens se toman del buffer de uno
en uno.
 Se utiliza una pila (stack ) para
almacenar la entrada procesada hasta
ese momento y reducida en lo posible.
 La pila estará inicialmente vacía.
SHIFT-REDUCE
 En cada momento el estado del
analizador queda determinado por el
contenido de la pila junto con la
entrada que queda por procesar.
 Una configuración es el par formado
por la pila y el resto de la entrada.
 Configuración

PILA : [$]
ENTRADA : w $
SHIFT-REDUCE
1. El analizador empuja 0 o mas símbolos a la pila
hasta detectar que en el tope de la pila existe
una subcadena que cuadra con el lado derecho
 de alguna producción A .
2. Si cuadra con  el analizador reduce la cadena 
al símbolo A.
3. Se repite hasta que la cadena de entrada este
vacía y la pila contenga $ y el símbolo inicial.

Configuración final
PILA : $S
ENTRADA : $
SHIFT-REDUCE
Análisis Shift-reduce para la
gramática siguiente:

G=( VN , VT , P, E )
VN = { E } VT ={ +, *, (, ), id }
P= { EE+E/ E*E/ (E)
E  id }

Se prueba para la frase de entrada :


id + id * id
DERIVACIONES
Las derivaciones son por la derecha

drch drch
E  E+E  E+E*E

EE+E EE * E Eid

drch drch drch


E+E*id  E + id*id  id + id *id

Eid Eid Eid


Analisis de una secuencia

No PILA ENTRADA ACCION


1 $ id + id * id $ Desplazar
G=( VN , VT , P, E )
2 $id + id * id $ Reducir Eid
3 $E + id * id $ Desplazar
VN = { E } VT ={ +, *, (, ), id }
4 $E+ id * id $ Desplazar P= { EE+E/ E*E/ (E)
5 $E+id * id $ Reducir Eid
E  id }
6 $E+E * id $ Desplazar
7 $E+E* id $ Desplazar
8 $E+E*id $ Reducir Eid
9 $E+E*E $ Reducir EE * E
10 $E+E $ Reducir EE + E
11 $E $ Aceptar
ACCIONES

 Desplazar ( shift)
 Reducir ( reduce)
 Aceptar
 Error
ACCION ERROR
 Consiste en descubrir un error sintáctico y llamar a
una rutina de recuperación de errores.
 En los analizadores ascendentes es mas complejo
que en los analizadores descendentes.
 Los analizadores ascendentes no son guiados por
objetivo
CONFLICTOS SHIFT REDUCE
 No todas las GLC pueden ser analizadas por este analizador
por dos tipos de posibles problemas:

 Conociendo el contenido de la pila y del próximo token


de entrada no pueda decidirse la acción, desplazar o
reducir.
 Cuando existen varias posibles producciones a utilizar
para reducir.

 En ambos casos decimos que la gramática no es de tipo


shift-reduce o LR.
CONDICION SHIFT REDUCE
Una gramática ambigua no puede ser nunca del tipo LR.

NOTA
La gramática anterior es ambigua y existe otra posible
derivación por la derecha y por lo tanto, otra posible
secuencia de acciones del analizador
CONFLICTO SHIFT /REDUCE
Ejemplo 3
Observe el siguiente caso para esta gramática ambigua.
G = (VN , VT , P, S )
VT ={ if, then, else, otras} VN = { E, S }
P ={ 1. S  if E then S
2. S if E then S else S
3. S  otras }

PILA : …….if E then S


ENTRADA : else ….. $
Explicación
 No se sabe si reducir por la producción 1
o si debemos desplazar el próximo token
de la entrada, else para poder llegar
posteriormente a reducir por la
producción 2. PILA : …….if E then S
 La gramática no es LR
 En la práctica cuando los LR llegan a este ENTRADA : else ….. $
conflicto se elige shift

else …..$
Cadena de entrada
G = (VN , VT , P, S )
VT ={ if, then, else, otras} VN = { E, S }
S PILA
P ={ 1. S  if E then S
2. S if E then S else S Then
S  if E then S
3. S  otras } E
if
:
CONFLICTO REDUCE/REDUCE
EJEMPLO 4
Para una gramática con las características siguientes:

 El token id es para todo tipo de


identificadores (variables o G=(Vn , Vt , P, S )
procedimientos) Vn = { S,…, P, L, I, A}
Vt = { id , (, ) , ,}
 Usa la notación id( id,…) para
P = { ……………
indexar un array como para
1. P id( L)
llamar a un procedimiento.
2. L  id
 Asi v(5) podría ser una llamada a 3. L  L , id
un procedimiento o en v(5):=2 4. A  id ( I )
sería una asignación en una 5. I  id
posición de un array v 6. I  I , id
}

P: llamada a procedimiento
L: lista de parametros
A: array indexado
I : lista de indices
UN CASO DE CONFLICTO
1. Una entrada como B( i, j) aparecerá al
analizador como id ( id, id ).
2. Supongamos que despues de
desplazar los 3 primeros tokens a la G=(Vn , Vt , P, S )
pila tenemos la siguiente Vn = { S,…, P, L, I, A}
configuración: Vt = { id , (, ) , ,}
P = { ……………
1. P id( L)
PILA : …id ( id
2. L  id
ENTRADA : , id )…$ 3. L  L , id
4. A  id ( I )
5. I  id
6. I  I , id
, id ) …..$ }
Cadena de entrada

PILA id
(
id
:
UN CASO DE CONFLICTO
3. Es evidente que debemos reducir el id que esta en la
cima de la pila pero ¿que producción utilizamos?
4. Podría utilizarse la producción 2 interpretando a la
cadena como una llamada a un procedimiento o
podriamos tomar la producción 5 interpretándola
como un array indexado.

NOTA
El caso se conoce como REDUCE /REDUCE

, id ) …..$ G=(Vn , Vt , P, S )
Vn = { S,…, P, L, I, A}
Cadena de entrada
Vt = { id , (, ) , ,}
P = { ……………
PILA id 1. P id( L)
2. L  id
( 3. L  L , id
4. A  id ( I )
id 5. I  id
6. I  I , id
: }
SOLUCION AL CONFLICTO
 Una posible solución consiste en modificar el
analizador léxico para que produsca dos tokens
distintos segun se trate de un procedimiento ( proce )
o el de identificador de una variable ( id )
 Una configuración:
PILA : …proce ( id )
ENTRADA : , id ) …$

Obligaría a utilizar la producción 2. El token proce en


la pila determina la producción a usar G=(Vn , Vt , P, S )
Vn = { S,…, P, L, I, A}

, id ) …..$ ,
Vt = { id , (, ) , , proce}
P = { ……………
Cadena de entrada 1. P proce( L)
2. L  id
3. L  L , id
PILA id L  id 4. A  id ( I )
5. I  id
( 6. I  I , id
}
proce
:
SOLUCION AL CONFLICTO
 Otra solución consiste en usar paréntesis diferentes

G=(Vn , Vt , P, S ) Vn = { S,…, P, L, I, A} Vt = { id , (, ) , ,}
P = { ………
1. P id( L)
2. L  id
3. L  L , id
4. A  id [ I ]
5. I  id
, id ) …..$
6. I  I , id
} Cadena de entrada

PILA id L  id
(
id
:
ANALIZADORES LR(K)
 Los LR(k) constituyen una familia en la que
existen numerosas variantes
 La L se refiere a que se realiza una lectura de
izquierda (left) a derecha de la cadena de
entrada
 La R significa que construyen una derivación por
la derecha (right) de la entrada
 La k es el número de símbolos que se deben
mirar por adelantado para tomar decisiones

SINTACTICO
GRAMATICA LR
 Todos los analizadores LR actuan de
modo similar, diferenciandose en como
se construyen las tablas de acción, e
ir_a.
 Una gramática LR es aquella a la que se
puede construir una TAS.
 Un analizador LR solo necesita mirar el
estado(contiene toda la información
necesaria) en la cima de la pila para
reconocer una subcadena a reducir.
TIPOS DE LR(k)
 LR SIMPLE.- es el menos potente. Se construye con
elementos LR(0).
 LR CANONICO.- es el mas general y dificil de
implementar. Se construye con elementos LR(1)
 LALR ( Look Ahead Left Right). – es el mas empleado por
analizadores como YACC y BISON
RAZONES PARA UN LR(k)
Se utilizan por las siguientes razones

 Para reconocer prácticamente todas las estructuras de


los lenguajes de programación para los que se pueden
escribir GLC.
 El análisis LR(k) es el método conocido mas general
basado en técnicas shift-reduce y que no utiliza
retroceso
 Analiza cualquier gramática LL(K) pero no a la inversa (
LL(1)  LR(1))
 Detecta rapidamente los errores sintácticos
INCONVENIENTE DE UN LR(K)
Requiere mucho trabajo para construir a
mano un analizador de tipo LR(0) para un
lenguaje de programación típico

NOTA
Se necesitan herramientas especializadas como
YACC o BISON
ESQUEMA DE UN LR(K)
CONSTRUCCION DE UN LR(0)

EJEMPLO 5

Partimos usando la siguiente


gramática

G=(VN , VT , P, S )
VN = { E,T, F } VT = { id , *, + , ( , ) }

P={ 1. E  E+T
2. E T
3. TT*F
4. TF
5. F(E)
6. F  id
}
GRAMATICA AUMENTADA
G=(VN , VT , P, S )
VN = { E,T, F }
VT = { id , *, + , ( , ) } Se añade una producción para señalar
el momento de la aceptación. Se
P={ E’ E realizará la acción ACEPTAR en el
momento que vallamos a reducir por
E  E+T esta producción
E T
TT*F
TF
F(E)
F  id
}
AUTOMATA FINITO
 Se construirá un AFD (S = { I1, I2,..,In }) tal que
ejecutandose sobre los símbolos de la pila del
analizador LR nos determine si tenemos que
realizar una acción DESPLAZAR o REDUCIR.
USO DEL PUNTO
Para mostrar el momento actual por el que vamos
durante el análisis de una producción utilizaremos
una notación que consiste en colocar un punto
separando la subcadena que ya hemos procesado
de aquella que esperamos encontrar

Es una producción con un punto en


algún lugar de su cuerpo. Por ejemplo
son LR(0) los siguientes elementos:

E  E + T
EE+T
EE+T
EE+T
OPERACION CERRADURA
Si I es un conjunto de elementos para una
gramática G entonces cerradura (I) es el
conjunto de elementos construidos a partir de I
por las dos reglas:

 En inicio todo elemento de I se añade a


cerradura(I)

 Si AB esta en cerradura(I) y B   es


una producción entonces añádase B a
cerradura(I), si todavía no esta ahí.
CONJUNTOS
G=(VN , VT , P, S ) En inicio todo
elemento de I se
VN = { E,T, F }
añade a
VT = { id , *, + , ( , ) }
cerradura(I)
P={ E’ E

E  E+T
E T
TT*F
TF
F(E)
F  id I0={ E'  E
} E   E+T
ET
T   T*F
TF
F   (E)
F   id }
CONJUNTOS
I0={ E'  E
Si AB esta en
E   E+T cerradura(I) y B   es
ET una producción
T   T*F entonces añádase
TF B a cerradura(I), si
G=(VN , VT , P, S ) todavía no esta ahí.
F   (E)
VN = { E,T, F } F   id }
VT = { id , *, + , ( , ) }

P={ E’ E
I1 = { E ' E  I4= { F ( E)
E  E+T
E  E +T } E   E+T
E T
TT*F ET
TF I2 = { E  T  T   T*F
F(E) T  T *F } TF
F  id F  (E)
} I3 = { T  F  } F   id }

I5={ F  id  } I7={ T  T*F I9 ={ E  E+T 


F  (E) T  T *F }
F   id }

I6={ E  E+ T I8={ F  (E ) I10={ T  T*F  }


T   T *F E  E  +T }
TF I11={ F  (E)  }
F   (E)
F   id }
CONSTRUIR TABLA DESDE EL AFD

1. RESPECTO A LA PARTE DE ACCION


 Si [ A a ] esta en Ii osea [ Ii , a]= IJ entonces
asígnese "desplazar j" a accion[ i, a ], aquí aVT .
 Si [ A ] esta en Ii , entonces asígnese "reducir
A " a accion[ i, a ] para toda a en siguiente(A), aquí
A  S'.
 Si [ S'  S] esta en Ii , entonces asígnese aceptar a
accion[ i, $ ]
CONSTRUIR TABLA DESDE EL AFD
2. RESPECTO A LA PARTE IR_A
 Si [ Ii , A] = Ij , para cualquier AVN , entonces
ir_a[ i , A] = j

3. Todas las entradas no definidas en 1 y 2 son


ERROR
4. El estado inicial es [ S '  S ]
TAS análisis

ESTADO ACCION IR_A


id + * ( ) $ E T F
I5={ F  id  }
0 D5 D4 1 2 3
1 D6
I7={ T  T*F I9 ={ E  E+T 
F  (E) T  T *F }
2 R2 D7 R2 R2 F   id }
3 R4 R4 R4 R4
I6={ E  E+ T I8={ F  (E )
4 D5 D4 8 2 3
T   T *F E  E  +T }
5 R6 R6 R6 R6 TF
6 D5 D4 9 3 F   (E)
F   id }
7 D5 D4 10
8 D6 D11 I10= { T  T*F  } I11={ F  (E)  }
9 R1 D7 R1 R1
10 R3 R3 R3 R3
11 R5 R5 R5 R5

P={ 1. E  E+T
I0={ E'  E I1 = { E ' E  I4= { F ( E) 2. E T
E   E+T E  E +T } E   E+T 3. TT*F Vn SIGUIENTE
ET ET 4. TF
T   T*F I2 = { E  T  T   T*F E $ , +, )
5. F(E)
TF T  T *F } TF T $ , +, ) , *
F   (E) F  (E) 6. F  id
F $,+,),*
F   id } I3 = { T  F  } F   id } }
OPERACIONES
Para I0
Si F (E)  I0 e ir_a( I0, ( ) = I4  accion[ 0, ( ] = D4
Si F d  I0 e ir_a(I0, d ) = I5  accion[ 0, ( ] = D5

Para I1
Si E 'E  I1  accion[ 1, $ ] = aceptar
Si E E+T  I1 e ir_a(I1, + ) = I6  accion[ 1, + ] = D6
Para I2
ET  I2 entonces :
Accion[ 2, $ ] = reducir R2
Accion[ 2, + ] = reducir R2
Accion[ 2, ) ] = reducir R2
Donde
R2 = E T ,  Vt  siguiente(E) = { $, +, ) }

Si TT*F  I2  ir_a( I2, * ) = I7  accion[ 2, * ] = D7


OPERACIONES
Para I3
T  F  I3 entonces:
Accion[ 3, * ] = reducir R4
Accion[ 3, + ] = reducir R4
Accion[ 3, ) ] = reducir R4
Accion[ 3, $ ] = reducir R4
Donde:
R4 = TF ,  Vt  siguiente(T) = {*, +, ) , $ }

Para I4
Si F (E)  I4  ir_a(I4 , ( ) = I4  accion[ 4, ( ] = D4
Si F d  I4  ir_a(I4 , d ) = I5  accion[ 4, d ] = D5

Para I5
F  d  I5 entonces:
Accion[ 5, ) ] = reducir R6
Accion[ 5, * ] = reducir R6
Accion[ 5, + ] = reducir R6
Accion[ 5, $ ] = reducir R6
Donde:
R6 = Fd ,  Vt  siguiente (F)= { ), *, + , $ }
OPERACIONES
Para I6
Si F (E)  I6  ir_a(I6 , ( ) = I4  accion[ 6, ( ] = D4
Si F d  I6  ir_a(I6 , d ) = I5  accion[ 6, d ] = D5

Para I7
Si F (E)  I7  ir_a(I7 , ( ) = I4  accion[ 7, ( ] = D4
Si F d  I7  ir_a(I7 , d ) = I5  accion[ 7, d ] = D5

Para I8
Si F (E)  I8  ir_a(I8 , ) ) = I11  accion[ 8, ) ] = D11
Si E E+T  I8  ir_a(I8 , + ) = I6  accion[ 8, + ] = D6
OPERACIONES
Para I9
Si E  E + T  I9 entonces :
Accion[ 9, $ ] = reducir EE+T = R1
Accion[ 9, ) ] = reducir EE+T = R1
Accion[ 9, + ] = reducir EE+T = R1

Donde:
R1= EE+T ,  Vt  siguiente(E) ={ ) , + , $ }

Si T T*F  I9  ir_a(I9 , * ) = I7  accion[ 9, * ] = D7

Para I10

Si TT * F  I10 entonces :


Accion[ 10, * ] = reducir R3
Accion[ 10, + ] = reducir R3
Accion[ 10, ) ] = reducir R3
Accion[ 10, $ ] = reducir R3
Donde:
R3= TT*F ,  Vt  siguiente(T) ={ * , + , ) , $ }
OPERACIONES
Para I11

Si F  (E)  I11 entonces:


Accion[ 11, ) ] = reducir R5
Accion[ 11, * ] = reducir R5
Accion[ 11, + ] = reducir R5
Accion[ 11, $ ] = reducir R5
Donde:
R5= F(E) ,  Vt  siguiente(F) ={ ) , * , + , $ }
ALGORITMO DE ANALISIS LR
ENTRADA : una cadena w  Vt * y una TAS
SALIDA : si w  L(G)  G es una gramática
LR(1) o w  L(G) G no es LR(1)

variables usadas en el algoritmo:


s , s’ : son estados
ae : variable que apunta a un símbolo de entrada
a : símbolo de entrada apuntado por ae
A : valor no terminal
 : tira  (Vn  Vt )*
ae apunta al primer símbolo de w$
REPETIR
Sea s esta en la cima de la pila y a es apuntado por ae
si accion[ s, a] = desplazar s’
meter a y despues s’ en la cima
avanzar ae al siguiente símbolo de entrada
sino si acción[ s, a] = reducir A 
sacar 2* |  | símbolos de la pila
sea s’ que esta ahora en la cima
meter A y despues ir_a[ s’, A ] en la cima
sino si acción[ s, a ] = aceptar
retornar
sino error( )
FIN REPETIR
ANALISIS LR(0) ESTADO ACCION
TAS
IR_A

id + * ( ) $ E T F

0 D5 D4 1 2 3

ANALISIS 1

2
D6

R2 D7 R2 R2
No PILA ENTRADA ACCION 3 R4 R4 R4 R4
1 0 id * id + id $ Desplazar 5 4 D5 D4 8 2 3
2 0 id 5 * id + id $ Reducir F id 5 R6 R6 R6 R6
3 0F3 * id + id $ Reducir T F 6 D5 D4 9 3

4 0T2 * id + id $ Desplazar 7 7 D5 D4 10

5 0T2*7 id + id $ Desplazar 5 8 D6 D11

6 0 T 2 * 7 id 5 + id $ Reducir F  id 9 R1 D7 R1 R1

7 0 T 2 * 7 F 10 + id $ Reducir T T*F 10 R3 R3 R3 R3

11 R5 R5 R5 R5
8 0T2 + id $ Reducir E  T
9 0E1 + id $ Desplazar 6
10 0E1+6 id $ Desplazar 5 P={ 1. E  E+T
11 0 E 1 + 6 id 5 $ Reducir Fid 2. E T
12 0E1+6F3 $ Reducir TF 3. TT*F
13 0E1+6T9 $ Reducir EE+T 4. TF
14 0E1 $ ACEPTAR 5. F(E)
6. F LR(0)
 id
}
EJERCICIOS PARA LABORATORIO

1. Dada la siguiente gramática G:

G=(Vn, Vt, P, S) Vn={S,L} Vt={a, (, ), ,}


P={ S(L) | a
LL,S | S }

Escriba un LR(0) y después prográmelo en C++ o java .

2. Dada la siguiente gramática G:

Vn={S,A} Vt={a,b}
P={ S  b A / a S / 
A  bA /  }

Escriba un LR(0) y después prográmelo en C++ o java .