TEMA 4

´ ´ ANALISIS SINTACTICO DESCENDENTE

Bibliograf´a: ı

¯ Aho, A.V., Sethi, R., Ullman, J.D. (1990), Compiladores: principios, t´ cnicas y herramientas, Tema 4, p´ ginas: 186-200. e a ¯ Louden, K.C. (1997), Compiler Construction: Principles and Practice, Tema 4, p´ ginas: 143-193. a ¯ Vivancos, E. (2000), Compiladores I: una introducci on a la fase de ´ an´ lisis, Tema 3, p´ ginas: 23-48. Especialmente para ejercicios. a a
Contenido: 1 An´ lisis descendente: el aut´ mata predice/concuerda. a o 2 Problemas en el an´ lisis descendente: Recursividad a izquierdas y su a eliminaci´ n. Indeterminismo en las alternativas. o 3 Gram´ ticas LL(1): Los conjuntos de PRIMEROS y SIGUIENTES. a La condici´ n LL(1). o 4 Analizador sint´ ctico predictivo recursivo. a 5 Analizador sint´ ctico predictivo dirigido por tabla. a 6 Recuperaci´ n de errores en los analizadores descendentes: Los cono juntos de predicci´ n y sincronizaci´ n. Recuperaci´ n en modo de o o o p´ nico. a

78

´ ´ 4.1. ANALISIS DESCENDENTE: EL AUT OMATA PREDICE/CONCUERDA

7 Limitaciones de los m´ todos descendentes. e

´ ´ 4.1 ANALISIS DESCENDENTE: EL AUTOMATA PREDICE/CONCUERDA Especificaci´ n de la sintaxis de un lenguaje mediante gram´ ticas indepeno a dientes del contexto (GIC). Estas gram´ ticas permiten recursividad y esa e tructuras anidadas. Por ejemplo: sentencias if-else anidadas, par´ ntesis anidados en expresiones aritm´ ticas, que no pueden ser representadas mee diante expresiones regulares. La recursividad va a implicar:

¯ Algoritmos de reconocimiento m´ s complejos, que hagan uso de llaa madas recursivas o usen expl´citamente una pila, la pila de an´ lisis ı a sint´ ctico. a ¯ La estructura de datos usada para representar la sintaxis del lenguaje ´ ha de ser tambi´ n recursiva (el arbol de an´ lisis sint´ ctico), en vez de e a a lineal (caso de un vector de caracteres para almacenar los lexemas en el analizador l´ xico). e
Fundamento de los m´ todos descendentes: aut´ mata predice/concuerda e o ´ En cada paso del proceso de derivacion de la cadena de entrada se realiza una predicci´ n de la posible producci´ n a aplicar y se comprueba si o o existe una concordancia entre el s´mbolo actual en la entrada con el primer ı ´ terminal que se puede generar a partir de esa regla de produccion, si existe ´ esta concordancia se avanza en la entrada y en el arbol de derivaci´ n, en cao so contrario se vuelve hacia atr´ s y se elige una nueva regla de derivaci´ n. a o

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

79

Ejemplo Supongamos la siguiente gram´ tica que permite generar exprea siones aritm´ ticas: e
E E’ T T’ F T E’ + T E’ - T E’ F T’ * F T’ / F T’ ( E ) num id
¯ ¯

Para la entrada num + id * num. Crear el arbol de an´ lisis sint´ ctico... a a ´ Nos restringimos al caso de m´ todos deterministas (no hay vuelta atr´ s) tee a niendo en cuenta un s´ lo s´mbolo de prean´ lisis (componente l´ xico que se o ı a e est´ analizando en la cadena de entrada en ese momento), sabemos exactaa mente en todo momento que producci´ n aplicar. El s´mbolo de prean´ lisis o ı a se actualiza cada vez que se produce una concordancia. Los m´ todos descendentes se caracterizan porque analizan la cadena de e componentes l´ xicos de izquierda a derecha, obtienen la derivaci´ n m´ s a e o a ´ la izquierda y el arbol de derivaci´ n se construye desde la ra´z hasta las o ı hojas. Problemas de decisi´ n: ¿Qu´ producci´ n elegir cuando hay varias o e o alternativas?

Conjunto PRIMEROS(«): el conjunto de tokens que pueden comenzar cualquier frase derivable de «, « ¾ ´ÎÌ ÎÆÌ µ£. Conjunto SIGUIENTES( ): el conjunto de tokens que pueden aparecer despu´ s de un no-terminal , ¾ ÎÆÌ e

« ¬

80

´ 4.2. PROBLEMAS EN EL ANALISIS DESCENDENTE:

´ 4.2 PROBLEMAS EN EL ANALISIS DESCENDENTE: ´ ¯ La recursividad a izquierdas da lugar a un bucle infinito de recursion.

¯ Problemas de indeterminismo cuando varias alternativas en una misma producci´ n comparten el mismo prefijo. No sabr´amos cu´ l elegir. o ı a Probar´amos una y si se produce un error har´amos backtracking. Si ı ı queremos que el m´ todo sea determinista hay que evitarlas. e
Existen transformaciones de gram´ ticas para su la eliminaci´ n. Estas transa o formaciones no modifican el lenguaje que se est´ reconociendo, pero si que a cambian el aspecto de la gram´ tica, que es en general menos intuitiva. a

4.2.1

Recursividad a izquierdas y su eliminaci´ n o tal

Una gram´ tica es recursiva por la izquierda si tiene un no-terminal a «. que existe una producci´ n o Algoritmo para eliminar recursividad a izquierdas:

¯ primer paso: se agrupan todas las producciones de

en la forma:

«½

«½

«Ñ ¬½ ¬¾

¬Ò
por:

donde ninguna ¬ comienza con una .

¯ segundo paso: se sustituyen las producciones de
¼

¬½ ¼ ¼ «¬¾ ¼ ¼ «½ ¾

¬Ò ¼¼ ¯ «Ñ

Ejemplo: Eliminar la recursividad a izquierdas de
E T F E+T T T*F F ( E ) num id

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

81

Una gram´ tica recursiva a izquierdas nunca puede ser LL(1). En efecto, a ´ asume que encontramos un token t, tal que predecimos la produccion ¬ , despu´ s de la prediccion, al apilar la parte derecha de la producci´ n, e o a a el s´mbolo estar´ en la cima de de la pila, y por tanto, se predecir´ la ı ı misma producci´ n, y tendiramos de nuevo en la cima, as´ hasta que el o infinito, produciendose un desbordamiento de la pila de an´ lisis sint´ ctico. a a

4.2.2 Indeterminismo en las alternativas. Factorizaci´ n o Cuando dos alternativas para un no-terminal empiezan igual, no se sabe qu´ alternativa expandir. Por ejemplo: e
Stmt if E then Stmt else Stmt if E then Stmt otras

Si en la entrada tenemos el token if no se sabe cual de las dos alternativas o elegir para expandir ËØÑØ. La idea es reescribir la producci´ n para retrasar la decisi´ n hasta haber visto de la entrada lo suficiente para poder elegir la o opci´ n correcta. o
Stmt Stmt’ if E then Stmt Stmt’ otras else Stmt ¯

Algoritmo para factorizar la gramatica: ´

¯ primer paso: para cada no-terminal com´ n a dos o m´ s alternativas de , u a

buscar el prefijo « m´ s largo a

«¬½ «¬¾

«¬Ò ­

¯ segundo paso: Si « ¯, sustituir todas las producciones de , de la «¬½ «¬¾ «¬Ò ­ , donde ­ representa todas las alterforma nativas de que no comienzan con « por:

82

´ 4.3. GRAMATICAS LL(1)

A A’

«

A’

­ ¬¾

¬½

...

¬Ò

´ 4.3 GRAMATICAS LL(1) Las gram´ ticas LL(1) permiten construir de forma autom´ tica un anala a izador determinista descendente con tan s´ lo examinar en cada momeno to el s´mbolo actual de la cadena de entrada (s´mbolo de prean´ lisis) para ı ı a saber que producci´ n aplicar. o

¯ L: m´ todo direccional, procesamos la entrada de izquierda a derecha e (from left to rigth). ¯ L: obtenemos derivaci´ n m´ s a la izquierda (left-most derivation). o a ¯ 1: usamos un s´mbolo de prean´ lisis para decidir la producci´ n a ı a o aplicar.
Teorema 1: Una gram´ tica LL(1) no puede ser recursiva a izquiera das y debe estar factorizada. Teorema 2: Una gram´ tica LL(1) es no ambigua. a Las afirmaciones inversas no tienen porque ser ciertas. Ejemplo de gram´ tica LL(1). a
S B aB b aBb

Para la cadena aabb. ´ Construir el arbol . . .

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

83

4.3.1 ¿C´ mo garantizar que una gram´ tica es LL(1): los conjuntos o a PRIMEROS y SIGUIENTES? Sea « ¾ ´ÎÆ ÎÌ µ£, PRIMEROS(«) indica el conjunto de terminales que pueden aparecer al principio de cadenas derivadas de «. Si « µ
£ £ ½

Ò

entonces

¾ PRIMEROS(«) con

¾ ÎÌ

Si « µ ¯ entonces

¯

¾ PRIMEROS(«)

Sea ¾ ÎÆ entonces SIGUIENTES(A) indica el conjunto de terminales que en cualquier momento de la derivaci´ n pueden aparecer inmediatao mente a la derecha (despu´ s de) . e ¾ SIGUIENTES(A) si existe « ¬ ¾ ´ÎÆ ÎÌ µ£ tales Sea ¾ ÎÌ , £ que Ë µ « ¬ . Algoritmo para calcular el conjunto de PRIMEROS: ´ Para X un unico s´mbolo de la gram´ tica (terminal o no-terminal). Enı a tonces PRIMEROS(X) consiste de s´mbolos terminales y se calcula: ı

¯ Si X es un terminal o ¯, entonces PRIMEROS(X)= X ¯ Si X es un no-terminal, entonces para cada producci´ n de la forma o ½ ¾ Ò , PRIMEROS(X) contiene a PRIMEROS( ½ µ   ¯ . Si adem´ s para alg´ n Ò todos los conjuntos PRIMEROS( ½) a u . . . PRIMEROS( ) contienen a ¯, entonces PRIMEROS(X) contiene a PRIMEROS( ·½ µ   ¯ .
Para « cualquier cadena, « ½ ¾ Ò , de terminales y no-terminales, entonces PRIMEROS(«) contiene a u ¾ Ò, si PRIMEROS( ) conPRIMEROS( ½ µ   ¯ . Para alg´ n ½   ½, entonces PRIMEROS(«) contiene ¯ para todos los ½ Ò, tiene a PRIMEROS( µ   ¯ . Finalmente, si para todo PRIMEROS( ) contiene ¯, entonces PRIMEROS(«) contiene a ¯ .

84

´ 4.3. GRAMATICAS LL(1)

Algoritmo para calcular el conjunto de SIGUIENTES:

¾ ÎÆÌ , entonces SIGUIENTES(A) consiste de terminales y Dado ı del s´mbolo (s´mbolo de fin de cadena) y se calcula como: ı ¯ Si
es el s´mbolo de inicio, entonces ı

¾ SIGUIENTES(A)

¯ Si hay una producci´ n o « ÈÊÁÅ ÊÇË ´­ µ   ¯ ¾ ËÁ

¯ Si existe una producci´ n o ÈÊÁÅ ÊÇË ´­ µ entonces SIGUIENTES(B)

­ , entonces ÍÁ ÆÌ Ë ´ µ ´ « o « ­

tal que ¯ ¾ SIGUIENTES(A).

Ejemplo: calcular PRIMEROS y SIGUIENTES para la gram´ tica a
E E’ T T’ F T E’ + T E’ - T E’ F T’ * F T’ / F T’ ( E ) num id
¯ ¯

PRIMEROS(E)= (,id,num PRIMEROS(T)= (,id,num PRIMEROS(F)= (,id,num PRIMEROS(E’)= +,-,¯ PRIMEROS(T’)= *, /, ¯ SIGUIENTES(E)= #,) SIGUIENTES(E’)= #,) SIGUIENTES(T)= #,),+,SIGUIENTES(T’)= #,),+,SIGUIENTES(F)= +,-,*,/,),#

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

85

4.3.2

La condici´ n LL(1) o

Para que una gram´ tica sea LL(1) se debe cumplir que: a 1 Para las producciones de la forma que:

« ½ «¾

«Ò se debe cumplir
para todo i,j ( ).

ÈÊÁÅ ÊÇË ´« µ ÈÊÁÅ ÊÇË ´« µ

Ì

Esta regla permite decidir qu´ alternativa elegir conociendo s´ lo un e o s´mbolo de la entrada. ı 2 Si

¾ ÎÆ , tal que
µ

¯

¾ PRIMEROS(A), entonces:
µ

ÈÊÁÅ ÊÇË ´

Ì ËÁ ÍÁ ÆÌ Ë ´

Esta condici´ n garantiza que para aquellos s´mbolos que pueden derivar o ı la cadena vac´a, el primer s´mbolo que generan y el siguiente que ı ı puede aparecer detr´ s de ellos sean distintos, sino no sabr´amos c´ mo a ı o decidir si vamos a empezar a reconocer el no-terminal o que ya lo hemos reconocido. Comprobar que la gram´ tica anterior para generar expresiones aritm´ ticas a e es LL(1).

86

´ 4.4. ANALIZADOR SINTACTICO PREDICTIVO RECURSIVO

4.4

´ ANALIZADOR SINTACTICO PREDICTIVO RECURSIVO

En este m´ todo se considera a cada regla de la gram´ tica como la definici´ n e a o de un procedimiento que reconocer´ al no-terminal de la parte izquierda. a El lado derecho de la producci´ n especifica la estructura del c´ digo para o o ese procedimiento: los terminales corresponden a concordancias con la entrada, los no-terminales con llamadas a procedimientos y las alternativas ´ a casos condicionales en funcion de lo que se est´ observando en la entrada. e Se asume que hay una variable global que almacena el componente l´ xico e actual (el s´mbolos de prean´ lisis), y en el caso en que se produce una ı a concordancia se avanza en la entrada, o en caso contrario se declara un error. Implementaci´ n de un analizador sint´ ctico recursivo Consta de: o a

¯ Un procedimiento, que llamaremos Parea/Match que recibe como entrada un terminal y comprueba si el s´mbolo de prean´ lisis coincide ı a con ese terminal. Si coinciden se avanza en la entrada, en caso contrario se declara un error sint´ ctico (lo que esperamos en la gram´ tica a a no coincide con la entrada).
Procedimiento Parea(terminal) inicio si preanalisis == terminal entonces preanalisis=siguiente token sino error sint´ctico a fin

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

87

¯ Un procedimiento para cada no-terminal con la siguiente estructura:

– Para las reglas de la forma «½ «¾ «Ò, decidir la producci´ n a utilizar en funci´ n de los conjuntos PRIMEROS(« ). o o
Procedimiento A() inicio seg´n preanalisis est´ en: u a PRIMEROS(«½ ): PRIMEROS(«¾ ): ... PRIMEROS(«Ò ): fin seg´n u si prean´lisis no pertenece a ning´n PRIMEROS(« ) a u entonces error sint´ctico, excepto si existe la a alternativa fin proceder seg´n alternativa «Ò u proceder seg´n alternativa «½ u proceder seg´n alternativa «¾ u

¯ en cuyo caso no se hace nada

– Para cada alternativa « del no-terminal, proceder analizando secuencialmente cada uno de los s´mbolos que aparece en la parte ı derecha terminales y no-terminales.
Si es un no-terminal haremos una llamada a su procedimiento ; Si es un terminal haremos una llamada al procedimiento Parea con ese terminal como par´metro. a

¯ Para lanzar el analizador sint´ ctico se hace una llamada al proceda imiento que corresponde con el s´mbolo de inicio en la gram´ tica, el ı a axioma. ¡ Cuidado, no olvidar hacer una llamada previa al analizador l´ xico para inicializar el s´mbolo de prean´ lisis (variable global) con e ı a el primer token del fichero de entrada!.

88

´ 4.4. ANALIZADOR SINTACTICO PREDICTIVO RECURSIVO

Implementar un analizador sint´ ctico predictivo recursivo para: Procedimiento a
E E’ T T’ F T E’ + T E’ - T E’ F T’ * F T’ / F T’ ( E ) num id
¯ ¯

Expresion()

Termino(); Expresion Prima();

Procedimiento Expresion Prima()

seg´n prean´lisis est´ en: u a a TKN MAS : Parea(TKN MAS); Termino(); Expresion Prima(); TKN MENOS : Parea(TKN MENOS); Termino(); Expresion Prima(); si no est´ en ninguno de los anteriores entonces no hacer nada a fin seg´n u

Procedimiento Termino()

Factor(); Termino Prima();

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

89

Procedimiento Termino Prima()

seg´n prean´lisis est´ en: u a a TKN POR : Parea(TKN POR); Factor(); Termino Prima(); TKN DIV : Parea(TKN DIV); Factor(); Termino Prima(); si no est´ en ninguno de los anteriores entonces no hacer nada a fin seg´n u

Procedimiento Factor()

seg´n prean´lisis est´ en: u a a TKN ABREPAR : Parea(TKN ABREPAR); Expresion(); Parea(TKN CIERRAPAR); TKN NUM : TKN ID : Parea(TKN NUM); Parea(TKN ID);

si no est´ en ninguno de los anteriores entonces error(); a fin seg´n u

Se introduce una producci´ n m´ s (se amplia la gram´ tica): o a a
Procedimiento S() Expresion(); Parea(TKN #);

90

´ 4.4. ANALIZADOR SINTACTICO PREDICTIVO RECURSIVO

Analizar la entrada num

* num #

´ y crear el arbol de an´ lisis sint´ ctico. a a

Ejemplo 2: Constuir un analizar predictivo recursivo para la siguiente gram´ tica que genera una declaraci´ n de tipos en Pascal a o
Tipo Simple id array [ Simple] of Tipo Simple integer char num puntopunto num

´ Construir el arbol para la entrada array [ num .. num ] of integer

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

91

´ 4.5 ANALIZADOR SINTACTICO PREDICTIVO DIRIGIDO POR TABLA Se puede construir un analizador sint´ ctico descendente predictivo noa recursivo sin llamadas recursivas a procedimientos, sino que se utiliza una pila auxiliar de s´mbolos terminales y no-terminales. Para determiı nar qu´ producci´ n debe aplicarse en cada momento se busca en una tabla e o de an´ lisis sint´ ctico (parsing table) en funci´ n del s´mbolo de prean´ lisis a a o ı a que se est´ observando en ese momento y del s´mbolo en la cima de la pila a ı se decide la acci´ n a realizar. o Esquema de un analizador sint´ ctico descendente dirigido por tabla a
Secuencia de tokens de entrada id Pila de anal. sintac. * id + num #

preanálisis

+ Analizador Sintáctico Z Y X # V U V N T Tabla de Análisis Sint.

Salida

¯ Buffer de entrada: que contiene la cadena de componentes l´ xicos e que se va a analizar seguida del s´mbolo de fin de cadena. ı ¯ La pila de an´ lisis sint´ ctico: que contiene una secuencia de s´mbolos a a ı de la gram´ tica con el s´mbolo en la parte de abajo que indica la a ı base de la pila.

92

´ 4.5. ANALIZADOR SINTACTICO PREDICTIVO DIRIGIDO POR TABLA

¯ Una tabla de an´ lisis sint´ ctico: que es una matriz bidimensional a a Å con ¾ ÎÆÌ y ¾ ÎÌ . La tabla de an´ lisis sint´ ctico a a ´ dirige el an´ lisis y es lo unico que cambia de una analizador a otro (de a una gram´ tica a otra). a ¯ Salida: la serie de producciones utilizadas en el an´ lisis de la secuena cia de entrada.
El analizador sint´ ctico tiene en cuenta en cada momento, el s´mbolo de a ı la cima de la pila y el s´mbolo en curso de la cadena de entrada (el ı s´mbolo de prean´ lisis). Estos dos s´mbolos determinan la acci´ n a reı a ı o alizar, que pueden ser:

¯ Si , el an´ lisis sint´ ctico ha llegado al final y la cadena a a ´ ha sido reconocida con exito. ¯ Si , el terminal se desapila (se ha reconocido ese terminal) y se avanza en la entrada obteniendo el siguiente componente l´ xico. e ¯ Si es no-terminal, entonces se consulta en la tabla Å . La tabla contiene una producci´ n a aplicar o si est´ vac´a significa un o a ı error. Si es una producci´ n de la forma o ½ ¾ Ò , entonces se meten los s´mbolos Ò ı ½ en la pila (notar el orden inverso). Si es un error el analizador llama a una rutina de error.

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

93

Algoritmo de an´ lisis sint´ ctico predictivo recursivo dirigido por tabla: a a
Entrada: Salida: una cadena Û, una tabla de anal. sint´ct. a y una gram´tica G a

o a Si Û ¾ Ä´ µ, la derivaci´n m´s a la izquierda de la cadena Û, sino

una indicaci´n de error o M´ todo: e Como configuraci´n inicial se tiene en el fondo de la pila el s´mbolo o ı el axioma Ë en la cima y la cadena Û en el buffer de entrada. ,

Iniciar prean´lisis con el primer s´mbolo de Û . a ı repetir Sea si el s´mbolo de la cima de la pila ı es un terminal o si entonces

ÔÖ Ò Ð × × entonces
extraer de la pila y obtener nuevo componente l´xico e

sino error(); sino si Å

ÔÖ Ò Ð × ×
extraer meter
Ò
¾ ½,

½ ¾

Ò entonces

de la pila con
½

en la cima de la pila

sino error(); hasta que (* la pila est´ vac´a y hemos procesado toda la entrada*) a ı

Cadena reconocida con ´xito e

El an´ lisis sint´ ctico dirigido por tabla es m´ s eficiente en cuanto a tiema a a po de ejecuci´ n y espacio, puesto que usa una pila para almacenar los o s´mbolos a reconocer en vez de llamadas a procedimientos recursivos. ı C´ mo construir la tabla de an´ lisis sint´ ctico o a a Entrada: una gram´ tica G a Salida: la tabla de an´ lisis sint´ ctico, con una fila para cada no-terminal, a a una columna para cada terminal y otra para . M´ todo: e

¯ Ampliar la gram´ tica con una producci´ n a o

˼

Ë

donde

Ë es el

94

´ 4.5. ANALIZADOR SINTACTICO PREDICTIVO DIRIGIDO POR TABLA

axioma.

¯ Para cada producci´ n de la gram´ tica o a

« hacer: – Para cada terminal ¾ ÈÊÁÅ ÊÇË ´«µ, « en la casilla M[A,a]. a˜ adir la producci´ n n o – Si ¯ ¾ ÈÊÁÅ ÊÇË ´«µ, « en la casilla Å ´ µ ¾ ËÁ ÍÁ ÆÌ Ë ´ a˜ adir n

µ.

¯ Las celdas de la tabla que hayan quedado vac´as se definen como ı error.
Pueden aparecer m´ s de una producci´ n en una misma casilla. Esto supona o dr´a que estamos en el caso no-determinista en el que tendr´amos que proı ı ´ bar una producci´ n y si esta produce un error, probar la otra... Ineficiente. o Las gram´ ticas LL(1) garantizan que s´ lo tenemos una producci´ n por a o o casilla. As´, el coste del an´ lisis es lineal con el n´ mero de componentes ı a u l´ xicos de la entrada. e Teorema: Una gram´ tica es LL(1) si y s´ lo si el algoritmo de a o construcci´ n de la tabla de an´ lisis sint´ ctico no genera ninguna o a a celda con m´ s de una producci´ n, es decir, si para todo par de a o tales que ¾ ÎÆ y ¾ ÎÌ , Å ´ µ ½. s´mbolos ı

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

95

Ejemplo: para la gram´ tica anterior a
E E’ T T’ F T E’ + T E’ - T E’ F T’ * F T’ / F T’ ( E ) num id
¯ ¯

+ E E’ T T’ F

¼

*
¼

/ err err err
̼ Ì

(
¼

) err
¯
¼

num
Ì
¼

id
Ì
¼

·Ì

err err
¯

 

err
Ì

err
¯

£

err err err
̼

err
¯

err
Ì

err
Ì
¼

err
Ì
¼

err
¯

err
¯

err

err

err

err

´ µ

err

err
ÒÙÑ

err

err

err

Insertar el calculo de la tabla. Insertar el contenido de la pila, la entrada y la producci´ n utilizada para o procesar la entrada num+num*num#.

´ ´ ´ 4.6 ANALISIS SINTACTICO Y ACCIONES SEMANTICAS Las acciones sem´ nticas insertadas en las producciones de la gram´ tica se a a pueden considerar como si fueran s´mbolos adiciones y que tienen asoı ciado un procedimiento a ejecutar (S´mbolos de acciones). Las llamadas ı a rutinas sem´ nticas no se les pasa param´ tros expl´citos, los par´ metros a e ı a necesarios se pueden transmitir a traves de una pila sem´ ntica. En los a analizadores descendentes recursivos, la pila de an´ lisis sint´ ctico est´ a a a “escondida” en la pila de llamadas recursivas a los procedimientos. La pila sem´ ntica tambi´ n se puede “esconder”, si hacemos que cada rutina a e sem´ ntica devuelva informaci´ n. a o El programa conductor (driver) para gestionar acciones sem´ nticas ser´a: a ı

96

´ ´ 4.7. RECUPERACION DE ERRORES SINTACTICOS

Entrada: Salida:

una cadena Û, una tabla de anal.

sint´ct. a

y una gram´tica G a

o a Si Û ¾ Ä´ µ, la derivaci´n m´s a la izquierda de la cadena Û, sino

una indicaci´n de error o M´ todo: e Como configuraci´n inicial se tiene en el fondo de la pila el s´mbolo o ı el axioma Ë en la cima y la cadena Û en el buffer de entrada. ,

Iniciar prean´lisis con el primer s´mbolo de Û . a ı repetir Sea si el s´mbolo de la cima de la pila ı es un terminal o si

ÔÖ Ò Ð × ×
extraer de la pila y obtener nuevo componente l´xico e

sino error(); sino si Å

ÔÖ Ò Ð × ×
extraer meter
Ò
¾ ½,

½ ¾

Ò

de la pila con
½

en la cima de la pila

sino si

es s´mbolo de acci´n ı o desapilar, llamar a rutina sem´ntica correspondiente a

sino error(); hasta que (* la pila est´ vac´a y hemos procesado toda la entrada*) a ı

Cadena reconocida con ´xito e

´ ´ 4.7 RECUPERACION DE ERRORES SINTACTICOS Funciones de un gestor de errores:

¯ Determinar si el programa es sint´ cticamente correcto (reconocedor). a ¯ Proporcionar un mensaje de error significativo.
parser error: line 10 column 4, found simbol expected simbol ;

¯ Reanudar el an´ lisis tan pronto como sea posible. Sino podemos a perder demasiada parte de la entrada.

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

97

¯ Evitar errores en cascada, un error genera una secuencia de sucesivos errores espurios. Para evitarlo se debe consumir (ignorar parte de la entrada). ¯ Realizar una correcci´ n (reparaci´ n) del error. El analizador inteno o ´ ta inferir un programa correcto de uno incorrecto. Correccion de m´nima distancia (el n´ mero de tokens que deben ser insertados, borı u rados o cambiados debe ser m´nimo). Extremadamente complicado ı “adivinar” la intenci´ n del programador. S´ lo util para situaciones o o ´ sencillas como: “falta ;”.
Los m´ todos de recuperaci´ n de errores suelen ser m´ todos “ad-hoc”, en el e o e sentido de que se aplican a lenguajes espec´ficos y a m´ todos concretos de ı e an´ lisis sint´ ctico (descendente, ascendente. etc), con muchas situaciones a a particulares. Para emitir un mensaje significativo de error se usa el conjunto de s´mbolos ı ´ de PREDICCION definidos para cada no-terminal como: «, Dada ´ µ ÈÊÁÅ ´ µ   ¯ ËÁ ´ µ si ¯ ¾ ÈÊÁÅ ´ µ entonces ÈÊ sino ÈÊ ´ µ ÈÊÁÅ ´ µ

98

´ ´ 4.7. RECUPERACION DE ERRORES SINTACTICOS

Recuperaci´ n en modo de p´ nico: se ignoran s´mbolos de la entrada hasta o a ı encontrar un componente l´ xico con el cual reanudar el an´ lisis. En el peor e a caso se podr´a haber consumido por completo el resto del fichero que queda ı por analizar (panic mode), en cuyo caso no ser´a mejor que simplemente ı hacer terminar con el an´ lisis al detectar el error. a Si se implementa con cuidado puede ser mejor que lo que su nombre implica (N. Wirth en su intento de mejorar su imagen le llam´ don’t panic o mode).

4.7.1 Recuperaci´ n de errores sint´ cticos en el m´ todo descendente o a e predictivo recursivo Implementaci´ n o A cada procedimiento se le proporciona un conjunto de tokens de sincronizaci´ n (cada no-terminal de la gram´ tica se le asocia un conjunto o a de sincronizaci´ n). Si se encuentra un error, el analizador avanza en la o entrada (consume tokens), ignorando tokens hasta que encuentra uno del conjunto de sincronizaci´ n, a partir del cual se continua con el an´ lisis. o a ¿Qu´ componentes l´ xicos nos van a servir para establecer una sine e cronizaci´ n? o

¯ El conjunto de SIGUIENTES. ¯ El conjunto de PRIMEROS, para prevenir el ignorar estructuras internas.
Insertar un ejemplo de por qu´ es importante poner los dos tipos de e conjuntos.

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

99

Una forma sencilla de implementar la recuperacion en modo de p´ nico es a al principio de cada procedimiento comprobar si el s´mbolo de prean´ lisis ı a pertenece al conjunto de SINC. Si no pertenece al conjunto de SINC, entonces ignoramos parte de la entrada hasta que encontremos un token que pertenezca al conjunto de SINC. Si el token actual pertenece al conjunto de PRIM entonces ejecutamos el contenido del procedimiento, puesto que hemos encontrado lo “primero” que el genera. Sino (es que pertenece al de SIG), salimos del procedimiento sin ejecutar su cuerpo, pues quiere decir que ya hemos encontrado lo que sigue a ese no-terminal y por tanto, no podemos pretender reconocerlo.
Procedimiento A(FIRSTSet, FOLLOWSet) while not (preanalisis ¾ (FIRSTSet FOLLOWSet #) )

error, saltamos simbolo en la entrada; scanTo (FIRSTSet FOLLOWSet);

if (preanalisis ¾ FISRTSet) ejecutar cuerpo procedimiento else salir

100

´ ´ 4.7. RECUPERACION DE ERRORES SINTACTICOS

4.7.2 Recuperaci´ n de errores sint´ cticos en el m´ todo dirigido por o a e tabla Para cada no-terminal se marcan las casillas correspondientes a los s´mbolos ı de sincronizaci´ n con la palabra × Ò , siempre que no exista una produco ci´ n. o Implementaci´ n: o est´ en blanco, es decir ¾ ËÁÆ ´ µ, a Si al buscar en la tabla Å ´ avanzamos en la entrada hasta encontrar un terminal de sincronizacion. Si ¾ ËÁ ´ µ se saca el no-terminal A de la pila (desistimos de reconoo cerlo). Si ¾ ÈÊÁÅ ´ µ no se saca y se aplica la producci´ n correspondiente. La primera situaci´ n corresponde al caso en que se han omitido s´mbolos o ı y no podemos reconocer lo que genera el no-terminal y el segundo caso corresponde a que hay un exceso de s´mbolos que hay que ignorar en la ı entrada. Insertar el procesado de la entrada ´ÒÙÑ · £ÒÙѵ anterior. para la gram´ tica a

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

101

4.8 EJERCICIOS 1 (0.2 ptos) Demuestra que la gram´ tica siguiente no es LL(1). a

¯
´ Construye el pseudocodigo correspondiente para un analizador descendente recursivo como si lo fuera y comenta el problema que se encuentra. 2 (0.2 ptos) Demuestra que la gram´ tica siguiente es LL(1). a
´ µ

¯

´ Construye el pseudocodigo correspondiente para un analizador descendente y analiza la entrada ´´µµ. 3 (0.2 ptos) Dada la siguiente gram´ tica: a
Stmt Assign stmt Call stmt other Assign stmt id := Exp Call stmt id ( Exp )

Escribe el pseudoc´ digo para analizar de forma descendente recursiva o esta gram´ tica. Muestra la traza para una entrada concreta. a 4 (0.25 ptos) Dada la siguiente gram´ tica: a
Lexp Atom List Atom num id List ( Lexp seq ) Lexp seq Lexp , Lexp seq Lexp

¯ Factoriza la gram´ tica. a ¯ Construye el conjunto de PRIMEROS y SIGUIENTES para los no-terminales de la gram´ tica resultante. a ¯ Muestra que la gram´ tica generada es LL(1). a

102

4.8. EJERCICIOS

¯ Construye la tabla de an´ lisis sint´ ctico. a a ¯ Muestra el contenido de la pila, de la entrada y las producciones aplicadas para la entrada (a, (b, (2)), (c))
5 (0.2 ptos) Considera el siguiente fragmento de gram´ tica que permite a generar identificadores como etiquetas:
Stnt Label Unlabeled stmt Label id : Label ¯ Unlabeled stmt id := Expresion

¿Es LL(1)? Si no, transformala para que lo sea. Implementa un analizador descendente recursivo y dibuja la traza de llamadas recursivas a procedimientos para reconocer la cadena de entrada: etiqueta1 : a:= 3 + 4; 6 (0.25 ptos) Dada la siguiente gram´ tica de una simplificaci´ n de las a o declaraciones en C:
Declaration Type Var list int float Type Var list identifier , Var list identifier

¯ Factoriza la gram´ tica. a ¯ Construye el conjunto de PRIMEROS y SIGUIENTES para los no-terminales de la gram´ tica resultante. a ¯ Muestra que la gram´ tica resultante es LL(1). a ¯ Construye la tabla de an´ lisis sint´ ctico. a a ¯ Muestra el contenido de la pila, de la entrada y las producciones elegidas para la entrada int x,y,z

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

103

¯ Calcula el conjunto de s´mbolos de sincronizaci´ n y aplica el ı o m´ todo de recuperaci´ n en modo de p´ nico para la entrada int x e o a y, z emitiendo un mensaje de error significativo (calcula el con´ junto de PREDICCION).

104

4.8. EJERCICIOS

7 (0.2 ptos) Dada la siguiente gram´ tica que genera una lista de sentena cias donde pueden aparecer asignaciones, sentencias condicionales y bloques de sentencias:
L S C S L;S id := C if ( C ) then S begin L end id = id id id id and id

¯ Demuestra que no es LL(1). ¯ Hallar una gram´ tica LL(1) equivalente y construye la tabla de a an´ lisis sint´ ctico. a a ¯ Muestra el contenido de la pila, de la entrada y las producciones aplicadas para la entrada if (id=id) then id:= id and id
Ideas:

¯ Parsons Mostrar la idea de como se puede evitar el tener que hacer backtracking si dotamos al analizador la posibilidad de mirar un simbolo de look-ahead en la entrada para anticoparse ne la determinaci´ n de que terminales son derivables a partir de un cierto s´mbolo. o ı Mostrar ejemplo pagina 96, para indicar lo que significa el conjunto de PRIMEROS. ¯ Los analizadores que usan el conjunto de PRIMEROS se les conoce como Analizadores Predictivos. ¯ Mostrar el problema de que cuando existen producciones ¯, el conjunto de PRIMEROS no es suficiente para determinar la producci´ n o ¯. a utilizar. No nos dice cuando tenemos que usar ¯ Insertar dibujo pag 99, en donde se refleja por que el conjunto de SIG de un simbolo tiene que incluir al conjunto de SIG del otro. ¯ Indicar que para el calculo de SIG una regla consigo misma no debe ser considerada.

´ ´ TEMA 4. ANALISIS SINTACTICO DESCENDENTE

105

¯ Sobre las condiciones para LL(1): si se viola la primera no sabremos que alternativa coger para un mismo s´mbolo. Si se viola la segunda, ı enonces abria algun token en la intersecci´ n seg´ n el cual no podrio u amos saber si coger la alternativa correspondiente o serivar en ¯. ¯ Una forma no-recursiva del analizador predictivo consiste en un programa simple de control que lee de una tabla. Las ventajas es que el procedimiento de control es general, y si se cambia la gramatica solo se reescribe la tabla.

Sign up to vote on this title
UsefulNot useful