Alma Mara Pisabarro, 2007 ANLISIS SINTCTICO Funcin Entrada: sucesin de componentes lxicos <clex, vlex> Salida: la entrada es o no correcta sintcticamente Adems: si la entrada es correcta, rbol de derivacin si no indicacin de errores
Uso de gramticas independientes de contexto Especificacin precisa y fcil de entender Construccin automtica de analizadores sintcticos Imparten una estructura al programa fuente, a la que se asigna el significado. Deteccin adecuada de errores Fcil mantenimiento: evolucin del lenguaje
<programa> <cabecera> <bloque> <cabecera> program <identificador>; <cabecera> program <identificador> (<ids.archivos>); <bloque> <declaraciones y definiciones de entorno> <def. de subprogramas> <sent. secuencial>. <sent. secuencial> begin <sentencias> end ...
TIPOS DE ANLISIS SINTCTICOS Universales (CYK, Earley, ...) Descendentes. Subclases de gramticas adecuadas (LL) Ascendentes. Subclases de gramticas adecuadas (LR)
<programa> ...
<cabecera> <bloque> <cabecera> ... ....
program id ... program id ; begin ... ERRORES: TIPOS Lxicos (a!b, begon) Sintcticos (X := a *(b-(c+d);;) Semnticos (3 div sqrt(2)) Lgicos (bucle infinito) Consideraciones La mayora de los errores son simples La mayora son o se manifiesten en la fase de anlisis sintctico La deteccin de errores lgicos es muy difcil o imposible A veces el error est mucho antes de que se pueda detectar ERRORES: OBJETIVOS DEL GESTOR DE ERRORES Informar con claridad y exactitud lnea, posicin, mensajes (falta un ;) Recuperarse con rapidez No se abandona al primer error Introduccin de errores espurios (sintcticos o semnticos): inhibir mensajes de demasiado cercanos Se abandona si hay muchos errores No retrasar significativamente la traduccin de programas correctos Mecanismos sencillos de recuperacin
ERRORES: ESTRATEGIAS En modo pnico: descartar smbolos de entrada (hasta que alguno permita la recuperacin: elementos de sincronizacin) A nivel de frase: correccin local segn el error concreto (borrar, sustituir, insertar: peligro de bucle infinito) De producciones de error: prever errores (frecuentes o probables) ampliando la gramtica con reglas especficas de error De correccin global: hallar el programa correcto ms cercano al de entrada: costoso y no necesariamente se encuentra el deseado ANLISIS SINTCTICO DESCENDENTE tipo simple | ^ simple | array [simple] of tipo simple integer | char | num ptpt num tipo tipo tipo
simple ^ simple array [ simple ] of tipo
simple simple simple
integer char num ptpt num Anlisis Sintctico Predictivo Anlisis Sintctico Descendente Recursivo Conjunto de procedimientos recursivos Cada no terminal de la gramtica tiene asociado un procedimiento El smbolo de preanlisis determina sin ambigedad el procedimiento seleccionado para cada no terminal Procedimiento adicional parea
procedimiento simple: segn que regla se aplique: ?: { <simple> integer } parea (integer) ?: { <simple> char } parea (char) ?: { <simple> num ptpt num } parea (num); parea (ptpt); parea (num)
parea (num); parea(ptpt); parea(num) procedure parea (t:TCompLex); begin if preanalisis = t then preanalisis := SgteCompLex() else error end;
simple simple simple
? num ptpt num num ptpt num
num ptpt num ... ... num ptpt num ... .... num ptpt num ... ...
parea parea parea parea( ^ ); simple
tipo tipo tipo
? ^ simple ^ simple ?
^ char ^ char ^ char
parea parea (array); parea ([); simple; parea (]); parea(of); tipo parea(^); simple tipo tipo tipo ? array [ simple ] of tipo array [ simple ] of tipo ?
array [num ptpt num] of char array [ num ptpt num ] of char array [ num ptpt num ] of char
tipo tipo
array [ simple ] of tipo array [ simple ] of tipo ?
array [ num ptpt num ] of char array [ num ptpt num ] of char Eleccin de regla a aplicar: tipo simple | ^ simple | array [ simple ] of tipo simple integer | char | num ptpt num tipo: regla 1: preanalisis in [integer, char, num] regla 2: preanalisis = ^ regla 3: preanalisis = array simple: regla 4: preanalisis = integer regla 5: preanalisis = char regla 6: preanalisis = num const INTEGER = 257; CHAR = 258; ... var preanalisis: TCompLex; function StgteCompLex(): TCompLex; procedure parea(...)...; procedure simple; begin if preanalisis = INTEGER then parea (INTEGER) else if preanalisis = CHAR then parea (CHAR) else if preanalisis = NUM then begin parea(NUM); parea(PTPT); parea(NUM); end else error end; procedure tipo; begin if preanalisis in [INTEGER, CHAR, NUM] then simple else if preanalisis = ^ then begin parea(^); simple end else if preanalisis = ARRAY then begin parea(ARRAY); parea([); simple; parea (OF); tipo end else error end; begin preanalisis := SgteCompLex(); tipo; end. Anlisis Sintctico Predictivo no Recursivo Utilizan una pila en lugar de llamadas recursivas Guiado por una tabla Las tablas se construyen directamente slo para ciertos tipos de gramticas
Tabla de anlisis Sintctico M Programa para anlisis sintctico predictivo a + b $ X Y Z $ ENTRADA SALIDA PILA Inicialmente: Buffer: cadena de entrada finalizada con el smbolo $ Pila: smbolo $ y en la cima el smbolo inicial de la gramtica Tabla M: Si A es un no terminal y a un terminal, M[A,a] contiene una regla de produccin de la gramtica X: Cima de la pila A: smbolo de la entrada (preanalisis) Anlisis Sintctico Predictivo no recursivo Si X terminal Si X <> a Llamar a la rutina de recuperacin de error Si X = a Si X = a = $ Fin con xito Si X = a <> $ Sacar X de la pila Obtener siguiente smbolo de la entrada Si X no terminal Si M [X, a] contiene una regla Sacar X de la pila Meter en la pila la parte derecha de la regla en orden inverso Si M [X, a] no contiene una regla Llamar a la rutina de recuperacin de error Gramtica: E TE E +TE | T FT T *FT | F (E) | id
No terminal Smbolo de entrada id + * ( ) $ E E TE E TE E E +TE E E T T FT T FT T T T *FT T T F F id F (E) PILA ENTRADA SALIDA $E $ET $ETF $ETid $ET $E $ET+ $ET $ETF $ETid $ET $ETF* $ETF $ETid $ET $E $ id + id * id $ id + id * id $ id + id * id $ id + id * id $ + id * id $ + id * id $ + id * id $ id * id $ id * id $ id * id $ * id $ * id $ id $ id $ $ $ $
E TE T FT F id
T E +TE
T FT F id
T *FT
F id
T E Algoritmo de Anlisis Sintctico Predictivo no recursivo apuntar ae al primer smbolo de w$ repetir X smbolo de la cima de la pila a smbolo apuntado por ae si x es un terminal o $ entonces si X = a entonces extraer X de la pila avanzar ae si_no error fin_si si_no si M[x,a] = X Y 1 Y 2 ...Y k entonces extraer X de la pila meter Y k , Y k-1 , ..., Y 1 en la pila, con Y 1 en la cima emitir la produccin X Y 1 Y 2 ...Y k
si_no error fin_si fin_si hasta_que X = $ /*la pila est vacia*/
Funciones PRIMERO y SIGUIENTE La funcin PRIMERO(a) devuelve el conjunto de terminales que inician las cadenas derivadas de a La funcin SIGUIENTE(a) devuelve el conjunto de terminales que pueden aparecer inmediatamente a la derecha de a en alguna forma de frase Son funciones asociadas a una gramtica G Permiten rellenar las entradas de una tabla de ASP para G Los conjuntos de componentes lxicos devueltos por la funcin SIGUIENTE se pueden utilizar como elementos de sincronizacin durante la recuperacin de errores en modo pnico
FUNCIN PRIMERO (X) Para todos los smbolos X de la gramtica Repetir hasta que no se puedan aadir ms smbolos a ningn conjunto 1. Si existe la regla x PRIMERO (X) = PRIMERO(X) U {} 2. Si x es un smbolo terminal PRIMERO (X) = {X} 3. Si x es un smbolo no terminal Para cada produccin x y 1 y 2 ...y k PRIMERO (X) = PRIMERO (X) U PRIMERO (Y 1 ) si existe la regla y 1
PRIM (X) = PRIM (X) U PRIM (Y 1 ) U PRIM (Y 2 ) si existen las reglas y 1 y y 2
PRIM (X) = PRIM (X) U PRIM (Y 1 ) U PRIM (Y 2 ) U PRIM (Y 3 ) .... si existe la regla y n n=1...k PRIM (X) = PRIM (X) U PRIM (Y 1 ) U PRIM (Y 2 ) U .... U PRIM (Y k ) U {}
FUNCIN SIGUIENTE (X) Para todos los smbolos A no terminales de la gramtica Repetir hasta que no se puedan aadir ms smbolos a ningn conjunto 1. Si S es el smbolo inicial de la gramtica SIGUIENTE (S) = SIGUIENTE (S) U {$} 2. Si existe una regla A B SIGUIENTE (B) = PRIMERO () - {} 3. Si existe una regla A B SIGUIENTE (B) = SIGUIENTE (B) U SIGUIENTE (A) 4. Si existe una regla A B y PRIMERO () SIGUIENTE (B) = SIGUIENTE (B) U SIGUIENTE (A) Gramtica: E TE T *FT | E +TE | F (E) | id T FT
E E T T F + * ( ) id E E T T F ( + ( * ( + * ( ) id $ $ $ $ $ id id id ) ) + + + ) ) * ) PRIMEROS SIGUIENTES ALGORITMO DE CONSTRUCCIN DE TASP Entrada: Una gramtica G Salida: La tabla de anlisis sintctico M Para cada regla X de G 1. Para terminal t de PRIMERO () Aadir X a M[X, t] 2. Si PRIMERO () Aadir X a M[X, b], b SIGUIENTE (x) Si PRIMERO () y $ SIGUIENTE (X) Aadir X a M[X, $] 3. Poner error en todas las entradas no definidas de M regla E TE PRIMERO (TE) = PRIMERO (T) = {(, id} M [ E, ( ] = E TE M [ E, id ] = E TE regla E +TE PRIMERO (+TE) = PRIMERO (+) = { + } M [ E, + ] = E +TE regla E SIGUIENTE (E) = { ), $ } M [ E, ) ] = E M [ E, $ ] = E regla T FT PRIMERO (FT) = PRIMERO (F) = {(, id} M [ T, ( ] = T FT M [ T, id ] = T FT regla T *FT PRIMERO (*FT) = PRIMERO (*) = { * } M [ T, * ] = T *FT regla T SIGUIENTE (T) = { ), +, $ } M [ T, ) ] = T M [ T, + ] = T M [ T, $ ] = T regla F (E) PRIMERO ((E)) = PRIMERO (() = { ( } M [ F, ( ] = F (E) regla F id PRIMERO (id) = { id } M [ F, id ] = F id
No terminal Smbolo de entrada id + * ( ) $ E E TE error error E TE error error E error E +TE error error E E T T FT error error T FT error error T error T T *FT error T T F F id error error F (E) error error GRAMTICAS LL(1) Si una gramtica es recursiva por la izquierda o ambigua la TASP tendr al menos una entrada con definicin mltiple. Recurso: Transformar la gramtica Una gramtica cuya TASP no tiene entradas con definiciones mltiples se define como LL(1) Ninguna gramtica ambigua o recursiva por la izquierda puede ser LL(1) G es LL(1), si y solo si, cuando A | siendo dos reglas distintas de G se cumple: PRIMERO () PRIMERO () = Solo puede derivarse de o de Si deriva , no deriva ninguna cadena que comience con un terminal de SIGUIENTE (A) ANLISIS ASCENDENTE Estilo general: Anlisis sintctico por desplazamiento y reduccin Por precedencia de operadores (gramticas muy especficas) LR (generadores automticos de AS) Se construye el rbol de AS para una cadena w a partir de las hojas y se avanza hacia la raz Proceso: reducir w al smbolo inicial de la gramtica Cada reduccin sustituye una subcadena (asidero o mango) que concuerde con el lado derecho de un regla de produccin por el smbolo no terminal del lado izquierdo de esa regla ASIDEROS O MANGOS Un asidero de una cadena es una subcadena que concuerda con el lado derecho de una produccin y cuya reduccin al no terminal del lado izquierdo de la regla es un paso de una derivacin por la derecha Ejemplo S aABe A Abc A b B d a b b c d e asidero posicin 2 (regla A b) a A b c d e asidero posicin 2 (regla A Abc) a A d e asidero posicin 3 (regla B d) a A B e asidero posicin 1 (regla S aABe) S ASIDEROS O MANGOS La produccin situada ms a la izquierda de que concuerda con el lado derecho de una produccin A no es un asidero si la reduccin por esa regla genera una cadena no reducible al smbolo inicial Ejemplo S aABe A Abc A b B d
a A b c d e aunque b es la subcadena situada ms a la izquierda que concuerda con una parte derecha (regla A b) no es un asidero a A A c d e No se puede reducir a S ASIDEROS O MANGOS Formalmente, un asidero de una forma de frase derecha es una regla A y una posicin de donde la cadena podra encontrarse y sustituirse por A para producir la forma de frase derecha previa en una derivacin por la derecha de Ejemplo E E + E E E * E E ( E ) E id Formas de Frase Derecha Asidero Regla de Reduccin id 1 + id 2 * id 3 id 1 E id E
+ id 2 * id 3 id 2 E id E
+ E * id 3 id 3 E id E + E * E E * E E E * E E + E E + E E E + E E USO DE UNA PILA EN AS POR DESPLAZAMIENTO Y REDUCCIN Problemas de implantacin del AS por desplazamiento y reduccin Situar la subcadena a reducir Elegir la regla adecuada en caso de que haya ms de una con esa subcadena en la parte derecha Posible solucin utilizar: Una pila para manejar los smbolos gramaticales Buffer de entrada para gestionar la cadena w a analizar FUNCIONAMIENTO DEL ANALIZADOR Inicialmente: En la pila el smbolo de fin de cadena ($) En el buffer la cadena a analizar seguida de la marca de fin de lnea (w$) Repetir hasta que se detecte un error o en la pila solo haya el smbolo inicial (E$) y la entrada est vaca ($) Desplazar cero o ms smbolos de la entrada a la pila hasta que en la cima haya un asidero Reducir al lado izquierdo de la regla adecuada OPERACIONES DEL ANALIZADOR Desplazar: Mover el siguiente smbolo de entrada a la cima de la pila Reducir: (En este momento el extremo derecho del asidero est en la cima de la pila) Localizar el extremo izquierdo del asidero dentro de la pila y decidir el no terminal con el que se debe sustituir el asidero. Aceptar: Anunciar el fin con xito del anlisis Error: Llamar a la rutina de recuperacin de errores
pila entrada accin $ id 1 + id 2 * id 3 $ desplazar $ id 1 + id 2 * id 3 $ reducir por E id $ E + id 2 * id 3 $ desplazar $ E + id 2 * id 3 $ desplazar $ E + id 2 * id 3 $ reducir por E id $ E + E * id 3 $ desplazar $ E + E * id 3 $ desplazar $ E + E * id 3 $ reducir por E id $ E + E * E $ reducir por E E * E $ E + E $ reducir por E E + E $ E $ aceptar PREFIJOS VIABLES Este mtodo de anlisis garantiza que el asidero siempre aparecer en la cima de la pila, nunca dentro Los prefijos de las formas de frase derecha que pueden aparecer en la pila se denominan prefijos viables Un prefijo viable es un prefijo de una forma de frase derecha que no continua ms all del extremo derecho del asidero situado ms a la derecha de esta forma de frase
CONFLICTOS Existen gramticas independientes de contexto para las que no se pueden utilizar analizadores sintcticos por desplazamiento y reduccin (gramticas no LR) En esas gramticas se puede llegar a una configuracin en la que, conociendo el contenido de la pila y el siguiente smbolo de entrada, no se puede decidir si Desplazar o reducir (conflicto de desplazamiento/reduccin) Que tipo de reduccin efectuar (conflicto de reduccin/reduccin) ANALIZADORES SINTCTICOS LR Se pueden construir AS LR para casi todos los lenguajes que se pueden describir con GLC Es el mtodo de anlisis por desplazamiento y reduccin sin retroceso ms general pero eficiente La clase de gramticas aplicables es un supraconjunto de las que se pueden analizar con ASP Detectan los errores sintcticos tan pronto como sea posible en un examen de izquierda a derecha Inconveniente: costosos de construir a mano ALGORITMO DE ANLISIS SINTCTICO LR a 1 $
a n ...
a i ...
S m S 0 S m - 1 X m - 1 ...
X m
Programa para anlisis sintctico LR
accin ir_a SALIDA ALGORITMO DE ANLISIS SINTCTICO LR Entrada Cadena de entrada w Tabla de AS LR con las funciones accin e ir_a para la gramtica G Salida Si w est en L(G) una derivacin ascendente Si no indicacin de error Mtodo Inicialmente: La pila contiene S 0 (estado inicial) El buffer de entrada contiene w$ (la cadena de entrada seguida de la marca de fin de cadena) Ejecucin del programa de anlisis hasta encontrar una accin de aceptacin o de error PROGRAMA DE ANLISIS apuntar ae al primer smbolo de w$ repetir sea S el estado en la cima de la pila y a el smbolo apuntado por ae si accion [S,a]= desplazar S entonces meter a y despus S en la cima de la pila avanzar ae al siguiente smbolo de entrada si_no si accin [S, a] = reducir A entonces sacar 2 * || smbolos de la pila sea S el estado que hay ahora en la cima de la pila meter en la cima de la pila A y despus ir_a [S, A] emitir la produccin A si_no si accin [S, a] = aceptar entonces fin con xito si_no error fin_repetir
EJEMPLO Gramtica (1) E E + T (2) E T (3) T T * F (4) T F (5) F (E) (6) F id
Cdigos de las acciones 1. di significa desplazar y meter en la pila el estado i 2. rj significa reducir por la regla de nmero j 3. Acep significa aceptar 4. El espacio en blanco significa error
TABLA DE ANLISIS SINTCTICO LR (para la gramtica del ejemplo)
Estado accin ir_a id + * ( ) $ E T F 0 d5 d4 1 2 3 1 d6 acep 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 r5 MOVIMIENTOS DEL ANALIZADOR SINTCTICO LR DEL EJEMPLO (para la entrada id * id + id) PILA ENTRADA ACCION (1) 0 id * id + id $ desplazar (2) 0 id 5 * id + id $ reducir por F id (3) 0 F 3 * id + id $ reducir por T F (4) 0 T 2 * id + id $ desplazar (5) 0 T 2 * 7 id + id $ desplazar (6) 0 T 2 * 7 id 5 + id $ reducir por F id (7) 0 T 2 * 7 F 10 + id $ reducir por T T * F (8) 0 T 2 + id $ reducir por E T (9) 0 E 1 + id $ desplazar (10) 0 E 1 + 6 id $ desplazar (11) 0 E 1 + 6 id 5 $ reducir por F id (12) 0 E 1 + 6 F 3 $ reducir por T F (13) 0 E 1 + 6 T 9 $ reducir por E E + T (14) 0 E 1 $ aceptar GENERADORES DE AS: YACC Yacc es un generador de analizadores sintcticos LALR Resolucin de conflictos en Yacc Un conflicto reduccin/reduccin se resuelve eligiendo la regla en conflicto que se haya listado primero en la especificacin en Yacc Un conflicto de desplazamiento/reduccin se resuelve a favor del desplazamiento Invocando a Yacc con la opcin v se genera el archivo y.output que contiene Los ncleos de los conjuntos de elementos encontrados por el analizador sintctico Una descripcin de los conflictos en las acciones del anlisis generados por el algoritmo LALR Una representacin legible de la tabla de anlisis sintctico LR que muestra como se resolvieron los conflictos de las acciones del anlisis sintctico