04.03.2015 Views

Deteccion y recuperacion de errores - GIAA

Deteccion y recuperacion de errores - GIAA

Deteccion y recuperacion de errores - GIAA

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!