You are on page 1of 67

Leccin 4: Anlisis Sintctico LL(1) 1) Estrategias para el Anlisis Sintctico 2) Anlisis Sintctico descendente 3) Factorizacin a izda.

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

Compiladores I. C.P.S. Universidad de Zaragoza

-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

Compiladores I. C.P.S. Universidad de Zaragoza

-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

derivacin por dcha.

k tokens de lookahead

-J.Ezpeleta-

Estrategias para analizadores sintcticos Propiedades deseables en un analizador sintctico


eficiente en general, se buscarn polinomiales en el tamao del programa a reconocer determinar la accin reconociendo unos pocos tokens de entrada como mximo, un k preestablecido en la prctica, suele ser k=1 no necesitar marcha atrs (backtracking) i.e., evitar decisiones las acciones semnticas son difciles de deshacer no ocupar mucha memoria actualmente, esto no es tan importante

Compiladores I. C.P.S. Universidad de Zaragoza

-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)

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

Anlisis descendente Ejemplo: c a d


c A d S S S

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

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

Anlisis descendente Sobre implementacin de analizadores descendentes


la forma ms natural es asociar un procedimiento con cada no terminal cada procedimiento: comprueba la correccin del token en estudio con el que el propio procedimiento representa
incorrecto: mensaje de error y/o estrategia de recuperacin

hacer avanzar al siguiente token afinando un poco ms: no terminal: genera invocaciones terminal: concordancia entre terminales
error sintctico avanzar a token siguiente

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

Anlisis descendente Un ejemplo muy sencillo


int elToken; int yylex(){ return(getchar()); } void terminal(int t){ if(elToken==t) elToken=yylex(); else errorSintactico(); } void A(){ terminal((int)a); }

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-

Anlisis descendente Una solucin predictiva


int elToken; int yylex(){ return(getchar()); } void terminal(int t){ if(elToken==t) elToken=yylex(); else errorSintactico(); } void A(){ terminal((int)a); if(elToken==(int)b) terminal((int)b); }

S cAd A a|ab
void S(){ terminal((int)c); A(); terminal((int)d); } void main(){ elToken=yylex(); S(); }

preanlisis

Compiladores I. C.P.S. Universidad de Zaragoza

-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

Anlisis descendente. Un ejemplo


enum{ASIGNACION=257,IDENTIFICADOR}; %{ #include <stdio.h> #include "tokens.h" extern char yytext[]; /* extern char *yytext*/ %} /*EXPRESIONES REGULARES*/ separador [\t \n]+ /*tabs,blancos*/ letra [a-zA-Z] digito [0-9] identificador {letra}({letra}|{digito})* %% {separador} {/*me los como*/} ":=" {return(ASIGNACION);} {identificador} {return(IDENTIFICADOR);} . {return(yytext[0]);} %% /* no hay funciones de usuario */
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta-

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

Anlisis descendente. Un ejemplo


#include <stdio.h> sinDescen.c #include "tokens.h" int elToken; /*global con sig. token*/ void terminal(int token{ if(elToken==token) elToken=yylex(); else hayError(...INFO(elToken) inesperado...); } void instruccion(){ instruccion terminal(IDENTIFICADOR); identificador terminal(ASIGNACION); opas expresion ; expresion(); terminal((int) ;); } void main(){ elToken=yylex(); instruccion(); }
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta14

Anlisis descendente. Un ejemplo

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 '('"); }

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

15

Anlisis descendente. Un ejemplo


expresion void expresion(){ termino(); expresionP(); } void expresionP(){ if(elToken=='+'){ terminal((int) +); termino();expresionP(); } /*else: corresponde a */ }
termino expresionP

sinDescen.c

expresionP + termino expresionP


|

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

16

Anlisis descendente En general, el mtodo puede presentar incovenientes:


necesidad de backtracking: cuando la regla elegida no es la correcta devolver a la entrada todos los tokens recorridos Ejemplo: instIF
tkIF expr tkTHEN insts | tkIF expr tkTHEN insts tkELSE insts

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

Compiladores I. C.P.S. Universidad de Zaragoza

-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

Cuando se trata de derivar


velocidad:=(vel1+vel2)+vel3;

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 |

Ambas gramticas son equivalentes

Compiladores I. C.P.S. Universidad de Zaragoza

-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.

eliminaRecIzda(E G:GLC; S G:GLC)

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(); }

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

23

Anlisis descendente. Recursividad a izda.


void S(){ switch(tok){ case IF: eat(IF);E();eat(THEN); S(); eat(ELSE);S();break; case BEGIN: eat(BEGIN);S();L();break; case PRINT: eat(PRINT);E();break; default: error(); } } void L(){ switch(tok){ case END: eat(END); break; case SEMI: eat(SEMI);S();L();break; default: error(); } } void E(){ eat(NUM); eat(EQ); eat(NUM); } Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta-

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

Esto es posible cuando (una de dos):


ningn no terminal tiene alternativas en su parte derecha gramticas poco interesantes no terminales con alternativas que empiecen por distintos smbolos

Aunque hay ms casos en que tambin es posible

Compiladores I. C.P.S. Universidad de Zaragoza

-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)

(no terminal,sig. token)


Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta26

Analizadores sintcticos predictivos no rec. Esta forma de implementacin da lugar anal. sintcticos dirigidos por tabla Esquema general:
entrada

Z Y k analizador analizador sintctico sintctico

pila de smbolos (a reconocer)

salida

..b c b a..

S X X Z Y k

tabla de anlisis M[Z,a]


Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta27

Analizadores sintcticos predictivos no rec. Esquema de funcionamiento:


Pre: M:Nx(T{$})2P:tabla de anl. sint. la sec. de tokens termina con $ Post: sec. de prod. aplicadas o error Variables p:pila de smbolos gramaticales;sigTok,X:token Principio pilaVacia(p);sigTok=yylex();push(p,$,S) Repetir X=cima(p) Si X es terminal X=$ entonces Si X=sigTok entonces pop(p); sigTok=yylex() Si no errorSintctico() FSi Si no .... Hasta Que X=$
Fin
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta28

Analizadores sintcticos predictivos no rec.


Pre: M:Nx(T{$})2P:tabla de anl. sint. la sec. de tokens termina con $ Post: sec. de prod. aplicadas o error Variables p:pila de smbolos gramaticales;sigTok,X:token Principio Repetir ... Si no Si M[X,sigTok]= XY1... Yk entonces pop(p) push(p,YkYk-1... Y1) emitir produccin XY1... Yk Si no errorSintctico() FSi FSi Hasta Que X=$ Fin
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta29

Analizadores sintcticos predictivos no rec. Ejemplo: reconocer (x;(x)) para S A B C


( A ) CB ; A | x | S

( S S(A) A ACB B C CS

x ACB

B;A

Cx

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

30

pila

entrada (x;(x))$ (x;(x))$ x;(x))$ x;(x))$ x;(x))$ ;(x))$ ;(x))$ (x))$ (x))$ (x))$ (x))$ x))$ x))$ x))$ ))$ ))$ )$ )$ $

Analizadores sintcticos predictivos no rec.

produccin usada (salida) S(A) ACB Cx B;A ACB C S S(A) ACB C x B B


31

$S $)A( $)A $)BC $)Bx

$)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

Compiladores I. C.P.S. Universidad de Zaragoza

-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()

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

33

Construccin de una tabla para el anlisis


Paso 1: Calcular los conjuntos PRI(X) para cualquier smbolo gramatical XNT Paso 2: Sea X1...Xn (N T)*
Si Si Si Aadir a PRI(X1...Xn ) los smbolos de PRI(X1)\{}

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)

PRI(X1) PRI(X1) aadir a

..... Si

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

34

Construccin de una tabla para el anlisis Paso 1: aplicar el siguiente algoritmo


--Pre: X NT --Post: calcula PRI(X) Repetir Si XT aadir X a PRI(X) FSi Si X es una produccin aadir a PRI(X) FSi Si X Y1...Yk es una produccin Si aPRI(Yj) PRI(Y1)... PRI(Yj-1) aadir a a PRI(X) FSi Si PRI(Y1)... PRI(Yk) aadir a PRI(X) FSi FSi Hasta Que no se aada nada a ningn PRI
-J.Ezpeleta35

Compiladores I. C.P.S. Universidad de Zaragoza

Construccin de una tabla para el anlisis Ejemplos: S A B c A a | B b |


PRI(S)={a,b,c} PRI(A)={a,} PRI(B)={b,} PRI(a)={a} PRI(b)={b} PRI(c)={c} PRI(AB)={a,b,}

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-

PRI(S)={a,b,c,d} PRI(B)={b,c,d} PRI(C)={c,d} PRI(a)={a} PRI(b)={b} ....


36

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

Construccin de una tabla para el anlisis Construccin de los conjuntos SIG


--Pre: TRUE --Post: calcula SIG(A) para todo A N aadir $ a SIG(S) Repetir Si A B es una produccin aadir PRI()\{} a SIG(B) FSi Si A B es una produccin (A B con PRI() es produccin) aadir SIG(A) a SIG(B) FSi Hasta Que no se aada nada a ningn SIG

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

38

Construccin de una tabla para el anlisis Ejemplos: S A B c A a | B b |

SIG(S)={$} SIG(A)={b,c} SIG(B)={c}

S a S e | B B b B e | C C c C e | d

SIG(S)={e,$} SIG(B)={e,$} SIG(C)={e,$}

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

39

Construccin de una tabla para el anlisis Construccin de la tabla:


filas indexadas por no terminales columnas indexadas por terminales ( {$})

Ideas a seguir para la produccin A


Si aPRI(), cuando entra a se expande A por Si = * expandir A por cuando llegue algo de SIG(A)

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

40

Construccin de una tabla para el anlisis


Pre: Una gramtica G=(N,T,S,P) Post: M: tabla de anl. desc.
Principio Para cada (n,t)Nx(T{$}) M[n,t]:= /*Conjunto?*/ FPara Para cada produccin X Para cada aPRI() M[X,a]:= M[X,a]{X } FPara Si PRI() entonces Para cada bTSIG(X) M[X,b]:= M[X,b]{X } FPara Si $SIG(X) entonces M[X, $]:= M[X, $]{X } FSi FSi

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

Construccin de una tabla para el anlisis


Una gramtica es LL(1) cuando en la gramtica LL(1) tabla construda segn el mtodo anterior cada elemento es una de las dos cosas siguientes: *ERROR *un conjunto con una nica produccin

Aternativamente, G es LL(1) ssi para toda produccin

y no pueden derivar cadenas que comiencen por un mismo terminal

a
( ( * ) ( * ) ) Si * , no deriva ninguna cadena que comience con un elemento de TSIG(A)
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta42

Construccin de una tabla para el anlisis Notar las ventajas de LL(1):


por cada token de entrada, sabemos exactamente qu produccin se debe aplicar no hay backtracking asegura un anal. descendente correcto no son ambguas funcin de long. complejidad de los anal. LL(1) : de la cadena de tokens lineal en tiempo lineal en espacio

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

Sobre recuperacin/reparacin de errores Cul es el objetivo de la recuperacin de errores?


no abortar la compilacin informar de las decisiones tomadas

Situacin de error:

pila

A . . . $

... b ...
entrada

T(A,b)=error

Cmo recuperarse de la situacin?


recuperacin: eliminar smbolos de la entrada o de la pila hasta llegar a un estado que pueda seguir reparacin: reparar la entrada del usuario
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta44

Sobre recuperacin/reparacin de errores Recuperacin


modo pnico: eliminar smbolos de la entrada hasta encontrar alguno especfico del conjunto de sincronizacin

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

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

45

Sobre recuperacin/reparacin de errores


... x := 27 z ; y := 29 ; ...
insts insts inst instAS instMQ ...

insts ; inst inst instMQ | instAS | ... tkID tkOPAS exp tkMQ exp insts

al encontrar z podemos tratar de arreglarlo como:


Se esperaba ;
por lo que lo insertamos. Sin embargo ....

Se esperaba ;
por lo que seguimos hasta encontrarlo. Sin embargo ....

Compiladores I. C.P.S. Universidad de Zaragoza

-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

bloque instruccin expresin trmino factor ....


47

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

Sobre recuperacin/reparacin de errores Ejemplo:


insts x = 3 While (x > y) { .... }

inst insts

insts inst instAS instMQ

inst insts | instMQ | instAS | ... tkID tkOPAS exp ; tkMQ ( exp ) insts ...

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

48

Sobre recuperacin/reparacin de errores


para AN, aadir PRI(A) a sinc(A) Seguir anlisis por A cuando llegue uno de ellos si A *

, cima(p)=A, disparar A *
Es una insercin virtual

si cima(p)=x y x<>sigToken (x es terminal) eliminar x de la pila dar mensaje x ha sido insertado

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

49

Sobre recuperacin/reparacin de errores


procedure pruebaErrores1 is x: integer; gnatmake y: integer := 1; begin 5:15: missing ";" x := 3 9:13: missing operand while x>y loop x := x-1; end loop; x := ; end; int main(){ int x, gcc y = 1; 6: parse error before `while' x = 3 while(x>y) x = x-1; x = ; }
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta50

8: parse error before `;'

Sobre recuperacin/reparacin de errores


procedure pruebaErrores2 is x: integer; gnatmake y: integer := 1; 10:10: binary operator expected begin 14:08: missing operand x := 3 z; while x>y loop x := x-1; end loop; x := ; end; int main(){ int x, gcc y = 1; 5:parse error before `z` x = 3 z; while(x>y) x = x-1; x = ; }
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta51

8:parse error before `;`

Sobre recuperacin/reparacin de errores


int main(){ int x, y = 1; x = 3 while(x>y) x = x-1; x = ; } error 1000: Unexpected symbol: "while". error 1000: Unexpected symbol: "x". error 1000: Unexpected symbol: ";". error 1533: Illegal function call. warning 714. error 1549: Modifiable lvalue required for assignment operator. warning 517: Function returns no value. warning 845: errors seen skipping the code including function.

lint
line line line line line line line line 6: 7: 8: 5: 5: 5: 1: 1:

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

52

Sobre recuperacin/reparacin de errores

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.

Compiladores I. C.P.S. Universidad de Zaragoza

-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..

Compiladores I. C.P.S. Universidad de Zaragoza

-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)

Compiladores I. C.P.S. Universidad de Zaragoza

-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)

Compiladores I. C.P.S. Universidad de Zaragoza

-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

Compiladores I. C.P.S. Universidad de Zaragoza

-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

--> an-1 | Xn --> an

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

Sintaxis expresiones en Pascal

[ identif. de variable
variable

expresin ,

identificador de campo

. ^

identif. de campo

expresin

expresin simple = < > <= >= <> IN expresin simple

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

60

Sintaxis expresiones en Pascal


expresin simple

+ trmino trmino + OR

trmino

factor * factor / div mod and

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

61

Sintaxis expresiones en Pascal


factor

constante sin signo variable identificador de funcin ( expresin , ( expresin ) )

NOT

factor

expresin ,

..

expresin

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

62

Sintaxis expresiones en Pascal


constante sin signo

identificador de constante numero sin signo NIL ' caracter '

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

63

Sintaxis expresiones en Pascal


expr: expSimple | expr opRel expSimple expSimple: term | expSimple opSum term opRel: '=' | '<' | '>' | MEI | MAI | NI opSum: '+' | '-' | OR term: factor | '+' term | '-' term %prec '-' | term opMul factor opMul: '*' | '/' | DIV | MOD | AND
-J.Ezpeleta64

Compiladores I. C.P.S. Universidad de Zaragoza

Sintaxis expresiones en Pascal


factor: constante | IDENTIFICADOR | IDENTIFICADOR '[' expr ']' | IDENTIFICADOR '(' listaActuales ')' | '(' expr ')' | NOT factor %prec NOT constante: CONSTENTERA | CONSTBOOLEANA | CONSTCADENA | CONSTCARACTER

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

65

Sintaxis expresiones en Ada


expression relation | relation | relation | relation | relation ::= {and relation} {and then relation} {or relation} {or else relation} {xor relation}

[...]: 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

Compiladores I. C.P.S. Universidad de Zaragoza

-J.Ezpeleta-

66

Sintaxis expresiones en Ada


primary ::= numeric_literal | null | string_literal | aggregate | name | qualified_expression | allocator | (expression) logical_operator ::= and | or | xor relational_operator ::= = | /= | < | <= | > | >= binary_adding_operator ::= + | - | & unary_adding_operator ::= + | multiplying_operator ::= * | / | mod | rem highest_precedence_operator ::= ** | abs | not
Compiladores I. C.P.S. Universidad de Zaragoza -J.Ezpeleta-

[...]: 0 1 {...}: 0 ms

67

You might also like