TEMA 6 GRAMÁTICAS INDEPENDIENTES DEL CONTEXTO TEMA 6.- GRAMÁTICAS INDEPENDIENTES DEL CONTEXTO 6.1. Gramáticas independientes del contexto. 6.2. Limpieza de Gramáticas Independientes del contexto. 6.3. Gramáticas limpias y gramáticas sucias. 6.4. Limpieza de gramáticas 6.4.1. Teorema de los símbolos vivos 6.4.2.Teorema de los símbolos accesibles 6.4.3. Análisis automático de la limpieza de gramáticas 6.5 Gramáticas bien formadas 6.6. Formas Normales de Gramáticas Independientes del contexto. 6.6.1. Forma Normal de Chomsky (FNC) 6.6.2. Forma Normal de Greibach (FNG) TALF. Tema6 nº 2 6.1. Gramáticas independientes del contexto. Técnicas para preparar una gramática tipo 2 para ser tratada eficientemente por un autómata con pila: Gramáticas limpias Gramáticas bien formadas Formas normales de Chomsky y Greibach TALF. Tema6 nº 3 6.2. Limpieza de Gramáticas Independientes del contexto. Las gramáticas de los lenguajes de programación están formadas por un conjunto de reglas BNF, cuyo número suele ser bastante amplio, lo cual incide en la ocultación de distintos problemas que pueden producirse, tales como tener reglas que produzcan símbolos que no se usen después, o que nunca se llegue a cadenas terminales. Todo esto se puede solventar realizando la transformación de la gramática inicial “sucia” a una gramática “limpia”. TALF. Tema6 nº 4 6.3. Gramáticas limpias y gramáticas sucias. Definiciones. Símbolo muerto (superfluo): es un símbolo no terminal que no genera ninguna cadena de símbolos terminales. Símbolo vivo: es un símbolo no terminal del cual se puede derivar una cadena de símbolos terminales. Todos los símbolos terminales son símbolos vivos. Es decir son símbolos vivos lo que no son muertos. Símbolo inaccesible: es un símbolo no terminal al que no se puede llegar por medio de producciones desde el símbolo inicial. Símbolo accesible: es un símbolo que aparece en una cadena derivada del símbolo inicial. Es decir, aquel símbolo que no es inaccesible. Símbolo extraño: se denomina así a todo símbolo muerto o inaccesible. Gramática sucia: es toda gramática que contiene símbolos extraños. Gramática limpia: es toda gramática que no contiene símbolos extraños. TALF. Tema6 nº 5 6.4. Limpieza de gramáticas toda gramática en bruto ha de limpiarse con el objetivo de eliminar todos los símbolos extraños. El método de limpiar las gramáticas sucias consiste en detectar en primer lugar todos los símbolos muertos, y a continuación se detectan todos los símbolos inaccesibles. Es importante seguir este orden, puesto que la eliminación de símbolos muertos puede generar nuevos símbolos inaccesibles. Los algoritmos que se utilizan en la limpieza de gramáticas se basan en los teoremas que se enuncian a continuación TALF. Tema6 nº 6 6.4. Limpieza de gramáticas 6.4.1. Teorema de los símbolos vivos Si todos los símbolos de la parte derecha de una producción son vivos, entonces el símbolo de la parte izquierda también lo es. Algoritmo para detectar símbolos muertos: 1. Hacer una lista de no-terminales que tengan al menos una producción sin símbolos no terminales en la parte derecha. 2. Dada una producción, si todos los no-terminales de la parte derecha pertenecen a la lista, entonces podemos incluir al no terminal de la parte izquierda. 3. Cuando no se puedan incluir más símbolos mediante la aplicación del paso 2, la lista contendrá todos los símbolos vivos, el resto serán muertos. TALF. Tema6 nº 7 6.4. Limpieza de gramáticas. Ejemplo. Determinar los símbolos muertos de la gramática expresada en BNF: <INICIAL>::= a <NOTA 1> <NOTA2> <NOTA3> | <NOTA4> d <NOTA 1>::= b <NOTA2> <NOTA3> <NOTA2>::= e | d <NOTA3>::= g <NOTA2> <NOTA4>::= <NOTA 1> f <NOTA5> <NOTA5>::= t <NOTA4> | v <NOTA5> 1. 2. 3. aplicando los pasos del algoritmo: Confección de la lista: sólo hay un símbolo no terminal con el cual comenzar la lista. <NOTA2> Aplicando el teorema 6.4.1. se incluyen en la lista por el siguiente orden: <NOTA3> <NOTA1> <INICIAL> No se puede aplicar el teorema más veces, por lo tanto la lista de símbolos vivos está completa y los símbolos <NOTA4> y <NOTA5> son no terminales muertos. TALF. Tema6 nº 8 6.4. Limpieza de gramáticas 6.4.2.Teorema de los símbolos accesibles Si el símbolo no terminal de la parte izquierda de una producción es accesible, entonces todos los símbolos de la parte derecha también lo son. Algoritmo para detectar símbolos accesibles: 1. Se comienza la lista con un único no terminal, el símbolo inicial. 2. Si la parte izquierda de la producción está en la lista, entonces se incluyen en la misma a todos los no terminales que aparezcan en la parte derecha. 3. Cuando ya no se puedan incluir más símbolos mediante la aplicación del paso 2, la lista contendrá todos los símbolos accesibles, y el resto será inaccesible. TALF. Tema6 nº 9 6.4. Limpieza de gramáticas. Ejemplo. Sea la siguiente gramática en BNF: <INICIAL>::= a<NOTER1><NOTER2>|<NOTER1> <NOTER1>::= c <NOTER2> d <NOTER2>: := e | f <INICIAL> <NOTER3>::= g <NOTER4> | h <NOTER4> t <NOTER4>::= x l y l z Aplicando el algoritmo los símbolos inaccesibles son: 1. Confección de la lista: <INICIAL> 2. Aplicación del teorema 6.4.2 <NOTER1> <NOTER2> 3. No se puede aplicar más veces el paso, luego la lista de símbolos accesibles está completa, y los no terminales inaccesibles son: <NOTER3> <NOTER4> TALF. Tema6 nº 10 6.4. Limpieza de gramáticas. 6.4.3. Análisis automático de la limpieza de gramáticas Los algoritmos de limpieza de gramáticas comprueban si las gramáticas son limpias. Los pasos para el tratamiento de cualquier gramática son: Una gramática es limpia si no tiene: símbolos muertos símbolos inaccesibles reglas innecesarias (A::=A; éstas se eliminan directamente) TALF. Tema6 nº 11 6.4. Limpieza de gramáticas. Ejemplo. Ejemplo: <INICIAL>::= A <NOTER1> <NOTER2> <INICIAL>: := <NOTER1> <NOTER1>::= C <NOTER2> D <NOTER2>::= E <NOTER2>::= F <INICIAL> <NOTER3>::= G <NOTER4> <NOTER3>::= H <NOTER4> T <NOTER4>::= X <NOTER4>::= Y <NOTER4>::= Z El analizador indicará que la gramática no es limpia. La relación de símbolos no accesibles: NOTER3 y NOTER4. TALF. Tema6 nº 12 6.5 Gramáticas bien formadas Una gramática está bien formada si: 1. Está limpia. Sin símbolos muertos Sin símbolos inaccesibles Sin reglas innecesarias 2. No tiene reglas no generativas (A::= , A≠S). 3. No tiene reglas de redenominación (A::=B). TALF. Tema6 nº 13 6.5 Gramáticas bien formadas Algoritmo para eliminar las reglas no generativas (A::= , A≠S): P´ = P //P´= reglas no generativas; P=reglas generativas Repetir Para cada P=( A P´ y A≠S ) P´ = P´- {P} Para cada P´ = (B::=xAy) P´ P´ = P´ {B::=xy} Hasta que todas las reglas sean generativas TALF. Tema6 nº 14 6.5 Gramáticas bien formadas. Ejemplo. Ejemplo: P = {(A::=C0B), (A::=), (B::=BC), (B::=), (C::=0B), (C::=)} Aplicando el algoritmo: Eliminación de la regla B::= : P = {(A::=C0B), (A::=C0) ,(A::=), (B::=BC), (B::=C), (C::=0B), (C::=0), (C::=)} Eliminación de la regla C::= : P = {(A::=C0B), (A::=0B), (A::=C0) , (A::=0) ,(A::=), (B::=BC), (B::=C), (B::=B), (B::=), (C::=0B), (C::=0)} Eliminación de la regla B::= que ha aparecido de nuevo: P = {(A::=C0B), (A::=0B), (A::=C0) , (A::=0) ,(A::=), (B::=BC), (B::=C), (C::=0B), (C::=0)} Esta será la gramática sin reglas regenerativas Par eliminar las reglas de redenominación (A::=B) se genera una nueva producción A::= por cada regla B::=, con * y se borra la regla A::=B. TALF. Tema6 nº 15 6.6. Formas Normales de Gramáticas Independientes del contexto. En algunas ocasiones es imprescindible que las gramáticas se hallen dispuestas de una forma especial. Es decir, se trata de obtener una gramática equivalente, que genera el mismo lenguaje, pero que debe cumplir unas especificaciones determinadas. A continuación se muestran las dos formas normalizadas más frecuentes, que se emplean en los lenguajes formales y sus aplicaciones. 6.6.1. Forma Normal de Chomsky (FNC) 6.6.2. Forma Normal de Greibach (FNG) TALF. Tema6 nº 16 6.6.1. Forma Normal de Chomsky (FNC) Una gramática se dice que está en la Forma Normal de Chomsky si sus reglas son de una de estas formas: A BC Aa Siendo A, B, C no terminales y a un terminal. Teorema de la forma normal de Chomsky Toda gramática libre de contexto sin la cadena vacía tiene una gramática equivalente cuyas producciones están en la Forma Normal de Chomsky. Forma Normal de Chomsky (FNC) Una gramática se dice que está en la Forma Normal de Chomsky si sus reglas son de una de estas formas: A BC Aa Siendo A, B, C no terminales y a un terminal. TALF. Tema6 nº 17 6.6.1. Forma Normal de Chomsky (FNC) El algoritmo a seguir es: 1. PiP / Pi: A 1...n, donde i(NT ), n2 1. j, si jT (es terminal) entonces hacer: 1. N =N {Cj} 2. P= P {Cj j} 3. Modificar Pi, donde antes ponía j ahora poner Cj. 2. PkP / Pk: A B1...Bm, donde BN , m3 1. N =N {Dj} j=1..m-2. 2. Reemplazar Pk por las producciones: A B1D1, D1 B2D2,..., Dm-2 Bm-1Bm TALF. Tema6 nº 18 6.6.1. Forma Normal de Chomsky (FNC). Ejemplo. Sea la gramática G=( N={S, A, B}, T ={a, b}, P, S) cuyas producciones son: las reglas pueden reescribirse: S A B encontrar bA | aB bAA | aS | a aBB | bS | b una gramática equivalente en FNC. (1) (2) (3) (4) (5)(*) (6) (7) S S A A A B B (8)(*) bA aB bAA aS a aBB bS B b Solamente las señaladas con (*) están en forma FNC. La producción (1) se sustituye por dos: S CbA Cb b Igualmente la (2) puede sustituirse por S Ca B Ca a Las producciones (3) y (4) se sustituyen por A CbD1 A Ca S D1 AA y la (6) y la (7) por B C aD 2 D2 BB B Cb S TALF. Tema6 nº 19 6.6.1. Forma Normal de Chomsky (FNC). Ejemplo. la gramática equivalente en FNC es: S CbA S Ca B A Ca S A CbD1 A a B Cb S B CaD2 B b D1 AA D2 BB Ca a Cb b TALF. Tema6 nº 20 6.6.2. Forma Normal de Greibach (FNG) Se dice que una gramática está en la Forma Normal de Greibach si sus reglas de producción son de la forma: A a A a donde A ∑N, a ∑T ∑N* Teorema de la forma normal de Greibach Todo lenguaje de contexto libre sin la cadena vacía puede ser generado por una gramática cuyas reglas de producción son de la forma A a A a donde A ∑N, a ∑T ∑N* Ejemplo: La gramática dada en el ejemplo anterior. S bA | aB A bAA | aS | a B aBB | bS | b TALF. Tema6 nº 21 6.6.2. Forma Normal de Greibach (FNG) Funciones previas utilizadas en el algoritmo para obtener la FNG: 1. Eliminar recursividad a izquierdas, las producciones A A. Operación para eliminar la recursividad en un símbolo: 1. Crear una nueva variable BA, ∑N = ∑N BA 2. PiP, Pi: A A, 1. Añadir a P: BA y BA BA 2. Sacar A A de P. 3. PjP, Pj: A , y no empieza por A 1. Añadir A BA La notamos como ELIMINArecursividad(A) 2. Sustiruir en las reglas A B las reglas de B Operación para eliminar una producción A B, con AB. 1. Sacar A B de P. 2. PiP, tq B , añadir A La notamos como ELIMINAproducción(A B) TALF. Tema6 nº 22 6.6.2. Forma Normal de Greibach (FNG) Pasos para conseguir la FNG: 1. Partir de una gramática en forma normal de Chomsky. En realidad basta con que sea una gramática limpia y sus producciones tengan la forma: A a o A 2. donde A ∑N, a ∑T ∑N* Establecer un determinado orden en los símbolos no-terminales y Poner las producciones en la forma: AiAj, con j>i. 1. Para k=1,...,m 1. Para j=1,...,k-1 1. PiP, Pi: Ak Aj, ELIMINARproducción(Ak Aj) 2. Si Ak Ak entonces ELIMINArecursividad(Ak) TALF. Tema6 nº 23 6.6.2. Forma Normal de Greibach (FNG) 3. Poner las producciones en la forma: Aia. 1. Para i=m-1,...,1 1. PiP, Pi: Ai Aj, y j>i ELIMINARproducción(Ai Aj) 2. Para k=1,...,m 1. PiP, Pi: Bj Ak, 1. ELIMINARproducción(Bj Ak) TALF. Tema6 nº 24 6.6.2. Forma Normal de Greibach (FNG). Ejemplo. Ejemplo: 1. Partimos de la gramática en FNC del ejemplo anterior: 1. S CbA |CaB 2. A Ca S| CbD1|a 3. B Cb S| CaD2|b 4. D1 AA 5. D2 BB 6. Ca a 7. Cb b 2. Tomamos el orden anterior para ∑N ={S=A1…}. Poner las producciones en la forma: AiAj, con j>i. TALF. Tema6 nº 25 6.6.2. Forma Normal de Greibach (FNG) 2. Tomamos el orden anterior para ∑N ={S=A1…}. 1. Poner las producciones en la forma: AiAj, con j>i. 1. 2. 3. 4. 5. 6. 7. S CbA |CaB A Ca S| CbD1|a B Cb S| CaD2|b D1 AA D2 BB Ca a Cb b Resultado paso 2 1. 2. 3. S CbA |CaB A Ca S| CbD1|a B Cb S| CaD2|b ELIMINARproducción(D2 BB) por: 4. D1 CaSA| CbD1A| aA D2 CbSB| CaD2B|bB 5. 6. 7. D2 CbSB| CaD2B|bB Ca a Cb b Para k=1,...,m //m=7 1. Para j=1,...,k-1 1. PiP, Pi: Ak Aj, ELIMINARproducción(Ak Aj) k=4 (D1), j=2 (A) cambian las producciones: ELIMINARproducción(D1 AA) por: D1 CaSA| CbD1A| aA 2. K=5 (D2), , j=3(B) No Ak Ak TALF. Tema6 nº 26 6.6.2. Forma Normal de Greibach (FNG) 3. Poner las producciones en la forma: Aia. 1. Para i=m-1,...,1 //m=7 1. PiP, Pi: Ai Aj, y j>i i=5 ELIMINARproducción(D2 CbSB| CaD2B|bB) por: D2 bSB| aD2B|bB i= 4 ELIMINARproducción(D1 CaSA| CbD1A| aA) por: D1 aSA| bD1A| aA i= 3 ELIMINARproducción(B Cb S| CaD2|b) por: B bS| aD2|b i= 2 ELIMINARproducción(A Ca S| CbD1|a) A aS| bD1|a i= 2 ELIMINARproducción(S CbA |CaB) por: S bA |aB 1. Para k=1,...,m 1. PiP, Pi: Bj Ak, No existen TALF. Tema6 1. 2. 3. S CbA |CaB A Ca S| CbD1|a B Cb S| CaD2|b 4. D1 CaSA| CbD1A| aA 5. 6. 7. D2 CbSB| CaD2B|bB Ca a Cb b 1. 2. 3. Resultado paso 3 S bA |aB A aS| bD1|a B bS| aD2|b 4. D1 aSA| bD1A| aA 5. 6. 7. D2 bSB| aD2B|bB Ca a Cb b nº 27 6.6.2. Forma Normal de Greibach (FNG) Resultado paso 3: gramática equivalente e FNG: 1. S bA |aB 1. S bA |aB 2. A aS| bD1|a 2. A aS| bD1|a 3. B bS| aD2|b 3. B bS| aD2|b 4. D1 aSA| bD1A| aA 4. D1 aSA| bD1A| aA 5. D2 bSB| aD2B|bB 5. D2 bSB| aD2B|bB 6. Ca a 7. Cb b Si ahora la limpiamos: Quedando la gramática limpia: Simbolos vivos: todos Símbolos accesibles: S, A, B, D1, D1 Eliminamos C1,C2 TALF. Tema6 Equivalente a: 1. S bA | aB 2. A bAA | aS | a 3. B aBB | bS | b nº 28