SlideShare uma empresa Scribd logo
1 de 64
Baixar para ler offline
Análisis Sintáctico
                            Tema 3
                        Juan A. Bot´a Blaya
                                   ı
                          juanbot@um.es

http://ants.dif.um.es/staff/juanbot/traductores/traductores.html


                                           ´
 Departamento de Ingenier´a de la Informacion y las Comunicaciones
                         ı
                      Universidad de Murcia




                                                                       ´          ´
                                                                     Analisis Sintactico – p.1/64
Índice
Introducción al Análisis Sintáctico.
1. Objetivo del analizador sintáctico
2. Gramáticas libres de contexto y autómatas con pila
3. Análisis sintáctico ascendente y descendente
4. El problema de la ambigüedad en el análisis sintáctico
5. Métodos Universales de análisis sintáctico
  (a) El método de Cocke-Younger-Kasami
  (b) El método de Early
6. Transformaciones de gramáticas




                                                      ´          ´
                                                    Analisis Sintactico – p.2/64
Gramáticas libres de contexto (CFG) y Autómatas de pila (PA)


Definición 1 Una gramática libre de contexto G = (V N , Vt , S, P ) es aquella cuyas
producciones tienen la forma A → α, siendo A ∈ VN y α ∈ (VN VT )∗ .
Definición 2 Un autómata de pila se define como una 7-tupla AP = (Q, V, Σ, δ, q 0 , z0 , F )
en donde:
     Q es un conjunto finito de estados.
     V es el alfabeto de entrada.
     Σ es el alfabeto de la pila.
     q0 es el estado inicial.
     z0 es el símbolo inicial de la pila.
     F ⊆ Q es el conjunto de estados finales.
     δ es la función de transición:

                                                                  ∗
                                    δ: Q × (V ∪ {λ}) × Σ → 2Q×Σ




                                                                                    ´          ´
                                                                                  Analisis Sintactico – p.3/64
Gramáticas libres de contexto (CFG) y Autómatas de pila (PA)


Definición 3 Se entiende por configuración de un atomómata con pila a su situación en un
instante considerado expresada formalmente por medio de una tripla
(q, w, α) ∈ (Q × V ∗ × Σ∗ ) en donde:
     q ∈ Q es el estado actual del autómata.
     w ∈ V ∗ es la subcadena de entrada que aun no se ha analizado.
     α ∈ Σ∗ es el contenido actual de la pila.


Si w = λ no queda nada por analizar. Si α = λ se ha reconocido la cadena.




                                                                               ´          ´
                                                                             Analisis Sintactico – p.4/64
Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) (II)


 Definición 4 Un movimiento de un AP es una transición entre configuraciones. Una
 transición no tiene porqué realizarse en un solo movimiento.
 Por ej. el movimiento (q, aw, Zα) (q , w, βα) es un movimiento válido siempre y cuando
 (q , β) ∈ δ(q, a, Z) con q ∈ Q, a ∈ (V ∪ λ), w ∈ V ∗ , α, β ∈ Σ∗ .
 Se debe señalar que un AP no puede realizar ningún movimiento si la pila está vacía.
 Entonces, un autómata de pila reconocerá una cadena de entrada sii partiendo de su
 configuración inicial, (q0 , t, Z0 ), llega a una configuración final (qf , λ, α) empleando
 movimientos válidos y lo expresamos:

                                          ∗
                          (q0 , t, Z0 )       (qf , λ, α), qf ∈ F, α ∈ Σ∗


 La cadena será aceptada por vaciado de pila si despues de leerse toda la cadena se llega a
 un estado con la pila vacía, independientemente del tipo de estado en el que se encuentre
 el AP.




                                                                                    ´          ´
                                                                                  Analisis Sintactico – p.5/64
Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) (III)


  Ejemplo. Sea G = (VN , VT , P, S) con P
        S →S+A
        S→A
        A→A∗B
        A→B
        B → (S)
        B→a
  Sea AP = (Q, V, Σ, δ, q, s, ∅) en donde Q = {q}, V = {a, +, ∗, (, )} y δ:

        δ(q, λ, S) = {(q, S + A), (q, A)}
        δ(q, λ, A) = {(q, A ∗ B), (q, B)}
        δ(q, λ, B) = {(q, (S)), (q, a)}
        δ(q, op, op) = {(q, λ)}

  siendo op ∈ V . Intentaremos reconocer la cadena w = a + a ∗ a.




                                                                                ´          ´
                                                                              Analisis Sintactico – p.6/64
Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) (IV)


  Ejemplo (y II) El árbol de alternativas posibles es
                                       (q,a+a*a,S)


                         .
                     (q,a+a*a,A)
                         .            (q,a+a*a,S+A)
                         .
                                                            .
                                                      (q,a+a*a,S+A+A)
                                      (q,a+a*a,A+A)
                                                            .
                                                            .
                                      (q,a+a*a,B+A)         .
                                                      (q,a+a*a,A*B+A)
                                                            .
                                                            .
                         .
                    (q,a+a*a,(S)+A)   (q,a+a*a,a+A)
                         .
                         .             (q,+a*a,+A)



                                        (q,a*a,A)

                                                           .
                                                        (q,a*a,B)
                                       (q,a*a,A*B)         .
                                                           .
                                       (q,a*a,B*B)
                                                      (q,a*a,(S)*B)
                                                           .
                                       (q,a*a,a*B)
                                                           .
                                                           .
                                        (q,*a,*B)

                                         (q,a,B)

                                         (q,a,a)

                                         (q,,)
                                                                          ´          ´
                                                                        Analisis Sintactico – p.7/64
Análisis Sintáctico Ascendente y Descendente


Definición 5 Una sentencia w ∈ L(G), para alguna CFG (Context Free Grammar) ha sido
reconocida cuando conocemos alguno de (o quizá todos) sus árboles de derivación.


Definición 6 Sea una gramática G = (VN , VT , P, S). Se dice que la cadena α deriva
directamente a la cadena β, denotándolo α ⇒ β, si se puede escribir

                                  α = δAµ y β = δγµ

para alguna cadena δ y µ ∈ (VT ∪ VN )∗ , y además existe A → γ ∈ P .


Definición 7 Sea una gramática G = (VN , VT , P, S). Para cualquier A ∈ VN y
                                  ∗
α ∈ (VN ∪ VT )∗ se dice que A =⇒ α si α se deriva de A, con una cadena de derivaciones
de longitud cualqiera, incluso nula.




                                                                                ´          ´
                                                                              Analisis Sintactico – p.8/64
Análisis Sintáctico Ascendente y Descendente


Definición 8 Sea una gramática G = (VN , VT , P, S). Las formas sentenciales de G vienen
dadas por el conjunto

                                        ∗
                       D(G) = {α / S =⇒ α y α ∈ (VN ∪ VT )∗ }

Definición 9 El lenguaje definido por una gramática G, denotado L(G) es el conjunto de
cadenas de símbolos terminales, que se pueden derivar partiendo del axioma de la
gramática, y empleando para las derivaciones las reglas de P . E.d.:

                                            ∗
                            L(G) = {x/S =⇒ x, y x ∈ T ∗ }

Definición 10 Sea una gramática G = (VN , VT , P, S). Sea una forma sentencial αβγ en
donde α ∈ VT , β ∈ VN y γ ∈ (VT ∪ VN )∗ . Una derivación izquierda se obtiene
             ∗

sustituyendo β por alguna de las partes derechas que la definen.
Definición 11 Sea una gramática G = (VN , VT , P, S). Sea una forma sentencial αβγ en
donde α ∈ (VT ∪ VN )∗ , β ∈ VN y γ ∈ VT . Una derivación derecha se obtiene sustituyendo
                                        ∗

β por alguna de las partes derechas que la definen.



                                                                                 ´          ´
                                                                               Analisis Sintactico – p.9/64
Análisis Sintáctico Ascendente y Descendente (II)


                                                                                                          A   →   BF
                                                                                                          B   →   EC
Un ejemplo de este tipo de derivaciones, para la gramática                                                E   →   a    puede verse
                                                                                                          C   →   b
                                                                                                          F   →   c
                                                                        A
                                                                             D Derivación derecha
                                                                             I Derivación izquierda
                                                                        BF
                                                          I                       D



                                              ECF                                           Bc

                                    I
                                                                                             D


                        aCF                   EbF               ECc                         ECc

                    I                                                                             D


                  abF         aCc       abF         Ebc   aCc         Ebc             aCc         Ebc

              I                                                                                       D

en el árbol       abc         abc       abc         abc   abc         abc          abc            abc




                                                                                                                            ´          ´
                                                                                                                          Analisis Sintactico – p.10/64
Análisis Sintáctico Ascendente y Descendente (III)


Existen dos grandes grupos de métodos de análisis sintáctico, dependiendo de la dirección
en la que se recorre el árbol sintáctico.
     Descendente: en este tipo de análisis, se va recorriendo el árbol sintáctico desde la raíz
     hasta las hojas, llegando a generar la sentencia que se está analizando. La raíz
     representa al símbolo inicial de la gramática.
     Ascendente:  se parte de las hojas y se intenta construir el árbol hacia arriba, hasta
     llegar al símbolo inicial de la gramática.
En un análisis top-down un parser hacer corresponder cadenas de entrada con sus
correspondientes derivaciones izquierdas.
En un análisis bottom-up un parser hace corresponder cadenas de entrada con las inversas
de las correspondientes derivaciones derechas.
Entre los métodos generales, los algoritmos de Cocke-Younger-Kasami (CYK) y el método de
Early son los más conocidos → son bastante ineficientes desde un punto de vista
computacional.
Para la mayoría de lenguajes de programación es suficiente con trabajar con subconjuntos
de las CFG, como los de las LL y LR que permiten algoritmos de parsing más eficientes.



                                                                                       ´          ´
                                                                                     Analisis Sintactico – p.11/64
El problema de la ambigüedad en el análisis sintáctico


Definición 12 Un árbol ordenado y etiquetado D es un árbol de derivación para una
gramática libre de contexto G(S) = (VN , VT , P, S) si:
  1. La raíz de D está etiquetada con S.
  2. Si D1 , . . . , Dk son los subárboles de los descendientes directos de la raíz, y la raíz de
     cada Di está etiquetada con Xi , entonces S → X1 · · · Xk ∈ P . Además Di debe ser
     un árbol de derivación en G(Xi ) = (VN , VT , P, Xi ) si Xi ∈ VN , bien un nodo hoja
     con etiqueta Xi si Xi ∈ VT .
  3. Alternativamente, si D1 es el único subárbol de la raíz de D, y la raíz de D 1 tiene
     como etiqueta e, entonces S → e ∈ P .
Definición 13 La frontera de un árbol de derivación es la cadena que se obtiene
concatenando, de izquierda a derecha, las etiquetas de las hojas.
Definición 14 Sea una CFG G = (VN , VT , P, S). Decimos que G es ambigua si existe al
menos una sentencia w ∈ L(G) para la cual hay un árbol de derivación distinto, con frontera
w.




                                                                                        ´          ´
                                                                                      Analisis Sintactico – p.12/64
El problema de la ambigüedad en el análisis sintáctico (II)


El hecho de que una gramática sea ambigua es una situación indeseable ya que cada árbol
de derivación representa una ejecución distinta de la misma sentencia, y por lo tanto cada
uno podría producir resultados distintos.


       sea la gramática G = (VN , VT , P, S) con P = {E → E + E, E → E ∗ E, E → a}
Ejemplo:
Caben dos interpretaciones para a + a ∗ a:

                           E                               E


                      E    +    E                  E       *      E


                      a    E    *    E      E     +    E           a



                           a         a      a          a




                                                                                  ´          ´
                                                                                Analisis Sintactico – p.13/64
El problema de la ambigüedad en el análisis sintáctico (III)


Otro ejemplo clásico de este tipo de problemas es el de las gramáticas que incluyen
sentencias del tipo if-then/if-then-else.
Sea la gramática
                          prop             →           if   expr then prop
                                            |          if   expr then prop else prop
                                            |          otra
De acuerdo con ella, la sentencia
                               if   E1 then S1 else if E2 then S2 else S3
no es ambigua, ya que el árbol de derivación correspondiente sería
                                                  prop




                          if        expr   then   prop           else   prop

                                    E1             S1


                                                  if    expr        then   prop   else   prop
                                                            E2             S2            S3




                                                                                                  ´          ´
                                                                                                Analisis Sintactico – p.14/64
El problema de la ambigüedad en el análisis sintáctico (IV)


sin embargo, la sentencia
                                      if   E1 then if E1 then S1 else S2
si lo sería, ya que daría lugar a la siguiente pareja de árboles de
derivación distintos.
                                                                                      prop
                               prop



             if        expr    then    prop
                        E1                                      if   expr    then     prop   else        prop
                                                                     E1                                   S1
                  if    expr    then       prop   else   prop
                         E2                  S1            S2               if   expr   then   prop
                                                                                 E2                 S2




                                                                                                                  ´          ´
                                                                                                                Analisis Sintactico – p.15/64
El problema de la ambigüedad en el análisis sintáctico (V)


Hay dos enfoques distintos usados para solucionar este
problema.
1. Transformar la definición del lenguaje para que las
   construcciones if-then-else tengan delimitadores de
   bloque, y los else se asocien con los if explícitamente.
2. Transformar la gramática en otra equivalente y que no
   sea ambigua.




                                                          ´          ´
                                                        Analisis Sintactico – p.16/64
El problema de la ambigüedad en el análisis sintáctico (VI)


Ejemplo con el método 1:

           prop    →     if   expr then prop endif
                    |    if   expr then prop else prop endif
                    |    otra

entonces, para escribir una sentencia como la del ejemplo, y en la que se asocie el else al
segundo if quedaría

      if   E1 then if E1 then S1 else S2 endif endif

Una sentencia que ahora asociara el else con el primer if sería

      if   E1 then if E1 then S1 endif else S2 endif




                                                                                     ´          ´
                                                                                   Analisis Sintactico – p.17/64
El problema de la ambigüedad en el análisis sintáctico (VII)


Ejemplo con el método 2:

      Se debe elegir entre los dos árboles de la transparencia 10.
           Elegir el árbol de la izquierda implica emparejar el else con el then anterior y sin emparejar
           más cercano.
           Elegir el árbol de la derecha implica emparejar el else con el then más lejano y que aun esté
           sin emparejar.

      Eligiendo el árbol de la izquierda, se dividen las proposiciones entre emparejadas y no
      emparejadas.
           Toda proposición que aparezca entre un then y un else debe estar emparejada, e.d. no debe
           terminar con un then sin emparejar porque entonces el else estaría obligado a concordar con
           ella.
           Una proposición emparejada es ó una proposición if-then-else que no contenga proposiciones
           sin emparejar o cualquier otra clase de proposición no condicional.

        prop                     →      prop_emparejada
                                 |      prop_no_emparejada

        prop_emparejada          →      if expr then   prop_emparejada else prop_emparejada
                                 |      otra

        prop_no_emparejada       →      if   expr then prop
                                 |      if   expr then prop_emparejada else prop_no_emparejada


                                                                                                  ´          ´
                                                                                                Analisis Sintactico – p.18/64
Métodos universales de análisis sintáctico


Aplicables a cualquier GLC
Métodos tabulares
Complejidad espacial O(n2 ) y temporal O(n3 )
No aplicables para lenguajes de programación
convencionales
Aplicables si interesan todos los árboles de derivación
posibles (G. ambiguas)




                                                     ´          ´
                                                   Analisis Sintactico – p.19/64
Algoritmo Cocke-Younger-Kasami
 Basado en programación dinámica
 Poca aplicabilidad
    Complejidad espacial proporcional a n2 (n longitud de
    w)
    Complejidad temporal proporcional a n3
    Algoritmo de Early consigue complejidades lineales
    para muchas gramáticas LC
 Necesita gramáticas en CNF y λ−libres




                                                     ´          ´
                                                   Analisis Sintactico – p.20/64
CYK-Funcionamiento básico
Sea w = a1 a2 . . . an con ai ∈ VT ∀i = 1, . . . , n
El algoritmo construye una tabla T triangular, con elementos

                 tij ⊂ VN , 1 ≤ i ≤ n y 1 ≤ j ≤ n − i + 1,
                                           j



                             t11     t12       t13     t14



                             t21     t22       t23
                       i


                             t31     t32



                             t41




en donde A ∈ tij sii A ⇒+ ai ai+1 · · · ai+j−1
Entonces w ∈ L(G) si S ∈ t1n

                                                                 ´          ´
                                                               Analisis Sintactico – p.21/64
Métodos Universales de análisis sintáctico. El algoritmo CYK


Algoritmo 1 Algoritmo de análisis sintáctico de Cocke-Younger-Kasami.
Entrada: Una gramática G = (VN , VT , P, S) en CNF y sin λ-producciones, junto con una
                                        ∗
cadena de entrada w = a1 a2 · · · an ∈ VT .
                                                                 +
Salida: La tabla T en la que cada ti,j contiene a A ∈ VN sii A =⇒ ai ai+1 · · · ai+j−1 .
Método:
  1. Hacer ti,1 = {A|A → ai ∈ P } para todo i.
  2. Supongamos que ti,j se ha calculado para todo i, 1 ≤ i ≤ n, y para todo j ,
     1 ≤ j < j. Hágase

         ti,j = {A| para algun k , 1 ≤ k < j, A → BC ∈ P, B ∈ ti,k , y C ∈ ti+k,j−k }

      Dado que i ≤ k < j, tanto k como j − k son menores que j. Por lo tanto, t i,k y
      ti+k,j−k han sido calculados antes de ti,j . Después de este paso, si ti,j contiene a
      A, entonces
                            +                    +
                 A ⇒ BC =⇒ ai · · · ai+k−1 C =⇒ ai · · · ai+k−1 ai+k · · · ai+j−1
  3. Realizar el paso anterior, hasta que ti,j haya quedado calculado para todo 1 ≤ i ≤ n
     y 1 ≤ j ≤ n − i + 1.


                                                                                      ´          ´
                                                                                    Analisis Sintactico – p.22/64
CYK-Observaciones
Se trata de encontrar A, B, C tales que
                                     C

                              A          B
                a1 a2 . . . ai . . .. . . ai+j−1 . . . an

hasta que al final tengamos
                                   S

                               D         E
                           a1 a2 . . .. . . an

y por lo tanto podamos asegurar que
S → DE ⇒+ a1 a2 . . . E ⇒+ a1 a2 . . . an

                                                              ´          ´
                                                            Analisis Sintactico – p.23/64
Métodos Universales de análisis sintáctico. El algoritmo CYK (II)


 Veámos la aplicación del algoritmo con un ejemplo en el que el conjunto P de nuestra
 gramática viene dado por el conjunto de producciones
      S → AA|AS|b
      A → SA|AS|a
 Sea w = abaab la cadena de entrada. Aplicando el algoritmo, la tabla resultante será una
 triangular de 5 × 5. Aplicando el paso 1, tenemos
      t11 = {A}, ya que A → a ∈ P .
      t21 = {S}, ya que S → b ∈ P .
      t31 = {A}, ya que A → a ∈ P .
      t41 = {A}, ya que S → a ∈ P .
      t51 = {S}, ya que A → b ∈ P .




                                                                                    ´          ´
                                                                                  Analisis Sintactico – p.24/64
Métodos Universales de análisis sintáctico. El algoritmo CYK (III)


 Ahora, hacemos j = 2. Tenemos que ti,j se ha calculado para j = 1. Tenemos que
 encontrar no-terminales que produzcan subcadenas de w de longitud 2.
      t1,2 = {S, A}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de
      la parte derecha esté en t1,1 y el segundo no-terminal en t2,1 . Por lo tanto la parte
      derecha ha de ser AS. Tanto S como A tienen reglas con esa parte derecha.
      t22 = {A}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de la
      parte derecha esté en t2,1 y el segundo no-terminal en t3,1 . La parte derecha sería
      SA. Únicamente A tiene partes derechas de ese tipo.
      t3,2 = {S}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de la
      parte derecha esté en t3,1 , y el segundo en t4,1 . Por lo tanto, la parte derecha sería
      AA. Sólamente S tiene reglas de producción con esa parte derecha.
      t4,2 = {A, S}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de
      la parte derecha esté en t4,1 , y el segundo en t5,1 . Por lo tanto, la parte derecha sería
      AS.




                                                                                        ´          ´
                                                                                      Analisis Sintactico – p.25/64
Métodos Universales de análisis sintáctico. El algoritmo CYK (IV)


 Después de hacer el paso 2, con j = 2 la tabla T queda así:


                        1    2    3 4 5
                   1   {A} {S, A}
                   2   {S}  {A}
                   3   {A}  {S}
                   4   {A} {A, S}
                   5   {S}




                                                           ´          ´
                                                         Analisis Sintactico – p.26/64
Métodos Universales de análisis sintáctico. El algoritmo CYK (V)


 Ahora, hacemos j = 3. Tenemos que ti,j se ha calculado para 1 ≤ j < 3. Tenemos que
 encontrar no-terminales que produzcan subcadenas de w, de longitud 3.
      t1,3 = {A, S}, ya que 1 ≤ k < 3, y la regla ha de ser tal que el primer no-terminal de
      la parte derecha esté en t1,1 (o en t1,2 ) y el segundo no-terminal en t2,2 (o en t3,1 ).
      Por lo tanto la parte derecha ha de ser AA (o SA).
      t2,3 = {S}, ya que 1 ≤ k < 3, y la regla ha de ser tal que el primer no-terminal de la
      parte derecha esté en t2,1 (o en t2,2 ) y el segundo no-terminal en t3,2 (o en t4,1 ). La
      parte derecha sería SS (o AA). Únicamente S tiene una producción S → AA.
      t3,3 = {A, S}, ya que 1 ≤ k < 3, y la regla ha de ser tal que el primer no-terminal de
      la parte derecha esté en t3,1 (o en t3,2 ), y el segundo en t4,2 (o en t5,1 ). Con t3,1 y
      t4,2 tenemos dos posibles partes derechas que son AA y AS, y por ello tanto S como
      A deben estar en t3,3 . Con t3,2 y t5,1 tenemos como parte derecha SS, que no es
      generada por ningun no-terminal.




                                                                                        ´          ´
                                                                                      Analisis Sintactico – p.27/64
Métodos Universales de análisis sintáctico. El algoritmo CYK (VI)


 Después de hacer el paso 2, con j = 3 la tabla T queda así:


                     1    2      3    4 5
                1   {A} {S, A} {A, S}
                2   {S}  {A}    {S}
                3   {A}  {S}   {A, S}
                4   {A} {A, S}
                5   {S}




                                                           ´          ´
                                                         Analisis Sintactico – p.28/64
Métodos Universales de análisis sintáctico. El algoritmo CYK (VII)


  Ahora, hacemos j = 4. Tenemos que ti,j se ha calculado para 1 ≤ j < 4. Tenemos que
  encontrar no-terminales que produzcan subcadenas de w, de longitud 4.
       t1,4 = {A, S}, ya que 1 ≤ k < 4, y la regla ha de ser tal que el primer no-terminal de
       la parte derecha esté en t1,1 , k = 1, o en t1,2 , k = 2, o en t1,3 , k = 3 y el segundo
       no-terminal en t2,3 , k = 1, o en t3,2 , k = 2 o en t4,1 . El conjunto de no-terminales que
       podrían formar el primer no-terminal de la parte derecha es {A, S} y el de
       no-terminales que podrían formar el segundo no-terminal de la parte derecha es
       {A, S}. Por lo tanto la parte derecha va a estar en {AA, AS, SA, SS}.
       t2,4 = {A, S}, ya que 1 ≤ k < 4, y la regla ha de ser tal que el primer no-terminal de
       la parte derecha esté en t2,1 , k = 1, o en t2,2 , k = 2 o en t2,3 , k = 3 y el segundo
       no-terminal en t3,3 , k = 1, o en t4,2 , k = 2, o en t5,1 . El conjunto de no-terminales
       que podrían formar el primer no-terminal de la parte derecha es {A, S}, y el de
       no-terminales que podrían formar el segundo no-terminal de la parte derecha es
       {A, S}. Por lo tanto la parte derecha va a estar en {AA, AS, SA, SS}.




                                                                                         ´          ´
                                                                                       Analisis Sintactico – p.29/64
Métodos Universales de análisis sintáctico. El algoritmo CYK (VIII)


  Después de hacer el paso 2, con j = 4 la tabla T queda así:


                  1       2       3        4    5
             1 {A} {S, A} {A, S} {A,S}
             2 {S}      {A}      {S}     {A, S}
             3 {A}       {S}   {A, S}
             4 {A} {A, S}
             5 {S}
  Hacer el paso 2, con j = 5 en clase, y completar la tabla T
  con t1,5 .


                                                            ´          ´
                                                          Analisis Sintactico – p.30/64
Obteniendo una secuencia de derivaciones a partir de T


Especifiación algorítmica
Algoritmo 2 Derivación más a la izquierda a partir de la tabla T de parsing.
Entrada: una gramática G = (VN , VT , P, S) en formato CNF, y en la que las
producciones de P están numeradas de 1 a p, una cadena de entrada
w = a1 a2 · · · an , y la tabla T generada por el algoritmo CYK.
Salida: una derivación izquierda de w o un error.
Método: se va a basar en el uso de una rutina recursiva gen(i, j, A) que va a generar
                +
la derivación A =⇒ ai ai+1 · · · ai+j−1 . Se define como sigue:
 1. Si j = 1 y la producción m-ésima es A → ai , entonces la salida de gen(i, 1, A)
    es m.
 2. Si j > 1, sea k el entero más pequeño, 1 ≤ k < j, tal que para algún B ∈ t i,k y
    C ∈ ti+k,j−k se tiene que A → BC ∈ P . Si hay varias, elegimos la que tenga el
    índice más pequeño, digamos m. La salida de gen(i, j, A) es m, más las salidas
    de gen(i, k, B) y gen(i + k, j − k, C).
Por lo tanto, para obtener la derivación para w llamamos a gen(1, n, S)




                                                                              ´          ´
                                                                            Analisis Sintactico – p.31/64
Obteniendo una secuencia de derivaciones a partir de T


Tomemos la gramática del ejemplo anterior y dispongámosla en el orden
siguiente:
    (1)S → AA
    (2)S → AS
    (3)S → b
    (4)A → SA
    (5)A → AS
    (6)A → a

    Sea la cadena de entrada w = abaab la misma que para T
    Tenemos que llamar a gen(1, 5, S), siempre que S ∈ t1,5




                                                                ´          ´
                                                              Analisis Sintactico – p.32/64
Obteniendo una secuencia de derivaciones a partir de T


Ahora la evolución, con el k y m correspondientes es
                                                      k=1
                                           gen(1,5,S) m=1

                                     k=1                         k=1
                          gen(1,1,A) m=6              gen(2,4,A) m=4


                                                k=1              k=1
                                     gen(2,1,S) m=3   gen(3,3,A) m=5


                                                k=1              k=1
                                     gen(3,1,A) m=6    gen(4,2,5)m=2


                                                k=1              k=1
                                     gen(4,1,A) m=6    gen(5,1,S)m=3

En esa figura puede verse que la secuencia de derivaciones obtenida es la siguiente

S ⇒1 AA ⇒6 aA ⇒4 aSA ⇒3 abA ⇒5 abAS ⇒6 abaS ⇒2 abaAS ⇒6 abaaS ⇒3 abaab




                                                                                 ´          ´
                                                                               Analisis Sintactico – p.33/64
El algoritmo de Early
Complejidad proporcional a n2 si gramática no es ambigua
Para lenguajes más usados, complejidades espacial y temporal son
lineales
Partimos de
   La gramática G = (VN , VT , P, S), de tipo CFG.
                                                 ∗
   Una cadena w = a1 a2 · · · an , en donde w ∈ VT .
Un elemento [A → X1 X2 · · · Xk • Xk+1 · · · Xm , i] es lo que vamos a
denominar un item para la cadena w, si A → X1 · · · Xm ∈ P y
0 ≤ i ≤ n.
El punto • es un símbolo adicional, y el entero k es tal que
0 ≤ k ≤ m.
Si la producción es A → λ entonces el item es [A → •, i]


                                                                 ´          ´
                                                               Analisis Sintactico – p.34/64
El algoritmo de Early (II)
El algoritmo trabaja construyendo un conjunto de items I j para cada j, 0 ≤ j ≤ n, de
tal forma que [A → α • β, i] ∈ Ij , con 0 ≤ i ≤ j sii para algún γ y δ, se tiene que:
        ∗
     S ⇒ γAδ
       ∗
     γ ⇒ a1 · · · a i
       ∗
     α ⇒ ai+1 · · · aj
Los índices i y j delimitan el segmento de cadena en w que se produce por la cadena
que está a la izquierda del símbolo •, si se observa la tercera derivación.
Las dos derivaciones primeras aseguran que el prefijo izquierdo de la cadena, desde
a1 hasta ai se ha producido a partir del símbolo inicial de la gramática.
La secuencia de listas de items generada, I 0 , I1 , . . . , In se denomina listas del parser,
para la cadena de entrada w.
w ∈ L(G) sii existe algún item en la forma [S → α•, 0] ∈ In .




                                                                                     ´          ´
                                                                                   Analisis Sintactico – p.35/64
El algoritmo de Early (III)
Algoritmo 3 El algoritmo de parsing de Early
Entrada: la gramática CFG, G = (VN , VT , P, S) y la cadena de entrada
                         ∗
w = a 1 a2 · · · a n ∈ V T .
Salida: Las listas del parser, I0 , I1 , . . . , In .
Método: Primero se construye I0 usando los pasos (1) a (3)
  1. Si S → α ∈ P entonces, añadir el item [S → •α, 0] a I0 .
     Ejecutar (2) y (3) hasta que no se añada ningún item nuevo a I 0 .
  2. Si [B → γ•, 0] ∈ I0 , añadir [A → αB • β, 0] para todo [A → α • Bβ, 0] ∈ I0 .
  3. Sea [A → α • Bβ, 0] ∈ I0 . Para toda producción B → γ, añadir el item [B → •γ, 0] a
     I0 , siempre que no estuviera añadido ya.
     Ahora, sea I0 , I1 , . . . , Ij−1 el conjunto de listas de items ya construidos. Para la
     construcción de Ij , hacer:
  4. Para cada [B → α • aβ, i] ∈ Ij−1 tal que a = aj , añadir [B → αa • β, i] a Ij .
     Ejecutar los dos últimos pasos, para cada j, hasta que no se pueda añadir ningún
     item más a Ij .
  5. Sea [A → γ•, i] ∈ Ij . Si existe un [B → α • Aβ, k] ∈ Ii , entonces, añadir
     [B → αA • β, k] a Ij .
  6. Sea [A → α • Bβ, i] ∈ Ij . Para todo B → γ ∈ P , añadimos [B → •γ, j] a Ij .

                                                                                     ´          ´
                                                                                   Analisis Sintactico – p.36/64
Interpretación del algoritmo
Paso 1: Iniciamos la construcción de la tabla con todas las producciones de S
Paso 2: Exploramos todas las λ−producciones a partir de S
Paso 3: Si en I0 tenemos A → B, debemos incluir también todas las producciones de
B
Paso 4: Si [B → α • aβ, i] ∈ Ij−1 sabemos entonces que (suponiendo que w ∈ L(G))

                                             α

                         a1 a2 . . . ai+1 ai+2 . . . aj−1 aj . . . an

entonces, si a = aj podemos decir que

                                           αa≡αaj

                         a1 a2 . . . ai+1 ai+2 . . . aj−1 aj . . . an

por lo tanto incluimos [B → αa • β, i] → Ij




                                                                             ´          ´
                                                                           Analisis Sintactico – p.37/64
Interpretación del algoritmo
Paso 5: Si [A → γ•, i] ∈ Ij tenemos que

                                            γ

                              . . . ai+1 ai+2 . . . aj . . .

y como A → γ entonces decimos también que

                                           A

                                            γ

                                  ai+1 ai+2 . . . aj

entonces, si tenemos que [B → α • Aβ, k] ∈ Ii significa que tenemos

                                                   A

                                 α                 γ

                            ak+1 . . . ai ai+1 ai+2 . . . aj

por lo que hacemos [B → αA • β, k] → Ij
Paso 6: análogo al 3

                                                                       ´          ´
                                                                     Analisis Sintactico – p.38/64
Ejemplo
Veámos la aplicación del algoritmo con un ejemplo: sea G = (V N , VT , P, E) en donde P
viene dado por
      1. E → T + E
      2. E → T
      3. T → F ∗ T
      4. T → F
      5. F → (E)
      6. F → a
Y sea w = (a + a) ∗ a la cadena de entrada.

     Según el paso (1) añadimos a I0 los items [E → •T + E, 0] y [E → •T, 0].
     Dado que la gramática es λ−libre, el paso (2) no incorpora ningún item adicional.
     Si en el paso (3) hacemos α = λ tenemos que incluir [T → •F ∗ T, 0] y [T → •F, 0].
     En otra iteración más del paso (3) incluimos además [F → •(E), 0], y [F → •a, 0].




                                                                                   ´          ´
                                                                                 Analisis Sintactico – p.39/64
Ejemplo
No podemos incluir más. El contenido de I0 queda:
   [E → •T + E, 0]
   [E → •T, 0]
   [T → •F ∗ T, 0]
   [T → •F, 0]
   [F → •(E), 0]
   [F → •a, 0]
Así que pasamos a construir ahora I1 . Por el paso (4)
observamos que [F → •(E), 0] cumple que (= a1 , y por lo
tanto añadimos [F → (•E), 0] a I1 .



                                                   ´          ´
                                                 Analisis Sintactico – p.40/64
Ejemplo
Por el paso (6), intentamos desplazar el metasímbolo a la derecha
del no-terminal E, y para ello añadimos [E → •T + E, 1] y
[E → •T, 1] a I1 . A su vez, estos generan la adición de
[T → •F ∗ T, 1] y [T → •F, 1]. Estos generan también la
incorporación de [F → •(E), 1], y [F → •a, 1]. I1 queda entonces con
el siguiente contenido:
   [F → (•E), 0]
   [E → •T + E, 1]
   [E → •T, 1]
   [T → •F ∗ T, 1]
   [T → •F, 1]
   [F → •(E), 1]
   [F → •a, 1]
Construímos ahora I2 . Ahora a2 = a. Por el paso (4), añadimos
[F → a•, 1].
                                                              ´          ´
                                                            Analisis Sintactico – p.41/64
Ejemplo
Ahora, por el paso (5) intentamos aprovechar el hecho de que se ha
reconocido parcialmente a para reducir el no-terminal que la
produce, y por ello introducimos [T → F • ∗T, 1] y [T → F •, 1].
Dado que acabamos de añadir [T → F •, 1], nuevamente, por el paso
(5) añadimos [E → T • +E, 1] y [E → T •, 1]. Este último causa la
introducción de [F → (E•), 0]. Ahora, I2 está completo.
El contenido de I2 queda:
   [F → a•, 1]
   [T → F • ∗T, 1]
   [T → F •, 1]
   [E → T • +E, 1]
   [E → T •, 1]
   [F → (E•), 0]


                                                             ´          ´
                                                           Analisis Sintactico – p.42/64
Ejemplo
La colección de cjtos. de items queda:


                    I1                    I2                      I3                    I4
            [F   → (•E), 0]                               [E   → T + •E, 1]     [F   → a•, 3]
                                [F   → a•, 1]                                   [T   → F • ∗T, 3]
            [E   → •T + E, 1]                             [E   → •T + E, 3]
                                [T   → F • ∗T, 1]                               [T   → F •, 3]
            [E   → •T, 1]                                 [E   → •T, 3]
                                [T   → F •, 1]                                  [E   → T • +E, 3]
            [T   → •F ∗ T, 1]                             [T   → •F ∗ T, 3]
                                [E   → T • +E, 1]                               [E   → T •, 3]
            [T   → •F, 1]                                 [T   → •F, 3]
                                [E   → T •, 1]                                  [E   → T + E•, 1]
            [F   → •(E), 1]                               [F   → •(E), 3]
                                [F   → (E•), 0]                                 [F   → (E•), 0]
            [F   → •a, 1]                                 [F   → •a, 3]


                      I5                             I6                               I7
                                                                        [F    → a•, 6]
       [F   → (E)•, 0]                   [T   → F ∗ •T, 0]              [T    → F • ∗T, 6]
       [T   → F • ∗T, 0]                 [T   → •F ∗ T, 6]              [T    → F •, 6]
       [T   → F •, 0]                    [T   → F •, 6]                 [T    → F ∗ T •, 0]
       [E   → T • +E, 0]                 [F   → •(E), 6]                [E    → T • +E, 0]
       [E   → T •, 0]                    [F   → •a, 6]                  [E    → T •, 0]

y como [E → T •, 0] ∈ I6 , tenemos que w ∈ L(G).



                                                                                                  ´          ´
                                                                                                Analisis Sintactico – p.43/64
Obtención de una derivación derecha
Algoritmo 4 Construcción de un árbol de derivación a partir de I 0 , I1 , . . . , In .
Entrada: una gramática CFG, libre de ciclos, G = (VN , VT , P, S), en donde las
producciones están numeradas, de 1 . . . p, una cadena w = a 1 . . . an , y la lista
I0 , I 1 , . . . , I n .
Salida: Ψ, un árbol de derivación derecho para w, ó un mensaje de error.
Método: si ∃ un [S → α•, 0] en In , entonces w ∈ L(G). Emitir salida de error. Si
                                                 /
no, hacer Ψ = λ. Ejecutar R([S → α•, 0], n), en donde R se define como sigue:
Rutina R([A → β•, i], j):
  1. Sea h el índice de A → β. Entonces, hacer Ψ ← Ψ + h
  2. Si β = X1 X2 · · · Xm , hacer k = m, l = j.
  3. Mientras que k > 0 hacer:
     (a) Si Xk ∈ VT , hacer k = k − 1 y l = l − 1.
     (b) Si Xk ∈ VN ,
          i. Encontrar un item [Xk → γ•, r] ∈ Il , para algún r
         ii. Ejecutar R([Xk → γ•, r], l). Hacer k = k − 1 y l = r.



                                                                                ´          ´
                                                                              Analisis Sintactico – p.44/64
Ejemplo
Vamos a obtener un árbol de derivación, que defina una derivación más a la derecha
para
    1.   E →T +E
    2.   E→T
    3.   T →F ∗T
    4.   T →F
    5.   F → (E)
    6.   F →a
Y w = (a + a) ∗ a la misma cadena de entrada que el ejemplo anterior. Usaremos
también la lista I1 , . . . , I7 producida en el ejemplo anterior.
Inicialmente ejecutamos R([E → T •, 0], 7). Ψ = {2}.
Paso 2. Ahora, β = T . Hacemos k = 1 y l = 7.
Paso 3b. Como X1 = T ∈ VN , tenemos que encontrar un item [T → γ•, r] ∈ I7 tal
que [E → •T, 0] esté en Ir .
    El item [T → F •, 6] ∈ I7 no vale pues [E → •T, 0] ∈ I6 .
                                                       /
    El item [T → F ∗ T •, 0] ∈ I7 si pues [E → •T, 0] ∈ I0 .


                                                                          ´          ´
                                                                        Analisis Sintactico – p.45/64
Ejemplo
Llamamos a R([T → F ∗ T •, 0], 7):
    Paso 2: β = F ∗ T , k = 3 y l = 7.
    Paso 3b: Se ha de encontrar un [T → γ•, r] ∈ I7 tal que [T → F ∗ •T, 0] ∈ Ir .
       Una opción no válida es [T → F ∗ T •, 0] porque [T → F ∗ •T.0] ∈ I 0 .
                                                                         /
       La opción correcta es [T → F •, 6] ya que [T → F ∗ •T, 0] ∈ I 6 .
    Llamamos a R([T → F •, 6], 7).
       Paso 2: β = F , k = 1 y l = 7.
       Paso 3b: Se ha de encontrar un [F → γ•, r] ∈ I7 tal que [T → •F, 6] ∈ Ir . La
       única opción es [F → a•, 6] porque [T → •F, 6] ∈ I6 .
       Al llamar a R([F → a•, 6], 7) termina la ejecución de esta rama.
       Paso 3bcont: k = k − 1. Termina.




                                                                            ´          ´
                                                                          Analisis Sintactico – p.46/64
Ejemplo
Seguimos:
   Seguimos con R([T → F ∗ T •, 0], 7)
   Paso 3bcont: k = k − 1, l = l − 1.
   Paso 3a: k = k − 1, k = 1, l = l − 1, l = 5.
   Paso 3b: Se ha de encontrar un [F → γ•, r] ∈ I5 tal que [T → •F ∗ T, 0] ∈ Ir .
   La única opción es [F → (E)•, 0] y [T → •F ∗ T, 0] ∈ I0 .
   Llamamos a R([F → (E)•, 0], 5).
      Paso 2: β = (E), k = 3 y l = 5.
      Paso 3a: k = k − 1, k = 2, l = l − 1, l = 4.




                                                                           ´          ´
                                                                         Analisis Sintactico – p.47/64
Ejemplo
Paso 3b: Se ha de encontrar un [E → γ•, r] ∈ I4 tal que [F → (•E), 0] ∈ Ir .
Tenemos las opciones:
    [E → T • +E, 3] y [E → T •, 3], no válidas.
    [E → T + E•, 1] válida ya que [F → (•E), 0] ∈ I1 .
Llamamos a R([E → T + E•, 1], 4):
    Paso 2: β = T + E, k = 3 y l = 4
    Paso 3b: Se debe encontrar un [E → γ•, r] ∈ I4 tal que [E → T + •E, 1] ∈ Ir .
    1. [E → T + E•, 1] no es válida
    2. [E → •, 3] si ya que, [E → T + •E, 1] ∈ I3 .
    Llamamos a R([E → T •, 3], 4)
    ···
Se obtiene el árbol de derivación derecho 64642156432.




                                                                             ´          ´
                                                                           Analisis Sintactico – p.48/64
Árbol de derivación obtenido
                                                 E   R([E → T •, 0], 7)




                                                 T   R([T → F ∗ T •, 0], 7)


          R([F → (E)•, 0], 5)   F                *             T    R([T → F •, 6], 7)


                        (                  )
                                                               F    R([F → a•, 6], 7)

                                E   R([E → T + E•, 1], 4)


  R([T → F •, 1], 2)    T                  E                   a
                                               R([E → T •, 3], 4)
                                +


R([F → a•, 1], 2)       F                  T   R([T → F •, 3], 4)




                        a                  F   R([F → a•, 3], 4)



                                           a




                                                                                           ´          ´
                                                                                         Analisis Sintactico – p.49/64
Transformaciones de gramáticas
1. Eliminación de símbolos inútiles
2. Gramática λ-libre
3. Eliminación de producciones unitarias
4. Eliminación de la recursividad por la izquierda
5. Factorización
6. Forma normal de Chomsky




                                                       ´          ´
                                                     Analisis Sintactico – p.50/64
Eliminación símbolos inútiles
Pasos para eliminar los símbolos no útiles de una gramática
 1. Eliminación de variables (A ∈ VN ) improductivas.
 2. Eliminación de símbolos inaccesibles.
Definición 15 Una variable A ∈ VN es improductiva si no existe ninguna
derivación tal que A ⇒∗ w con w ∈ VT .
                                   ∗

Definición 16 Un símbolo X es inaccesible si no aparece en ninguna
forma sentencial de la gramática, es decir, ¬∃α, β ∈ (VN VT )∗ tal que
S ⇒∗ αXβ.
Teorema 1 Dada una g.l.c. G = (VN , VT , S, P ), con L(G) = ∅, existe una
g.l.c. equivalente G = (VN , VT , S, P ) tal que ∀A ∈ VN se cumple que
existe una serie de derivaciones tal que A ⇒∗ w, w ∈ VT , es decir, existe
                                                          ∗

una gramática equivalente sin variables improductivas.



                                                                    ´          ´
                                                                  Analisis Sintactico – p.51/64
Eliminación de variables improductivas


El algoritmo para el cálculo de G (VN y P ) es el siguiente:
Algoritmo 5
begin
    OLDV := ∅
                                      ∗
    NEWV := {A ∈ VN |A → w ∈ P , w ∈ VT }
    while OLDV = NEWV do
    begin
       OLDV := NEWV
       NEWV := OLDV {A ∈ VN |A → α, α ∈ (VT            OLDV )∗ }
    end
    VN := NEWV
    P = {A → α ∈ P |A ∈ VN , α ∈ (VN VT )∗ }
end



                                                                     ´          ´
                                                                   Analisis Sintactico – p.52/64
Eliminación de símbolos inaccesibles
Teorema 2 Dada una g.l.c. G = (VN , VT , S, P ), con L(G) = ∅, existe una
g.l.c. equivalente G = (VN , VT , S, P ) sin símbolos inaccesibles.
El algoritmo para el cálculo de G (VN , VT y P ) es el siguiente:
Algoritmo 6
begin
    VN := {S}; VT := ∅; P := ∅;
    repeat
        for A ∈ VN , A → α1 |α2 | · · · |αn , no procesada a´n
                                                            u
            {a˜adir todas las variables de αi a VN
              n
            a˜adir todos los terminales de αi a VT }
             n
        until VN no var´e ı
    P = {A → α ∈ P |A ∈ VN ∧ α ∈ (VN VT )∗ }
end



                                                                      ´          ´
                                                                    Analisis Sintactico – p.53/64
Eliminación de símbolos inútiles
Teorema 3 Dada una gramática libre de contexto G, con
L(G)= ∅, existe una GLC G’ equivalente sin símbolos inútiles.
Los pasos a seguir serían (el orden es importante):
    Pasamos de G a G1 según el algoritmo 5
    Pasamos de G1 a G’ según el algoritmo 6
G’ no contiene símbolo inútiles, es decir, todo símbolo
X ∈ (VN ∪ VT ) es tal que S ⇒∗ αXβ ⇒∗ w.




                                                            ´          ´
                                                          Analisis Sintactico – p.54/64
Grámatica λ-libre
Definición 17 Decimos que una gramática l.c.
G = (VN , VT , S, P ) es λ-libre si cumple que en sus reglas de
producción no aparece ninguna de la forma A → λ, excepto a
los sumo S → λ, con la condición de que S no aparezca en la
parte derecha de ninguna otra regla de producción.



Teorema 4 Dada una g.l.c. G = (VN , VT , S, P ), existe una
g.l.c. equivalente G = (VN , VT , S , P ) que es λ-libre.




                                                          ´          ´
                                                        Analisis Sintactico – p.55/64
Grámatica λ-libre
Algoritmo 7

  1. Obtenemos Vλ = {A ∈ VN |A ⇒∗ λ}: Conjunto de variables anulables
     Inicialmente Vλ contiene A si A → λ. Luego, si tenemos B → x1 x2 . . . xn y xi ∈ Vλ
     ∀i, añadir B.
  2. Obtenemos P del siguiente modo:
     Por cada producción A → x1 x2 . . . xk (k > 0) añadimos:
     A → Y1 Y2 . . . Yn , dónde cada Yi es:
     (a) Si xi no es anulable entonces Yi = xi
     (b) Si x ∈ Vλ , entonces se toma Yi como xi y como λ
     (c) No añadir ninguna producción A → λ
  3. Si λ ∈ L(G) entonces VN = VN y S = S.
     En otro caso,
     (a) si S no aparece en la parte derecha
          i. Añadir la producción S → λ
         ii. VN = VN y S = S
     (b) en otro caso
          i. VN = VN {S }, siendo S el nuevo símbolo inicial
         ii. Añadir a P S → S|λ
                                                                                 ´          ´
                                                                               Analisis Sintactico – p.56/64
Eliminación de producciones unitarias
 Definición 18 Llamamos producciones unitarias a las que tienen la
 forma A → B, con A, B ∈ VN .
 Teorema 5 Dada una g.l.c. G = (VN , VT , S, P ) existe una g.l.c.
 equivalente G = (VN , VT , S, P ) que no contiene producciones unitarias.
 El algoritmo para calcular G’ es el siguiente:
 Algoritmo 8 1. Suponemos que G es λ-libre; si no es así, se
     transforma según el algoritmo 3
  2. Para cada A ∈ VN se calcula VV (A) = {B ∈ VN |A ⇒+ B}.
  3. P = Producciones no unitarias de P .
  4. Para cada A ∈ VN tal que VV (A) = ∅.
        Para cada B ∈ VV (A)
            Para cada B → β ∈ P (no unitaria)
              Añadir A → β a P

                                                                     ´          ´
                                                                   Analisis Sintactico – p.57/64
Gramática libre de ciclos
Definición 19 Una gramática libre de ciclos es aquella que no contiene
derivaciones de la forma A ⇒∗ A.
Definición 20 Una gramática es propia si no tiene símbolos inútiles, es
λ-libre y libre de ciclos.
Para convertir una gramática en otra equivalente propia, podemos seguir
los siguientes pasos:
 1. Pasar la gramática a una equivalente λ-libre.
 2. Eliminar las producciones unitarias (no hay ciclos).
 3. Eliminar símbolos inútiles.

No debemos olvidar que una gramática puede tener producciones uni-

tarias y ser propia.



                                                                  ´          ´
                                                                Analisis Sintactico – p.58/64
Recursividad en las gramáticas
Definición 21 Una gramática G = (VN , VN , P, S) es recursiva por la izquierda (derecha) si
                                                    +             +
existe un A ∈ VN tal que existe una derivación A =⇒ Aα (A =⇒ αA) para alguna cadena
α.
Definición 22 Una gramática G = (VN , VN , P, S) es recursiva si existe un A ∈ VN tal que
                        +
existe una derivación A =⇒ αAβ.
Algoritmo 9 Eliminación de la recursividad inmediata por la izquierda.
Entrada: Un conjunto de producciones {pi /pi ∈ P } con el no terminal A ∈ VN como parte
izquierda de una gramática G CFG sin λ-producciones.
Salida: Un nuevo conjunto de producciones sin recursividad inmediata por la izquierda.
  1. Ordénense las producciones de Ai en la forma
                            A → Aα1 |Aα2 | · · · |Aαm |β1 |β2 | · · · |βn
     en donde ninguna βi comienza con A.
  2. Sustituir todas las producciones de A por
     A → β1 A |β2 A | · · · |βn A
     A → α1 A |α2 A | · · · |αm A |λ
  3. La salida es el conjunto de nuevas producciones obtenidas en el paso anterior.


                                                                                  ´          ´
                                                                                Analisis Sintactico – p.59/64
Recursividad en las gramáticas (III)
Algoritmo 10 Eliminación de la recursividad por la izquierda.
Entrada: La gramática G propia
Salida: Una gramática equivalente, sin recursividad por la izquierda.
 1. Ordénense los Ai ∈ VN en un orden A1 , A2 , . . . , An .
 2. for i:=1 to n do
        begin
           forj:= 1 to i − 1 do
              sustituir cada producción de la forma Ai → Aj γ
              por las producciones Ai → δ1 γ|δ2 γ| · · · |δk γ, en
              donde Aj → δ1 |δ2 | · · · |δk es el conjunto de
              producciones actuales del no terminal Aj ;
           Además, eliminar la recursividad inmediata por la
           izquierda de las producciones de Ai .
        end

                                                                       ´          ´
                                                                     Analisis Sintactico – p.60/64
Forma normal de Chomsky


Definición 23 Sea una CFG G = (VN , VT , P, S). Se dice que
G está en Forma Normal de Chomsky (CNF), si toda
producción de P está en una de las formas siguientes:
1. A → BC, en donde A, B y C están en VN ,
2. A → a, en donde A ∈ VN y a ∈ VT ,
3. Si λ ∈ L(G) entonces S → λ está en P y además S no
   aparece en la parte derecha de ninguna producción de P .




                                                      ´          ´
                                                    Analisis Sintactico – p.61/64
Forma normal de Chomsky (II)

Algoritmo 11 Conversión a Forma Normal de Chomsky.
Entrada: Una gramática CFG propia, G = (VN , VT , P, S) sin producciones simples.
Salida: Una gramática G en forma CNF, tal que L(G) = L(G ).
Método: Sea el conjunto P formado por las producciones siguientes:
   1. Añadir toda producción en la forma A → a ∈ P
   2. Añadir toda producción en la forma A → AB ∈ P
   3. Si S → λ ∈ P entonces añadirla también.
   4. Para cada producción en la forma A → X1 · · · Xk con k > 2, añadir las producciones resultantes a
       continuación: asumimos que Xi representa a Xi si Xi ∈ VN , y Xi es un nuevo no-terminal si Xi ∈ VT . Las
       nuevas producciones serán las siguientes:
             A → X 1 < X2 · · · X k >
             < X2 · · · Xk >→ X2 < X3 · · · Xk >
             ···
             < Xk−2 · · · Xk >→ Xk−2 < Xk−1 Xk >
            < Xk−1 Xk >→ Xk−1 Xk
       en donde cada < Xi · · · Xk > es un nuevo símbolo no-terminal.
   5. Para cada producción de la forma A → X1 X2 en donde bien X1 o X2 ó los dos están en VT , añadir
       A → X 1 X2 a P

   6. Para cada a introducido en los pasos 4 y 5, añadir a → a. Sea VN igual a VN más todos los nuevos
      no-terminales introducidos en los pasos anteriores.
La nueva gramática G = (VN , VT , P , S) es la deseada.


                                                                                                       ´          ´
                                                                                                     Analisis Sintactico – p.62/64
Forma normal de Chomsky (III)


Veamos la aplicación del algoritmo con la gramática CFG cuyo conjunto
P está formado por las siguientes producciones:
    S → aAB|BA
    A → BBB|a
    B → AS|b
En el nuevo conjunto P introducimos las producciones S → BA, A → a y
B → AS|b. La producción S → aAB generará el siguiente grupo de
nuevas producciones
    S → a < AB >
    < AB >→ AB
    a →a

que irán a parar a P .


                                                                 ´          ´
                                                               Analisis Sintactico – p.63/64
Forma normal de Chomsky (IV)


Para la producción A → BBB, se generarán las siguientes nuevas producciones
     A → B < BB >
     < BB >→ BB
que también se introducirán en P . La nueva gramática, G = (VN , VT , P , S) quedará, con
VN = {S, A, B, < BB >, < AB >, a }, y P contendrá las siguientes producciones:
     S → a < AB > |BA
     A → B < BB > |a
     B → AS|b
     < AB >→ AB
     < BB >→ BB
     a →a




                                                                                 ´          ´
                                                                               Analisis Sintactico – p.64/64

Mais conteúdo relacionado

Mais procurados

Conjuntos regulares 04[1]
Conjuntos regulares 04[1]Conjuntos regulares 04[1]
Conjuntos regulares 04[1]
edeciofreitez
 
Ejercicios con Lenguajes Formales
Ejercicios con Lenguajes FormalesEjercicios con Lenguajes Formales
Ejercicios con Lenguajes Formales
vmtorrealba
 
Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1
Osiris Mirerus
 
Clase4: Transformación desde Expresión regular a Autómata finito determinista
Clase4: Transformación desde Expresión regular a Autómata finito deterministaClase4: Transformación desde Expresión regular a Autómata finito determinista
Clase4: Transformación desde Expresión regular a Autómata finito determinista
mvagila
 
Analisis lexico 2
Analisis lexico 2Analisis lexico 2
Analisis lexico 2
perlallamas
 
Maquina de Estado Finito, Circuito Secuenciales y Automatas de Estado Finito
Maquina de Estado Finito, Circuito Secuenciales y Automatas de Estado FinitoMaquina de Estado Finito, Circuito Secuenciales y Automatas de Estado Finito
Maquina de Estado Finito, Circuito Secuenciales y Automatas de Estado Finito
Rosangela Perez
 

Mais procurados (20)

Lenguajes no regulares
Lenguajes no regularesLenguajes no regulares
Lenguajes no regulares
 
Conjuntos regulares 04[1]
Conjuntos regulares 04[1]Conjuntos regulares 04[1]
Conjuntos regulares 04[1]
 
Ejercicios con Lenguajes Formales
Ejercicios con Lenguajes FormalesEjercicios con Lenguajes Formales
Ejercicios con Lenguajes Formales
 
Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1
 
Curso de UML 2.0
Curso de UML 2.0 Curso de UML 2.0
Curso de UML 2.0
 
Autómatas Finitos
Autómatas FinitosAutómatas Finitos
Autómatas Finitos
 
09 Clases Abstractas E Interfaces
09   Clases Abstractas E Interfaces09   Clases Abstractas E Interfaces
09 Clases Abstractas E Interfaces
 
Clase4: Transformación desde Expresión regular a Autómata finito determinista
Clase4: Transformación desde Expresión regular a Autómata finito deterministaClase4: Transformación desde Expresión regular a Autómata finito determinista
Clase4: Transformación desde Expresión regular a Autómata finito determinista
 
04 j flex
04 j flex04 j flex
04 j flex
 
Manejo de memoria
Manejo de memoriaManejo de memoria
Manejo de memoria
 
Redes neuronales-funciones-activacion-hardlim- hardlims-matlab
Redes neuronales-funciones-activacion-hardlim- hardlims-matlabRedes neuronales-funciones-activacion-hardlim- hardlims-matlab
Redes neuronales-funciones-activacion-hardlim- hardlims-matlab
 
Analisis lexico 2
Analisis lexico 2Analisis lexico 2
Analisis lexico 2
 
Autómatas de pila
Autómatas de pila Autómatas de pila
Autómatas de pila
 
Maquina de Estado Finito, Circuito Secuenciales y Automatas de Estado Finito
Maquina de Estado Finito, Circuito Secuenciales y Automatas de Estado FinitoMaquina de Estado Finito, Circuito Secuenciales y Automatas de Estado Finito
Maquina de Estado Finito, Circuito Secuenciales y Automatas de Estado Finito
 
Gramaticas y lic
Gramaticas y licGramaticas y lic
Gramaticas y lic
 
Tipos de autómatas
Tipos de autómatasTipos de autómatas
Tipos de autómatas
 
Operaciones entre lenguajes
Operaciones entre lenguajesOperaciones entre lenguajes
Operaciones entre lenguajes
 
Tutorial de JFLAP
Tutorial de JFLAPTutorial de JFLAP
Tutorial de JFLAP
 
Algoritmos de Dijkstra, Warshall, Ordenación Topológica.
Algoritmos de Dijkstra, Warshall, Ordenación Topológica.Algoritmos de Dijkstra, Warshall, Ordenación Topológica.
Algoritmos de Dijkstra, Warshall, Ordenación Topológica.
 
Gramática Libre de Contexto
Gramática Libre de ContextoGramática Libre de Contexto
Gramática Libre de Contexto
 

Mais de Oscar Eduardo (20)

Introducción a IngSW_2022.pptx
Introducción a IngSW_2022.pptxIntroducción a IngSW_2022.pptx
Introducción a IngSW_2022.pptx
 
Inventario tic
Inventario ticInventario tic
Inventario tic
 
Trayecto de actividades_diplomado
Trayecto de actividades_diplomadoTrayecto de actividades_diplomado
Trayecto de actividades_diplomado
 
Modelo pruebas
Modelo pruebasModelo pruebas
Modelo pruebas
 
Framework Android
Framework AndroidFramework Android
Framework Android
 
Comunicación
ComunicaciónComunicación
Comunicación
 
Modelos de Mediación
Modelos de MediaciónModelos de Mediación
Modelos de Mediación
 
Lenguajes regulares
Lenguajes regularesLenguajes regulares
Lenguajes regulares
 
User stories
User storiesUser stories
User stories
 
App upb móvil 20141
App upb móvil 20141App upb móvil 20141
App upb móvil 20141
 
Subir una aplicación a google play
Subir una aplicación a google playSubir una aplicación a google play
Subir una aplicación a google play
 
Analisis sintáctico
Analisis sintácticoAnalisis sintáctico
Analisis sintáctico
 
Iswiii
IswiiiIswiii
Iswiii
 
Presentacion rup
Presentacion rupPresentacion rup
Presentacion rup
 
Arquitectura sistema
Arquitectura sistemaArquitectura sistema
Arquitectura sistema
 
Doctic modelopropuestadeintervencin
Doctic modelopropuestadeintervencinDoctic modelopropuestadeintervencin
Doctic modelopropuestadeintervencin
 
Isw
IswIsw
Isw
 
Iswii
IswiiIswii
Iswii
 
Cod intermedio
Cod intermedioCod intermedio
Cod intermedio
 
Generalidades sobre windows phone 7.5
Generalidades sobre windows phone 7.5Generalidades sobre windows phone 7.5
Generalidades sobre windows phone 7.5
 

Analisis sintactico

  • 1. Análisis Sintáctico Tema 3 Juan A. Bot´a Blaya ı juanbot@um.es http://ants.dif.um.es/staff/juanbot/traductores/traductores.html ´ Departamento de Ingenier´a de la Informacion y las Comunicaciones ı Universidad de Murcia ´ ´ Analisis Sintactico – p.1/64
  • 2. Índice Introducción al Análisis Sintáctico. 1. Objetivo del analizador sintáctico 2. Gramáticas libres de contexto y autómatas con pila 3. Análisis sintáctico ascendente y descendente 4. El problema de la ambigüedad en el análisis sintáctico 5. Métodos Universales de análisis sintáctico (a) El método de Cocke-Younger-Kasami (b) El método de Early 6. Transformaciones de gramáticas ´ ´ Analisis Sintactico – p.2/64
  • 3. Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) Definición 1 Una gramática libre de contexto G = (V N , Vt , S, P ) es aquella cuyas producciones tienen la forma A → α, siendo A ∈ VN y α ∈ (VN VT )∗ . Definición 2 Un autómata de pila se define como una 7-tupla AP = (Q, V, Σ, δ, q 0 , z0 , F ) en donde: Q es un conjunto finito de estados. V es el alfabeto de entrada. Σ es el alfabeto de la pila. q0 es el estado inicial. z0 es el símbolo inicial de la pila. F ⊆ Q es el conjunto de estados finales. δ es la función de transición: ∗ δ: Q × (V ∪ {λ}) × Σ → 2Q×Σ ´ ´ Analisis Sintactico – p.3/64
  • 4. Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) Definición 3 Se entiende por configuración de un atomómata con pila a su situación en un instante considerado expresada formalmente por medio de una tripla (q, w, α) ∈ (Q × V ∗ × Σ∗ ) en donde: q ∈ Q es el estado actual del autómata. w ∈ V ∗ es la subcadena de entrada que aun no se ha analizado. α ∈ Σ∗ es el contenido actual de la pila. Si w = λ no queda nada por analizar. Si α = λ se ha reconocido la cadena. ´ ´ Analisis Sintactico – p.4/64
  • 5. Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) (II) Definición 4 Un movimiento de un AP es una transición entre configuraciones. Una transición no tiene porqué realizarse en un solo movimiento. Por ej. el movimiento (q, aw, Zα) (q , w, βα) es un movimiento válido siempre y cuando (q , β) ∈ δ(q, a, Z) con q ∈ Q, a ∈ (V ∪ λ), w ∈ V ∗ , α, β ∈ Σ∗ . Se debe señalar que un AP no puede realizar ningún movimiento si la pila está vacía. Entonces, un autómata de pila reconocerá una cadena de entrada sii partiendo de su configuración inicial, (q0 , t, Z0 ), llega a una configuración final (qf , λ, α) empleando movimientos válidos y lo expresamos: ∗ (q0 , t, Z0 ) (qf , λ, α), qf ∈ F, α ∈ Σ∗ La cadena será aceptada por vaciado de pila si despues de leerse toda la cadena se llega a un estado con la pila vacía, independientemente del tipo de estado en el que se encuentre el AP. ´ ´ Analisis Sintactico – p.5/64
  • 6. Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) (III) Ejemplo. Sea G = (VN , VT , P, S) con P S →S+A S→A A→A∗B A→B B → (S) B→a Sea AP = (Q, V, Σ, δ, q, s, ∅) en donde Q = {q}, V = {a, +, ∗, (, )} y δ: δ(q, λ, S) = {(q, S + A), (q, A)} δ(q, λ, A) = {(q, A ∗ B), (q, B)} δ(q, λ, B) = {(q, (S)), (q, a)} δ(q, op, op) = {(q, λ)} siendo op ∈ V . Intentaremos reconocer la cadena w = a + a ∗ a. ´ ´ Analisis Sintactico – p.6/64
  • 7. Gramáticas libres de contexto (CFG) y Autómatas de pila (PA) (IV) Ejemplo (y II) El árbol de alternativas posibles es (q,a+a*a,S) . (q,a+a*a,A) . (q,a+a*a,S+A) . . (q,a+a*a,S+A+A) (q,a+a*a,A+A) . . (q,a+a*a,B+A) . (q,a+a*a,A*B+A) . . . (q,a+a*a,(S)+A) (q,a+a*a,a+A) . . (q,+a*a,+A) (q,a*a,A) . (q,a*a,B) (q,a*a,A*B) . . (q,a*a,B*B) (q,a*a,(S)*B) . (q,a*a,a*B) . . (q,*a,*B) (q,a,B) (q,a,a) (q,,) ´ ´ Analisis Sintactico – p.7/64
  • 8. Análisis Sintáctico Ascendente y Descendente Definición 5 Una sentencia w ∈ L(G), para alguna CFG (Context Free Grammar) ha sido reconocida cuando conocemos alguno de (o quizá todos) sus árboles de derivación. Definición 6 Sea una gramática G = (VN , VT , P, S). Se dice que la cadena α deriva directamente a la cadena β, denotándolo α ⇒ β, si se puede escribir α = δAµ y β = δγµ para alguna cadena δ y µ ∈ (VT ∪ VN )∗ , y además existe A → γ ∈ P . Definición 7 Sea una gramática G = (VN , VT , P, S). Para cualquier A ∈ VN y ∗ α ∈ (VN ∪ VT )∗ se dice que A =⇒ α si α se deriva de A, con una cadena de derivaciones de longitud cualqiera, incluso nula. ´ ´ Analisis Sintactico – p.8/64
  • 9. Análisis Sintáctico Ascendente y Descendente Definición 8 Sea una gramática G = (VN , VT , P, S). Las formas sentenciales de G vienen dadas por el conjunto ∗ D(G) = {α / S =⇒ α y α ∈ (VN ∪ VT )∗ } Definición 9 El lenguaje definido por una gramática G, denotado L(G) es el conjunto de cadenas de símbolos terminales, que se pueden derivar partiendo del axioma de la gramática, y empleando para las derivaciones las reglas de P . E.d.: ∗ L(G) = {x/S =⇒ x, y x ∈ T ∗ } Definición 10 Sea una gramática G = (VN , VT , P, S). Sea una forma sentencial αβγ en donde α ∈ VT , β ∈ VN y γ ∈ (VT ∪ VN )∗ . Una derivación izquierda se obtiene ∗ sustituyendo β por alguna de las partes derechas que la definen. Definición 11 Sea una gramática G = (VN , VT , P, S). Sea una forma sentencial αβγ en donde α ∈ (VT ∪ VN )∗ , β ∈ VN y γ ∈ VT . Una derivación derecha se obtiene sustituyendo ∗ β por alguna de las partes derechas que la definen. ´ ´ Analisis Sintactico – p.9/64
  • 10. Análisis Sintáctico Ascendente y Descendente (II) A → BF B → EC Un ejemplo de este tipo de derivaciones, para la gramática E → a puede verse C → b F → c A D Derivación derecha I Derivación izquierda BF I D ECF Bc I D aCF EbF ECc ECc I D abF aCc abF Ebc aCc Ebc aCc Ebc I D en el árbol abc abc abc abc abc abc abc abc ´ ´ Analisis Sintactico – p.10/64
  • 11. Análisis Sintáctico Ascendente y Descendente (III) Existen dos grandes grupos de métodos de análisis sintáctico, dependiendo de la dirección en la que se recorre el árbol sintáctico. Descendente: en este tipo de análisis, se va recorriendo el árbol sintáctico desde la raíz hasta las hojas, llegando a generar la sentencia que se está analizando. La raíz representa al símbolo inicial de la gramática. Ascendente: se parte de las hojas y se intenta construir el árbol hacia arriba, hasta llegar al símbolo inicial de la gramática. En un análisis top-down un parser hacer corresponder cadenas de entrada con sus correspondientes derivaciones izquierdas. En un análisis bottom-up un parser hace corresponder cadenas de entrada con las inversas de las correspondientes derivaciones derechas. Entre los métodos generales, los algoritmos de Cocke-Younger-Kasami (CYK) y el método de Early son los más conocidos → son bastante ineficientes desde un punto de vista computacional. Para la mayoría de lenguajes de programación es suficiente con trabajar con subconjuntos de las CFG, como los de las LL y LR que permiten algoritmos de parsing más eficientes. ´ ´ Analisis Sintactico – p.11/64
  • 12. El problema de la ambigüedad en el análisis sintáctico Definición 12 Un árbol ordenado y etiquetado D es un árbol de derivación para una gramática libre de contexto G(S) = (VN , VT , P, S) si: 1. La raíz de D está etiquetada con S. 2. Si D1 , . . . , Dk son los subárboles de los descendientes directos de la raíz, y la raíz de cada Di está etiquetada con Xi , entonces S → X1 · · · Xk ∈ P . Además Di debe ser un árbol de derivación en G(Xi ) = (VN , VT , P, Xi ) si Xi ∈ VN , bien un nodo hoja con etiqueta Xi si Xi ∈ VT . 3. Alternativamente, si D1 es el único subárbol de la raíz de D, y la raíz de D 1 tiene como etiqueta e, entonces S → e ∈ P . Definición 13 La frontera de un árbol de derivación es la cadena que se obtiene concatenando, de izquierda a derecha, las etiquetas de las hojas. Definición 14 Sea una CFG G = (VN , VT , P, S). Decimos que G es ambigua si existe al menos una sentencia w ∈ L(G) para la cual hay un árbol de derivación distinto, con frontera w. ´ ´ Analisis Sintactico – p.12/64
  • 13. El problema de la ambigüedad en el análisis sintáctico (II) El hecho de que una gramática sea ambigua es una situación indeseable ya que cada árbol de derivación representa una ejecución distinta de la misma sentencia, y por lo tanto cada uno podría producir resultados distintos. sea la gramática G = (VN , VT , P, S) con P = {E → E + E, E → E ∗ E, E → a} Ejemplo: Caben dos interpretaciones para a + a ∗ a: E E E + E E * E a E * E E + E a a a a a ´ ´ Analisis Sintactico – p.13/64
  • 14. El problema de la ambigüedad en el análisis sintáctico (III) Otro ejemplo clásico de este tipo de problemas es el de las gramáticas que incluyen sentencias del tipo if-then/if-then-else. Sea la gramática prop → if expr then prop | if expr then prop else prop | otra De acuerdo con ella, la sentencia if E1 then S1 else if E2 then S2 else S3 no es ambigua, ya que el árbol de derivación correspondiente sería prop if expr then prop else prop E1 S1 if expr then prop else prop E2 S2 S3 ´ ´ Analisis Sintactico – p.14/64
  • 15. El problema de la ambigüedad en el análisis sintáctico (IV) sin embargo, la sentencia if E1 then if E1 then S1 else S2 si lo sería, ya que daría lugar a la siguiente pareja de árboles de derivación distintos. prop prop if expr then prop E1 if expr then prop else prop E1 S1 if expr then prop else prop E2 S1 S2 if expr then prop E2 S2 ´ ´ Analisis Sintactico – p.15/64
  • 16. El problema de la ambigüedad en el análisis sintáctico (V) Hay dos enfoques distintos usados para solucionar este problema. 1. Transformar la definición del lenguaje para que las construcciones if-then-else tengan delimitadores de bloque, y los else se asocien con los if explícitamente. 2. Transformar la gramática en otra equivalente y que no sea ambigua. ´ ´ Analisis Sintactico – p.16/64
  • 17. El problema de la ambigüedad en el análisis sintáctico (VI) Ejemplo con el método 1: prop → if expr then prop endif | if expr then prop else prop endif | otra entonces, para escribir una sentencia como la del ejemplo, y en la que se asocie el else al segundo if quedaría if E1 then if E1 then S1 else S2 endif endif Una sentencia que ahora asociara el else con el primer if sería if E1 then if E1 then S1 endif else S2 endif ´ ´ Analisis Sintactico – p.17/64
  • 18. El problema de la ambigüedad en el análisis sintáctico (VII) Ejemplo con el método 2: Se debe elegir entre los dos árboles de la transparencia 10. Elegir el árbol de la izquierda implica emparejar el else con el then anterior y sin emparejar más cercano. Elegir el árbol de la derecha implica emparejar el else con el then más lejano y que aun esté sin emparejar. Eligiendo el árbol de la izquierda, se dividen las proposiciones entre emparejadas y no emparejadas. Toda proposición que aparezca entre un then y un else debe estar emparejada, e.d. no debe terminar con un then sin emparejar porque entonces el else estaría obligado a concordar con ella. Una proposición emparejada es ó una proposición if-then-else que no contenga proposiciones sin emparejar o cualquier otra clase de proposición no condicional. prop → prop_emparejada | prop_no_emparejada prop_emparejada → if expr then prop_emparejada else prop_emparejada | otra prop_no_emparejada → if expr then prop | if expr then prop_emparejada else prop_no_emparejada ´ ´ Analisis Sintactico – p.18/64
  • 19. Métodos universales de análisis sintáctico Aplicables a cualquier GLC Métodos tabulares Complejidad espacial O(n2 ) y temporal O(n3 ) No aplicables para lenguajes de programación convencionales Aplicables si interesan todos los árboles de derivación posibles (G. ambiguas) ´ ´ Analisis Sintactico – p.19/64
  • 20. Algoritmo Cocke-Younger-Kasami Basado en programación dinámica Poca aplicabilidad Complejidad espacial proporcional a n2 (n longitud de w) Complejidad temporal proporcional a n3 Algoritmo de Early consigue complejidades lineales para muchas gramáticas LC Necesita gramáticas en CNF y λ−libres ´ ´ Analisis Sintactico – p.20/64
  • 21. CYK-Funcionamiento básico Sea w = a1 a2 . . . an con ai ∈ VT ∀i = 1, . . . , n El algoritmo construye una tabla T triangular, con elementos tij ⊂ VN , 1 ≤ i ≤ n y 1 ≤ j ≤ n − i + 1, j t11 t12 t13 t14 t21 t22 t23 i t31 t32 t41 en donde A ∈ tij sii A ⇒+ ai ai+1 · · · ai+j−1 Entonces w ∈ L(G) si S ∈ t1n ´ ´ Analisis Sintactico – p.21/64
  • 22. Métodos Universales de análisis sintáctico. El algoritmo CYK Algoritmo 1 Algoritmo de análisis sintáctico de Cocke-Younger-Kasami. Entrada: Una gramática G = (VN , VT , P, S) en CNF y sin λ-producciones, junto con una ∗ cadena de entrada w = a1 a2 · · · an ∈ VT . + Salida: La tabla T en la que cada ti,j contiene a A ∈ VN sii A =⇒ ai ai+1 · · · ai+j−1 . Método: 1. Hacer ti,1 = {A|A → ai ∈ P } para todo i. 2. Supongamos que ti,j se ha calculado para todo i, 1 ≤ i ≤ n, y para todo j , 1 ≤ j < j. Hágase ti,j = {A| para algun k , 1 ≤ k < j, A → BC ∈ P, B ∈ ti,k , y C ∈ ti+k,j−k } Dado que i ≤ k < j, tanto k como j − k son menores que j. Por lo tanto, t i,k y ti+k,j−k han sido calculados antes de ti,j . Después de este paso, si ti,j contiene a A, entonces + + A ⇒ BC =⇒ ai · · · ai+k−1 C =⇒ ai · · · ai+k−1 ai+k · · · ai+j−1 3. Realizar el paso anterior, hasta que ti,j haya quedado calculado para todo 1 ≤ i ≤ n y 1 ≤ j ≤ n − i + 1. ´ ´ Analisis Sintactico – p.22/64
  • 23. CYK-Observaciones Se trata de encontrar A, B, C tales que C A B a1 a2 . . . ai . . .. . . ai+j−1 . . . an hasta que al final tengamos S D E a1 a2 . . .. . . an y por lo tanto podamos asegurar que S → DE ⇒+ a1 a2 . . . E ⇒+ a1 a2 . . . an ´ ´ Analisis Sintactico – p.23/64
  • 24. Métodos Universales de análisis sintáctico. El algoritmo CYK (II) Veámos la aplicación del algoritmo con un ejemplo en el que el conjunto P de nuestra gramática viene dado por el conjunto de producciones S → AA|AS|b A → SA|AS|a Sea w = abaab la cadena de entrada. Aplicando el algoritmo, la tabla resultante será una triangular de 5 × 5. Aplicando el paso 1, tenemos t11 = {A}, ya que A → a ∈ P . t21 = {S}, ya que S → b ∈ P . t31 = {A}, ya que A → a ∈ P . t41 = {A}, ya que S → a ∈ P . t51 = {S}, ya que A → b ∈ P . ´ ´ Analisis Sintactico – p.24/64
  • 25. Métodos Universales de análisis sintáctico. El algoritmo CYK (III) Ahora, hacemos j = 2. Tenemos que ti,j se ha calculado para j = 1. Tenemos que encontrar no-terminales que produzcan subcadenas de w de longitud 2. t1,2 = {S, A}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t1,1 y el segundo no-terminal en t2,1 . Por lo tanto la parte derecha ha de ser AS. Tanto S como A tienen reglas con esa parte derecha. t22 = {A}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t2,1 y el segundo no-terminal en t3,1 . La parte derecha sería SA. Únicamente A tiene partes derechas de ese tipo. t3,2 = {S}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t3,1 , y el segundo en t4,1 . Por lo tanto, la parte derecha sería AA. Sólamente S tiene reglas de producción con esa parte derecha. t4,2 = {A, S}, ya que 1 ≤ k < 2, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t4,1 , y el segundo en t5,1 . Por lo tanto, la parte derecha sería AS. ´ ´ Analisis Sintactico – p.25/64
  • 26. Métodos Universales de análisis sintáctico. El algoritmo CYK (IV) Después de hacer el paso 2, con j = 2 la tabla T queda así: 1 2 3 4 5 1 {A} {S, A} 2 {S} {A} 3 {A} {S} 4 {A} {A, S} 5 {S} ´ ´ Analisis Sintactico – p.26/64
  • 27. Métodos Universales de análisis sintáctico. El algoritmo CYK (V) Ahora, hacemos j = 3. Tenemos que ti,j se ha calculado para 1 ≤ j < 3. Tenemos que encontrar no-terminales que produzcan subcadenas de w, de longitud 3. t1,3 = {A, S}, ya que 1 ≤ k < 3, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t1,1 (o en t1,2 ) y el segundo no-terminal en t2,2 (o en t3,1 ). Por lo tanto la parte derecha ha de ser AA (o SA). t2,3 = {S}, ya que 1 ≤ k < 3, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t2,1 (o en t2,2 ) y el segundo no-terminal en t3,2 (o en t4,1 ). La parte derecha sería SS (o AA). Únicamente S tiene una producción S → AA. t3,3 = {A, S}, ya que 1 ≤ k < 3, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t3,1 (o en t3,2 ), y el segundo en t4,2 (o en t5,1 ). Con t3,1 y t4,2 tenemos dos posibles partes derechas que son AA y AS, y por ello tanto S como A deben estar en t3,3 . Con t3,2 y t5,1 tenemos como parte derecha SS, que no es generada por ningun no-terminal. ´ ´ Analisis Sintactico – p.27/64
  • 28. Métodos Universales de análisis sintáctico. El algoritmo CYK (VI) Después de hacer el paso 2, con j = 3 la tabla T queda así: 1 2 3 4 5 1 {A} {S, A} {A, S} 2 {S} {A} {S} 3 {A} {S} {A, S} 4 {A} {A, S} 5 {S} ´ ´ Analisis Sintactico – p.28/64
  • 29. Métodos Universales de análisis sintáctico. El algoritmo CYK (VII) Ahora, hacemos j = 4. Tenemos que ti,j se ha calculado para 1 ≤ j < 4. Tenemos que encontrar no-terminales que produzcan subcadenas de w, de longitud 4. t1,4 = {A, S}, ya que 1 ≤ k < 4, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t1,1 , k = 1, o en t1,2 , k = 2, o en t1,3 , k = 3 y el segundo no-terminal en t2,3 , k = 1, o en t3,2 , k = 2 o en t4,1 . El conjunto de no-terminales que podrían formar el primer no-terminal de la parte derecha es {A, S} y el de no-terminales que podrían formar el segundo no-terminal de la parte derecha es {A, S}. Por lo tanto la parte derecha va a estar en {AA, AS, SA, SS}. t2,4 = {A, S}, ya que 1 ≤ k < 4, y la regla ha de ser tal que el primer no-terminal de la parte derecha esté en t2,1 , k = 1, o en t2,2 , k = 2 o en t2,3 , k = 3 y el segundo no-terminal en t3,3 , k = 1, o en t4,2 , k = 2, o en t5,1 . El conjunto de no-terminales que podrían formar el primer no-terminal de la parte derecha es {A, S}, y el de no-terminales que podrían formar el segundo no-terminal de la parte derecha es {A, S}. Por lo tanto la parte derecha va a estar en {AA, AS, SA, SS}. ´ ´ Analisis Sintactico – p.29/64
  • 30. Métodos Universales de análisis sintáctico. El algoritmo CYK (VIII) Después de hacer el paso 2, con j = 4 la tabla T queda así: 1 2 3 4 5 1 {A} {S, A} {A, S} {A,S} 2 {S} {A} {S} {A, S} 3 {A} {S} {A, S} 4 {A} {A, S} 5 {S} Hacer el paso 2, con j = 5 en clase, y completar la tabla T con t1,5 . ´ ´ Analisis Sintactico – p.30/64
  • 31. Obteniendo una secuencia de derivaciones a partir de T Especifiación algorítmica Algoritmo 2 Derivación más a la izquierda a partir de la tabla T de parsing. Entrada: una gramática G = (VN , VT , P, S) en formato CNF, y en la que las producciones de P están numeradas de 1 a p, una cadena de entrada w = a1 a2 · · · an , y la tabla T generada por el algoritmo CYK. Salida: una derivación izquierda de w o un error. Método: se va a basar en el uso de una rutina recursiva gen(i, j, A) que va a generar + la derivación A =⇒ ai ai+1 · · · ai+j−1 . Se define como sigue: 1. Si j = 1 y la producción m-ésima es A → ai , entonces la salida de gen(i, 1, A) es m. 2. Si j > 1, sea k el entero más pequeño, 1 ≤ k < j, tal que para algún B ∈ t i,k y C ∈ ti+k,j−k se tiene que A → BC ∈ P . Si hay varias, elegimos la que tenga el índice más pequeño, digamos m. La salida de gen(i, j, A) es m, más las salidas de gen(i, k, B) y gen(i + k, j − k, C). Por lo tanto, para obtener la derivación para w llamamos a gen(1, n, S) ´ ´ Analisis Sintactico – p.31/64
  • 32. Obteniendo una secuencia de derivaciones a partir de T Tomemos la gramática del ejemplo anterior y dispongámosla en el orden siguiente: (1)S → AA (2)S → AS (3)S → b (4)A → SA (5)A → AS (6)A → a Sea la cadena de entrada w = abaab la misma que para T Tenemos que llamar a gen(1, 5, S), siempre que S ∈ t1,5 ´ ´ Analisis Sintactico – p.32/64
  • 33. Obteniendo una secuencia de derivaciones a partir de T Ahora la evolución, con el k y m correspondientes es k=1 gen(1,5,S) m=1 k=1 k=1 gen(1,1,A) m=6 gen(2,4,A) m=4 k=1 k=1 gen(2,1,S) m=3 gen(3,3,A) m=5 k=1 k=1 gen(3,1,A) m=6 gen(4,2,5)m=2 k=1 k=1 gen(4,1,A) m=6 gen(5,1,S)m=3 En esa figura puede verse que la secuencia de derivaciones obtenida es la siguiente S ⇒1 AA ⇒6 aA ⇒4 aSA ⇒3 abA ⇒5 abAS ⇒6 abaS ⇒2 abaAS ⇒6 abaaS ⇒3 abaab ´ ´ Analisis Sintactico – p.33/64
  • 34. El algoritmo de Early Complejidad proporcional a n2 si gramática no es ambigua Para lenguajes más usados, complejidades espacial y temporal son lineales Partimos de La gramática G = (VN , VT , P, S), de tipo CFG. ∗ Una cadena w = a1 a2 · · · an , en donde w ∈ VT . Un elemento [A → X1 X2 · · · Xk • Xk+1 · · · Xm , i] es lo que vamos a denominar un item para la cadena w, si A → X1 · · · Xm ∈ P y 0 ≤ i ≤ n. El punto • es un símbolo adicional, y el entero k es tal que 0 ≤ k ≤ m. Si la producción es A → λ entonces el item es [A → •, i] ´ ´ Analisis Sintactico – p.34/64
  • 35. El algoritmo de Early (II) El algoritmo trabaja construyendo un conjunto de items I j para cada j, 0 ≤ j ≤ n, de tal forma que [A → α • β, i] ∈ Ij , con 0 ≤ i ≤ j sii para algún γ y δ, se tiene que: ∗ S ⇒ γAδ ∗ γ ⇒ a1 · · · a i ∗ α ⇒ ai+1 · · · aj Los índices i y j delimitan el segmento de cadena en w que se produce por la cadena que está a la izquierda del símbolo •, si se observa la tercera derivación. Las dos derivaciones primeras aseguran que el prefijo izquierdo de la cadena, desde a1 hasta ai se ha producido a partir del símbolo inicial de la gramática. La secuencia de listas de items generada, I 0 , I1 , . . . , In se denomina listas del parser, para la cadena de entrada w. w ∈ L(G) sii existe algún item en la forma [S → α•, 0] ∈ In . ´ ´ Analisis Sintactico – p.35/64
  • 36. El algoritmo de Early (III) Algoritmo 3 El algoritmo de parsing de Early Entrada: la gramática CFG, G = (VN , VT , P, S) y la cadena de entrada ∗ w = a 1 a2 · · · a n ∈ V T . Salida: Las listas del parser, I0 , I1 , . . . , In . Método: Primero se construye I0 usando los pasos (1) a (3) 1. Si S → α ∈ P entonces, añadir el item [S → •α, 0] a I0 . Ejecutar (2) y (3) hasta que no se añada ningún item nuevo a I 0 . 2. Si [B → γ•, 0] ∈ I0 , añadir [A → αB • β, 0] para todo [A → α • Bβ, 0] ∈ I0 . 3. Sea [A → α • Bβ, 0] ∈ I0 . Para toda producción B → γ, añadir el item [B → •γ, 0] a I0 , siempre que no estuviera añadido ya. Ahora, sea I0 , I1 , . . . , Ij−1 el conjunto de listas de items ya construidos. Para la construcción de Ij , hacer: 4. Para cada [B → α • aβ, i] ∈ Ij−1 tal que a = aj , añadir [B → αa • β, i] a Ij . Ejecutar los dos últimos pasos, para cada j, hasta que no se pueda añadir ningún item más a Ij . 5. Sea [A → γ•, i] ∈ Ij . Si existe un [B → α • Aβ, k] ∈ Ii , entonces, añadir [B → αA • β, k] a Ij . 6. Sea [A → α • Bβ, i] ∈ Ij . Para todo B → γ ∈ P , añadimos [B → •γ, j] a Ij . ´ ´ Analisis Sintactico – p.36/64
  • 37. Interpretación del algoritmo Paso 1: Iniciamos la construcción de la tabla con todas las producciones de S Paso 2: Exploramos todas las λ−producciones a partir de S Paso 3: Si en I0 tenemos A → B, debemos incluir también todas las producciones de B Paso 4: Si [B → α • aβ, i] ∈ Ij−1 sabemos entonces que (suponiendo que w ∈ L(G)) α a1 a2 . . . ai+1 ai+2 . . . aj−1 aj . . . an entonces, si a = aj podemos decir que αa≡αaj a1 a2 . . . ai+1 ai+2 . . . aj−1 aj . . . an por lo tanto incluimos [B → αa • β, i] → Ij ´ ´ Analisis Sintactico – p.37/64
  • 38. Interpretación del algoritmo Paso 5: Si [A → γ•, i] ∈ Ij tenemos que γ . . . ai+1 ai+2 . . . aj . . . y como A → γ entonces decimos también que A γ ai+1 ai+2 . . . aj entonces, si tenemos que [B → α • Aβ, k] ∈ Ii significa que tenemos A α γ ak+1 . . . ai ai+1 ai+2 . . . aj por lo que hacemos [B → αA • β, k] → Ij Paso 6: análogo al 3 ´ ´ Analisis Sintactico – p.38/64
  • 39. Ejemplo Veámos la aplicación del algoritmo con un ejemplo: sea G = (V N , VT , P, E) en donde P viene dado por 1. E → T + E 2. E → T 3. T → F ∗ T 4. T → F 5. F → (E) 6. F → a Y sea w = (a + a) ∗ a la cadena de entrada. Según el paso (1) añadimos a I0 los items [E → •T + E, 0] y [E → •T, 0]. Dado que la gramática es λ−libre, el paso (2) no incorpora ningún item adicional. Si en el paso (3) hacemos α = λ tenemos que incluir [T → •F ∗ T, 0] y [T → •F, 0]. En otra iteración más del paso (3) incluimos además [F → •(E), 0], y [F → •a, 0]. ´ ´ Analisis Sintactico – p.39/64
  • 40. Ejemplo No podemos incluir más. El contenido de I0 queda: [E → •T + E, 0] [E → •T, 0] [T → •F ∗ T, 0] [T → •F, 0] [F → •(E), 0] [F → •a, 0] Así que pasamos a construir ahora I1 . Por el paso (4) observamos que [F → •(E), 0] cumple que (= a1 , y por lo tanto añadimos [F → (•E), 0] a I1 . ´ ´ Analisis Sintactico – p.40/64
  • 41. Ejemplo Por el paso (6), intentamos desplazar el metasímbolo a la derecha del no-terminal E, y para ello añadimos [E → •T + E, 1] y [E → •T, 1] a I1 . A su vez, estos generan la adición de [T → •F ∗ T, 1] y [T → •F, 1]. Estos generan también la incorporación de [F → •(E), 1], y [F → •a, 1]. I1 queda entonces con el siguiente contenido: [F → (•E), 0] [E → •T + E, 1] [E → •T, 1] [T → •F ∗ T, 1] [T → •F, 1] [F → •(E), 1] [F → •a, 1] Construímos ahora I2 . Ahora a2 = a. Por el paso (4), añadimos [F → a•, 1]. ´ ´ Analisis Sintactico – p.41/64
  • 42. Ejemplo Ahora, por el paso (5) intentamos aprovechar el hecho de que se ha reconocido parcialmente a para reducir el no-terminal que la produce, y por ello introducimos [T → F • ∗T, 1] y [T → F •, 1]. Dado que acabamos de añadir [T → F •, 1], nuevamente, por el paso (5) añadimos [E → T • +E, 1] y [E → T •, 1]. Este último causa la introducción de [F → (E•), 0]. Ahora, I2 está completo. El contenido de I2 queda: [F → a•, 1] [T → F • ∗T, 1] [T → F •, 1] [E → T • +E, 1] [E → T •, 1] [F → (E•), 0] ´ ´ Analisis Sintactico – p.42/64
  • 43. Ejemplo La colección de cjtos. de items queda: I1 I2 I3 I4 [F → (•E), 0] [E → T + •E, 1] [F → a•, 3] [F → a•, 1] [T → F • ∗T, 3] [E → •T + E, 1] [E → •T + E, 3] [T → F • ∗T, 1] [T → F •, 3] [E → •T, 1] [E → •T, 3] [T → F •, 1] [E → T • +E, 3] [T → •F ∗ T, 1] [T → •F ∗ T, 3] [E → T • +E, 1] [E → T •, 3] [T → •F, 1] [T → •F, 3] [E → T •, 1] [E → T + E•, 1] [F → •(E), 1] [F → •(E), 3] [F → (E•), 0] [F → (E•), 0] [F → •a, 1] [F → •a, 3] I5 I6 I7 [F → a•, 6] [F → (E)•, 0] [T → F ∗ •T, 0] [T → F • ∗T, 6] [T → F • ∗T, 0] [T → •F ∗ T, 6] [T → F •, 6] [T → F •, 0] [T → F •, 6] [T → F ∗ T •, 0] [E → T • +E, 0] [F → •(E), 6] [E → T • +E, 0] [E → T •, 0] [F → •a, 6] [E → T •, 0] y como [E → T •, 0] ∈ I6 , tenemos que w ∈ L(G). ´ ´ Analisis Sintactico – p.43/64
  • 44. Obtención de una derivación derecha Algoritmo 4 Construcción de un árbol de derivación a partir de I 0 , I1 , . . . , In . Entrada: una gramática CFG, libre de ciclos, G = (VN , VT , P, S), en donde las producciones están numeradas, de 1 . . . p, una cadena w = a 1 . . . an , y la lista I0 , I 1 , . . . , I n . Salida: Ψ, un árbol de derivación derecho para w, ó un mensaje de error. Método: si ∃ un [S → α•, 0] en In , entonces w ∈ L(G). Emitir salida de error. Si / no, hacer Ψ = λ. Ejecutar R([S → α•, 0], n), en donde R se define como sigue: Rutina R([A → β•, i], j): 1. Sea h el índice de A → β. Entonces, hacer Ψ ← Ψ + h 2. Si β = X1 X2 · · · Xm , hacer k = m, l = j. 3. Mientras que k > 0 hacer: (a) Si Xk ∈ VT , hacer k = k − 1 y l = l − 1. (b) Si Xk ∈ VN , i. Encontrar un item [Xk → γ•, r] ∈ Il , para algún r ii. Ejecutar R([Xk → γ•, r], l). Hacer k = k − 1 y l = r. ´ ´ Analisis Sintactico – p.44/64
  • 45. Ejemplo Vamos a obtener un árbol de derivación, que defina una derivación más a la derecha para 1. E →T +E 2. E→T 3. T →F ∗T 4. T →F 5. F → (E) 6. F →a Y w = (a + a) ∗ a la misma cadena de entrada que el ejemplo anterior. Usaremos también la lista I1 , . . . , I7 producida en el ejemplo anterior. Inicialmente ejecutamos R([E → T •, 0], 7). Ψ = {2}. Paso 2. Ahora, β = T . Hacemos k = 1 y l = 7. Paso 3b. Como X1 = T ∈ VN , tenemos que encontrar un item [T → γ•, r] ∈ I7 tal que [E → •T, 0] esté en Ir . El item [T → F •, 6] ∈ I7 no vale pues [E → •T, 0] ∈ I6 . / El item [T → F ∗ T •, 0] ∈ I7 si pues [E → •T, 0] ∈ I0 . ´ ´ Analisis Sintactico – p.45/64
  • 46. Ejemplo Llamamos a R([T → F ∗ T •, 0], 7): Paso 2: β = F ∗ T , k = 3 y l = 7. Paso 3b: Se ha de encontrar un [T → γ•, r] ∈ I7 tal que [T → F ∗ •T, 0] ∈ Ir . Una opción no válida es [T → F ∗ T •, 0] porque [T → F ∗ •T.0] ∈ I 0 . / La opción correcta es [T → F •, 6] ya que [T → F ∗ •T, 0] ∈ I 6 . Llamamos a R([T → F •, 6], 7). Paso 2: β = F , k = 1 y l = 7. Paso 3b: Se ha de encontrar un [F → γ•, r] ∈ I7 tal que [T → •F, 6] ∈ Ir . La única opción es [F → a•, 6] porque [T → •F, 6] ∈ I6 . Al llamar a R([F → a•, 6], 7) termina la ejecución de esta rama. Paso 3bcont: k = k − 1. Termina. ´ ´ Analisis Sintactico – p.46/64
  • 47. Ejemplo Seguimos: Seguimos con R([T → F ∗ T •, 0], 7) Paso 3bcont: k = k − 1, l = l − 1. Paso 3a: k = k − 1, k = 1, l = l − 1, l = 5. Paso 3b: Se ha de encontrar un [F → γ•, r] ∈ I5 tal que [T → •F ∗ T, 0] ∈ Ir . La única opción es [F → (E)•, 0] y [T → •F ∗ T, 0] ∈ I0 . Llamamos a R([F → (E)•, 0], 5). Paso 2: β = (E), k = 3 y l = 5. Paso 3a: k = k − 1, k = 2, l = l − 1, l = 4. ´ ´ Analisis Sintactico – p.47/64
  • 48. Ejemplo Paso 3b: Se ha de encontrar un [E → γ•, r] ∈ I4 tal que [F → (•E), 0] ∈ Ir . Tenemos las opciones: [E → T • +E, 3] y [E → T •, 3], no válidas. [E → T + E•, 1] válida ya que [F → (•E), 0] ∈ I1 . Llamamos a R([E → T + E•, 1], 4): Paso 2: β = T + E, k = 3 y l = 4 Paso 3b: Se debe encontrar un [E → γ•, r] ∈ I4 tal que [E → T + •E, 1] ∈ Ir . 1. [E → T + E•, 1] no es válida 2. [E → •, 3] si ya que, [E → T + •E, 1] ∈ I3 . Llamamos a R([E → T •, 3], 4) ··· Se obtiene el árbol de derivación derecho 64642156432. ´ ´ Analisis Sintactico – p.48/64
  • 49. Árbol de derivación obtenido E R([E → T •, 0], 7) T R([T → F ∗ T •, 0], 7) R([F → (E)•, 0], 5) F * T R([T → F •, 6], 7) ( ) F R([F → a•, 6], 7) E R([E → T + E•, 1], 4) R([T → F •, 1], 2) T E a R([E → T •, 3], 4) + R([F → a•, 1], 2) F T R([T → F •, 3], 4) a F R([F → a•, 3], 4) a ´ ´ Analisis Sintactico – p.49/64
  • 50. Transformaciones de gramáticas 1. Eliminación de símbolos inútiles 2. Gramática λ-libre 3. Eliminación de producciones unitarias 4. Eliminación de la recursividad por la izquierda 5. Factorización 6. Forma normal de Chomsky ´ ´ Analisis Sintactico – p.50/64
  • 51. Eliminación símbolos inútiles Pasos para eliminar los símbolos no útiles de una gramática 1. Eliminación de variables (A ∈ VN ) improductivas. 2. Eliminación de símbolos inaccesibles. Definición 15 Una variable A ∈ VN es improductiva si no existe ninguna derivación tal que A ⇒∗ w con w ∈ VT . ∗ Definición 16 Un símbolo X es inaccesible si no aparece en ninguna forma sentencial de la gramática, es decir, ¬∃α, β ∈ (VN VT )∗ tal que S ⇒∗ αXβ. Teorema 1 Dada una g.l.c. G = (VN , VT , S, P ), con L(G) = ∅, existe una g.l.c. equivalente G = (VN , VT , S, P ) tal que ∀A ∈ VN se cumple que existe una serie de derivaciones tal que A ⇒∗ w, w ∈ VT , es decir, existe ∗ una gramática equivalente sin variables improductivas. ´ ´ Analisis Sintactico – p.51/64
  • 52. Eliminación de variables improductivas El algoritmo para el cálculo de G (VN y P ) es el siguiente: Algoritmo 5 begin OLDV := ∅ ∗ NEWV := {A ∈ VN |A → w ∈ P , w ∈ VT } while OLDV = NEWV do begin OLDV := NEWV NEWV := OLDV {A ∈ VN |A → α, α ∈ (VT OLDV )∗ } end VN := NEWV P = {A → α ∈ P |A ∈ VN , α ∈ (VN VT )∗ } end ´ ´ Analisis Sintactico – p.52/64
  • 53. Eliminación de símbolos inaccesibles Teorema 2 Dada una g.l.c. G = (VN , VT , S, P ), con L(G) = ∅, existe una g.l.c. equivalente G = (VN , VT , S, P ) sin símbolos inaccesibles. El algoritmo para el cálculo de G (VN , VT y P ) es el siguiente: Algoritmo 6 begin VN := {S}; VT := ∅; P := ∅; repeat for A ∈ VN , A → α1 |α2 | · · · |αn , no procesada a´n u {a˜adir todas las variables de αi a VN n a˜adir todos los terminales de αi a VT } n until VN no var´e ı P = {A → α ∈ P |A ∈ VN ∧ α ∈ (VN VT )∗ } end ´ ´ Analisis Sintactico – p.53/64
  • 54. Eliminación de símbolos inútiles Teorema 3 Dada una gramática libre de contexto G, con L(G)= ∅, existe una GLC G’ equivalente sin símbolos inútiles. Los pasos a seguir serían (el orden es importante): Pasamos de G a G1 según el algoritmo 5 Pasamos de G1 a G’ según el algoritmo 6 G’ no contiene símbolo inútiles, es decir, todo símbolo X ∈ (VN ∪ VT ) es tal que S ⇒∗ αXβ ⇒∗ w. ´ ´ Analisis Sintactico – p.54/64
  • 55. Grámatica λ-libre Definición 17 Decimos que una gramática l.c. G = (VN , VT , S, P ) es λ-libre si cumple que en sus reglas de producción no aparece ninguna de la forma A → λ, excepto a los sumo S → λ, con la condición de que S no aparezca en la parte derecha de ninguna otra regla de producción. Teorema 4 Dada una g.l.c. G = (VN , VT , S, P ), existe una g.l.c. equivalente G = (VN , VT , S , P ) que es λ-libre. ´ ´ Analisis Sintactico – p.55/64
  • 56. Grámatica λ-libre Algoritmo 7 1. Obtenemos Vλ = {A ∈ VN |A ⇒∗ λ}: Conjunto de variables anulables Inicialmente Vλ contiene A si A → λ. Luego, si tenemos B → x1 x2 . . . xn y xi ∈ Vλ ∀i, añadir B. 2. Obtenemos P del siguiente modo: Por cada producción A → x1 x2 . . . xk (k > 0) añadimos: A → Y1 Y2 . . . Yn , dónde cada Yi es: (a) Si xi no es anulable entonces Yi = xi (b) Si x ∈ Vλ , entonces se toma Yi como xi y como λ (c) No añadir ninguna producción A → λ 3. Si λ ∈ L(G) entonces VN = VN y S = S. En otro caso, (a) si S no aparece en la parte derecha i. Añadir la producción S → λ ii. VN = VN y S = S (b) en otro caso i. VN = VN {S }, siendo S el nuevo símbolo inicial ii. Añadir a P S → S|λ ´ ´ Analisis Sintactico – p.56/64
  • 57. Eliminación de producciones unitarias Definición 18 Llamamos producciones unitarias a las que tienen la forma A → B, con A, B ∈ VN . Teorema 5 Dada una g.l.c. G = (VN , VT , S, P ) existe una g.l.c. equivalente G = (VN , VT , S, P ) que no contiene producciones unitarias. El algoritmo para calcular G’ es el siguiente: Algoritmo 8 1. Suponemos que G es λ-libre; si no es así, se transforma según el algoritmo 3 2. Para cada A ∈ VN se calcula VV (A) = {B ∈ VN |A ⇒+ B}. 3. P = Producciones no unitarias de P . 4. Para cada A ∈ VN tal que VV (A) = ∅. Para cada B ∈ VV (A) Para cada B → β ∈ P (no unitaria) Añadir A → β a P ´ ´ Analisis Sintactico – p.57/64
  • 58. Gramática libre de ciclos Definición 19 Una gramática libre de ciclos es aquella que no contiene derivaciones de la forma A ⇒∗ A. Definición 20 Una gramática es propia si no tiene símbolos inútiles, es λ-libre y libre de ciclos. Para convertir una gramática en otra equivalente propia, podemos seguir los siguientes pasos: 1. Pasar la gramática a una equivalente λ-libre. 2. Eliminar las producciones unitarias (no hay ciclos). 3. Eliminar símbolos inútiles. No debemos olvidar que una gramática puede tener producciones uni- tarias y ser propia. ´ ´ Analisis Sintactico – p.58/64
  • 59. Recursividad en las gramáticas Definición 21 Una gramática G = (VN , VN , P, S) es recursiva por la izquierda (derecha) si + + existe un A ∈ VN tal que existe una derivación A =⇒ Aα (A =⇒ αA) para alguna cadena α. Definición 22 Una gramática G = (VN , VN , P, S) es recursiva si existe un A ∈ VN tal que + existe una derivación A =⇒ αAβ. Algoritmo 9 Eliminación de la recursividad inmediata por la izquierda. Entrada: Un conjunto de producciones {pi /pi ∈ P } con el no terminal A ∈ VN como parte izquierda de una gramática G CFG sin λ-producciones. Salida: Un nuevo conjunto de producciones sin recursividad inmediata por la izquierda. 1. Ordénense las producciones de Ai en la forma A → Aα1 |Aα2 | · · · |Aαm |β1 |β2 | · · · |βn en donde ninguna βi comienza con A. 2. Sustituir todas las producciones de A por A → β1 A |β2 A | · · · |βn A A → α1 A |α2 A | · · · |αm A |λ 3. La salida es el conjunto de nuevas producciones obtenidas en el paso anterior. ´ ´ Analisis Sintactico – p.59/64
  • 60. Recursividad en las gramáticas (III) Algoritmo 10 Eliminación de la recursividad por la izquierda. Entrada: La gramática G propia Salida: Una gramática equivalente, sin recursividad por la izquierda. 1. Ordénense los Ai ∈ VN en un orden A1 , A2 , . . . , An . 2. for i:=1 to n do begin forj:= 1 to i − 1 do sustituir cada producción de la forma Ai → Aj γ por las producciones Ai → δ1 γ|δ2 γ| · · · |δk γ, en donde Aj → δ1 |δ2 | · · · |δk es el conjunto de producciones actuales del no terminal Aj ; Además, eliminar la recursividad inmediata por la izquierda de las producciones de Ai . end ´ ´ Analisis Sintactico – p.60/64
  • 61. Forma normal de Chomsky Definición 23 Sea una CFG G = (VN , VT , P, S). Se dice que G está en Forma Normal de Chomsky (CNF), si toda producción de P está en una de las formas siguientes: 1. A → BC, en donde A, B y C están en VN , 2. A → a, en donde A ∈ VN y a ∈ VT , 3. Si λ ∈ L(G) entonces S → λ está en P y además S no aparece en la parte derecha de ninguna producción de P . ´ ´ Analisis Sintactico – p.61/64
  • 62. Forma normal de Chomsky (II) Algoritmo 11 Conversión a Forma Normal de Chomsky. Entrada: Una gramática CFG propia, G = (VN , VT , P, S) sin producciones simples. Salida: Una gramática G en forma CNF, tal que L(G) = L(G ). Método: Sea el conjunto P formado por las producciones siguientes: 1. Añadir toda producción en la forma A → a ∈ P 2. Añadir toda producción en la forma A → AB ∈ P 3. Si S → λ ∈ P entonces añadirla también. 4. Para cada producción en la forma A → X1 · · · Xk con k > 2, añadir las producciones resultantes a continuación: asumimos que Xi representa a Xi si Xi ∈ VN , y Xi es un nuevo no-terminal si Xi ∈ VT . Las nuevas producciones serán las siguientes: A → X 1 < X2 · · · X k > < X2 · · · Xk >→ X2 < X3 · · · Xk > ··· < Xk−2 · · · Xk >→ Xk−2 < Xk−1 Xk > < Xk−1 Xk >→ Xk−1 Xk en donde cada < Xi · · · Xk > es un nuevo símbolo no-terminal. 5. Para cada producción de la forma A → X1 X2 en donde bien X1 o X2 ó los dos están en VT , añadir A → X 1 X2 a P 6. Para cada a introducido en los pasos 4 y 5, añadir a → a. Sea VN igual a VN más todos los nuevos no-terminales introducidos en los pasos anteriores. La nueva gramática G = (VN , VT , P , S) es la deseada. ´ ´ Analisis Sintactico – p.62/64
  • 63. Forma normal de Chomsky (III) Veamos la aplicación del algoritmo con la gramática CFG cuyo conjunto P está formado por las siguientes producciones: S → aAB|BA A → BBB|a B → AS|b En el nuevo conjunto P introducimos las producciones S → BA, A → a y B → AS|b. La producción S → aAB generará el siguiente grupo de nuevas producciones S → a < AB > < AB >→ AB a →a que irán a parar a P . ´ ´ Analisis Sintactico – p.63/64
  • 64. Forma normal de Chomsky (IV) Para la producción A → BBB, se generarán las siguientes nuevas producciones A → B < BB > < BB >→ BB que también se introducirán en P . La nueva gramática, G = (VN , VT , P , S) quedará, con VN = {S, A, B, < BB >, < AB >, a }, y P contendrá las siguientes producciones: S → a < AB > |BA A → B < BB > |a B → AS|b < AB >→ AB < BB >→ BB a →a ´ ´ Analisis Sintactico – p.64/64