Está en la página 1de 35

Traductores, Compiladores e Intrpretes

Tema 3. Anlisis Sintctico.


Todo lenguaje de programacin tiene reglas que describen la estructura sintctica de programas bien formados. En Pascal, por ejemplo, un programa se compone de bloques, un bloque de proposiciones, una proposicin de expresiones, una expresin de componentes lxicos, y as sucesivamente. Se puede describir la sintaxis de las construcciones de los lenguajes de programacin por medio de gramticas de contexto libre o notacin BNF ( Backus-Naur Form). Las gramticas ofrecen ventajas significativas a los diseadores de lenguajes y a los desarrolladores de compiladores. Las gramticas son especificaciones sintcticas y precisas de lenguajes de programacin. A partir de una gramtica se puede generar automticamente un analizador sintctico. El proceso de construccin puede llevar a descubrir ambigedades. Una gramtica proporciona una estructura a un lenguaje de programacin, siendo ms fcil generar cdigo y detectar errores. Es ms fcil ampliar/modificar el lenguaje si est descrito con una gramtica.

La mayor parte de este tema est dedicada a los mtodos de anlisis sintctico de uso tpico en compiladores. Primero se introducen los conceptos bsicos, despus las tcnicas adecuadas para la aplicacin manual. Adems como los programas pueden contener errores sintcticos, los mtodos de anlisis sintctico se pueden ampliar para que se recuperen de los errores sintcticos ms frecuentes.

Qu es el analizador sintctico ? Es la fase del analizador que se encarga de chequear el texto de entrada en base a una gramtica dada. Y en caso de que el programa de entrada sea vlido, suministra el rbol sintctico que lo reconoce. En teora, se supone que la salida del analizador sintctico es alguna representacin del rbol sintctico que reconoce la secuencia de tokens suministrada por el analizador lxico. En la prctica, el analizador sintctico tambin hace: Acceder a la tabla de smbolos (para hacer parte del trabajo del analizador semntico). Chequeo de tipos ( del analizador semntico). Generar cdigo intermedio. Generar errores cuando se producen.

En definitiva, realiza casi todas las operaciones de la compilacin. Este mtodo de trabajo da lugar a los mtodos de compilacin dirigidos por sintaxis.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Anlisis Sintctico.

Manejo de errores sintcticos Si un compilador tuviera que procesar slo programas correctos, su diseo e implantacin se simplificaran mucho. Pero los programadores a menudo escriben programas incorrectos, y un buen compilador debera ayudar al programador a identificar y localizar errores. Es ms, considerar desde el principio el manejo de errores puede simplificar la estructura de un compilador y mejorar su respuesta a los errores. Los errores en la programacin pueden ser de los siguientes tipos: Lxicos, producidos al escribir mal un identificador, una palabra clave o un operador. Sintcticos, por una expresin aritmtica o parntesis no equilibrados. Semnticos, como un operador aplicado a un operando incompatible. Lgicos, puede ser una llamada infinitamente recursiva.

El manejo de errores de sintaxis es el ms complicado desde el punto de vista de la creacin de compiladores. Nos interesa que cuando el compilador encuentre un error, se recupere y siga buscando errores. Por lo tanto el manejador de errores de un analizador sintctico debe tener como objetivos: Indicar los errores de forma clara y precisa. Aclarar el tipo de error y su localizacin. Recuperarse del error, para poder seguir examinando la entrada. No ralentizar significativamente la compilacin.

Un buen compilador debe hacerse siempre teniendo tambin en mente los errores que se pueden producir; con ello se consigue: Simplificar la estructura del compilador. Mejorar la respuesta ante los errores.

Tenemos varias estrategias para corregir errores, una vez detectados: Ignorar el problema (Panic mode ): Consiste en ignorar el resto de la entrada hasta llegar a una condicin de seguridad. Una condicin tal se produce cuando nos encontramos un token especial (por ejemplo un ; o un END).A partir de este punto se sigue analizando normalmente.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Anlisis Sintctico.
Ejemplo: aux = a[i] a[i] = a[j]; a[j] = aux; Error id = id [ id ] id [ id ] = id [ id ] ; id [ id ] = id ; Token especial, seguimos compilando a partir de l Recuperacin a nivel de frase: Intenta recuperar el error una vez descubierto. En el caso anterior, por ejemplo, podra haber sido lo suficientemente inteligente como para insertar el token ; . Hay que tener cuidado con este mtodo, pues puede dar lugar a recuperaciones infinitas. Reglas de produccin adicionales para el control de errores: La gramtica se puede aumentar con las reglas que reconocen los errores ms comunes. En el caso anterior, se podra haber puesto algo como: sent_errnea sentencia_acabada sent_sin_acabar sent_sin_acabar sentencia_acabada ; sentencia ; sentencia

Lo cual nos da mayor control en ciertas circunstancias Correccin Global : Dada una secuencia completa de tokens a ser reconocida, si hay algn error por el que no se puede reconocer, consiste en encontrar la secuencia completa ms parecida que s se pueda reconocer. Es decir, el analizador sintctico le pide toda la secuencia de tokens al lxico, y lo que hace es devolver lo ms parecido a la cadena de entrada pero sin errores, as como el rbol que lo reconoce.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Anlisis Sintctico.

Tipo de gramtica que acepta un analizador sintctico Nosotros nos centraremos en el anlisis sintctico para lenguajes basados en gramticas formales, ya que de otra forma se hace muy difcil la comprensin del compilador, y se pueden corregir, quizs ms fcilmente, errores de muy difcil localizacin, como es la ambigedad en el reconocimiento de ciertas sentencias. La gramtica que acepta el analizador sintctico es una gramtica de contexto libre:

Gramtica : G (N, T, P, S) N = No terminales. T = Terminales. P = Reglas de Produccin. S = Axioma Inicial. Ejemplo : Se considera la gramtica que reconoce las operaciones aritmticas. E T F E+T |T T*F |F ID | NUM |(E)

En el que: N = {E, T, F} estn a la izquierda de la regla. T = {ID, NUM, ( ,) ,+ ,*} P = Son las siete reglas de produccin. S = Axioma inicial. Podra ser cualquiera, en este caso es E. Derivaciones : La idea central es que se considera una produccin como una regla de reescritura, donde el no terminal de la izquierda es sustituido por la cadena del lado derecho de la produccin. De un modo ms formal:  con ,  (N . T)* , si

, -

8A/ 89/

con A N; , ,

(N . T)*; y

regla de produccin A 

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Anlisis Sintctico.
Derivacin por la izquierda : Derivacin donde solo el no terminal de ms a la izquierda de cualquier forma de frase se sustituye en cada paso. Derivacin por la derecha o Derivacin cannica: Derivacin donde el no terminal ms a la derecha se sustituye en cada paso. Ejemplo: Sea la gramtica E+E | E- E | E* E | E/ E | E^ E | id Constryase una derivacin por la izquierda y por la derecha para la siguiente frase: a*c+b ( id1 * id2 + id3) Derivacin ms a la izquierda: E E+E E*E+E id1 * E + E id1 * id2 + E id1 * id2 + id3 E

Derivacin ms a la derecha:: E E+E E + id3 E * E + id3 E * id2 + id3 id1 * id2 + id3

rbol sintctico de una sentencia de un lenguaje Es una representacin que se utiliza para describir el proceso de derivacin de dicha sentencia. Como nodos internos del rbol, se sitan los elementos no terminales de las reglas de producci n que vayamos aplicando, y tantos hijos como smbolos existan en la parte derecha de dichas reglas. Veamos un ejemplo: Sea la gramtica anterior. E T F E+T|T T*F|F (E)|a|b

Supongamos que hay que reconocer: ( a + b ) * a + b Si el rbol puede construirse, es que la sentencia es correcta:
Anlisis Sintctico Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Anlisis Sintctico.
E E T T F ( E T F a E + ) T F b * F a + T F b

Ambigedad: Una gramtica es ambigua si derivando de forma diferente con el mismo tipo de derivacin se llega al mismo resultado. Ejemplo: Considrese la gramtica EE+E EE*E E(E) E  id | num si tenemos aux + cont + i <ID><+><ID><+><ID>

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Tipos de anlisis sintcticos


Forma Sentencial Es cualquier secuencia de terminales y no terminales obtenida mediante derivaciones a partir del axioma inicial.

Tipos de Anlisis De la forma de construir el rbol sintctico se desprenden dos tipos o clases de analizadores sintcticos. Pueden ser descendentes o ascendente

Descendentes : Parten del axioma inicial, y van efectuando derivaciones a izquierda hasta obtener la secuencia de derivaciones que reconoce a la sentencia. Pueden ser: Con retroceso. Con recursin. LL(1)

Ascendentes: Parten de la sentencia de entrada, y van aplicando reglas de produccin hacia atrs (desde el consecuente hasta el antecedente), hasta llegar al axioma inicial. Pueden ser: Con retroceso. LR(1)

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Anlisis Descendentes

Anlisis descendente con retroceso. Objetivo : El mtodo parte del axioma inicial y aplica todas las posibles reglas al no terminal ms a la izquierda. Ejemplo: Utilizaremos la siguiente gramtica (No recursiva por la izquierda) E E T T F F F T+E T F*T F a b (E)

para reconocer la cadena de entrada: (a + b) * a + b

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

Anlisis Descendentes
Mediante este rbol se pueden derivar todas las posibles sentencias reconocibles por esta gramtica y el objetivo de este algoritmo es hacer una bsqueda en este rbol de la rama que culmine en la sentencia a reconocer. El mecanismo funciona mediante una bsqueda primero en profundidad. Mira si todos los tokens a la izquierda de un No Terminal coincide con la cabeza de la secuencia a reconocer. En todo el rbol de derivaciones, se pretende profundizar por cada rama hasta llegar a encontrar una forma sentencial que no puede coincidir con lo que se busca, en cuyo caso se desecha, o que coincide con lo buscado, momento en que se acepta la sentencia. Si por ninguna rama se puede reconocer, se rechaza la sentencia. Algoritmo : Sea k N el no terminal ms a la izquierda de la forma sentencial. Sea T* la secuencia de tokens en la izquierda de k. Ensayar (forma_sentencial, entrada) } for {pi P pi k forma_sentencial = Aplicar(pi, k, forma_sentencial) if = Parte_izquierda (entrada) if forma_sentencial == entrada Sentencia reconocida ! else Ensayar (forma_sentencial, entrada) endif endif endfor; En el programa principal Ensayar (S, cadena a reconocer) if not Sentencia reconocida ! Sentencia no reconocida !! endif;

Problemas : Este mtodo no funciona con gramticas recursivas a la izquierda, ya que puede ocurrir que entre en un bucle infinito. No existen muchos analizadores sintcticos con retroceso. En parte, porque casi nunca se necesita el retroceso para analizar sintcticamente las construcciones de los lenguajes de programacin. En casos como el anlisis sintctico del lenguaje natural, el retroceso tampoco es muy eficiente, y se prefieren otros mtodos.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

10

Anlisis Descendentes
Reconocer con el algoritmo (a+b)*a+b
forma_sentencial E T+E F * T +E a*T+E F * T +E b*T+E F * T +E (E) * T +E (T + E) * T + E (F * T + E) * T + E (a * T + E) * T + E (F * T + E) * T + E (b * T + E) * T + E (F * T + E) * T + E ((E) * T + E) * T + E (F * T + E) * T + E (T + E) * T + E (F + E) * T + E (a + E) * T + E (a + T + E) * T + E (a + F * T + E) * T + E (a + a * T + E) * T + E (a + F * T + E) * T + E (a + b * T + E) * T + E (a + F * T + E) * T + E (a + (E) * T + E) * T + E (a + F * T + E) * T + E (a + T + E) * T + E (a + F + E) * T + E .... (a + E) * T + E (a + T) * T + E ... 1-3-7-1-4-5-2 Pila (de reglas utilizadas) 1 1-3 1-3-5 1-3 1-3-6 1-3 1-3-7 1-3-7-1 1-3-7-1-3 1-3-7-1-3-5 1-3-7-1-3 1-3-7-1-3-6 1-3-7-1-3 1-3-7-1-3-7 1-3-7-1-3 1-3-7-1 1-3-7-1-4 1-3-7-1-4-5 1-3-7-1-4-5-1 1-3-7-1-4-5-1-3 1-3-7-1-4-5-1-3-5 1-3-7-1-4-5-1-3 1-3-7-1-4-5-1-3-6 1-3-7-1-4-5-1-3 1-3-7-1-4-5-1-3-7 1-3-7-1-4-5-1-3 1-3-7-1-4-5-1 1-3-7-1-4-5-1-4

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

11

Anlisis Descendentes

Anlisis descendente con recursin. Diagramas de Conway. Una gramtica de contexto libre puede expresar un lenguaje al igual que puede hacerlo la notacin BNF, y los diagramas de Conway. Definicin: Un diagrama de Conway es un grafo dirigido donde los elementos no terminales aparecen como rectngulos, y los terminales como crculos.

Para demostrar que permite representar las mismas gramticas que la BNF, se hace por induccin sobre las operaciones bsicas de BNF: Operacin Yuxtaposicin BNF AB Diagrama de Comway

Opcin

A|B

|B

Repeticin

1 o ms veces {B}

0 o ms veces [B]

De esta forma todos los posibles caminos desde el inicio del grafo hasta el final, representan formas sentenciales vlidas. En todo diagrama de Conway hay un origen y un destino.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

12

Anlisis Descendentes
Vamos a intentar establecer una comparacin entre el flujo de un programa y el camino que puedo establecer en los diagramas de Conway Ejemplo: Yuxtaposicin Flujo AxiomaInicial( ) A( ); B( ); Fin AxiomaInicial

Es importante el ejercicio de programacin consistente en seguir la evolucin detallada de las llamadas de los procedimientos entre s. prog: sent ;

Prog ( ); sent ( ); if el siguiente token es ; entonces consumir el token else !Error sintctico fi FinProg prog: sent ; FIN

Prog ( ); sent ( ); if el siguiente token es ; entonces Consumir el token else !Error sintctico fi if el siguiente token es FIN entonces Consumir el token else !Error sintctico fi FinProg

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

13

Anlisis Descendentes
Secuencia

main ( ) { get_token ( ); do { expresin ( ); while (token != PUNTOYCOMA) { !Error en expresin get_token ( ); }; get_token( ); }while (token != EOF); }; En este caso se considera al ; como un token de seguridad, lo que permite hacer una recuperacin de errores mediante el mtodo panic mode. Se supone que el sintctico pide al lexicogrfico tokens a travs de get_token ( );, y que el lexicogrfico deja el token actual en la variable global token. Antes de entrar a una funcin, en token debemos tener el token de lookahead, que esa funcin necesita consultar.

expresin ( ){ expr_simple ( ); if ((token == IGUAL)|| (token == ME)|| (token == MEI)|| (token == DIST)|| (token == MAI)|| (token == MA)) get_token ( ) ; expr_simple ( ) ; } }
Anlisis Sintctico Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

14

Anlisis Descendentes

expr_simple ( ) { if ((token == IGUAL) || (token == MENOS)) { get_token( ); } trmino ( ); while ((token == MAS) || (token == MENOS) || (token == OR)) { get_token( ); trmino ( ); } }

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

15

Anlisis Descendentes
trmino ( ){ factor ( ); while ((token == POR) || (token == DIV) || (token == DIV_ENT) || (token == MOD) || (token == AND) { get_token( ); factor( ); }

factor ( ){ switch (token) { case ID : get_token ( ); break; case NUM : get_token ( ); break; case NOT : get_token ( ); factor ( ); break; case AB_PARID : get_token ( ); expresin ( ); if (token != CE_PAR) {Error: Parntesis de cierre} else get_token ( ); break; default : Error : Expresin no vlida. } }

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

16

Anlisis Descendentes

Anlisis descendente de gramticas LL(1) Una gramtica LL(1) es aquella en la que su tabla de chequeo de sintaxis no posee entradas mltiples, o sea, es suficiente con examinar slo un smbolo a la entrada, para saber qu regla aplicar. Toda gramtica reconocible mediante el mtodo de los diagramas de Conway es LL(1) El mtodo consiste en seguir un algoritmo partiendo de: - La cadena a reconocer, junto con un apuntador, que nos indica cual es el token actual. - Una pila de smbolos ( terminales y no terminales) - Una tabla asociada de forma unvoca a una gramtica. En esta asignatura no vamos a ver como calcular dicha tabla. La cadena de entrada acabar en el smbolo $, que consideramos como si fuese un EOF( End Of File - Fin de Fichero). Sea X el elemento encima de la pila, y a, el apuntado en la entrada. El algoritmo consiste en: 1.- Si X = a = $ entonces ACEPTAR. 2.- Si X = a C $ entonces - se quita X de la pila - y se avanza el apuntador. 3.- Si X T y X C a entonces RECHAZAR. 4.- Si X N entonces consultamos la entrada M[X,a] de la tabla: - M[X,a] es vacia : RECHAZAR. - M [X,a] no es vacia, se quita a X de la pila y se inserta el consecuente en orden inverso. Ejemplo: Si M[X,a] = {X  UVY}, se quita a X de la pila, y se meten UVY en orden inverso :

5.- Ir al paso 1. Una vez aplicada una regla, no ser desaplicada por ningn tipo de retroceso. El algoritmo comienza con $ y con el axioma inicial metidos en la pila.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

17

Anlisis Descendentes
Este tipo de anlisis tiene el inconveniente de que muy pocas gramticas son LL(1), aunque muchas pueden traducirse a LL(1), tras un adecuado estudio. Por ejemplo: E T F E+T|T T*F|F ( E ) | id

Esta gramtica no es LL(1). La sustituimos por: E E T T F T E + T E | F T * F T | ( E ) | id

que es equivalente y LL(1) Tabla M :

T N E E T T F F T E

id TE E F T T id

* E

( TE E T F T T F (E)

+TE

* F T

Reconocer a* (b + c) id * ( id + id) $

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

18

Anlisis Descendentes
Inicialmente E $ T E $ F T E $ id T E $ T E $ * F T E $ id * ( id + id ) $ id * ( id + id ) $ M[T, *] = T * F T id * ( id + id ) $ M[E, id] = E T E

M[T, id] = T

F T

M[F, id] = F

id

id = id Avanzar apuntador

* = * Avanzar apuntador

F T E $ ( E ) T E $ E ) T E $ T E ) T E $

M[F, (] = F

(E)

( = ( Avanzar apuntador id * ( id + id ) $ M[E,id] = E T E

M[T,id] = T

F T

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

19

Anlisis Descendentes

F T E ) T E $ id T E ) T E $ T E ) T E $ E ) T E $ + T E ) T E $ T E ) T E $ id * ( id + id ) $

M[F, id] = F

id

id = id Avanzar apuntador

M[T,+] = T

M[E,+] = E

+ T E

+ = + Avanzar apuntador

id * ( id + id ) $

M[T,id] = T

F T

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

20

Anlisis Descendentes

F T E ) T E $ id T E ) T E $ T E ) T E $ E ) T E $ id * ( id + id ) $

M[F, id] = F

id

id = id Avanzar apuntador

M[T,)] = T

M[E,)] = E

Las reglas que hemos ido aplicando en cada caso, nos van dando el parse izquierdo que reconoce la sentencia.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

21

Anlisis Ascendentes
Aqu se construye el rbol sintctico de abajo hacia arriba, lo cual disminuye el nmero de reglas mal aplicadas con respecto al caso descendente (si hablamos del caso con retroceso). Tanto si hay retroceso como si no, en un momento dado, la cadena de entrada estar dividida en dos partes y :

: El trozo de la cadena de entrada (secuencia de tokens) por reconocer. Coincidir siempre con algn trozo de la parte derecha de la cadena de entrada : T*.Vamos consumiendo tokens, y todos los tokens que nos queden por consumir constituyen .
: coincidir siempre con el resto de la cadena de entrada, trozo al que se habrn aplicado algunas reglas de produccin, (N.T)* en sentido inverso. Ejemplo: Comienza el anlisis sintctico.

id + id + id id Ahora, es F
 + id + id 

Consumimos el primer token

F
id + id + id

Aplicamos una regla al revs

T
F id Forma sentencial + id + id


Secuencia de tokens

...

T | F T | | id + id

+ id


Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

22

Anlisis Ascendentes
En un momento dado, el analizador sintctico se encuentra en con un par ,  concreto, al que se llama configuracin. El analizador sintctico para poder trabajar puede realizar una de las cuatro operaciones siguientes: - Aceptar : Cadena reconocida. - Rechazar : La entrada no es vlida. - Reducir : Aplicar una regla de produccin a los elementos de

- Desplazar : Se desplaza el terminal ms de la izquierda de  a la derecha de

Es posible reducir por las reglas .

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

23

Anlisis Ascendentes
Mediante reducciones y desplazamientos, tenemos que llegar a aceptar o rechazar la cadena de entrada. Antes de hacer los desplazamientos tenemos que hacerles todas las reducciones posibles a . Cuando es el axioma inicial y  es la tira nula, se acepta la cadena de entrada. Cuando  no es la tira nula o no es el axioma inicial y no se puede aplicar ninguna regla, entonces se rechaza la cadena de entrada.

Anlisis Ascendente con retroceso.

Cuando se da cuenta que llega a una situacin en la que no puede continuar, entonces vuelve atrs deshaciendo todos los cambios. En el anlisis con retroceso no se permiten las reglas , puesto que estas se podrn aplicar de forma indefinida. El algoritmo es el siguiente: Ensayar ( , ) for pi P hacer if consecuente (pi) == cola( ) = Reducir la cola de por pi if ( == Axioma inicial) AND ( == ) ACEPTAR else Ensayar ( , ) Endif endif endfor if ( C ) ,  = Desplazar de  a Ensayar ( , ) endif endEnsayar En el programa principal pondremos: Ensayar( , cadena a reconocer); if NOT se ha aceptado then RECHAZAR endif;

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

24

Anlisis Ascendentes
Ejemplo: (Vamos a ver por que no se permiten las reglas ). Supongamos la siguiente gramtica. E E T T F F F F T+E T F*T F (E) id num

No puede aparecer recursin infinita.

en una gramtica ascendente con retroceso porque da lugar a

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

25

Anlisis Ascendentes
Ejemplo: Reconocer a*a

id * id, dada la siguiente gramtica:


E E T T F F F E+T T T*F F (E) id num

(Llevaremos una pila para el Backtraking) Pila 6 6-4 6-4-2 6-4-2 6-4-2 6-4-2-6 6-4-2-6-4 6-4-2-6-4-2 6-4 6-4 6-4 6-4-6 6-4-6-3 6-4-6-3-2 id F T E E* E * id E*F E*T E*E T T* T * id T*F T E * id id


id * id * id * id * id * id id

Accin Desplazar F T E id F T

Desplazar Desplazar F T E id F T

Retroceso Desplazar Desplazar F T E id T*F T

Aceptar

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

26

Anlisis Ascendentes

Analizadores LR

Vamos a analizar una tcnica eficiente de anlisis sintctico ascendente que se puede utilizar para analizar una amplia clase de gramticas de contexto libre. La tcnica se denomina anlisis sintctico LR(k); la L es por el examen de la entrada de izquierda a derecha (en ingls, left-to-right), la R por construir una derivacin por la derecha (en ingls, rightmost derivation) en orden inverso, y la k por el nmero de smbolos de entrada de examen por anticipado utilizados para tomar las decisiones del anlisis sintctico. Cuando se omite, se asume que k, es 1. El anlisis LR es atractivo por varias razones. Pueden reconocer la inmensa mayora de los lenguajes de programacin que puedan ser generados mediante gramticas de contexto-libre. El mtodo de funcionamiento de estos analizadores posee la ventaja de localizar un error sintctico en el mismo instante que se produce con lo que se adquiere una gran eficiencia de tiempo de compilacin frente a procedimientos menos adecuados como puedan ser los de retroceso. El principal inconveniente del mtodo es que supone demasiado trabajo construir un analizador sintctico LR a mano para una gramtica de un lenguaje de programacin tpico. Se necesita una herramienta especializada - un generador de analizadores sintcticos LR - . Por fortuna, existen disponibles varios de estos generadores. Ms adelante estudiaremos el diseo y uso de uno, el programa YACC. Con este generador se puede escribir una gramtica de contexto libre y el generador produce automticamente un analizador sintctico de dicha gramtica. Si la gramtica contiene ambigedades u otras construcciones difciles de analizar en un examen de izquierda a derecha de la entrada, el generador puede localizar dichas construcciones e informar al diseador del compilador de su presencia. Existen tres tcnicas para construir una tabla de anlisis sintctico LR para una gramtica. El primer mtodo, llamado LR sencillo (SLR, en ingls) es el ms fcil de implantar, pero el menos poderoso de los tres. Puede que no consiga producir una tabla de anlisis sintctico para algunas gramticas que otros mtodos si consiguen. El segundo mtodo, llamado LR cannico, es el ms poderoso y costoso. El tercer mtodo, llamado LR con examen por anticipado (LALR, en ingls), est entre los otros dos en cuanto a poder y costo. El mtodo LALR funciona con las gramticas de la mayora de los lenguajes de programacin y, con un poco de esfuerzo, se puede implantar en forma eficiente. Funcionalmente hablando, un analizador LR consta de dos partes diferenciadas, un programa de proceso y una tabla del anlisis. El programa de proceso posee como veremos seguidamente un funcionamiento muy simple y permanece invariable de analizador a analizador. Segn sea la gramtica a procesar deber variarse el contenido de la tabla de anlisis que es la que identifica plenamente al analizador. La figura muestra un esquema sinptico de la estructura general de una analizador LR.
Anlisis Sintctico Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

27

Anlisis Ascendentes

Como puede apreciarse en la figura, el analizador consta de una tira de entrada donde se encuentra la cadena a reconocer finalizada con el smbolo $ que representa el delimitador. Esta tira lee de izquierda a derecha un smbolo cada vez en el proceso de reconocimiento. El contenido de la pila tiene la forma s0 X1 s1 X2 s2 ... Xm sm donde el smbolo sm se encuentra en la cabeza tal y como se muestra en la figura. Cada uno de los Xi son smbolos de la gramtica y a los si vamos a denominarlos estados del analizador. Los estados se utilizan para representar toda la informacin contenida en la pila y situada antes del propio estado. Es mediante el estado en cabeza de la pila por el que se decide qu reduccin ha de efectuarse o bien qu desplazamiento. Tradicionalmente, una tabla de anlisis para un reconocedor LR consta de dos partes claramente diferenciadas entre s que representan dos funciones, la funcin GOTO y la funcin ACCION. Seguidamente estudiaremos los cometidos de ambas acciones. El funcionamiento del analizador LR es el siguiente 1.- Se determina el estado sm en cabeza de la pila y el smbolo actual ai en el instante de la cadena de entrada. 2.- Se consulta en la tabla de anlisis la funcin accin con los parmetros anteriores y que puede dar como resultado. D esp lazar S Accin (sm,ai) =

R edu cir A A ceptar R ech azar

por su parte la funcin GOTO acta igualmente con un estado y un smbolo de la gramtica produciendo un nuevo estado.
Anlisis Sintctico Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

28

Anlisis Ascendentes
Anlogamente puede definirse una configuracin de un analizador LR como un par de la forma (s0 X1 s1 X2 s2 ... Xm sm , ai ai+1 ... an $) es decir, el primer componente es el contenido actual de la pila, y el segundo la subtira de entrada que resta por reconocer, ai es el smbolo de entrada actual de anlisis. El movimiento del analizador se realiza teniendo en cuenta: 1. El smbolo ledo ai. 2. El smbolo en cabeza de la pila sm. Actuando con la funcin accin y dependiendo de las cuatro posibles alternativas pueden obtenerse las configuraciones que seguidamente se detallan. 1. Si accin (sm, ai) = desplazar s. entonces se introducen en la pila el smbolo actual analizado de la cadena de entrada y en la cabeza de la pila el nuevo estado obtenido mediante la funcin GOTO(sm, ai) = S. La configuracin as obtenida es la mostrada seguidamente. (s0 X1 s1 X2 s2 ... Xm sm ai s , ai+1 ... an $) pasando s a estar situado en cabeza de la pila y ai+1 el siguiente smbolo a explorar en la cinta de entrada. 2. Si accin (sm, ai) = reducir A  entonces el analizador ejecuta la reduccin oportuna donde el nuevo estado en cabeza de la pila se obtiene mediante la funcin GOTO(sm-r, ai) = s donde r es precisamente la longitud de la cadena  reducida. Aqu el analizador extrajo primero 2r smbolos de la pila ( r smbolos de estados y r smbolos de la gramtica), exponiendo el estado sm-r. Luego introdujo A, el lado izquierdo de la regla de produccin, y s, la entrada de GOTO(sm-r,A), en la pila. La configuracin as obtenida es la mostrada seguidamente. (s0 X1 s1 X2 s2 ... Xm-r sm-r A s , ai ai+1 ... an $) donde s es el nuevo estado en cabeza de la pila y no se ha producido variacin en la tira de entrada que aun queda por analizar.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

29

Anlisis Ascendentes
3. Si accin (sm, ai) = aceptar entonces se ha llegado a la finalizacin en el proceso de reconocimiento y el anlisis termina reconociendo la tira de entrada. 4. Si accin (sm, ai) = error entonces es muestra de que el analizador LR ha descubierto un error sintctico y proceder en consecuencia activando las rutinas de correccin de errores. Una de las ventajas de este tipo de anlisis es que , cuando se produce una accin de error, el token errneo suele estar al final de o al principio de , lo que permite depurar con cierta facilidad las cadenas de entrada (programas). La configuracin inicial del analizador es (s0
,

a1 a2 ... an $)

donde s0 es el estado inicial del reconocedor. Los sucesivos movimientos se realizan en base a los cuatro puntos anteriores hasta que se acepta la cadena de entrada o bien hasta la aparicin de un error.

Ejemplo: Expresiones aritmticas y tablas LR Sea la gramtica ya conocida de generacin de expresiones aritmticas. S S T T F F S+T T T*F F (S) id

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

30

Anlisis Ascendentes
La figura siguiente muestra la tabla de anlisis con las funciones ACCIN y GOTO para la gramtica anterior.

funcin ACCIN ESTADO 0 1 2 3 4 5 6 7 8 9 10 11 D5 D5 D6 R1 R3 R5 D7 R3 R5 D5 R6 R6 D4 D4 D11 R1 R3 R5 R1 R3 R5 id D5 D6 R2 R4 D7 R4 D4 R6 R6 R2 R4 + * ( D4 ACEP R2 R4 8 ) $ 1

funcin GOTO S 2 T 3 F

3 10

El significado de las entradas de la tabla anterior es la siguiente : 1. Di significa desplazar y meter en la pila el estado i, 2. Rj significa reducir por la regla de produccin con nmero j, 3. ACEP significa aceptar, 4. las entradas en blanco significan un error sintctico.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

31

Anlisis Ascendentes
En la siguiente figura muestra un ejemplo de reconocimiento para la cadena de entrada a * ( a + a)

id * (id + id)

(suponemos que el estado s0 queda representado por 0). PASO 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 PILA 0 0a5 0F3 0T2 0T2*7 0T2*7(4 0T2*7(4a5 0T2*7(4F3 0T2*7(4T2 0T2*7(4S8 0T2*7(4S8+6 0T2*7(4S8+6a5 0T2*7(4S8+6F3 0T2*7(4S8+6T9 0T2*7(4S8 0 T 2 * 7 ( 4 S 8 ) 11 0 T 2 * 7 F 10 0T2 0S1 aceptacin de la cadena CADENA DE ENTRADA id * (id + id )$ * (id + id ) $ * (id + id ) $ * (id + id ) $ (id + id ) $ id + id ) $ + id ) $ + id ) $ + id ) $ + id ) $ id ) $ )$ )$ )$ )$ $ $ $ $

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

32

Anlisis Ascendentes
Hemos estudiado como funcionan los analizadores LR mediante la utilizacin de sus correspondientes tablas de anlisis. En las lneas de reconocimiento anteriores puede observarse como el estado que siempre se encuentra en cabeza de la pila seala en todo momento la informacin necesaria para la reduccin, si esto procede. Hemos dejado al margen intencionadamente la estructura del programa de proceso puesto que se trata esencialmente de un autmata finito con pila. En general puede afirmarse que, dada la estructura de los analizadores LR, con la sola inspeccin de k smbolos de la cadena de entrada a la derecha del smbolo actual puede decidirse con toda exactitud cual es el movimiento (reduccin, desplazamiento, etc) a realizar. Es por este motivo por lo que suele denominarse a este tipo de gramticas como LR(k). Como ya se coment, en la prctica casi todos los lenguajes de programacin pueden ser analizados mediante gramticas LR(0) o LR(1). Las tablas LR(1) ideadas por Knuth en 1965 son demasiado grandes para las gramticas de los lenguajes de programacin. En 1969 De Remer y Korenjack descubrieron formas de compactar estas tablas, haciendo prctico y manejable este tipo de parser. El algoritmo es el mismo ya visto. Hay para ellos las gramticas Simples- LR (SLR) o bien Look-Ahead LR (LALR) estando las gramticas incluidas de la siguiente forma: LR(k)

0 LALR(k) 0 SLR(k)

pero no sus lenguajes respectivos que coinciden en sus conjuntos. El metacompilador YACC utiliza el anlisis LALR(1). El aut mata debe de mantener informacin de su configuracin ( ), y para mantener informacin sobre  se comunica con LEX, quin se encarga de la metacompilacin a nivel lxico.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

33

Anlisis Ascendentes
Consideraciones sobre el anlisis ascendente. Cuando usar recursin a derecha o a izquierda? Ejemplo : Reconocer identificadores separados por comas id, id, id, ... , id podramos optar por 2 gramticas diferentes ( lista ID | lista , ID lista ID | ID , lista Qu diferencia hay entre y ? y ):

Alternativamente se va desplazando y reduciendo con lo que el tamao de la pila se mantiene siempre estable ( es ms conveniente, pero no siempre se puede aplicar la recursin a la izquierda). Si hacemos la recursin a derecha, siempre existe la posibilidad de que se desborde la pila.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

34

Anlisis Ascendentes
Por la forma de construir las tablas pueden aparecer conflictos : - Shift/Reduce - Reduce/Reduce - Shift/Reduce :aparece cuando en la tabla de acciones hay que poner una R de reducir y una D de desplazar, el conflicto es que el programa no sabe si reducir o desplazar. Ej : expr expr + expr | NUM

En gramticas con ambigedad se produce el conflicto shift/reduce (relacionado con el hecho de considerar la gramtica como asociativa a izquierda o asociativa a derecha). - Reduce/Reduce : Se pueden utilizar dos reglas para reducir y no sabe cual elegir Ejemplo: S S B C aaBdd aCd a aa

Esta gramtica reconoce estas dos secuencia de tokens aaadd aaad

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

Traductores, Compiladores e Intrpretes

35

Anlisis Ascendentes
Suponemos la secuencia aaad

Aqu aunque lo correcto sera reducir por C, como el reconocimiento LALR(1) slo permite ver un token a la entrada, pues slo se ve la d. Como no se sabe si detrs hay otra d o no, pues es imposible tomar una decisin. Estamos ante una gramtica LALR(2). Los conflictos reduce/reduce se pueden eliminar en la mayora de los casos. Ej: S S B C aaBdd aCd a aa S S aaadd aaad

En este caso lo que se ha hecho ha sido aadir las secuencias que producen el conflicto como parte de la gramtica.

Anlisis Sintctico

Realizados por: Mara del Mar Aguilera Sierra y Sergio Glvez Rojas

También podría gustarte