Sunteți pe pagina 1din 29

Programacin de Sistemas

Anlisis Sintctico

Anlisis Sintctico

Programacin de Sistemas

Anlisis Sintctico

ndice

1.- INTRODUCCIN AL ANLISIS SINTCTICO 2.- ANLISIS SINTCTICO CON RETROCESO. 3.-MAQUINA DE KNUTH 4.- TRATAMIENTO DE ERRORES SINTCTICOS 5.- ANLISI SINTCTICO DESCENDENTE SIN RETROCESO. 5.1.- Analizador sintctico LL(1) recursivo. 5.2.- Condicin para ser LL(1). 5.3.- Analizador sintctico descendente no recursivo 6.- ANLISIS SINTCTICO ASCENDENTE 6.1.- Anlisis sintctico de Precedencia Simple. 6.2.- Anlisis sintctico de Precedencia de Operadores. 6.3.- Anlisis Sintctico LR(1).

Programacin de Sistemas

Anlisis Sintctico

1.- INTRODUCCIN AL ANLISIS SINTCTICO La funcin del analizador sintctico es la de encontrar un rbol de anlisis sintctico para una cadena de componentes lxicos, que tenga como raz el axioma de la gramtica, mediante la aplicacin de sus reglas: En caso de xito la cadena pertenece al lenguaje En caso de fracaso emisin de mensaje de error y / o recuperacin Dos tipos de anlisis: Descendentes : desde el axioma, mediante derivaciones de las reglas de la gramtica se encuentra un rbol de anlisis sintctico para la cadena de componentes lxicos a la entrada. Ascendentes: partiendo de la cadena de componentes lxicos, mediante reducciones se llega al axioma y por tanto se encuentra un rbol. Una forma de representar un rbol de anlisis sintctico: Numerar sucesivamente las reglas Cada aplicacin de una regla se representa por su nmero El parser ( anlisis ) es la secuencia de nmeros resultante Si aplicamos el punto anterior a una cadena de tokens, (empezando por la izquierda ) en un anlisis descendente derivando siempre lo ms a la izquierda posible, encontraremos el parse del anlisis sintctico descendente. (Recordad: cadena por la izquierda (left) y derivaciones a la izquierda (left). Descendentes :LL). Si lo aplicamos con derivaciones lo ms a la derecha posible (rigth) obtendramos un parse que es inverso al obtenido si para la misma cadena, se hubiera realizado un anlisis ascendente. ( por ello los ascendentes sern LR, L de entrada por la izquierda y R de parse derivaciones a la derecha ).

2.- ANLISIS SINTCTICO CON RETROCESO. El problema del retroceso se presenta cuando en las reglas de la gramtica hay alternativas. Si se quiere realizar el anlisis sintctico mediante un algoritmo es como si se quisiera construir un rbol sintctico simulando de manera determinista un proceso no determinista : Disponiendo las reglas alternativas en un determinado orden, aquel en que vayan a ser seleccionadas, y se apliquen las reglas de derivacin y entre ellas alguna de las alternativas, puede llegarse a un punto en que no es posible la continuacin correcta del proceso. Podemos preguntarnos y si hubiera elegido otra alternativa?. As pues se retroceder deshaciendo las derivaciones hasta llegar a una en que hemos empleado una alternativa y queda alguna otra por aplicar. Aplicar otra y continuar el proceso. Si habiendo retrocedido y elegido todas las alternativas de la gramtica no es posible construir el rbol sintctico para la cadena de entrada, entonces y slo entonces, se podr decir que esa entrada no cumple con la sintaxis de la gramtica.
3

Programacin de Sistemas

Anlisis Sintctico

Algoritmo para un anlisis sintctico descendente con retroceso: 1. colocar las reglas de la gramtica en un orden establecido 2. construir el rbol desde el axioma aplicando los siguientes pasos de manera recursiva: 2.1. escoger para el nodo en expansin la 1 de las alternativas 2.2. crear los n nodos descendientes ( A a b c...n ) 2.3. el nodo en expansin pasa a ser el 1 de la izquierda (a) 2.3.1. si no hay ya nodo a ser expandido se pasa al nodo derecho ms inmediato que pueda ser derivado 2.3.2. si el nodo en expansin es un terminal, compararle con el smbolo de entrada (componente lxico) actual: 2.3.2.1. si son iguales se avanza un componente lxico 2.3.2.2. si son diferentes se retrocede al nodo inmediato anterior y se reintenta con una nueva alternativa para el padre. En un anlisis descendente hay que eliminar la recursividad por la izquierda para evitar bucles infinitos. Sean las reglas alternativas siguientes, algunas recursivas y otras no: A A a1 | A a2 | b1 | b2 ( donde a1, a2, b1 y b2 son cadenas de terminales y / o no terminales) Para eliminar la recursividad por la izquierda se introduce un nuevo no terminal N: A A a1 | A a2 b1 | b2 A b1 N | b2 N N a1 N | a2 N |

Para un anlisis ascendente con retroceso el procedimiento o algoritmo sera similar al visto para el descendente pero usando reducciones en vez de derivaciones.

Programacin de Sistemas

Anlisis Sintctico

3.-MAQUINA DE KNUTH Un ejemplo de parse descendente con retroceso Maquina abstracta fcil de programar Baja velocidad, pero alto valor didctico Comprueba si una sentencia pertenece al lenguaje dada su gramtica Cada construccin tiene cuatro campos: Etiqueta Operacin Direccin verdad Direccin falso

En el campo de la etiqueta se escribe el smbolo no terminal de la parte izquierda de la regla En el campo de operacin se escribe en vertical la parte derecha de la regla. Los no terminales entre corchetes. Significa llamada a la funcin de ese no terminal.

Ejemplo: Sea S A | ( S ) AB>B B b | c | d | ( B * B) Aadir un Nuevo axioma con una regla que contenga el fn de cadena X S $ La entrada est compuesta de los siguientes componentes lxicos: ( b * c ) > c $ La especificacin de un analizador descendente con retroceso utilizando la mquina de KNUTH: Etiqueta X: S: Operacin [S] $ [A] ( S ) [ B] > [B ] b c d ( [B] * [B] ) Salida buena Goto siguiente ACEPTAR Return V Goto siguiente Goto siguiente Return V Goto siguiente Goto siguiente Return V Return V Return V Return V Goto siguiente Goto siguiente Goto siguiente Goto siguiente Return V Salida mala Trat. Error Trat: error Goto sig ALTER. Return F Return F Return F Return F Return F Return F Goto sig. ALTER. Goto sig. ALTER. Goto sig ALTER. Return F Return F Return F Return F Return F

A: B:

Programacin de Sistemas

Anlisis Sintctico

Se dispone de un cursor a la entrada que no es mas que un contador : i (inicializado a 1) Cuando en el campo de operacin hay un terminal t , se compara dicho terminal con el smbolo a la entrada ai . Si coinciden se va a la salida buena, se incrementa el contador i++ y se lee el siguiente carcter sigtecar (i) a la entrada. Si no coinciden se va a la salida mala. Cuando en el campo de operacin hay un no terminal [ N ] se va a la etiqueta cuyo nombre coincide con el del no terminal y se analiza su campo de operacin. Como puede haber retroceso hay que ser precavidos, hay que ir guardando el valor del cursor para poder recuperarlo si hubiera retroceso y volver a sealar un smbolo de entrada que ya haba sido comparado.as pues los pasos seran: o Salvar i : isave = i ; ( supongamos que se guarda en isave) o Llamar a la funcin ( [ N]) del No terminal entrando por la etiqueta (N:) o Si la salida de la funcin se hace con un return V (true) va a la salida buena y continua el anlisis. Si fuese con return F (false) se retoma el valor del cursor que se guard pues habr retroceso. La especificacin de la pgina anterior hay que verla como un programa estructurado en funciones: o Cada fila sera una instruccin. o Cada etiqueta marca una funcin . o Una funcin pueden tener ms de una rama (if-else), cuando en la regla correspondiente hay alternativas. o Cuando hay un return F, si hay alternativa indica que con la alternativa que se ha analizado no se puede construir el rbol, por tanto hay que ensayar con otra alternativa. o Si hay un return F y no hay ya ms alternativas en el camino de retroceso el anlisis da el diagnstico de cadena incorrecta.

Conclusiones del anlisis sintctico con retroceso Construccin fcil, aunque tedioso, pues se deduce inmediatamente de la misma sintaxis. Inconvenientes: Lentitud de anlisis Excesiva dependencia de la ordenacin de las reglas alternativas Pobre en el diagnstico, intenta todas las alternativas hasta decidir que la cadena no es vlida Dificulta la generacin de cdigo, pues habra que eliminar el cdigo generado al retroceder.

Programacin de Sistemas

Anlisis Sintctico

La traza para la entrada del ejemplo sera: i


X S A B b!= ( c!= ( d!= ( ( == ( B *==* B B ) == ) A > == > B b != c c == c A S X $ == $ ACEPTAR 8 $ 7 c b!=c c==c 5 6 ) > B b ==b 1

ai
(

2 3 4

b * c

Programacin de Sistemas

Anlisis Sintctico

Recordemos: caso de cdigo de operacin un terminal t: o if (ai == t ) { i++ ; ai = sigtecar(i); resultado = true; } o else resultado = false caso de cdigo de operacin no terminal [N]: o isave = i; N () ; o if (!resultado) { i = isave ; ai = sigtecar(i); resultado= false;} o else resultado = true; Veamos el pseudocdigo de algunas funciones:
Main X() S() int isave = 0; isave = i; A(); if(resultado ){ resultado =true; return resultado; } else{ i= isave; ai=sigtecar(i); if(ai ==(){ i++; ai = sigtecar(i); resultado = true isave = i; S ( ); if(!resultado){ i=isave; ai=sigtecar(i); resultado =false; return resultado; }else{ resultado = true; } if(ai==)){ i++; ai=sigtecar(i); resultado=true; return resultado; }else{ resultado = false; return resultado; } }else{ resultado =false; return resultado; } A( ) int isave = 0; isave =i; B( ); if(!resultado){ i=isave; ai=sigtecar(i); resultado=false; return resultado; }else{ resultado=true; if(ai==>){ i++; ai=sigtecar(i); isave=I; B ( ); if(!resultado){ i=isave; ai=sigtecar(i); resultado=false; return resultado; }else{ rersultado=true; return resultado; } }else{ resultado =false; return resultado; }

int isave = 0; int i = 0; boolean resultado; char ai; ai=sigtecar(i); isave=i; S (); if (!resultado ) traterror() else if (ai == FDC) ACEPTAR else traterror();

Programacin de Sistemas

Anlisis Sintctico

4.- TRATAMIENTO DE ERRORES SINTCTICOS: La mayora de las especificaciones de los lenguajes de programacin no describen cmo debe responder un compilador a los errores. Se deja esa tarea al diseador. Sera conveniente considerar desde el principio el tratamiento de errores. Podra simplificar la estructura del compilador. Gran parte de la deteccin y recuperacin de errores se centra en el analizador sintctico: o Pues la mayora de los errores son de naturaleza sintctica o se manifiestan en esa fase. o Gracias a la precisin de los mtodos modernos de anlisis. La deteccin exacta de errores semnticos y lgicos es mucho ms difcil.

Objetivos del Manejador de errores: Informar de los errores con claridad y exactitud Recuperarse de cada error con suficiente rapidez como para detectar errores posteriores. No retrasar significativamente el procesamiento de programas correctos.

Estrategias de recuperacin de errores: Modo pnico: Desechar smbolos de entrada hasta encontrar uno que pertenece a un conjunto llamado de sincronizacin (generalmente delimitadores, ;, END, etc.) Inconveniente: omite mucho anlisis de entrada Ventajas: Sencillez Alto rendimiento coste / eficacia. Garanta contra lazos infinitos Adecuado cuando hay pocos errores mltiples. En el nivel de frase: Al detectar un error realiza una correccin local de la entrada restante. Ejemplo. Sustituir un prefijo por una cadena que permita seguir el anlisis ( sustituir , por ;, suprimir ; sobrante, insertar ;) Gran peligro con las sustituciones: puede producir lazos infinitos. Desventaja: dificultad cuando el error real se produjo antes del lugar de la deteccin. Producciones de error: Si se tiene informacin sobre los errores ms comunes se aumentan las reglas de la gramtica con reglas que generan construcciones errneas, que a su vez generan diagnsticos. Correccin global: Algoritmos para elegir una secuencia mnima de cambios para conseguir una correccin global con el menor coste.
9

Programacin de Sistemas

Anlisis Sintctico

Implantacin costosa en tiempo y en memoria. Actualmente slo tiene inters terico. 5.- ANLISI SINTCTICO DESCENDENTE SIN RETROCESO. Nociones generales

El objetivo es construir el rbol de anlisis sintctico desde la raz (axioma) hasta las hojas (terminales) sin retroceso. Si es posible se dir que el fragmento de lenguaje analizado es correcto sintcticamente. Para que no haya retroceso se ha de saber qu regla alternativa debe ser derivada. Se vern dos tcnicas: Descenso recursivo Descenso no recursivo, utilizando una tabla. Se analizarn lenguajes que responden a gramticas LL(1): aquellas que leyendo un solo smbolo a la entrada se sabe qu regla alternativa ha de ser expansionada (derivada). Se puede saber si una gramtica es LL(1) o no. Bastar que cumpla cierta condicin que se ver ms adelante.

No existe un algoritmo que transforme una gramtica cualquiera en una LL(1), aunque en algunos casos se puede transformar convirtindola en LL(1): 1. Eliminando recursividad por la izquierda A A a (a,b: cadenas de smbolos terminales y no terminales. A no terminal) Ab Se transforma en A b A A a A |

2. Factorizando por la izquierda Aab Aac Se transforma en A a A A b | c

10

Programacin de Sistemas

Anlisis Sintctico

5.1.- Analizador sintctico LL(1) recursivo. Por el momento vamos a retrasar en el tiempo el conocer las condiciones que debe cumplir un lenguaje para ser LL(1). Vamos a dar por hecho que vamos a analizar uno que lo sea. En ese caso bastar saber qu smbolo hay a la entrada para elegir la regla alternativa que empiece con ese mismo terminal. Podemos utilizar una variante de la mquina de KNUTH: Aadiendo la pregunta de qu smbolo hay a la entrada (llamado smbolo de preanlisis) Eliminando la variable booleana resultado. En el momento que algo falle ya no es necesario retroceder ni seguir: el diagnstico es que la cadena es no vlida. Hagmoslo con un ejemplo: BD#P D D ; D | id tipo T T int | real P P ; P | id = E | if C then P E E + E | id | num | ( E ) C id == id

eliminar la recursividad por la izquierda: D id tipo T D D ; D D | P id = E P | if C then P P P ; P P | E id E | num E | ( E ) E E + E E | [B] $ ACEPTAR [D] # [P] return Id Tipo [T] [ D ] return int return real return Traterror () ; [D] [ D ] return no hacer nada return Id = [E] [ P ] return If [E] then [P] [ P ] return Traterror ( )
11

B: B: D:

T: D

Preanlisis = = int Preanlisis = = real Preanlisis = = otro Preanalisis == ; Preanalisis ==otro Preanlisis = = id

P:

Preanlisis = = if

Preanlisis = = otro

Programacin de Sistemas

Anlisis Sintctico

P:

Preanlisis = = ; Preanlisis = = otro Preanlisis = = (

E:

Preanlisis = = id Preanlisis = = num E: Preanlisis = = otro Preanlisis = = + Preanlisis = = otro C:

; [P] [ P ] return ( no hacer nada) return ( [E] ) [ E ] return Id [ E ] return Num [ E ] return Traterror () + [E] [ E ] return ( no hacer nada ) return id = = id return

En el pseudocdigo para cada funcin hay una sentencia que se repite: preanlisis = sigtecomlex( ); si incluimos esta sentencia en la siguiente funcin: void concuerda ( complex t) { if(preanlisis = = t) preanlisis = sigtecomplex(); else traterror (); } Aunque en la mayora de los casos pueda ser redundante queda ms claro desde un punto de vista conceptual:
B() B ( ) preanlisis = sigtecomplex(); B ( ); if(preanalisis = = $) mensaje (aceptar); else traterror(); D ( ); concuerda (#); P(); return P( ) switch(preanalisis){ case;: concuerda(;); P ( ); P( ); break; default: }return P( ) switch(preanalisis){ case id: concuerda(id); concuerda(=); E( ); P ( ); break; case if: concuerda(if) E( ); concuerda (then); P( ); P( ); break; default: traterror( ); }return

Para el resto de funciones se sigue el mismo criterio.

12

Programacin de Sistemas

Anlisis Sintctico

5.2.- Condicin para ser LL(1). En primer lugar veamos una serie de definiciones: Definiciones de CABECERA y SIGUIENTE Sea A PRIMERO a si.............. A a terminales y no terminales) Sea A PRIMERO+ a si......... A A1 1 A1 A2 2 A2 A3 3 ..................... An a n+1 Si A tiene varias alternatives: A 1 | 2 | 3 |........ | n Se llamar CABECERA (A) al conjunto de todos los A PRIMERO+ de todas las alternativas. Si se tiene B A ....... SIGUIENTE (A) sern todos los PRIMEROS+ de Si fuera anulable se aadirn los SIGUIENTE(B). ( este ltimo representa una cadena de

CONDICIN para que sea LL(1): Tomar las reglas que tienen alternativas. Sea A a1 | a2 (a1 y a2 son cadenas de terminales y / o no terminales): CAB(a1 SIG(A)) INTERSECCIN CAB(a2 SIG(A)) = CONSTRUCCIN DE CABECERA Y SIGUIENTE CABECERAS: Si A a cadena aadir a a CAB(A) Si A aadir a CAB(A) Si A X1 X2 X3 .....Xr (Xn son NO TERMINALES) o Incluir smbolos no nulos de CAB(X1) en la CAB(A) o Si est en CAB(X1) , aadir tambin la CAB(X2) o Si est en CAB(X2) , aadir tambin la CAB(X3) .................................................................................. o si est en CAB(Xr) aadir a CAB(A). SIGUIENTES: Si S es axioma incluir $ (fin de cadena) a SIG(S) Si A aBb (a y b cadenas, B no terminal) , aadir CAB(b) a SIG(B)
13

Programacin de Sistemas

Anlisis Sintctico

Si AaB o A aBb y b * incluir todos los SIG(A) a SIG(B)

14

Programacin de Sistemas

Anlisis Sintctico

Sea: PD e S p D id L ; | L , id L | S id = id | b S R end R; S R |

Diagramas de CONWAY
P: e D: id L L: , S: id b R: = S id R end id id , ; S p

15

Programacin de Sistemas

Anlisis Sintctico

Cab (P) = {id e} Cab (D) = {id } Cab (L) = {, } Cab (S) = {id b} Cab (R) = {; }
Es LL(1)?

Sig(P)={$ } Sig(D)={e} Sig(L)={;} Sig(S)={p; end} Sig(R)={end}

Cab( id L ; ) = { id } Cab ( Sig (D) ) = { e} Cab(, id L ) = { , } Cab ( Sig (L) ) = { ;} Cab( id = id ) = { id } Cab (b S R end) = {b} Cab( ; S R ) = { ; } Cab ( Sig (R) ) = { end} Todos disjuntos luego es LL(1) 5.3.- Analizador sintctico descendente no recursivo Utilizar una pila y una tabla que le indique qu alternativa debe escoger Su estructura ser:
Tokens a la entrada a pila X Y Y Z . $ Tabla de anlisis sintctico T [ A, a ] Matriz bidimensional Algoritmo salida + b

16

Programacin de Sistemas

Anlisis Sintctico

Inicialmente en la pila estar el axioma y el fin de cadena. El algoritmo ser el siguiente: Leer el smbolo en el tope de la pila: x Leer el terminal en curso a la entrada: a Si x = a = $ (fin de cadena) al ANASINT ACEPTA la cadena. Si x = = a saca x de la pila y mueve el cursor de la entrada al siguiente token Si X es un NO TERMINAL consulta la tabla T [ X, a ] resultando: Una regla de la gramtica X U V W El programa sustituye X en el tope de la pila por U V W ( U en el tope). Un error. El programa va al tratamiento de errores.

Para construir la tabla se ha de calcular previamente los conjuntos CABECERA Y SIGUIENTE. PASOS PARA CONSTRUIR LA TABLA: 1. Calcular CAB y SIG de todos los no terminales 2. Para cada A a ( a cadena) realizar los pasos 3 y 4 3. Para cada t de CAB(A) aadir la regla Aa a TABLA[ A,t] 4. Si est en CAB(A) aadir A en TABLA[A,m] si m est en SIG(A) (m puede ser $). Para el ejemplo anterior:
P D L S R e PDeS p D p id PDeS p DidL; Sid=id R;SR ; , = b end $

L,idL SbSRen d R

17

Programacin de Sistemas

Anlisis Sintctico

Realizar la traza del analizador para la entrada id , id ; e b id = id ; id = id end p Pila P$ D e S p$ id L ; e S p $ L;eSp$ , id L ; e S p $ id L ; e S p $ L;eSp$ ;e S p $ eSp$ Sp$ b S R end p $ S R end p $ id = id R end p $ = id R end p $ id R end p $ R end p $ ; S Rend p $ S R end p $ id = id R end p $ = id R end p $ id R end p $ R end p $ end p $ p$ $ Token id id id , , id ; ; e b b id id = id ; ; id id = id end end p $ accin P D e S p D id L ; Sacar y avanzar L , id L Sacar y avanzar Sacar y avanzar L Sacar y avanzar Sacar y avanzar S b S R end Sacar y avanzar S id = id Sacar y avanzar Sacar y avanzar Sacar y avanzar R;SR Sacar y avanzar S id = id Sacar y avanzar Sacar y avanzar Sacar y avanzar R Sacar y avanzar Sacar y avanzar ACEPTAR

OBSERVACIONES sobre la dependencia del contexto En los lenguajes de programacin hay construcciones dependientes del contexto. No se pueden analizar con los ANASINT pues estos reconocen slo los lenguajes dgenerados por una gramtica libre de contexto Se resuelven mediante acciones semnticas Veamos dos de ellas: L1 { w c w | w (a | b)* } Sera el caso de la obligatoriedad de declarar variables antes de usarlas L2 { an bm cn dm } n>= 1, m >= 1 Sera el caso de comprobar si el nimero de parmetros formales en la declaracin de una funcin coincide con el nmero de parmetros reales.

18

Programacin de Sistemas

Anlisis Sintctico

6.- ANLISIS SINTCTICO ASCENDENTE En este tipo de anlisis hay que resolver dos problemas: Situar la subcadena a ser reducida en forma de parte derecha de una regla. Determinar qu regla elegir (en el caso de que haya ms de una que pueda ser reducida). Se utilizar una pila que ser inicializada con el smbolo de fin de cadena. Comparando la cima de la pila en cualquier momento con el token de entrada, el analizador tomar una de estas cuatro acciones: Desplazar smbolos (tokens) a la pila hasta que un pivote ( subcadena susceptible de ser reducida) se encuentre en la cima. Reducir sustituyendo el pivote por la parte izquierda de la regla Aceptar la cadena de ntrada dndola vlida sintcticamente, cuando en la pila se halle el smbolo de fin de cadena y el axioma y en la entrada se tenga el smbolo de fin de cadena. Error En general, en un lenguaje generado por una gramtica libre de contexto, se puede dar dos tipos de conflictos: De desplazamiento-reduccin, cuando conociendo el contenido de la pila y el simbolo a la entrada no se puede decidir si desplazar o reducir. De reduccin-reduccin, cuando no se puede decidir qu regla aplicar para reducir. Hay otras gramticas que analizando k smbolos a la entrada por anticipado se puede decidir qu regla reducir. Son las llamadas LR(k). Una gramtica ambiga no puede ser LR , pero se pueden hacer fciles adaptaciones en el analizador para evitar los conflictos. Ejemplo: el else ambigo. Se aade la norma de que el else va con el then ms cercano y esto se resuelve forzando el desplazamiento en un conflicto de desplazamiento-reduccin.

19

Programacin de Sistemas

Anlisis Sintctico

6.1.- Anlisis sintctico de Precedencia Simple. Est basado en las relaciones llamadas de Precedencia que hay entre los smbolos de entrada, teniendo como objetivo localizar una subcadena para la que exista una reduccin y con sucesivas reducciones llegar al axioma. Ejemplo: S a A a .................. a igual precedencia que A (a+-A), A igual precedencia que a (A+-a) A b B (b +-B) y no la simtrica A c B A c d. (A+-c), (c+-d) Desarrollando todos los posibles rboles:
S S

a +-

A +-

a menor precedencia que b (ab) (b +-B) , (Ba) , (b A), (bc) , (c-->c), (d-->a)
a

b A c

+B

As con todos los posibles rboles Si hay como mximo una relacin de precedencia entre cada pareja hay un pivote susceptible de ser reducido

Si todas las relaciones encontradas se resumen en una tabla: S a A B c S a +A ++ B c b + d $

Los blancos de la tabla representan errores. La cadena susceptible de ser reducida es la que se encuentre entre ...y .....
20

Programacin de Sistemas

Anlisis Sintctico

El algoritmo de reconocimiento para precedencia simple: 1. Smbolos de entrada leidos de izquierda a derecha 2. Se van introduciendo en una pila hasta hallar una relacin (desplazamiento) 3. Inspeccionar el interior de la pila hasta hallar una relacin . El pivote est entre y . 4. Inspeccionar las partes derechas de las reglas y decidir qu reduccin 5. Sustituir en la pila el pivote por la parte izquierda de la regla. 6. Repetir los pasos anteriores. Ejemplo: con la gramtica anterior, la tabla hallada, escribir la traza del analizador para la cadena: a b c c d a Pila $ $a $ab $ab c $abA $abAc $ab Acd $a bB $aA $ aAa $S Relacin Precedencia ++ + Token ledo a b c c c d a a a $ $ Cadena restante bccda$ ccda$ cda$ da$ da$ a$ $ $ $

21

Programacin de Sistemas

Anlisis Sintctico

6.2.- Anlisis sintctico de Precedencia de Operadores. Para que sea una gramtica de Operadores se deben de cumplir : Ninguna parte derecha es vaca () No tiene 2 NO TERMINALES adyacentes Las relaciones entre los smbolos se establecen de manera similar a las de precedencia simple, pero ahora las tres relaciones de precedencia slo se establecen entre smbolos terminales, siendo los no terminales transparentes para estos efectos. El algoritmo es el mismo que el de precedencia simple, slo cambia que las relaciones se establecen entre los terminales. Como se ha dicho antes los no terminales son transparentes para establecer relaciones, slo sirven para reconocer los pivotes y ser reducidos como parte integrante de una parte derecha de una regla. Aunque slo una pequea clase de gramticas puede analizarse mediante este mtodo, por su sencillez se usa con gran xito para expresiones aritmticas. Cmo determinar las relaciones de Precedencia de Operadores ? Intuitivamente, basndose en nociones de asociatividad y prioridad Sea una gramtica no ambiga para las expresiones aritmticas: EE+T|ET| T TT*F|T/F|F F id | ( E ) Para establecer las relaciones los no terminales son transparentes , es decir es como si fueran el mismo no terminal. Bien, aplicaremos este artificio y transformaremos la gramtica en esqueltica: E E + E | E E | E * E | E / E | ( E ) | id Ahora trataremos de incluir prioridades y asociatividades en las relaciones: Sea OP1 de mayor prioridad que el OP2: OP1 OP2 *+ OP2 OP1 +* Sea OP1 y Op2 de igual prioridad: Si hay asociatividad por la izquierda OP1 OP2 + +, + -, - -, - + OP2 OP1 * *, * /, / /, / * Si hay asociatividad por la derecha OP1 OP2 OP2 Op1 Para los operadores unarios, si es de mayor prioridad que otro Opu OP, caso contrario Opu OP
22

Programacin de Sistemas

Anlisis Sintctico

Resumiendo: OP1 mayor prioridad que OP2: OP1 OP2 y OP2 OP1.. * + y + * OP1 y OP2 son el mismo operador o dos operadores de la misma prioridad: - si son asociativos por la izquierda: OP1 OP2 y OP2 OP1 + + , + - , - - , - + - si son asociativos por la derecha: OP1 OP2 y OP2 OP1 . ** ** Un operador y el terminal id: OP id y id OP Un operador y abre parntesis: OP ( y ( OP Un operador y cierra parntesis: OP ) y ) OP Un operador y el delimitador: OP $ y $ OP Abre y cierra parntesis: ( +- ) Abre y abre parntesis : (( Cierra y cierra parntesis: )) Abre parntesis y terminal id: ( id Cierra parntesis y terminal id: id ) Delimitador y abre parntesis: $( Delimitador y cierra parntesis: ) $ Delimitador y terminal id: id $ y $ id Operador binario y uno unario: OP OPU y si OPU es de mayor prioridad que OP: OPU OP caso contrario.OPU OP + * / ** Id ( ) $ + * / ** Id ( + ) $ Hay un problema con el operador -, pues se usa tanto binario como unario. En cadenas como id * - id podra haber un error que no se reconoce. El analex debera enviar un token diferente lo que significa que debera recordar el token anterior. Si ste fuera op ( ; := el que llega es unario

23

Programacin de Sistemas

Anlisis Sintctico

La traza del analizador para la cadena id * id * (id + id ) $, sera: Pila $ $id $E $E* $E*id $E*E $E $E* $E*( $E*(id $E*(E $E*(E+ $E*(E+id $E*(E+E $E*(E $E*(E) $E*E $E Relacin + Token ledo id * * id * * * ( id + + id ) ) ) $ $ $ Cadena restante * id + ( + id ) $ id * ( id + id ) $ id * ( id + id ) $ * ( id + id ) $ ( id + id ) $ ( id + id ) $ ( id + id ) $ id + id ) $ + id ) $ id ) $ id ) $ )$ $ $ $

Funciones de Precedencia Los ANASINT de precedencia de operadores no necesitan almacenar la tabla. Esta se codifica mediante dos funciones llamadas de precedencia f g que TRANSFORMAN los smbolos terminales en enteros de tal manera que: f(a) < g(b) cuando ab f(a) = g(b) cuando a+-b f(a) > g(b) cuando a b Se pueden establecer las relaciones mediante comparacin numrica entre f(a) y g(b)

Mtodo para obtener las funciones de Precedencia 1. Crear smbolos fa y ga para cada a que sea terminal o $ 2. Dividir los smbolos creados en grupos segn: 2.1. si (a +- b) fa y gb estarn en el mismo grupo 2.2. si (a+-b) y (c+-b) fa y fc estarn en el mismo grupo 3. Crear el grafo dirigido 4. Si hay ciclos no existen funciones de Precedncia
24

Programacin de Sistemas

Anlisis Sintctico

5. El valor de f(a) ser la longitud del camino ms largo hasta f($) o g($) Sea la tabla: id id + * $ Se construye el grafo:
fid gid Sera error pero con las funciones no se detecta directamente, pues: f(id) < g(id) por tanto sale el absurdo id id id f g f* g* Puede resolverse en tiempo de reduccin cuando existiendo una relacin ficticia, el ANASINT no sea capaz de encontrar un pivote y las funciones resulten ser f(id) y g(id) 4 5 + 2 1 * 4 3 $ 0 0

f+

g+

f$

g$

Incluyendo parntesis las funciones seran: f(a) g(b) id 4 5 + 2 1 2 1 * 4 3 / 4 3 ( 1 5 ) 4 1 $ 0 0

25

Programacin de Sistemas

Anlisis Sintctico

Veamos la traza del ANASINT con funciones de Precedencia para la cadena de entrada: id * (id +id) $ Pila $ $id $E $E* $E*( $E*(id $E*(E $E*(E+ $E*(E+id $E*(E+E $E*(E $E*(E) $E*E $E f(a) 0 4 0 4 1 4 0 2 4 2 1 4 4 Relacin + g(b) 5 3 3 5 5 1 1 5 1 1 1 0 0 Entrada id * (id +id )$ * (id +id )$ * (id +id )$ (id +id )$ id +id )$ +id )$ +id )$ id )$ )$ )$ )$ $ $ $

6.3.- Anlisis Sintctico LR(1). Es una clase muy amplia de gramticas libre de contexto con una tcnica muy eficiente. Ventajas: Puede reconocer practicamente todas las construcciones de los lenguajes de programacin generados por gramticas de libre contexto. Es el mtodo por desplazamniento-reduccin mas general conocido y muy eficaz. La clase de gramticas LR(k) es un supraconjunto de las grmticas LL(k). Puede detectar un error tan pronto como sea posible en un examen de izquierdaderecha de la entrada.

Inconvenientes: Mas complejos de diseo y uso. Se hace necesaria una herramienta (generador de LR).
26

Programacin de Sistemas

Anlisis Sintctico

Estructura de un analizador LR. Consta de pila, un algoritmo y una tabla.


a1 ai .. an $

Sm Xm Sm-1 Xm-1 . . . . S0

Algoritmo para el ANASINT LR

salida

tabla Accin

tabla Ir-a

Tabla de anlisis

El algoritmo es simple e invariante de un ANASINT a otro La tabla vara de una gramtica a otra. Es difcil de construir. Es la esencia del ANASINT. Consta de dos tablas: La tabla de accin, accin(s,t) (s : estado, t: smbolo a la entrada): Desplazar Reducir la regla i Aceptar Error La tabla de ir-a, goto(s1, x ) = s2 : Toma como argumentos un estado y un smbolo de la gramtica Produce otro estado En realidad es una funcin de transiciones de un autmata finito,cuyos smbolos de entrada son terminales y no terminales. La pila, que contiene estados tapando los smbolos de la gramtica: S0 X1S1 X2S2............Xm-1Sm-1 XmSm Los estados representan la informacin contenida en la pila, son utilizados para decidir qu reduccin o qu desplazamiento. La configuracin inicial ser: E la pila el estado inicia S0 En la entrada, los tokens a la entrada: a1 a2 a3 ..... an $

27

Programacin de Sistemas

Anlisis Sintctico

Algoritmo del ANASINT LR 1. Determinar el estado Sm en el tope de la pila y el smbolo actual a la entrada ai 2. Consultar la funcin accin: S 2.1. accon(Sm,ai)= desplazar ai ai+1 .... ai 2.1.1. introduce ai en la pila Sm 2.1.2. encabeza la pila con el nuevo estado goto(Sm,ai)=S Xm . 2.2. accon(Sm.ai) = reducir la regla j . 2.2.1. ejecuta la reduccin en la pila : S0 (j) A Xm-r+1 Xm-r+2.......Xm (r longitud de la parte derecha de la regla)
Sm Xm ... ... Sm-r+1 Xm-r+1 Sn Xn .. .. S0 S A Sn Xn .. .. S0

Al reducir por A

2.2.2. encabeza la pila con nuevo estado goto(Sn,A)= S 2.3. accin(Sm,ai)= aceptar. Fin del reconocimiento 2.4. accin(Sm,ai)=error. Activa las rutinas de tratamiento de errores. Ejemplo:
Dada la gramtica: (1) S -> S +T , (2) S -> T , siguientes: ACTION ES TA id + * ( DO 0 D E E D 1 E D E E 2 E R2 D E 3 E R4 R4 E 4 D E E D 5 E R6 R6 E 6 D E E D 7 D E E D 8 E D E E 9 E R1 D E 10 E R3 R3 E 11 E R5 R5 E (3) T -> T* F , (4) T -> F , (5) F -> ( S ) , (6) F-> id GOTO ) E E R2 R4 E R6 E E D R1 R3 R5 $ E AC R2 R4 E R6 E E E R1 R3 R5 id 5 6 7 5 5 5 6 7 4 4 4 11 8 2 9 3 3 10 + * ( 4 ) $ S 1 T 2 F 3 y las tablas

Siendo D = desplazar, Ri = reducir con la regla n (i), E = error, AC = aceptar y los nmeros de GOTO los nuevos estados. Describir la traza del contenido de la pila para reconocer la tira id*(id+id) 28

Programacin de Sistemas

Anlisis Sintctico

Pila 0 0id5 0F3 0T2 0T2*7 0T2*7(4 0T2*7(4id5 0T2*7(4F3 0T2*7(4T2 0T2*7(4S8 0T2*7(4S8+6 0T2*7(4S8+6id5 0T2*7(4S8+6F3 0T2*7(4S8+6T9 0T2*7(4S8 0T2*7(4S8)11 0T2*7F10 0T2 0S1

Entrada id*(id+id)$ *(id+id)$ *(id+id)$ *(id+id)$ (id+id)$ id+id)$ +id)$ +id)$ +id)$ +id)$ id)$ )$ )$ )$ )$ $ $ $ $

Accin D5: id5 R6:Fid,,goto(0,F)=3 R4:TF,,goto(0,T)=2 D7: *7 D4: (4 D5: id5 R6: Fid,,goto(4,F)=3 R4:TF,,goto(4,T)=2 R2:ST,,goto(4,S)=8 D6: +6 D5: id5 R6:Fid,,goto(6,F)=3 R4:TF,,goto(6,T)=9 R1:SS+T,,goto(4,S)=8 D11: )11 R5: F(S),,goto(7,F)=10 R3: TT*F,,goto(0,T)=2 R2: S T,,goto(0,S)=1 aceptar

29

S-ar putea să vă placă și