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
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: La entrada se examina de izquierda a derecha, un símbolo cada vez Trabajan con subclases de gramáticas En general las gramáticas serán LL y LR 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
Análisis Sintáctico Descendente 5 Algoritmo 1. Poner el axioma como raíz del árbol de derivación 2. 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: Si entrada es: Expresión.*.Término.+.Id el pivote es: Expresión.*.Término Algoritmo 1. Empezar con la cadena de entrada 2. 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
7 Analizadores Sintácticos, Problemas Descendentes Mas de una opción: A::= Retroceso Analizar los siguientes elementos de la entrada Recursividad izquierda Eliminación de la recursividad Ambigüedad Factorización por la izquierda Ascendentes 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
Análisis Sintáctico Predictivo 9 Árbol sintáctico Ejemplo: Id.*.Id.+.Id Expresión Expresión + Término Expresión * Término Id Término 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
11 Análisis Sintáctico Predictivo: Descendente Recursivo 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; 12 Análisis Sintáctico Predictivo, DEFINICIONES: PRIMERO 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 Y 1 Y 2...Y K Y a PRIMERO(X) si a PRIMERO(Y i ) y PRIMERO(Y 1 ), PRIMERO(Y 2 ),..., PRIMERO(Y i-1 ) Si Y 1 deriva a se añade PRIMERO(Y 2 ) Si Y 1 no deriva a no se añade más a PRIMERO(X) 6
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) = { (, Id } PRIMERO(T) = { (, Id } PRIMERO(Id.+.Id) = { Id } PRIMERO(F) = { (, Id } PRIMERO(Id) = { Id } PRIMERO(E ) = { +, } PRIMERO(T ) = { *, } 14 Análisis Sintáctico Predictivo, DEFINICIONES: SIGUIENTE Conjunto SIGUIENTE(A) SIGUIENTE(A)={x (S * A ), (A N ), ( * ), ( + ), (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. SIGUIENTE(S)={$} 2. La regla AB SIGUIENTE(B) = (PRIMERO()-{}) SIGUIENTE(B) 3. La regla AB =, * ( PRIMERO()) SIGUIENTE(B) = SIGUIENTE(A) SIGUIENTE(B) 4. Repetir hasta que no cambie ningún conjunto SIGUIENTE 7
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 SIGUIENTE E $, ) E $, ) F $, *, ), + T $, +, ) T $, +, ) 16 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
17 Análisis Sintáctico Predictivo: Condiciones Condición LL(1) No puede haber conflictos PRIMERO/PRIMERO N N, el conjunto PRIMERO de todas sus alternativas debe ser disjunto No puede haber múltiples alternativas nulas N N, solo pueden tener una producción N No puede haber conflictos PRIMERO/SIGUIENTE N N, con una alternativa nula, SIGUIENTE(N) debe ser disjunto de los conjuntos PRIMERO de todas sus alternativas No puede haber entradas con definiciones múltiples en la tabla de análisis 18 Análisis Sintáctico Predictivo: Tabla de Análisis Sintáctico Funcionamiento Sea A con a T aprimero(). El analizador sintáctico expandirá A por cuando el símbolo actual de la entrada sea a Algoritmo 1) ForAll (A::= ) do 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,$]= 2) ForAll A N y c T do a) If TABLA[A,c]= Then TABLA[A,c]= error 9
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 T.E T.E E +.T.E T F.T F.T T *.F.T F Id (.E.) 20 Análisis Sintáctico Predictivo No Recursivo; LL(1) Modelo de analizador sintáctico predictivo no recursivo ENTRADA a + b $ PILA X Y Z $ Programa de Análisis Sintáctico Predictivo Tabla de Análisis Sintáctico M SALIDA 10
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 X N, 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]=XY 1 Y 2..Y k then Pop; Push Y k,y k-1,...,y 1 Emitir la producción X else error(); until X=$ If X=$ and a=$ then Aceptar; else error(); 11
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 $ T ::= * F T $ E T F * * Id + Id $ $ E T F Id + Id $ F::= 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 ::= $ $ 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
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 A+ - * / EE+E E-E E*E E/E (E) -E id 26 Análisis Sintáctico Ascendente: Precedencia de Operador Inconvenientes Es difícil de manejar componentes léxicos con dos precedencias distintas, como el signo menos (unario y binario) No se puede tener la seguridad de que el analizador acepta exactamente el lenguaje deseado 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
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 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 28 Análisis Sintáctico Ascendente: Precedencia de Operador Entrada: Id + Id * Id Gramática 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 Pila de Operandos Id a + Id b * Id c + Id b * Id c Id a Id b * Id c + Id a * Id c + Id b Id a Id c *+ Id b Id a *+ Id c Id b Id a 14
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
31 Obtención de las relaciones de precedencia x y sii existe: A::=...xBy... B{N } x < y 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
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: 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 34 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
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 Tabla N Cabecera Último E +, *, (, Id +, *, ), Id T *, (, Id *, ), Id F (, Id ), Id Regla Precedencias(R 2 ) Precedencias (R 1 ) E::=E+T +, *, ), Id > + + < *, (, Id E::=T+F *, ), Id > * * < (, Id 36 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
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 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 38 Precedencia de Operador: Funciones de Precedencia Construcción de las Funciones de Precedencia 1. Crear los símbolos f a y g a a T {$} 2. Se dividen los f a y g a en tantos grupos como sea posible: Si a=b entonces f a y g b están en el mismo grupo 3. Crear un grafo dirigido cuyos nodos son los grupos encontrados en el paso 2, los arcos se etiquetan: si a< b, g b f a si a >b, f a g b 4. 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 f a y g a 19
39 Precedencia de Operador: Funciones de Precedencia Ejemplo Id + * $ Id > > > + < > < > * < > > > $ < < < Cada símbolo está solo en un grupo g Id g * g + g $ f Id f * f + f $ 40 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 g Id 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
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
Modelo de un Analizador LR 43 ENTRADA a 1... a 1... a n $ Pila s m X m Programa de Análisis Sintáctico LR SALIDA s m-1 X m-1... s 0 Acción Ir_a Tabla de Análisis Sintáctico LR Modelo de Analizador LR 44 El programa es el mismo para todos los analizadores LR X i es un símbolo gramatical y cada s i 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[s m, a i ]= Error: error de sintaxis Aceptar: acepta la entrada, el análisis sintáctico finaliza Desplazar: introduce en la pila el símbolo a i y el estado s m Reducción: extrae símbolos de la pila, ejecuta la acción semántica correspondiente a una producción Ir_a[s m, X i ]= s k 22
Modelo de Analizador LR 45 Configuración de un analizador sintáctico LR Tupla con el contenido de la pila y la entrada que resta por procesar (s 0 X 1 s 1 X 2 s 2... X m s m, a i a i+1... a n $) Acción[s m, a i ] = desplazar s (s 0 X 1 s 1 X 2 s 2... X m s m a i s, a i+1... a n $) Acción[s m, a i ] = reducir A (s 0 X 1 s 1 X 2 s 2... X m-r s m-r A s, a i a i+1... a n $) donde s=ir_a[s m-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
Ejemplo de Análisis LR Gramática 1. E::= E + T 2. E::= T 3. T::= T * F 4. T::= F 5. F::= ( E ) 6. F::= Id Tabla de análisis sintáctico Acción Ir_a Estado Id + * ( ) $ E T F 0 d5 d4 1 2 3 1 d6 ACP 2 r2 d7 r2 r2 3 r4 r4 r4 r4 4 d5 d4 8 2 3 5 r6 r6 r6 r6 6 d5 d4 9 3 7 d5 d4 10 8 d6 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 Acción 0 Id * Id + Id $ d5 0 Id 5 * Id + Id $ r6 0 F 3 * Id + Id $ r4 0 T 2 * Id + Id $ d7 0 T 2 * 7 Id + Id $ d5 0 T 2 * 7 Id 5 + Id $ r6 0 T 2 * 7 F 10 + Id $ r3 0 T 2 + Id $ r2 0 E 1 + Id $ d6 0 E 1 + 6 Id $ d5 0 E 1 + 6 Id 5 $ r6 0 E 1 + 6 F 3 $ r4 0 E 1 + 6 T 9 $ r1 0 E 1 $ ACP 24
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, S 0 ={(S ::= S)} Mientras se creen nuevos estados hacer Cierre: Si A::=x X S i entonces, Para cada X::=w P Creación S i =S i U {(X::= w)} Para cada z I i =(A::=x zw) S i Crear un nuevo estado S j ={(A::=xz w)} Para cada I k =(B::= z) S i, I k I i S j =S j U {(B::= z)} 25
Algoritmo de tabla SLR(1) 51 Desplazar Si A::=x aw S i, A::=xa w S j, a T Entonces Acción[S i,a]=desplazar S j Reducir Si A::=w S i, P j =(A::=w) Entonces Para cada a SIGUIENTE(A) Acción [S i,a]=reducir j Aceptar Si S ::=S S i Entonces Acción[S i,$]=aceptar Ir_a Si A::=x Bw S i, A::=xB w S j, B N Entonces Ir_a[S i,b]= S j 52 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
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: Desecha los símbolos de entrada hasta que encuentra componentes léxicos de sincronización (delimitadores, punto y coma, end) Adecuado para lenguajes en los que es raro que se produzcan varios errores en la misma línea Nivel de frase FUNCIONAMIENTO: 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 54 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