Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Analisis Sintactico
Analisis Sintactico
de gramticas 4) Eliminacin de la recursividad a izda. 5) Construccin de Analizadores Sintcticos predictivos 6) Construccin de Analizadores Sintcticos predictivos no recursivos 7) Construccin de una tabla para el anlisis sintctico predictivo 8) Sobre recuperacin de errores en el anlisis sintctico predictivo
-J.Ezpeleta-
Estrategias para analizadores sintcticos El analizador sintctico debe verificar si la entrada corresponde a alguna derivacin de S Primera aproximacin: a lo bestia
generar todas las derivaciones de S posibles comprobar si la entrada corresponde con alguna de ellas
Inviable, incluso para gramticas muy sencillas Son necesarias estrategias ms astutas Las estrategias son de dos categoras:
anlisis DESCENDENTE (Top-Down) construye el rbol desde la raz (S) hasta llegar a las hojas anlisis ASCENDENTE (Bottom-Up) construye el rbol desde las hojas hacia la raz (S)
2
-J.Ezpeleta-
Estrategias para analizadores sintcticos A distintos tipos de analizadores se les da nombres en funcin a varios elementos:
lectura de tokens (izda. a dcha., viceversa) mtodo de derivacin (izda. o dcha.) nmero de tokens de pre-anlisis (look-ahead)
Las ms comunes:
lectura de tokens left to right
LL(k) LL(k)
derivacin por izda. k tokens de lookahead
LR(k) LR(k)
lectura de tokens left to right
Compiladores I. C.P.S. Universidad de Zaragoza
k tokens de lookahead
-J.Ezpeleta-
-J.Ezpeleta-
Anlisis descendente Bsicamente, es un intento de encontrar una derivacin por la izda. Desde el punto de vista del rbol de sintaxis, correspondera a un recorrido en pre-orden Mtodo:
Objetivo: reconocer S Mtodo: se divide el objetivo en subobjetivos (de acuerdo a las producciones) se trata de cumplir cada subobjetivo se sigue con cada subobjetivo, hasta que se encuentren concordancias de terminales (o se detecte un error)
-J.Ezpeleta-
cad
S cAd A ab|a
S
c a d
c a
A b S
c a d
c a
A b S
c a d
d
c S
c a d
A a
c a d
A a
-J.Ezpeleta-
hacer avanzar al siguiente token afinando un poco ms: no terminal: genera invocaciones terminal: concordancia entre terminales
error sintctico avanzar a token siguiente
-J.Ezpeleta-
S cAd A a
void S(){ terminal((int)c); A(); terminal((int)d); } void main(){ elToken=yylex(); S(); }
Qu pasa con S S A A
cAd cAd a|ab a|ab
?
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta-
S cAd A a|ab
void S(){ terminal((int)c); A(); terminal((int)d); } void main(){ elToken=yylex(); S(); }
preanlisis
-J.Ezpeleta-
Anlisis descendente. Un ejemplo Ejemplo: Se desea construir un analizador sintctico para la siguiente gramtica instruccion identificador opas expr ; expr termino expr expr + termino expr | termino identificador | ( expr ) donde:
opas es un terminal de la gramtica que representa al operador de asignacin. Corresponde al lexema := identificador (letra seguido de letras o dgitos)
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta10
Anlisis descendente. Un ejemplo Como paso previo, necesitamos construir el analizador lxico Esquema del proceso:
lexDescen.l flex lex.yy.c gcc lex.yy.o gcc elAnalizador
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta11
tokens.h
sinDescen.c
sinDescen.o
-ll
tokens.h lexDescen.l
12
Anlisis descendente. Un ejemplo Para el analizador sintctico, construi remos un analizador sintctico descendente recursivo Ideas bsicas del mtodo:
construir un conjunto de procedimientos (recursivos si necesario) uno por cada no terminal de la gramtica cada procedimiento: determina la produccin a aplicar invoca los proc. correspondientes detecta error o pasa al siguiente token la secuencia de invocaciones a los procedimientos define implcitamente el rbol de sintaxis
En este ejemplo funciona bien por las razones que veremos, pero no siempre es tan sencillo
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta13
sinDescen.c void termino(){ if(elToken==IDENTIFICADOR) termino identificador terminal(IDENTIFICADOR); | ( expresion ) else if(elToken=='('){ terminal((int) (); expresion(); terminal((int) )); }else hayError("Se esperaba un IDENTIFICADOR o '('"); }
-J.Ezpeleta-
15
sinDescen.c
-J.Ezpeleta-
16
recursividad a izda.: si alguna regla se define con recursividad a izda., el analizador sintctico construdo entra en un bucle infinito Ejemplo: expr expr + term | termino
Soluciones:
factorizacin a izda. eliminacin de recursividad a izda.
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta17
Anlisis descendente. Factorizacin a izda. Consideremos la gramtica A C | B Si encontramos una cadena derivada de , Qu produccin aplicar? Si sigo C y era B ? Si sigo B y era C ? Idea: retrasar la decisin, de manera que siempre se tome la buena decisin A A A C | B Ambas gramticas generan el mismo lenguaje
-J.Ezpeleta-
18
Anlisis descendente. Eliminacin rec. izda. En analizadores descendentes, la recursividad a izda. da lugar a bucles infinitos Ejemplo:
instruccion identificador opas expr ; expr expr + termino
| termino | ( expr )
termino identificador
la invocacin expresion() se hace recursivamente sin consumir nuevos tokens, dando un bucle infinito
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta19
Anlisis descendente. Recursividad a izda. Por suerte, la rec. directa a izda. se puede eliminar mediante una transformacin de la gramtica A A |
A A |
-J.Ezpeleta-
20
Anlisis descendente. Recursividad a izda. Aplicando la transformacin a la gramtica anterior, obtenemos instruccion identificador opas expr ; expr termino expr expr + termino expr | termino identificador | ( expr ) Sin embargo, slo eliminamos la rec. izda. directa Qu pasa con A B | B AB | ?
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta21
Anlisis descendente. Recursividad a izda. El siguiente algoritmo resuelve el problema [AhSU 90]
Algoritmo
--Pre: G=(N,T,P,S) sin ciclos (A + A) ni -producciones (A ) N={A1,...,An} --Post: G G, sin rec. a izda.
Para tratamiento de ciclos y Principio G:=G producciones , ver [HoUl 79] Para i:=1 hasta n Para j:=1 hasta i-1 --Aj 1|...|k son las -producciones actuales de Aj sustituir en P Ai Aj por Ai 1|...|k FPara eliminar rec. inmediata de Ai FPara Fin
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta22
Anlisis descendente
Sep 97/98
Ejercicio 4 (1.5 ptos.): Considerar el siguiente cdigo C que corresponde a un analizador sintctico descendente recursivo. Determinar, a partir del propio cdigo, cul es la gramtica, y decir si el analizador funcionar correctamente.
enum token extern enum token getToken(void); enum token tok; void advance(){ void eat(enum token t){ tok=getToken(); if(tok==t) } advance(); else error(); }
-J.Ezpeleta-
23
24
Analizadores sintcticos predictivos Un analizador sintctico predictivo es un analizador sintctico descendente recursivo que NO necesita marcha atrs Condicin exigible a una gramtica para que sea posible:
que en todo momento, a partir del siguiente token de entrada, sea posible determinar qu regla aplicar
-J.Ezpeleta-
25
Analizadores sintcticos predictivos no rec. El hecho de que haya reglas recursivas hace que el analiziador predictivo implementado directamente sea recursivo Sin embargo, la recursividad se puede evitar mediante el uso explcito de una pila Un analizador predictivo sabe, a partir del smbolo que est analizando y el siguiente smbolo de entrada, qu regla aplicar Por lo tanto, se puede hacer corresponder a una tabla de doble entrada: (token de la forma de frase,sig. token)
Analizadores sintcticos predictivos no rec. Esta forma de implementacin da lugar anal. sintcticos dirigidos por tabla Esquema general:
entrada
salida
..b c b a..
S X X Z Y k
( S S(A) A ACB B C CS
x ACB
B;A
Cx
-J.Ezpeleta-
30
pila
entrada (x;(x))$ (x;(x))$ x;(x))$ x;(x))$ x;(x))$ ;(x))$ ;(x))$ (x))$ (x))$ (x))$ (x))$ x))$ x))$ x))$ ))$ ))$ )$ )$ $
$)B $)A; $)A $)BC $)BS $)B)A( $)B)A $)B)BC $)B)Bx $)B)B $)B) $)B $) $
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta-
Construccin de una tabla para el anlisis Lo fundamental para la construccin de un analizador sintctico predictivo no rec. construccin de la tabla Idea bsica: uso de las funciones primero y siguiente Objetivo: utilizar dichas funciones para construir la tabla de anlisis predictivo Es ms: una gramtica es LL(1) ssi la tabla construda tiene una nica salida para cada entrada
-J.Ezpeleta-
32
Construccin de una tabla para el anlisis Sea G=(N,T,S,P)una gramtica Sea una cadena de smbolos de la gramtica: (N T)* PRI(): terminales que pueden comenzar una forma de frase derivable de PRI()={aT| * a} (Si * entonces {} si no
) Importante: para (empezar a) reconocer , el siguiente token a procesar deber estar en PRI()
-J.Ezpeleta-
33
PRI(X1) PRI(X1)
aadir a PRI(X1...Xn) los smbolos de PRI(X2) \{} PRI(X2) aadir a PRI(X1...Xn) los smbolos de PRI(X3) \{} PRI(X2) PRI(X3) aadir a PRI(X1...Xn) los smbolos de PRI(X4) \{} .... PRI(Xn) PRI(X1...Xn)
..... Si
-J.Ezpeleta-
34
S a S e | B B b B e | C C c C e | d
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta-
Construccin de una tabla para el anlisis Sea G=(N,T,S,P) una gramtica Sea A un no terminal (A N) SIG(A) ser el conjunto de todos aquellos terminales que pueden aparecer detrs de A en alguna forma de frase SIG(A)={aT| S + ...Aa...} (Si S + A entonces {$} si no ) Importante: SIG(A)=conjunto de terminales que pueden indicar (fin del) reconocimiento de una regla que tenga A en la parte izda.
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta37
-J.Ezpeleta-
38
S a S e | B B b B e | C C c C e | d
-J.Ezpeleta-
39
-J.Ezpeleta-
40
FPara Para cada (n,t)Nx(T{$}) Si M[n,t]= ent M[n,t]=ERROR FSi FPara Fin
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta41
a
( ( * ) ( * ) ) Si * , no deriva ninguna cadena que comience con un elemento de TSIG(A)
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta42
Si la gramtica no es LL(1)?
intentar transformarla en LL(1) no siempre es posible aunque aparecen con mucha frecuencia
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta-
Tambin existen gramticas LL(k) que emplean una generalizacin de las tcnicas presentadas
43
Situacin de error:
pila
A . . . $
... b ...
entrada
T(A,b)=error
Reparacin:
supongamos una entrada en el estado t, donde es lo ya analizado y t el siguiente token tres actuaciones posibles: modificar insertar un esperando que t sea del lenguaje eliminar t esperando que sea del lenguaje
-J.Ezpeleta-
45
insts ; inst inst instMQ | instAS | ... tkID tkOPAS exp tkMQ exp insts
Se esperaba ;
por lo que seguimos hasta encontrarlo. Sin embargo ....
-J.Ezpeleta-
46
Sobre recuperacin/reparacin de errores No hay un mtodo universal, por lo que se aplican ciertas reglas heursticas Para cada no terminal, definamos sinc(A) Veamos algunos elementos a aadir en sinc(A)
aadir SIG(A) a sinc(A) usar la jerarqua del lenguaje aadir el conjunto de sinc de un nivel a los inferiores
-J.Ezpeleta-
inst insts
inst insts | instMQ | instAS | ... tkID tkOPAS exp ; tkMQ ( exp ) insts ...
-J.Ezpeleta-
48
, cima(p)=A, disparar A *
Es una insercin virtual
-J.Ezpeleta-
49
lint
line line line line line line line line 6: 7: 8: 5: 5: 5: 1: 1:
-J.Ezpeleta-
52
NAME lint - a C program checker/verifier SYNOPSIS lint [options] file ... DESCRIPTION lint attempts to detect features in C program files that are likely to be bugs, non-portable, or wasteful. It also checks type usage more strictly than the compilers. Program anomalies currently detected include unreachable statements, loops not entered at the top, automatic variables declared but not used, and logical expressions whose value is constant. Usage of functions is checked to find functions that return values in some places and not in others, functions called with varying numbers or types of arguments, and functions whose values are not used or whose values are used but none returned.
-J.Ezpeleta-
53
Ejercicios
Ejercicio 1: Considrese la siguiente gramtica:
S [ S | S1 S1 [a]
Jun. 96
1.1) (1 pto.) Establecer el lenguaje que genera. Es necesario que se justifique, lo ms formalmente posible, la respuesta 1.2) ..... 1.3) (1 pto.) Se trata de una gramtica LL(1)? 1.4) (0.5 ptos.) Si no es SLR(1), dar una gramtica equivalente que s lo sea. Anlogamente, si no es LL(1) dar una gramtica equivalente que s lo sea..
-J.Ezpeleta-
54
Ejercicios
Ejercicio 2 (5 ptos. ) : Considrese la siguiente gramtica (en negrita los terminales):
S S L L ( L ) a L , S S
Feb. 96
2.1 (0.5 ptos.) Qu lenguaje genera? 2.2 ..... 2.3 (2 ptos.) Evidentemente, se trata de una gramtica no LL(1). Transformarla en una equivalente que s lo sea, y contruir la tabla del anlisis sintctico LL(1)
-J.Ezpeleta-
55
Ejercicios
Ejercicio 3 (5.5 ptos. Sep. 98): Considrese la siguiente gramtica:
G: S uBDz B Bv Bw D EF Ey E Fx F
Sep. 98
1) Construir las tablas del anlisis sintctico SLR, y determinar si se trata de una gramtica SLR o no 2) Comprobar que se trata de una gramtica no LL(1). Transformarla en una gramtica LL(1), y calcular su tabla de anlisis LL(1)
-J.Ezpeleta-
56
Ejercicios
Ejercicio 3 (3.0 ptos.): Considerar la siguiente gramtica (en negrita los terminales): S P M P E | q M n E E , O | E O u | u,O
Feb. 98
Probar que se trata de una gramtica NO LL(1). Si es posible, realizar las transformaciones precisas para convertirla en LL(1) y, construyendo la tabla del anlisis LL(1), demostrar que la gramtica transformada es efectivamente de esta clase. Es necesario justificar las transformaciones que se realicen. Si no fuera posible transformarla en LL(1), explicar la razn
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta57
Ejercicios
Ejercicio 2 (1.5 ptos.): Dada una secuencia determinales el algoritmo de anlisis LL(1) emite la secuencia de producciones aplicadas para su derivacin, o error si no es capaz de encontrarla. Vamos a denotar n el nmero de no terminales de la gramtica, y || la longitud de la secuencia de entrada. Se sabe que, en el caso de que el algoritmo d respuesta afirmativa, el coste de ejecucin del algoritmo es (||), (n||). En el clculo de este coste se han considerado como operaciones de coste constante las siguientes:
obtener la cima de la pila apilar y desapilar smbolos gramaticales obtener el siguiente terminal de la sencuencia de entrada consultar el valor en la tabla correspondiente a un par (no terminal, terminal) emitir una produccin
-J.Ezpeleta-
58
Ejercicios
Consideremos ahora la siguiente gramtica:
X1 X2 X3 X4 .... Xn-1 Xn --> --> --> --> X2 a2 a3 a4 X2 X2 | X3 | X4 | X5
El ejercicio pide escribir dos frases del lenguaje generado por la gramtica anterior, w1 y w2, tal que los costes de ejecucin del algoritmo de reconocimiento sean, respectivamente, del orden de |w1| y n|w2|. Cul puede ser el coste del algoritmo, en el mejor y el peor caso, cuando se aplica a una frase que no es reconocida por el anlisis LL(1)? Nota: en todos los casos la respuesta debe ser razonada.
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta59
[ identif. de variable
variable
expresin ,
identificador de campo
. ^
identif. de campo
expresin
-J.Ezpeleta-
60
+ trmino trmino + OR
trmino
-J.Ezpeleta-
61
NOT
factor
expresin ,
..
expresin
-J.Ezpeleta-
62
-J.Ezpeleta-
63
-J.Ezpeleta-
65
[...]: 0 1 {...}: 0 ms
relation ::= simple_expression [relational_operator simple_expression] | simple_expression [not] in range | simple_expression [not] in subtype_mark simple_expression ::= [unary_adding_operator] term {binary_adding_operator term} term ::= factor {multiplying_operator factor} factor ::= primary [** primary] | abs primary | not primary
-J.Ezpeleta-
66
[...]: 0 1 {...}: 0 ms
67