1. Cadena de
tokens
Árbol
Sintáctico
ANÁLISIS SINTÁCTICO
1
Análisis Sintáctico
2
Funciones
Comprobar que la secuencia de componentes léxicos cumple las
reglas de la gramática
Generar el árbol sintáctico
Ventajas de utilizar gramáticas
Son especificaciones sintácticas y precisas de lenguajes
Se puede generar automáticamente un analizador
El proceso de construcción puede llevar a descubrir
ambigüedades
Imparte estructura al lenguaje de programación, siendo más fácil
generar código y detectar errores
Es más fácil ampliar y modificar el lenguaje
1
2. Analizador Sintáctico, Tipos
3
Tres tipos generales de analizadores sintácticos:
Métodos Universales: Cocke-Younger-Kasami y Earley
Sirven para cualquier gramática
Muy ineficientes
Descendentes (top-down)
Construyen el árbol de análisis sintáctico desde arriba (raíz, axioma)
hasta abajo (hojas, terminales)
Analizadores Descendentes Recursivos
Analizadores LL(1) con tabla
Ascendentes (bottom-up)
Construyen el árbol de análisis sintáctico desde abajo hacia arriba
Analizadores de Precedencia de Operador
Analizadores LR(1)
Analizador Sintáctico
4
Tanto para el análisis descendente como para el
ascendente:
En general las gramáticas serán LL y LR
La entrada se examina de izquierda a derecha, un símbolo cada
vez
Trabajan con subclases de gramáticas
LR(k) LL(k)
En la práctica solo se utilizan LR(1) y LL(1)
Muchos compiladores se llaman “parser-driven” debido
a que el analizador sintáctico es el que llama al léxico
Existen herramientas para generar automáticamente
analizadores sintácticos (YACC, Bison)
2
3. Análisis Sintáctico Descendente
5
Algoritmo
1.
2.
Poner el axioma como raíz del árbol de derivación
Hasta que solo haya símbolos terminales, derivar más a la izquierda
Ejemplo
Entrada: Id.*.Id.+.Id
Gramática:
Expresión::=Expresión.*.Término | Expresión.+.Término | Término
Término ::= Id | Número
Derivación:
Expresión Expresión.+.Término
Expresión.*.Término.+.Término
Término.*.Término.+.Término
Id.*.Término.+.Término
Id.*.Id.+.Término Id.*.Id.+.Id
Análisis Sintáctico Ascendente
6
Definición: Pivote
Secuencia más larga de símbolos (T y N) en la parte más izquierda
de la entrada que se puede encontrar en la parte derecha de una
producción y tal que todos los símbolos a su derecha son terminales
Ejemplo:
Algoritmo
1.
2.
Si entrada es: Expresión.*.Término.+.Id
el pivote es: Expresión.*.Término
Empezar con la cadena de entrada
Intentar llegar hasta el axioma, encontrando el pivote y reduciéndolo
con la producción correspondiente
Ejemplo
Id.*.Id.+.Id Término.*.Id.+.Id Expresión.*.Id.+.Id
Expresión.*.Término.+.Id Expresión.+.Id
Expresión.+.Término Expresión
3
4. 7
Analizadores Sintácticos,
Problemas
Descendentes
Mas de una opción: A::= |
Recursividad izquierda
Factorización por la izquierda
Ascendentes
Eliminación de la recursividad
Ambigüedad
Retroceso
Analizar los siguientes elementos de la entrada
Más de una opción: A::= y es el pivote
Otros
Problemas semánticos
Análisis Sintáctico Predictivo
8
No necesita realizar retroceso para analizar bien las
sentencias del lenguaje
Sólo con ver el siguiente carácter de la entrada puede
decidir cuál va a ser la siguiente producción a emplear
Condiciones
Diseñar bien la gramática
Eliminar la recursividad izquierda
Factorizar por la izquierda
No está asegurado el tener una gramática predictiva
Las gramáticas son difíciles de leer
Para las partes de las gramáticas que no son
predictivas se pueden utilizar otros analizadores
4
5. Análisis Sintáctico Predictivo
9
Árbol sintáctico
Ejemplo:
Id.*.Id.+.Id
Expresión
Expresión
Expresión
Término
*
+
Término
Término
Id
Id
Id
10
Análisis Sintáctico Predictivo:
Descendente Recursivo
Se ejecuta un conjunto de procedimientos recursivos para procesar
la entrada
A cada NO Terminal de una gramática se le asocia un
procedimiento
Decide la producción que utilizará analizando el símbolo de preanálisis,
si está en PRIMERO() entonces se usa la producción con lado derecho
si no está en ningún PRIMERO entonces se usa una producción
Usa una producción imitando al lado derecho
no terminal da como resultado una llamada a otro procedimiento
terminal (que coincide con el símbolo de preanálisis) produce otra lectura de
otro token. Si el token no coincide entonces Error
La secuencia de procedimientos llamados para procesar la entrada
define implícitamente un árbol de análisis sintáctico
5
6. Análisis Sintáctico Predictivo:
Descendente Recursivo
11
Ejemplo:
S if B then S | write B | i := B
B i = i | i <> i | true | false
Procedure S;
begin
if car= i then begin scan;
if car = asig then scan else error;
B
end
elseif car= if then begin scan;
B;
if car= then scan else error;
S;
end
elseif car=write then begin scan;
B
end
else error
end;
Procedure B;
begin
if car= i then begin scan;
if car in [igual, noigual] then scan else error;
if car = i then scan else error;
end
elseif car = in [true, false] then
scan
else
error
end;
Análisis Sintáctico Predictivo,
DEFINICIONES: PRIMERO
12
Si es una cadena de símbolos gramaticales, PRIMERO() es el
conjunto de terminales que inician las cadenas derivadas de .
PRIMERO()={x | ( * x.), (x T {}), ( *)}
Conjunto PRIMERO(X) para todos los símbolos gramaticales X
1.
Repetir hasta que no se puedan añadir más terminales o a ningún
conjunto PRIMERO
2.
Si X T PRIMERO(X) es { X }
3.
Si X añadir a PRIMERO(X)
4.
Si X N y X Y1Y2...YKY a PRIMERO(X) si a PRIMERO(Yi) y
PRIMERO(Y1), PRIMERO(Y2),..., PRIMERO(Yi-1)
Si Y1 deriva a se añade PRIMERO(Y2)
Si Y1 no deriva a no se añade más a PRIMERO(X)
6
7. 13
Análisis Sintáctico Predictivo,
DEFINICIONES: PRIMERO
PRIMERO(), Ejemplo:
E ::= T.E’
E’ ::= +.T.E’ |
T ::= F.T’
T’ ::= *.F.T’ |
F ::= (.E.) | Id
PRIMERO(E) = { (, Id }
PRIMERO(T) = { (, Id }
PRIMERO(F) = { (, Id }
PRIMERO(E’) = { +, }
14
PRIMERO(T.*.Id) = { (, Id }
PRIMERO(Id.+.Id) = { Id }
PRIMERO(Id) = { Id }
PRIMERO(T’) = { *, }
Análisis Sintáctico Predictivo,
DEFINICIONES: SIGUIENTE
Conjunto SIGUIENTE(A)
SIGUIENTE(A)={x|(S*·A·), (AN), (*), (+),
(xPRIMERO()-{})}
Conjunto de terminales que pueden aparecer inmediatamente
a la derecha de A en alguna forma sentencial, si A es el último
símbolo entonces se incluye el separador $
Algoritmo
1.
2.
3.
4.
SIGUIENTE(S)={$}
La regla AB
SIGUIENTE(B) = (PRIMERO()-{}) SIGUIENTE(B)
La regla AB | =, * ( PRIMERO())
SIGUIENTE(B) = SIGUIENTE(A) SIGUIENTE(B)
Repetir hasta que no cambie ningún conjunto SIGUIENTE
7
8. 15
Análisis Sintáctico Predictivo,
DEFINICIONES: SIGUIENTE
SIGUIENTE(A), Ejemplo:
E ::= T.E’
E’ ::= +.T.E’ |
T ::= F.T’
T’ ::= *.F.T’ |
F ::= (.E.) | Id
N
E
E’
F
T
T’
16
SIGUIENTE
$, )
$, )
$, *, ), +
$, +, )
$, +, )
Análisis Sintáctico Predictivo:
Condiciones
Pregunta:
¿Que
debe cumplir una gramática para que
pueda ser reconocida sin retroceso, con solo
mirar el siguiente elemento de la entrada, de
forma descendente?
Respuesta:
Si
A::= |
PRIMERO() PRIMERO() = . para ningún terminal a
tanto y derivan a la vez cadenas que comiencen con a
No puede ocurrir que * y *
Si *, entonces no deriva ninguna cadena que comience
con un terminal en SIGUIENTE(A)
Condición LL(1)
8
9. 17
Análisis Sintáctico Predictivo:
Condiciones
Condición LL(1)
No puede haber conflictos PRIMERO/PRIMERO
NN, el conjunto PRIMERO de todas sus alternativas debe ser
disjunto
No puede haber múltiples alternativas nulas
NN, solo pueden tener una producción N
No puede haber conflictos PRIMERO/SIGUIENTE
NN, con una alternativa nula, SIGUIENTE(N) debe ser disjunto
de los conjuntos PRIMERO de todas sus alternativas
18
No puede haber entradas con definiciones múltiples en la tabla
de análisis
Análisis Sintáctico Predictivo:
Tabla de Análisis Sintáctico
Funcionamiento
Sea A con aT | aPRIMERO(). El analizador sintáctico
expandirá A por cuando el símbolo actual de la entrada sea a
Algoritmo
ForAll (A::= ) do
1)
a)
ForAll a PRIMERO() do TABLA[A,a]=
b)
Si PRIMERO() Entonces ForAll b SIGUIENTE(A) do TABLA[A,b]=
c)
Si PRIMERO() $ SIGUIENTE(A) Entonces do TABLA[A,$]=
ForAll AN y cT do
2)
a)
If TABLA[A,c]= Then TABLA[A,c]= error
9
10. 19
Análisis Sintáctico Predictivo:
Tabla de Análisis Sintáctico
Ejemplo
E ::= T.E’
E’ ::= +.T.E’ |
T ::= F.T’
T’ ::= *.F.T’ |
F ::= (.E.) | Id
Id
E
E’
T
+
F
)
$
F.T’
(
T.E’
+.T.E’
F.T’
T’
20
*
T.E’
*.F.T’
Id
(.E.)
Análisis Sintáctico Predictivo
No Recursivo; LL(1)
Modelo de analizador sintáctico predictivo no
recursivo
ENTRADA
PILA
X
Y
Z
$
a + b $
Programa de
Análisis Sintáctico
Predictivo
SALIDA
Tabla de Análisis
Sintáctico M
10
11. 21
Análisis Sintáctico Predictivo
No Recursivo; LL(1)
Los símbolos de la entrada actual “a” y cima de
la pila “X” determinan la acción del analizador
Hay tres posibilidades:
X=a=$, el analizador se detiene y anuncia el éxito del
análisis
X=a$, el analizador saca X de la pila y mueve el
apuntador de la entrada al siguiente símbolo de
entrada
XN, el programa consulta la entrada M[X,a]
Si M[X,a]=UVW, se sustituye la X de la pila por WVU (U queda
como cima de la pila)
Si M[X,a]= error, se llama a la rutina de recuperación de error
Análisis Sintáctico LL(1)
22
Algoritmo:
pila =$;
meter$ al final de la entrada;
a:= GetToken;
Push S;
Repeat
If X T or
X=$ then
If X=a then
Pop;
a:= GetToken;
Else
error;
Else
If M[X,a]=XY1Y2..Yk then
Pop;
Push Yk,Yk-1,...,Y1
Emitir la producción X
else
error();
until X=$
If X=$ and a=$ then
Aceptar;
else
error();
11
12. Análisis Sintáctico LL(1)
23
Ejemplo:
Pila
Entrada
Producción
$E
Id * Id + Id $
E::= T E’
$ E’ T
Id * Id + Id $
T::= F T’
$ E’ T’ F
Id * Id + Id $
F::= Id
$ E’ T’ Id
Id * Id + Id $
$ E’ T’
* Id + Id $
$ E’ T’ F *
* Id + Id $
$ E’ T’ F
Id + Id $
$ E’ T’ Id
Id + Id $
$ E’ T’
+ Id $
T’::=
$ E’
+ Id $
E’::= + T E’
$ E’ T +
+ Id $
$ E’ T
Id $
T::= F T’
$ E’ T’ F
Id $
F::= Id
$ E’ T’ Id
Id $
$ E’ T’
$
T’::=
$ E’
$
E’::=
$
$
T’::= * F T’
F::= Id
Análisis Sintáctico Ascendente
24
Análisis por desplazamiento y reducción
Por precedencia de operadores
LR
Construir un árbol de análisis sintáctico para una
cadena de entrada que comienza por las hojas y avanza
hacia la raíz.
Reducir una cadena de entrada w al símbolo inicial de
la gramática
En cada paso de reducción se sustituye una subcadena
que concuerde con el lado derecho de una producción
por el símbolo del lado izquierdo, se traza una
derivación por la derecha en sentido inverso
12
13. 25
Análisis Sintáctico Ascendente:
Gramática de Operadores
Para una pequeña clase de gramáticas se puede
construir con facilidad, a mano, eficientes analizadores
sintácticos por desplazamiento y reducción
Gramática de operadores
No tiene reglas de producción del tipo A::=
No tiene dos no terminales adyacentes A::=·B·C· | A,B,C N
Ejemplo
No es G. de operadores
Si es G. de operadores
EEAE | (E) | -E | id
EE+E | E-E | E*E | E/E | (E) | -E | id
A+ | - | * | /
26
Análisis Sintáctico Ascendente:
Precedencia de Operador
Inconvenientes
No se puede tener la seguridad de que el analizador acepta
exactamente el lenguaje deseado
Es difícil de manejar componentes léxicos con dos precedencias
distintas, como el signo menos (unario y binario)
Sólo una pequeña clase de gramáticas puede analizarse
Ventajas
Sencillez
Se pueden establecer relaciones de precedencia (* precede a +)
Se aplican con otros analizadores para la parte que no
son de operador
13
14. 27
Análisis Sintáctico Ascendente:
Precedencia de Operador
El análisis recorre la entrada de izquierda a derecha y
se encuentra en dos posibles estados:
Esperando un operador
Esperando un operando
El análisis mantiene dos pilas
28
Pila de Operadores
Pila de Operandos
Cuando un operador en la cima de su pila es de más
prioridad que el siguiente de la pila, entonces el pivote
consiste en ese operador junto a los dos operandos
situados más arriba de la pila de operandos
Análisis Sintáctico Ascendente:
Precedencia de Operador
Entrada:
Gramática
Id·+·Id·*·Id
E:=E·+·E | E·*·E | (·E·) | Id
La gramática es ambigua pero este tipo de análisis
proporciona una única derivación
Entrada
Pila de Operadores
Ida·+·Idb·*·Idc
+·Idb·*·Idc
Idb·*·Idc
Pila de Operandos
Ida
+
Ida
*·Idc
+
Idb Ida
Idc
*+
Idb Ida
*+
Idc Idb Ida
14
15. 29
Precedencia de Operador:
Relaciones de Precedencia
Se definen tres relaciones de precedencia
disjuntas
a<•b si a tiene menos precedencia que b
a=b si a tiene igual precedencia que b
a•>b si a tiene más precedencia que b
Algoritmo
Sustituir todos los símbolos no terminales por un único símbolo
Insertar $ al principio y al final de la cadena de entrada
Insertar las relaciones de precedencia en la cadena de entrada
Mientras entrada$S$ hacer
Recorrer entrada desde la izquierda hasta encontrar •>
Buscar a la izquierda, a partir de ese punto, el primer <•
Reducir el pivote que se encuentra en el medio
Reinsertar las relaciones de precedencia, ignorando los no terminales
30
Precedencia de Operador:
Ejemplo
Entrada:
$·(·Id·+·Id·)·$
Gramática:
E::= E·+·E | E·*·E | (·E·) | Id
Tabla de precedencia:
(
Id
*
+
)
$
•>
)
•>
•>
•>
•>
•>
•>
•>
*
<•
<•
•>
•>
•>
•>
+
<•
<•
<•
•>
•>
•>
(
<•
<•
<•
<•
=
$
<•
<•
<•
<•
Id
Análisis
=
Entrada
Derivación
$ <• ( <• Id •> + <• Id •> ) •>$
$·(·E·+·Id·)·$
$ <• ( <• E + <• Id •> ) •> $
$·(·E·+·E·)·$
$ <• ( <• E + E •> ) •> $
$·(·E·)·$
$ <• ( E = ) •> $
$·E·$
15
16. 31
Obtención de las relaciones de
precedencia
xy
sii existe:
A::=...xBy...
x <• y
B{N }
sii existe:
A::=...xB...
C{N }
B::=+Cy...
x •> y
sii existe:
A::=...By...
C{N }
B::=+...xC
32
Precedencia de Operador:
Construir la Tabla de
Precedencia
Si el operador 1 tiene mayor precedencia que 2
entonces hacer 1 •>2 y 2 <• 1
Si los operadores 1 y 2 son de igual precedencia (por
ejemplo el mismo operador), entonces hacer:
1 •> y 2 •> 1 si son asociativos por la izquierda
1 <• y 2 <• 1 si son asociativos por la derecha
Hacer <•Id, Id•>, <•(, (<•, )•> , •>), •>$, $<•
(=) $<• (
$<•Id
(<• (
Id•>$
)•>$
(<•Id
Id•>)
)•>)
16
17. 33
Precedencia de Operador:
Construir la Tabla de
Precedencia
Definiciones:
Cabecera(A) = { x | (A* ·x·)
(x T) (A N) ( N*) ( *)}
Último(A) = { x | (A* ·x·)
(x T) (A N) ( *) ( N*)}
Ejemplo:
E::=E·+·E | T
T::=T·*·F | F
F::=(·E·) | Id
Propiedad:
34
Cabecera(E)={+, *, (, Id}
Último(E)={+, *, ), Id}
(A::= ·B·a·C·) P, a T, A, B, C N, , *, a siempre
aparece en un nivel superior a los símbolos terminales de
Cabecera(C) y Último(B) en el árbol de derivación
Precedencia de Operador:
Construir la Tabla de
Precedencia
Reglas:
(A::= ·B·a·C·) P, a T, A, B, C N, , *
1.
c Cabecera(C), a <• c
2.
b Último(B), b •> a
3.
(A::= ·a··b·) P, a, b T, a=b , *
Si existe más de una relación de precedencia entre dos símbolos
terminales, no es una gramática de precedencia
Algoritmo
ForAll (A::= ·B·a·C·) P do
Calcular Cabecera(C)
Calcular Último(B)
Calcular las precedencias usando las reglas 1, 2 y 3
ForAll a Cabecera(S) do $ <• a
ForAll a Último(S) do a •> $
17
18. 35
Precedencia de Operador:
Construir la Tabla de
Precedencia
Gramática
E::=E·+·E | T
T::=T·*·F | F
F::=(·E·) | Id
Cabecera y Último
N
Último
+, *, (, Id
+, *, ), Id
T
*, (, Id
*, ), Id
F
Cabecera
E
(, Id
), Id
Tabla
Regla
+, *, ), Id •> +
+ <• *, (, Id
E::=T+F
36
Precedencias(R2)
E::=E+T
Precedencias (R1)
*, ), Id •> *
* <• (, Id
Precedencia de Operador:
Operadores Unarios (¬)
Manejo de Operadores Unarios (¬)
Operador Unario que no es además Binario
<• ¬
¬ •> si ¬ tiene mayor precedencia que
¬ <• si ¬ tiene menor precedencia que
Operador Unario que además es Binario
Mediante la tabla de precedencia no puede analizarse correctamente
cadenas como: Id*-Id
Solución: Utilizar el analizador léxico para devolver dos componentes
léxicos distintos, recordando el componente léxico anterior debe
distinguir uno de otro.
Ejemplo: Es el menos unario si antes el componente léxico leído era
un operador, un paréntesis izquierdo, una coma o un símbolo de
asignación
18
19. 37
Precedencia de Operador: Funciones de
Precedencia
La tabla de precedencia se puede simplificar, con el
objetivo de ahorrar memoria y aumentar la velocidad de
proceso, mediante dos funciones f y g
Transforman los símbolos terminales en enteros
Tienen que cumplir que a,b T
38
si a = b, f(a) = g(b)
si a <• b, f(a) < g(b)
si a •> b, f(a) > g(b)
Para encontrar la relación de precedencia entre a y b se
realiza una comparación entre f(a) y g(b)
No todas las relaciones de precedencia tienen
funciones de precedencia
Precedencia de Operador:
Funciones de Precedencia
Construcción de las Funciones de Precedencia
1.
2.
Crear los símbolos fa y ga aT {$}
Se dividen los fa y ga en tantos grupos como sea
posible:
3.
Crear un grafo dirigido cuyos nodos son los grupos
encontrados en el paso 2, los arcos se etiquetan:
4.
Si a=b entonces fa y gb están en el mismo grupo
si a<•b, gb fa
si a•>b, fa gb
Ciclos en el grafo:
Respuesta SI, entonces no existen funciones de
precedencia
Respuesta NO, entonces f(a) y g(a) son los caminos más
largos que comienzan en fa y ga
19
20. 39
Precedencia de Operador:
Funciones de Precedencia
Ejemplo
Id
+
*
$
•>
Id
•>
•>
+
•>
<•
•>
<•
•>
•>
•>
$
<•
*
<•
<•
<•
Cada símbolo está solo en un grupo
gId
g+
g$
fId
40
g*
f*
f+
f$
Precedencia de Operador:
Funciones de Precedencia
No hay ciclos, entonces existen las funciones de
precedencia.
Como las funciones de $ no tienen arcos entonces
f($)=g($)=0
El camino más largo desde g+ tiene longitud 1, entonces
g(+)=1
El camino más largo desde gId a f* a g* a f+ a f$ por tanto
g(id)=5
Id
+
*
$
f
4
2
4
0
g
5
1
3
0
20
21. Análisis Ascendente LR
41
LR(k): Left-to-right, rightmost derivation, ·· (*, *T) k
símbolos de entrada son necesarios para tomar las decisiones de
análisis sintáctico
Ventajas
Es el método de análisis por desplazamiento y reducción sin retroceso más
general, a pesar de esto es igual de eficiente
La clase de gramáticas que pueden analizarse es un supraconjunto de la
clase de gramáticas que pueden analizarse con analizadores sintácticos
predictivos
Detectan los errores sintácticos tan pronto como es posible en un examen de
izquierda a derecha de la entrada
Se pueden reconocer prácticamente todas las construcciones de los
lenguajes de programación descritos por una gramática G2
Inconvenientes
La construcción “a mano” requiere mucho trabajo
Tipos de Análizadores LR
42
LR simple (SLR)
Fácil
de implementar
Menos poderoso, hay algunas gramáticas que los
otros métodos pueden analizar y este no puede
LR canónico
Es
muy costoso de implementar
El más potente
LALR (LR con examen por anticipado)
Intermedio
entre los dos métodos anteriores
21
22. Modelo de un Analizador LR
43
ENTRADA
Pila
a1 ... a1 ... an $
Programa de
Análisis Sintáctico
LR
sm
Xm
SALIDA
sm-1
Xm-1
...
Acción Ir_a
s0
Tabla de Análisis
Sintáctico LR
Modelo de Analizador LR
44
El programa es el mismo para todos los analizadores LR
Xi es un símbolo gramatical y cada si es un símbolo llamado estado
Se utiliza el símbolo de estado y el símbolo de la entrada para
indexar la tabla y determinar la acción siguiente
La tabla de análisis sintácticos tiene dos partes:
Acción[sm, ai]=
Aceptar: acepta la entrada, el análisis sintáctico finaliza
Desplazar:
introduce en la pila el símbolo ai y el estado sm
Error:
error de sintaxis
Reducción:
extrae símbolos de la pila, ejecuta la acción
semántica correspondiente a una producción
Ir_a[sm, Xi]= sk
22
23. Modelo de Analizador LR
45
Configuración de un analizador sintáctico LR
Acción[sm, ai] = desplazar s
Tupla con el contenido de la pila y la entrada que
resta por procesar
(s0 X1 s1 X2 s2 ... Xm sm, ai
ai+1 ... an$)
(s0 X1 s1 X2 s2 ... Xm sm ai s, ai+1 ... an$)
Acción[sm, ai] = reducir A
(s0 X1 s1 X2 s2 ... Xm-r sm-r A s, ai ai+1 ... an$)
donde s=Ir_a[sm-r, A] y r=|| (se extraen r
símbolos no
terminales y r símbolos de estados de
la pila)
Algoritmo de Análisis LR
46
apuntar ae al primer símbolo de w$ (s está en la cima y ae apunta al símbolo a)
repetir
caso Acción[s, a]
Desplazar s’
push a
push s’
leer en la entrada
Reducir A
pop 2*|| símbolos
s’ símbolo en la cima de la pila
s= Ir_a[s’, A]
push A
push s
Aceptar
Error
fincaso
hasta Aceptar o Error
23
24. Ejemplo de Análisis LR
Gramática
Tabla de análisis sintáctico
Acción
1. E::= E·+·T
Estado
0
Ir_a
Id
+
*
d5
(
)
2. E::= T
1
2
r2
4. T::= F
3
5. F::= (·E·)
4
6. F::= Id
E
F
2
3
8
2
3
ACP
d7
r4
r2
r4
d5
r2
r4
r4
r6
r6
d4
r6
r6
6
d5
d4
7
d5
d4
8
T
1
d6
3. T::= T·*·F
5
$
d4
d6
9
3
10
d11
9
r1
d7
r1
r1
10
r3
r3
r3
r3
11
r5
r5
r5
47
r5
Ejemplo de Análisis LR
48
Pila
Entrada
0
Id·*·Id·+·Id·$
0 Id 5
*·Id·+·Id·$
Acción
d5
r6
0F3
*·Id·+·Id·$
r4
0T2
*·Id·+·Id·$
d7
0T2*7
Id·+·Id·$
d5
0 T 2 * 7 Id 5
+·Id·$
r6
0 T 2 * 7 F 10
+·Id·$
r3
0T2
+·Id·$
r2
0E1
+·Id·$
d6
0E1+6
Id·$
d5
0 E 1 + 6 Id 5
$
r6
0E1+6F3
$
r4
0E1+6T9
$
r1
0E1
$
ACP
24
25. Construcción de una Tabla LR
49
Definiciones
Item
(elemento)
Producción
con un marcador de posición
S::= if • C then S
En la entrada se ha visto el
token if y queda por procesar C then S
Estado
Representa
un momento en la derivación, equivale a
un estado en el autómata que realiza el análisis
Un estado está formado por un conjunto de items
50
Algoritmo de definición de
estados
Crear un símbolo no terminal nuevo S’
Crear una nueva producción S’::=S, donde es el axioma
Crear el estado inicial, S0={(S’::=•S)}
Mientras se creen nuevos estados hacer
Cierre:
Si A::=x•X Si
entonces, Para cada X::=w P
Si=Si U {(X::= •w)}
Creación
Para cada z | Ii=(A::=x • zw) Si
Crear un nuevo estado Sj ={(A::=xz •w)}
Para cada Ik=(B::= • z) Si , Ik Ii
Sj=Sj U {(B::= • z)}
25
26. Algoritmo de tabla SLR(1)
51
Desplazar
Si A::=x•aw Si , A::=xa•w Sj , a T
Entonces Acción[Si,a]=Desplazar Sj
Reducir
Si A::=w• Si , Pj=(A::=w)
Entonces Para cada a SIGUIENTE(A) Acción [Si,a]=Reducir j
Aceptar
Si S’::=S• Si
Entonces Acción[Si,$]=Aceptar
Ir_a
52
Si A::=x•Bw Si , A::=xB•w Sj , B N
Entonces Ir_a[Si,B]= Sj
Análisis Sintáctico:
Manejo de Errores
Características
Informar con claridad y exactitud
Recuperación rápida
No debe retrasar el procesamiento de programas sin
errores
Estrategias de recuperación
Modo de pánico
Nivel de frase
Producciones de error
Corrección Global
26
27. 53
Estrategias de recuperación de
errores (I)
Modo de pánico
Método más sencillo
Lo pueden utilizar la mayoría de los métodos de análisis
FUNCIONAMIENTO:
Adecuado para lenguajes en los que es raro que se produzcan varios
errores en la misma línea
Nivel de frase
FUNCIONAMIENTO:
54
Desecha los símbolos de entrada hasta que encuentra componentes léxicos
de sincronización (delimitadores, punto y coma, end)
Realizar una corrección local de la entrada restante para poder continuar con
el análisis, (sustituir coma por punto y coma, añadir coma)
Dificultad para manejar situaciones en las que el error se produjo antes
del punto de detección
Estrategias de recuperación de
errores (II)
Producciones de error
FUNCIONAMIENTO
Si se conocen los errores que pueden suceder, entonces
puede extenderse la gramática para incluir producciones de
error
Corrección global
FUNCIONAMIENTO
Son algoritmos que minimiza el número de cambios
necesarios para convertir una cadena errónea en otra
correcta
Demasiado costoso, en tiempo y espacio
Solo tiene interés teórico
27