Está en la página 1de 26

Anlisis Sintctico Descendente

CI4721 Lenguajes de Programacin II

Ernesto Hernndez-Novich <emhn@usb.ve>


Universidad Simn Bolvar

Copyright c 2012

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

1 / 20

PDA Descendente con lookahead

Reconocedor descendente determinstico


Sea G = (N , , P , S ) una CFG cualquiera. Entonces el PDA extendido LLk (G ) = ({q0 , q1 }, , N , , q0 , {q1 }) con denida segn (q0 , , , ) = {(q1 , S )} (q1 , a, a, a) = {(q1 , )}, a (q1 , , u, A) = {A P u LAk (A ) : (q1 , )}, A N es un reconocedor descendente y determinstico para G .
u + corresponde al lookahead. Si G es LL(k ) la conjuncin asegura que habr exactamente una

transicin por cada combinacin de no-terminal y lookahead.


Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 2 / 20

Reconocedor basado en tablas

Cmo convertirlo en un programa?


Convirtiendo transiciones en datos

En nuestro PDA determinstico con lookahead . . . El estado inicial solamente se usa para empilar S . El estado nal solamente tiene transiciones a s mismo. En cada transicin solamente varan el lookahead y el smbolo a remover del tope de la pila. Las expansiones estn implcitas en las transiciones.

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

3 / 20

Reconocedor basado en tablas

Cmo convertirlo en un programa?


Convirtiendo transiciones en datos

En nuestro PDA determinstico con lookahead . . . El estado inicial solamente se usa para empilar S . El estado nal solamente tiene transiciones a s mismo. En cada transicin solamente varan el lookahead y el smbolo a remover del tope de la pila. Las expansiones estn implcitas en las transiciones. Podemos disear un algoritmo muy compacto alrededor de Una entrada con su marcador nal #k . Un buer de tamao k para el lookahead. Una pila que comienza conteniendo S sobre un centinela #. Una tabla cuyas entradas indiquen la produccin a expandir para cada combinacin de lookahead y tope de pila.

El algoritmo es independiente de la gramtica solamente necesita la tabla.


Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 3 / 20

Reconocedor basado en tablas

Reconocedor LL(k ) por Tabla


Inicializacin

input: w con #k marcadores y la Tabla M asociada a la gramtica {Empilar el centinela y el smbolo inicial} push(#) push(S ) {Preparar el k lookahead} a los primeros k smbolos de w {Determinar el tope de la pila sin consumirlo} X top()

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

4 / 20

Reconocedor basado en tablas

Reconocedor LL(k ) por Tabla


Procesamiento

while X = # do if X = trunc1 (a) then pop() y consumir siguiente de w al nal de a else if X then error por terminal inesperado en la entrada else if M [X , a] vaco then error por no poder expandir el no terminal else if M [X , a] = X Y1 Y2 . . . Yn then print X Y1 Y2 . . . Yn pop() push(Yn Yn1 . . . Y2 Y1 ) end if X top() end while output: Si w L(G ), la derivacin ms izquierda, sino error
Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 5 / 20

Reconocedor basado en tablas

El secreto est en la tabla


Caractersticas

Una la por cada A N . Una columna por cada lookahead posible.

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

6 / 20

Reconocedor basado en tablas

El secreto est en la tabla


Caractersticas

Una la por cada A N . Una columna por cada lookahead posible.


k

||i =
i =0

1 ||k +1 1 | |

(no se les olvide la columna para #k )

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

6 / 20

Reconocedor basado en tablas

El secreto est en la tabla


Caractersticas

Una la por cada A N . Una columna por cada lookahead posible.


k

||i =
i =0

1 ||k +1 1 | |

(no se les olvide la columna para #k ) En cada posicin se almacena


La produccin a expandir para ahorrar espacio, tpicamente es un

identicador numrico o apuntador a la representacin de la regla.


Un indicador de error sintctico.

Los requerimientos de espacio son prohibitivos para k > 1


Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 6 / 20

Reconocedor basado en tablas

El secreto est en la tabla


Construccin

input: G = (N , , P , S ) y A N , FIRSTk (A) y FOLLOWk (A) for all A P do for all a FIRSTk () do M [A, a] A end for if FIRSTk () then for all b FOLLOWk (A) do M [A, b ] A end for end if end for Las posiciones que queden vacas corresponden a errores de sintaxis.
Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 7 / 20

Reconocedor basado en tablas

Reconocer (mini) JSON


La gramtica

Gramtica inicial para una versin reducida de JSON J {L} L s :V L L, s :V A [X ] X V X V ,L V s V n V J V A


Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 8 / 20

La gramtica no es LL:
Smbolo inicial J recursivo

indirectamente a travs de L por ms de una va.


Recursin izquierda en L. Prejos comunes en X .

Reconocedor basado en tablas

Reconocer (mini) JSON


La gramtica transformada 30 % ms reglas

S J# J {L} L s :VR R ,L R A [X ] X VY Y ,X Y V s V n V J V A
Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 9 / 20

S J L R A X Y V

FIRST { { s , [ s n { [ , s n { [

FOLLOW # # , } ] } } , } ] ] ] , } ]

Veriquen que la gramtica es fuertemente LL(1)

Reconocedor basado en tablas

Reconocer (mini) JSON


La tabla

S J L L s :VR R R ,L A X X VY X VY Y Y ,X V V s V n
72 celdas 77 % vaco Por qu : es irrelevante? Por qu # es irrelevante?
Hernndez-Novich (USB)

{ S J# J {L}

R A [X ] X VY Y V J V A X VY

Anlisis Sintctico Descendente

2012

10 / 20

Reconocedor basado en tablas

Recuperacin de Errores
. . . porque el mundo no es perfecto

El reconocedor predictivo es capaz de detectar dos errores: Terminal al tope de la pila diferente del siguiente terminal de entrada. La combinacin de no terminal al tope de la pila y el lookahead no tiene regla de expansin asociada. Abortar el reconocimiento es inaceptable El programa est mal el proceso de sntesis no ocurrir, pero el anlisis debera continuar tanto como se pueda. Cada error debe ser amplio y detallado
Ubicacin lnea y columna, contexto de ser posible. Condicin esperaba X pero recib Y Encontrar otros defectos ayudar al programador.

Existen dos tcnicas de recuperacin aplicables

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

11 / 20

Reconocedor basado en tablas

Recuperacin de Errores
. . . porque el mundo no es perfecto

El reconocedor predictivo es capaz de detectar dos errores: Terminal al tope de la pila diferente del siguiente terminal de entrada. La combinacin de no terminal al tope de la pila y el lookahead no tiene regla de expansin asociada. Abortar el reconocimiento es inaceptable El programa est mal el proceso de sntesis no ocurrir, pero el anlisis debera continuar tanto como se pueda. Cada error debe ser amplio y detallado
Ubicacin lnea y columna, contexto de ser posible. Condicin esperaba X pero recib Y Encontrar otros defectos ayudar al programador.

Existen dos tcnicas de recuperacin aplicables Tcnica del Pnico (Panic Mode). Tcnica del Engao (Phrase Level Recovery).
Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 11 / 20

Reconocedor basado en tablas

Tcnica del Pnico


Panic Mode, a.k.a. Discard all the tokens!

Descartar tokens hasta encontrar alguno que permita resincronizar. Conjuntos de sincronizacin construidos con heursticas: Resincronizar A usando FOLLOW (A) se termin el A incompleto. FIRST de construcciones de alto nivel para resincronizar construcciones de bajo nivel depende de la gramtica. En algunos casos, agregar FIRST (A) para resincronizar A hace posible continuar reconociendo cuando aparezca depende de la gramtica. Ante un error expandiendo A, si existe A entonces usarlo esto diere el error para ms adelante. Si el terminal al tope de la pila no coincide con el de la entrada, eliminarlo como si lo hubieras visto faltaba un ; y lo agregu. La posicin de la tabla apunta al conjunto de resincronizacin.

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

12 / 20

Reconocedor basado en tablas

Tcnica del Engao


(Phrase Level Recovery, a.k.a. Let me type for you)

Aplicada para recuperarse de los errores de expansin. La posicin de la tabla apunta a una subrutina de manejo del error. Cada rutina es especca para la recuperacin particular altamente

dependiente del lenguaje.


Las rutinas completan lo que falta para continuar Agregan, quitan o cambian smbolos en la entrada. Sacan cosas de la pila Muy peligroso. Anuncian lo que hicieron para corregir el problema. Solamente aplicable a lenguajes (o sub-lenguajes) Se conocen los errores ms frecuentes. Es fcil alcanzar formas sentenciales vlidas con edicin mnima.

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

13 / 20

Reconocedor basado en tablas

Tcnica del Engao


(Phrase Level Recovery, a.k.a. Let me type for you)

Aplicada para recuperarse de los errores de expansin. La posicin de la tabla apunta a una subrutina de manejo del error. Cada rutina es especca para la recuperacin particular altamente

dependiente del lenguaje.


Las rutinas completan lo que falta para continuar Agregan, quitan o cambian smbolos en la entrada. Sacan cosas de la pila Muy peligroso. Anuncian lo que hicieron para corregir el problema. Solamente aplicable a lenguajes (o sub-lenguajes) Se conocen los errores ms frecuentes. Es fcil alcanzar formas sentenciales vlidas con edicin mnima.

No la llame ad hoc, llmela ad hack.


Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 13 / 20

Reconocedor Recursivo Descendiente

Cmo convertirlo en un programa?


Convirtiendo transiciones en llamadas a funciones

En nuestro PDA determinstico con lookahead . . . La pila se usa para almacenar formas sentenciales. Tan pronto se expande una forma sentencial, se intenta consumir tantos terminales como se pueda antes de volver a expandir. Las expansiones estn implcitas en las transiciones.

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

14 / 20

Reconocedor Recursivo Descendiente

Cmo convertirlo en un programa?


Convirtiendo transiciones en llamadas a funciones

En nuestro PDA determinstico con lookahead . . . La pila se usa para almacenar formas sentenciales. Tan pronto se expande una forma sentencial, se intenta consumir tantos terminales como se pueda antes de volver a expandir. Las expansiones estn implcitas en las transiciones. Podemos disear un algoritmo muy compacto alrededor de Una subrutina por cada no-terminal la ejecucin comienza por S(). Cada procedimiento modela la secuencia de expansiones y consumo de entrada para las reglas A .

El algoritmo es dependiente de la gramtica simulando la pila del PDA con la pila de ejecucin.

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

14 / 20

Reconocedor Recursivo Descendiente

Un procedimiento tpico
void A () { Escoger alguna A X1 X2 . . . Xn for i = 1 to n do if Xi es un no-terminal then call Xi () else if Xi = el smbolo actual de entrada then avanzar al siguiente smbolo de entrada else reportar error de sintaxis end if end for }
Si la seleccin no es determinstica, requiere backtracking. Para incluir backtracking el ciclo debe cambiarse por un avance

selectivo sin descartar la entrada hasta estar seguros.


Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 15 / 20

Reconocedor Recursivo Descendiente

Reconocer (mini) JSON


Uno de los procedimientos triviales

Reconocer L es trivial
Una sola regla L s :VR Lookahead segn FIRST1 (L s :VR ) void L () { try_rule (2); match ( L , s ); match ( L , : ); V (); R (); } try_rule permite recordar los pasos de derivacin. match verica el lookahead esperado o aborta con error.
Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 16 / 20

Reconocedor Recursivo Descendiente

Reconocer (mini) JSON


Uno de los procedimientos interesantes

Reconocer R es slo un poco ms complicado


Dos reglas R ,L y R Lookaheads FIRST1 (R ,L) y FOLLOW1 (R ), respectivamente. void R () { switch ( lookahead ) { case , : try_rule (3); match ( R , , ); L (); case } : try_rule (4); return ; default : error ( R , lookahead ); } } Necesario vericar el lookahead antes de decidir cul regla usar. Alternativa de error es explcita en este caso.
Hernndez-Novich (USB) Anlisis Sintctico Descendente 2012 17 / 20

Consideraciones

Consideraciones
El reconocedor por tabla solamente tiene sentido prctico para

gramticas LL(1) para el resto es muy costoso.


Las gramticas generales transformadas a LL(k ) suelen ser ms

complejas tanto en nmero como en forma de las reglas.


Cmo optimizara una tabla LL(k ) para reducir la ocupacin de

espacio al mnimo posible?


Aplique la tcnica de recuperacin de errores Modo de Pnico a la

tabla para (mini) JSON. Son tiles todas las heursticas?


Si el lenguaje es sucientemente simple y LL(1), un recursivo

descendiente es ms barato incluso si una de las subgramticas es LL(k ) > 1, por qu?
Cmo extender el reconocedor para construir el rbol de derivacin?

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

18 / 20

Consideraciones

En la prctica

Muchos lenguajes de programacin proveen libreras que asisten en la

construccin de Reconocedores Recursivos Descendentes con o sin backtracking.


Perl ofrece Parse::RecDescent. Haskell ofrece Parsec. Java dispone de JavaCC y ANTLR. C++ dispone de Spirit Parser Generator. . . . siempre se puede escribir a mano.

Si el lenguaje a reconocer es simple, es ms prctico usar esta tcnica Lenguaje de un archivo de conguracin INI, JSON, . . . Lenguaje de comandos interactivos.

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

19 / 20

Referencias Bibliogrcas

Bibliografa

[Aho ] Seccin 4.4 WikiPedia Recursive Descent Parser JSON: The Fat-Free alternative to XML

Hernndez-Novich (USB)

Anlisis Sintctico Descendente

2012

20 / 20

También podría gustarte