Deteccion y recuperacion de errores - GIAA
Deteccion y recuperacion de errores - GIAA
Deteccion y recuperacion de errores - GIAA
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Recuperación <strong>de</strong> Errores<br />
1<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Rutinas <strong>de</strong> Manejo <strong>de</strong> Errores<br />
Ocupan gran parte <strong>de</strong> los compiladores<br />
Objetivos<br />
• Informar con claridad, exactitud<br />
• Recuperación rápida<br />
• recuperación no es corrección<br />
• No <strong>de</strong>be retrasar el procesamiento <strong>de</strong> programas sin <strong>errores</strong><br />
• No generar <strong>errores</strong> en cascada (ej. eliminar i<strong>de</strong>ntificador)<br />
Acciones posibles<br />
• Detectar <strong>errores</strong><br />
• Informar <strong>de</strong> los <strong>errores</strong><br />
• Recuperar <strong>de</strong> los <strong>errores</strong><br />
• Corregir <strong>errores</strong><br />
¿Necesidad actual <strong>de</strong> recuperación?<br />
• Más rápido re-compilar que leer siguiente error…<br />
2
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Tipos <strong>de</strong> Errores<br />
Tipos <strong>de</strong> <strong>errores</strong><br />
• Léxicos: escribir mal un i<strong>de</strong>ntificador, número, …<br />
• Sintácticos: no poner un “;” al final <strong>de</strong> una sentencia,<br />
estructura incorrecta<br />
• Semánticos: multiplicar por una variable booleana<br />
• Lógicos: bucle infinito<br />
Herramientas para disminuir el número <strong>de</strong> <strong>errores</strong> ...<br />
• Léxicos<br />
• Si se utiliza alguna herramienta que complete palabras<br />
• Sintácticos<br />
• Si se utiliza algún editor basado en sintaxis (colores)<br />
• Semánticos<br />
• Busca funciones/clases e indica tipos especificados<br />
3<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación Errores Sintácticos<br />
Ejemplo 1: análisis <strong>de</strong>scen<strong>de</strong>nte<br />
Gramática:<br />
S::=a A S | b A<br />
A::=c A | d<br />
Tabla:<br />
a<br />
Σ N<br />
S aAS bA<br />
A<br />
cA d<br />
Entrada: a b ...<br />
Estado <strong>de</strong>l análisis cuando <strong>de</strong>tecta el error:<br />
Pila Entrada<br />
$S a b ...<br />
$SAa a b ...<br />
$SA b ...<br />
Error: Se ha encontrado una b, cuando se esperaba una c o d<br />
• Podría eliminarse<br />
b<br />
c<br />
d<br />
4
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Errores en Análisis LR<br />
Ejemplo 2: análisis ascen<strong>de</strong>nte<br />
Gramática<br />
1. S::=A A<br />
2. A::=x A<br />
3. A::=y<br />
Entrada: xy<br />
0<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
x<br />
d3<br />
d3<br />
d3<br />
r3<br />
r1<br />
r2<br />
acción<br />
y<br />
d4<br />
d4<br />
d4<br />
r3<br />
r2<br />
$<br />
acpt<br />
r3<br />
r2<br />
ir_a<br />
S A<br />
1 2<br />
5<br />
6 6<br />
7<br />
8<br />
Estado <strong>de</strong>l análisis cuando <strong>de</strong>tecta el error: Pila Entrada<br />
Se podría añadir un token y 0x3A6 $<br />
0A2 $<br />
0A2 $<br />
5<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Estrategias <strong>de</strong> Recuperación<br />
No hay una estrategia <strong>de</strong> aceptación universal<br />
• Abundan técnicas heurísticas y ad hoc<br />
Principio general <strong>de</strong> recuperación<br />
• Minimizar tokens eliminados/modificados<br />
• Dejar el analizador listo para continuar procesando<br />
Principales estrategias <strong>de</strong> recuperación son:<br />
• Modo <strong>de</strong> pánico/alarma<br />
• Nivel <strong>de</strong> frase<br />
• Producciones <strong>de</strong> error<br />
• Corrección Global<br />
6
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Modo <strong>de</strong> Pánico<br />
Características<br />
• Método más sencillo<br />
• Lo pue<strong>de</strong>n usar la mayoría <strong>de</strong> los AS<br />
• No entra en lazos infinitos<br />
• A<strong>de</strong>cuado para lenguajes en los que son raros múltiples<br />
<strong>errores</strong> en la misma proposición<br />
Funcionamiento general<br />
• El AS <strong>de</strong>secha símbolos <strong>de</strong> la entrada, uno por uno, hasta<br />
encontrar un token <strong>de</strong> sincronización para continuar<br />
• Delimitadores (punto y coma, palabras clave como end)<br />
Inconvenientes<br />
• Podrían omitirse gran cantidad <strong>de</strong> símbolos sin analizar<br />
7<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
A nivel <strong>de</strong> frase<br />
Características<br />
• Correcciones en la ca<strong>de</strong>na <strong>de</strong> entrada<br />
Funcionamiento<br />
• Descubierto el error se corrige (localmente) la entrada por un<br />
prefijo que permite continuar el AS<br />
• Sustituir una coma por un punto y coma, insertar un punto y<br />
coma, etc.<br />
Inconvenientes<br />
• Dificultad para resolver situaciones en las que el error se<br />
produjo antes <strong>de</strong> la <strong>de</strong>tección <strong>de</strong> éste<br />
• Pue<strong>de</strong>n producir lazos infinitos<br />
• Evitar insertar símbolos antes <strong>de</strong>l símbolo actual en la entrada<br />
8
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Producciones <strong>de</strong> error<br />
Funcionamiento<br />
• Conocidos los <strong>errores</strong> más comunes, se extien<strong>de</strong> la gramática<br />
con producciones <strong>de</strong> error<br />
• Reconocido el error, se dan diagnósticos precisos <strong>de</strong> la<br />
construcción errónea<br />
• Ej.:<br />
E->E op T | E->T<br />
E-> E T //falta operador<br />
T->id | num<br />
Inconvenientes<br />
• Dificultad para ir más allá <strong>de</strong> los casos particulares más<br />
frecuentes<br />
• Generación ambigüeda<strong>de</strong>s<br />
9<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Corrección Global<br />
Características<br />
• Algoritmos que eligen una secuencia mínima <strong>de</strong><br />
cambios para obtener una corrección global <strong>de</strong><br />
menor costo<br />
• Ej.: x=a(p+q(-b(r-s); -> a(p+q)-b(r-s);<br />
ifa=b then sum=0; -> if a =b then sum=0;<br />
Inconvenientes<br />
• Técnicas costosas en tiempo y espacio: métricas <strong>de</strong><br />
distancias, búsqueda, optimización, …<br />
10
Recuperación en Analisis<br />
Descen<strong>de</strong>nte Predictivo<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Detección <strong>de</strong>l error<br />
• En un procedimiento, el token <strong>de</strong> preanálisis no es<br />
válido en esa situación<br />
Recuperación<br />
• Modo pánico<br />
• Si no encuentra token apropiado, buscar hasta tokens <strong>de</strong><br />
sincronización<br />
• Calcular los tokens <strong>de</strong> sincronización apropiados en cada<br />
situación<br />
• Conjunto siguiente <strong>de</strong>l no terminal<br />
• Conjunto primero, <strong>de</strong>spués<br />
• Elección que permita rápida recuperación <strong>de</strong> los <strong>errores</strong><br />
más comunes<br />
11<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación en Análisis<br />
Descen<strong>de</strong>nte Predictivo. Ejemplo<br />
Ejemplo:<br />
S → if B then S | write B | i := B<br />
B → i = i | i i | true | false<br />
PRIMERO(S)= {if, write, i}<br />
PRIMERO(B)= {i,true,false}<br />
Procedure S()<br />
{<br />
if (token== if)<br />
{ scan();<br />
B();<br />
if (token== then) {scan();} else error();<br />
S();<br />
}<br />
else if (token==write)<br />
{scan();<br />
B();<br />
}<br />
else if (token== i)<br />
{ scan();<br />
if (token == asig) {scan();} else error();<br />
B();<br />
}<br />
else error()<br />
}<br />
Procedure B()<br />
{<br />
if (token= i)<br />
{ scan();<br />
if (token in [igual, noigual]) scan(); else error();<br />
if (token == i) then scan else error;<br />
}<br />
elseif (token in [true, false])<br />
scan();<br />
else<br />
error();<br />
}<br />
Procedure Main()<br />
{<br />
S();<br />
if (token!=“$”) error<br />
}<br />
12
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación en Analisis<br />
Descen<strong>de</strong>nte Predictivo. Ejemplo<br />
Ejemplo con modo pánico:<br />
S → if B then S | write B | i := B<br />
B → i = i | i i | true | false<br />
Procedure S(sync)<br />
{<br />
buscarSinc({if, write, i}, sync);<br />
if (not token in {if, write, i})return;<br />
if (token== if)<br />
{ scan();<br />
B({then});<br />
if (token== then) scan();<br />
S(sync); }<br />
else if (token==write)<br />
{scan();<br />
B({$}); }<br />
else if (token== i)<br />
{ scan();<br />
if (token == asig) scan();<br />
B({$}); }<br />
buscarSinc(sync, {})<br />
}<br />
Procedure B(sync)<br />
{<br />
buscarSinc({i, true, false}, sync);<br />
if (not token in {i, true, false}) return;<br />
if (token= i)<br />
{ scan();<br />
if (token in {igual, noigual}) scan();<br />
if (token == i) scan(); }<br />
elseif (token in {true, false})<br />
scan();<br />
buscarSinc(sync, {});<br />
}<br />
Procedure Main()<br />
{<br />
S({$, if, write, i});<br />
if (token!=“$”) error();<br />
}<br />
PRIMERO(S)= {if, write, i}<br />
PRIMERO(B)= {i,true, false}<br />
SIGUIENTE(S)= {$}<br />
SIGUIENTE(B)= {then, $}<br />
Procedure buscarSinc<br />
(PRIM,SIG)<br />
{<br />
if (not token in PRIM){<br />
mensajeError();<br />
avanzar(PRIM U SIG);}<br />
}<br />
Procedure avanzar(A)<br />
{<br />
while not (token in A){<br />
scan(); }<br />
}<br />
13<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación en Analisis<br />
Descen<strong>de</strong>nte Predictivo. Ejemplo<br />
Ej.:<br />
if a:=b then writte false<br />
Procedure S(sync)<br />
{<br />
buscarSinc({if, write, i}, sync);<br />
if (not token in {if, write, i})return;<br />
if (token== if)<br />
{ scan();<br />
B({then});<br />
if (token== then) scan();<br />
S(sync); }<br />
else if (token==write)<br />
{scan();<br />
B({$}); }<br />
else if (token== i)<br />
{ scan();<br />
if (token == asig) scan();<br />
B({$}); }<br />
buscarSinc(sync, {})<br />
}<br />
Procedure B(sync)<br />
{<br />
buscarSinc({i, true, false}, sync);<br />
if (not token in {i, true, false}) return;<br />
if (token= i)<br />
{ scan();<br />
if (token in {igual, noigual}) scan();<br />
if (token == i) scan(); }<br />
elseif (token in {true, false})<br />
scan();<br />
buscarSinc(sync, {});<br />
}<br />
Procedure Main()<br />
{<br />
S({$, if, write, i});<br />
if (token!=“$”) error();<br />
}<br />
PRIMERO(S)= {if, write, i}<br />
PRIMERO(B)= {i,true, false}<br />
SIGUIENTE(S)= {$}<br />
SIGUIENTE(B)= {then, $}<br />
Procedure buscarSinc<br />
(PRIM,SIG)<br />
{<br />
if (not token in PRIM){<br />
mensajeError();<br />
avanzar(PRIM U SIG);}<br />
}<br />
Procedure avanzar(A)<br />
{<br />
while not (token in A){<br />
scan(); }<br />
}<br />
14
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación en Analizador LL(1)<br />
Detección <strong>de</strong>l error<br />
• El terminal <strong>de</strong> la cima <strong>de</strong> la pila no concuerda con la<br />
entrada<br />
• El no terminal A <strong>de</strong> la cima <strong>de</strong> la pila y el termina a<br />
<strong>de</strong> la entrada in<strong>de</strong>xan la tabla <strong>de</strong> análisis sintáctico<br />
una entrada vacía, M[A,a]=∅<br />
Recuperación<br />
• Modo pánico<br />
• La eficacia <strong>de</strong> esta estrategia <strong>de</strong>pen<strong>de</strong> <strong>de</strong> la elección <strong>de</strong>l<br />
conjunto <strong>de</strong> tokens <strong>de</strong> sincronización<br />
• La elección <strong>de</strong>be ser tal que el AS se recupere rápidamente<br />
<strong>de</strong> los <strong>errores</strong> más comunes<br />
15<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación en AS LL(1)<br />
Heurísticas para modo pánico<br />
• Colocar todos los símbolos <strong>de</strong> SIGUIENTE(A) en el<br />
conjunto <strong>de</strong> sincronización <strong>de</strong> A<br />
• Saltar tokens hasta encontrar uno en SIGUIENTE(A) y sacar<br />
A <strong>de</strong> la pila, es probable que el AS pueda seguir<br />
• Acción especial si se vacía la pila: poner S y saltar hasta<br />
PRIMERO(S)<br />
• Añadir los símbolos <strong>de</strong> PRIMERO(A) al conjunto <strong>de</strong><br />
sincronización <strong>de</strong> A, el AS continúa con A si aparece<br />
un token <strong>de</strong> PRIMERO(A)<br />
• Añadir al conjunto <strong>de</strong> sincronización tokens <strong>de</strong> inicio<br />
<strong>de</strong> bloques <strong>de</strong> una jerarquía superior (bloques, sent,<br />
exp, …)<br />
16<br />
Si λ PRIMERO( ) d i ió l
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación AS LL(1)<br />
Modo Pánico<br />
Ejemplo:<br />
• E → TE’<br />
{(,id}<br />
{),$}<br />
E’<br />
• E’ → +TE’ | λ<br />
{+,λ} {),$}<br />
• T → FT’<br />
T {(,id} {+,),$}<br />
• T’ → *FT’ | λ T’ {*,λ} {+,),$}<br />
• F → (E) | id F {(,id} {+,*),$}<br />
Σ N<br />
E<br />
Primero<br />
Siguiente<br />
E<br />
E’<br />
T<br />
T’<br />
F<br />
id<br />
E→TE’<br />
scan<br />
T→FT’<br />
scan<br />
F→id<br />
+<br />
scan<br />
E’→+TE’<br />
ext<br />
T’→λ<br />
ext<br />
*<br />
scan<br />
scan<br />
scan<br />
T’→*FT’<br />
ext<br />
(<br />
E→TE’<br />
scan<br />
T→FT’<br />
scan<br />
F→(E)<br />
)<br />
ext<br />
E’→λ<br />
ext<br />
T’→λ<br />
ext<br />
$<br />
ext<br />
E’→λ<br />
ext<br />
T’→λ<br />
ext<br />
17<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación AS LL(1)<br />
Ejemplo entrada: )id*+id<br />
E<br />
E’<br />
T<br />
T’<br />
F<br />
id<br />
E→TE’<br />
scan<br />
T→FT’<br />
scan<br />
F→id<br />
+<br />
scan<br />
E’→+TE’<br />
ext<br />
T’→λ<br />
ext<br />
*<br />
scan<br />
scan<br />
scan<br />
T’→*FT’<br />
ext<br />
(<br />
E→TE’<br />
scan<br />
T→FT’<br />
scan<br />
F→(E)<br />
)<br />
ext<br />
E’→λ<br />
ext<br />
T’→λ<br />
ext<br />
$<br />
ext<br />
E’→λ<br />
ext<br />
T’→λ<br />
ext<br />
18
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación AS LL(1)<br />
A nivel <strong>de</strong> frase<br />
• Se llenan las entradas en blanco <strong>de</strong> la tabla con<br />
llamadas a rutinas <strong>de</strong> error<br />
• Las rutinas insertan, cambian o eliminan símbolos <strong>de</strong> la<br />
entrada y emiten mensajes <strong>de</strong> error<br />
• Pue<strong>de</strong>n sacar elementos <strong>de</strong> la pila<br />
• Hay que asegurarse <strong>de</strong> que no se produzcan lazos<br />
infinitos<br />
• Las acciones <strong>de</strong> recuperación <strong>de</strong>ben consumir símbolos <strong>de</strong><br />
la entrada o <strong>de</strong> la pila<br />
19<br />
Gramática:<br />
Tabla <strong>de</strong> prece<strong>de</strong>ncia:<br />
E::= E·+·E | E·*·E | (·E·) | Id<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación Prece<strong>de</strong>ncia por<br />
Operador<br />
( Id * + ) $<br />
) •> •> •> •><br />
Id •> •> •> •><br />
* •> •><br />
+ <br />
(
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación Prece<strong>de</strong>ncia por<br />
Operador<br />
Hay dos situaciones en las que un AS por prece<strong>de</strong>ncia<br />
<strong>de</strong>scubre <strong>errores</strong> sintácticos:<br />
• Encontrado el pivote, no existe ninguna producción que<br />
reducir<br />
• Para reducir hay que <strong>de</strong>cidir que regla <strong>de</strong> producción se asemeja<br />
más al pivote<br />
• No se cumple ninguna relación <strong>de</strong> prece<strong>de</strong>ncia entre el<br />
terminal <strong>de</strong> la pila y el <strong>de</strong> la entrada actual<br />
• Estrategia para continuar el análisis<br />
• Las entradas en blanco <strong>de</strong> la tabla <strong>de</strong> relación <strong>de</strong> prece<strong>de</strong>ncia<br />
<strong>de</strong>ben especificar rutinas <strong>de</strong> recuperación <strong>de</strong> <strong>errores</strong><br />
• Para recuperarse hay que modificar la pila, la entrada o ambas<br />
• Hay que prevenir los bucles infinitos<br />
21<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación Prece<strong>de</strong>ncia por<br />
Operador<br />
Problemas al reducir el pivote<br />
• Para reducir hay que <strong>de</strong>cidir que regla <strong>de</strong> producción se asemeja<br />
más al pivote<br />
• Una posibilidad es modificarlo, eliminando o insertando símbolos<br />
hasta encontrar producción más parecida<br />
• Ej.: A-> a E c<br />
encontrado: aac … …<br />
modificar a aEc … …<br />
“a” ilegal en línea …<br />
falta “E” en línea …<br />
• Para casos sencillos pue<strong>de</strong>n enumerarse todos los casos <strong>de</strong><br />
cada producción. Ej.: aritmética<br />
• si +,* se reduce y no hay no terminales a los lados: falta<br />
operando<br />
• Si id se reduce y no hay no terminal a un lado: falta operador<br />
• Si () se reduce si no terminal en medio: falta expresión<br />
• …<br />
22
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación Prece<strong>de</strong>ncia por<br />
Operador<br />
No se cumple ninguna relación <strong>de</strong> prece<strong>de</strong>ncia entre el terminal<br />
<strong>de</strong> la pila y el <strong>de</strong> la entrada actual<br />
• Las entradas en blanco <strong>de</strong> la tabla <strong>de</strong> relación <strong>de</strong> prece<strong>de</strong>ncia <strong>de</strong>ben<br />
especificar rutinas <strong>de</strong> recuperación <strong>de</strong> <strong>errores</strong><br />
• Para recuperarse hay que modificar la pila, la entrada o ambas<br />
• Hay que prevenir los bucles infinitos<br />
Ej.:E → E+E | E-E | E*E | E/E | E↑E | (E) | -E | id<br />
id<br />
(<br />
)<br />
$<br />
+<br />
*<br />
id<br />
•><br />
•><br />
•><br />
•><br />
(<br />
<br />
$<br />
<br />
*<br />
•><br />
<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación AS LR(1)<br />
Detección <strong>de</strong>l error<br />
• Al consultar la tabla <strong>de</strong> acciones <strong>de</strong>l AS y la entrada<br />
es <strong>de</strong> error<br />
• Detección más rápida que otros analizadores: propiedad<br />
<strong>de</strong>l prefijo viable<br />
• Nunca se hace un <strong>de</strong>splazamiento posterior al token<br />
errónea<br />
• LR canónico nunca hace una reducción antes <strong>de</strong> anunciar<br />
un error<br />
• SLR y LALR pue<strong>de</strong>n realizar varias reducciones antes <strong>de</strong><br />
anunciar un error, pero nunca <strong>de</strong>splazan un símbolo <strong>de</strong> la<br />
entrada erróneo<br />
• Mayor rapi<strong>de</strong>z <strong>de</strong> <strong>de</strong>tección al aumentar estados<br />
25<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Detección <strong>errores</strong> AS LR(1)<br />
Ej. SLR vs LR(1). Gramática: A->(A)|a<br />
E<br />
0<br />
1<br />
2<br />
3<br />
4<br />
5<br />
(<br />
d3<br />
d3<br />
acción<br />
a )<br />
d2<br />
d2<br />
r2<br />
d5<br />
r1<br />
$<br />
acpt<br />
r2<br />
r1<br />
ir_a<br />
A<br />
1<br />
4<br />
E<br />
0<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
acción<br />
( a )<br />
d2 d3<br />
d5 d6<br />
d7<br />
d5 d6<br />
r2<br />
$<br />
acpt<br />
r2<br />
ir_a<br />
A<br />
1<br />
4<br />
8<br />
Comparar: (a$<br />
a)$<br />
7<br />
8<br />
9<br />
d9<br />
r1<br />
r1<br />
26
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación AS LR(1)<br />
Recuperación LR en modo pánico<br />
• Procedimiento heurístico que preten<strong>de</strong>:<br />
• I<strong>de</strong>ntificar una construcción en proceso <strong>de</strong> ser reconocida<br />
cuando aparece el error<br />
• Determinar la posición en la entrada para continuar<br />
• Algoritmo<br />
• Se examina la pila hasta encontrar un estado s con valor<br />
<strong>de</strong> ir_a no vacío: al menos para un símbolo no terminal A<br />
• Se <strong>de</strong>sechan símbolos <strong>de</strong> la entrada hasta encontrar un<br />
terminal a válido para seguir al no terminal A (acción<br />
no vacía)<br />
• Poner en la pila el estado <strong>de</strong> ir_a[s,A] y sigue el análisis<br />
sintáctico<br />
27<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación AS LR(1)<br />
A nivel <strong>de</strong> frase<br />
• Se construyen procedimientos <strong>de</strong> recuperación que modifiquen<br />
la pila y/o la entrada <strong>de</strong>pendiendo <strong>de</strong>l error<br />
• Los procedimientos <strong>de</strong> recuperación eliminarán o <strong>de</strong>splazarán<br />
al menos un símbolo <strong>de</strong> la entrada o reducirán la pila si la<br />
entrada ha sido procesada (evitar bucles infinitos)<br />
• No extraer <strong>de</strong> la pila estados que alcancen un no terminal<br />
(estaremos extrayendo construcciones correctamente<br />
examinadas)<br />
• Para evitar excesivos mensajes <strong>de</strong> error se pue<strong>de</strong> exten<strong>de</strong>r, en<br />
los estados en los que las reducciones son siempre al mismo<br />
estado, la reducción a las entradas en blanco (los <strong>errores</strong> se<br />
<strong>de</strong>tectarán ahora al <strong>de</strong>splazar)<br />
28
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Recuperación AS LR(1)<br />
A nivel <strong>de</strong> frase<br />
Ejemplo: id+)<br />
E → E+E|E*E|(E)|id<br />
e1: se esperaba un operando id ó<br />
( pero se encontró operador o final<br />
• introducir id en la pila y estado 3<br />
• mostrar “falta operando”<br />
e2: encuentra un paréntesis<br />
• eliminar ) <strong>de</strong> la entrada<br />
• mostrar “) no equilibrado” 6 e3 d4 d5 e3 d9<br />
e3: se esperaba un operador pero 7 r1 r1 d5 r1 r1<br />
se encontró id ó )<br />
8 r2 r2 r2 r2 r2<br />
• introducir + en la pila y estado 4<br />
• mostrar “falta operador”<br />
9 r3 r3 r3 r3 r3<br />
e4: se esperaba operador ó ) pero encontró el final <strong>de</strong> la entrada<br />
• introducir ) en la pila y estado 9<br />
• mostrar “falta paréntesis <strong>de</strong>recho”<br />
0<br />
1<br />
2<br />
3<br />
4<br />
5<br />
id<br />
d3<br />
e3<br />
d3<br />
r4<br />
d3<br />
d3<br />
+<br />
e1<br />
d4<br />
e1<br />
r4<br />
e1<br />
e1<br />
acción<br />
*<br />
e1<br />
d5<br />
e1<br />
r4<br />
e1<br />
e1<br />
(<br />
d2<br />
e3<br />
d2<br />
r4<br />
d2<br />
d2<br />
)<br />
e2<br />
e2<br />
e2<br />
r4<br />
e2<br />
e2<br />
$<br />
e1<br />
acpt<br />
e1<br />
r4<br />
e1<br />
e1<br />
e4<br />
r1<br />
r2<br />
r3<br />
ir_a<br />
E<br />
1<br />
6<br />
7<br />
8<br />
29<br />
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Conj. LR(0)<br />
I 0<br />
: [E’→•E]<br />
[E→•E+ E]<br />
[E→•E * E]<br />
e1<br />
[E→• (E)]<br />
[E →•Id]<br />
I 1<br />
: [E’→E•]<br />
[E→E•+ E]<br />
[E→E•* E]<br />
e3<br />
E<br />
(<br />
Id<br />
+<br />
*<br />
I 2<br />
: [E→(•E)]<br />
[E→•E+ E]<br />
[E→•E * E]<br />
[E→• (E)]<br />
e1 [E →•Id]<br />
I 3<br />
: [E→Id•]<br />
I 4<br />
: [E→E+•E]<br />
[E→•E+ E]<br />
[E→•E * E]<br />
[E→•(E)]<br />
[E→•Id]<br />
e1<br />
I 5<br />
: [E→E *•E]<br />
[E→•E+ E]<br />
[E→•E * E]<br />
[E→•(E)]<br />
[E→•Id]<br />
e1<br />
Id<br />
e2<br />
+<br />
E<br />
(<br />
E<br />
+<br />
*<br />
E<br />
*<br />
I 6<br />
: [E→(E •)]<br />
[E→E•+ E]<br />
[E→E• * E]<br />
e3<br />
I 7<br />
: [ E→E+E•]<br />
[E→E•+ E]<br />
[E→E• * E]<br />
I 8<br />
: [E→E *E •]<br />
[E→E•+ E]<br />
[E→E•* E]<br />
e4<br />
)<br />
I 9<br />
: [E→(E) •]<br />
e1: esperaba operando o (<br />
e2: encuentra un paréntesis )<br />
e3: esperaba operador<br />
e4: esperaba)<br />
30
Tratamiento <strong>de</strong> Errores. Procesadores <strong>de</strong> Lenguaje I<br />
Conclusiones <strong>de</strong> Manejo <strong>de</strong> Errores<br />
Aspecto complejo <strong>de</strong>l diseño <strong>de</strong>l compilador<br />
• Análisis cuidadoso <strong>de</strong>l lenguaje y posibles <strong>errores</strong><br />
• No hay una estrategia <strong>de</strong> aceptación universal<br />
• Abundan técnicas heurísticas y ad hoc<br />
Principio general <strong>de</strong> recuperación<br />
• Minimizar tokens eliminados/modificados<br />
• Dejar el analizador listo para continuar procesando<br />
Objetivos<br />
• Informar con claridad, exactitud y extensión<br />
• Evitar <strong>errores</strong> en cascada y procesos infinitos<br />
Analizadores LL y LR gran capacidad para estrategias en modo<br />
pánico y frase en función <strong>de</strong>l contexto<br />
31