05/10/2022
En el vasto universo de la informática teórica y la lingüística computacional, las gramáticas libres de contexto (GLC) son una piedra angular. Permiten describir la estructura de los lenguajes naturales y de programación, siendo fundamentales para el diseño de compiladores y analizadores sintácticos. Sin embargo, para que estas gramáticas sean eficientes o para poder aplicar ciertos algoritmos, a menudo es necesario transformarlas en una forma estandarizada. Aquí es donde entra en juego la Forma Normal de Chomsky (FNC), un concepto esencial que simplifica la estructura de las producciones gramaticales.

La FNC, nombrada así en honor al lingüista Noam Chomsky, es una de esas formas estandarizadas que facilitan el análisis y la manipulación de las gramáticas. Pero, ¿qué implica exactamente que una gramática esté en FNC? ¿Y cómo podemos asegurarnos de que una gramática dada cumpla con estas estrictas reglas? A lo largo de este artículo, desglosaremos la definición, la importancia y el proceso paso a paso para convertir cualquier gramática libre de contexto a su equivalente en Forma Normal de Chomsky, prestando especial atención a las producciones unitarias, un tipo particular de regla que requiere un manejo cuidadoso.
- ¿Qué es la Forma Normal de Chomsky (FNC)?
- ¿Por qué es Importante la Forma Normal de Chomsky?
- Comprobando y Convirtiendo a la Forma Normal de Chomsky
- Preguntas Frecuentes (FAQs) sobre la Forma Normal de Chomsky
- ¿Todas las gramáticas libres de contexto pueden convertirse a FNC?
- ¿Es la FNC única para una gramática dada?
- ¿Qué significa que un símbolo sea 'útil'?
- ¿Cuál es la diferencia entre la Forma Normal de Chomsky y la Forma Normal de Greibach?
- ¿Por qué no se permiten terminales en las producciones A → BC?
- Conclusión
¿Qué es la Forma Normal de Chomsky (FNC)?
Una gramática libre de contexto se encuentra en Forma Normal de Chomsky si todas sus producciones tienen una de las siguientes dos formas:
A → BC, dondeA,ByCson variables (símbolos no terminales).A → c, dondeAes una variable yces un símbolo terminal.
Existe una excepción importante para los lenguajes que contienen la cadena vacía (épsilon, ε). Si el lenguaje generado por la gramática contiene ε, entonces se permite una producción adicional: S → ε, donde S es el símbolo de inicio de la gramática. Sin embargo, si esta producción existe, el símbolo de inicio S no debe aparecer en el lado derecho de ninguna otra producción. Esto garantiza que la cadena vacía sea la única excepción a las reglas estrictas de la FNC.
La belleza de la FNC radica en su simplicidad y uniformidad. Cada paso de derivación en una gramática en FNC aumenta la longitud de la cadena de terminales en exactamente uno (si la producción es A → c) o introduce dos nuevas variables (si es A → BC), lo que simplifica enormemente el análisis.
¿Por qué es Importante la Forma Normal de Chomsky?
La FNC no es solo un capricho teórico; tiene aplicaciones prácticas significativas en la ciencia de la computación:
- Algoritmos de Parsing: Uno de los usos más prominentes de la FNC es en el algoritmo CYK (Cocke-Younger-Kasami). Este algoritmo es un algoritmo de análisis sintáctico (parser) eficiente para gramáticas libres de contexto que funciona exclusivamente con gramáticas en FNC, permitiendo determinar si una cadena dada puede ser generada por una gramática.
- Pruebas de Propiedades de Lenguajes: La estructura uniforme de la FNC facilita la demostración de propiedades sobre los lenguajes libres de contexto. Por ejemplo, es fundamental para el lema del bombeo para lenguajes libres de contexto, una herramienta poderosa para demostrar que un lenguaje no es libre de contexto.
- Simplificación de Gramáticas: Al reducir las producciones a formas muy específicas, la FNC ayuda a simplificar la estructura interna de las gramáticas, lo que puede ser útil para la optimización o para entender mejor las relaciones entre los símbolos.
Comprobando y Convirtiendo a la Forma Normal de Chomsky
El proceso para convertir una gramática libre de contexto arbitraria a su equivalente en FNC es sistemático y consta de varias etapas. Es crucial seguir estos pasos en un orden específico, ya que la eliminación de un tipo de producción puede crear otras que deben ser manejadas en etapas posteriores.
Paso 1: Eliminar Producciones ε (Épsilon)
Las producciones ε son de la forma A → ε, donde A es una variable. Si el lenguaje no contiene la cadena vacía, estas producciones deben eliminarse. Si el lenguaje sí contiene ε, solo se permite S → ε (donde S es el símbolo de inicio), y S no puede aparecer en el lado derecho de ninguna producción.
El procedimiento general es identificar todas las variables anulables (aquellas que pueden derivar a ε). Para cada producción A → α, si α contiene variables anulables, se crean nuevas producciones reemplazando esas variables anulables con ε en todas las combinaciones posibles. Por ejemplo, si tenemos A → BC y B es anulable, se añade A → C. Si C también es anulable, se añade A → B. Si tanto B como C son anulables, también se añade A → ε (a menos que A sea el símbolo de inicio y ya tengamos S → ε).
Ejemplo de Eliminación de ε-Producciones:
Gramática original: S → AB | CD, A → aA | ε, B → bB | ε, C → c, D → d
1. Identificar variables anulables: A y B son anulables.
2. Para S → AB:
- Si
A → ε, añadirS → B - Si
B → ε, añadirS → A - Si
A → εyB → ε, añadirS → ε
3. Eliminar las producciones A → ε y B → ε.
Gramática resultante (parcial): S → AB | CD | B | A | ε, A → aA, B → bB, C → c, D → d.
Paso 2: Eliminar Producciones Unitarias
Las producciones unitarias son de la forma A → B, donde A y B son variables. Estas producciones son un tipo especial de regla que no contribuye directamente a la generación de terminales y pueden complicar el análisis. Su eliminación es un paso crucial hacia la FNC.
El método para eliminarlas es el siguiente: para cada producción unitaria A → B, se añaden todas las producciones de la forma A → γ por cada producción B → γ que no sea unitaria. Este proceso se repite hasta que no queden producciones unitarias. Es importante asegurarse de que las nuevas producciones añadidas no sean unitarias en sí mismas para evitar ciclos infinitos.
Ejemplo de Eliminación de Producciones Unitarias:
Gramática: S → A | b, A → B | c, B → d
1. Identificar unitarias: S → A y A → B.
2. Para A → B: B → d, así que añadir A → d.
Gramática: S → A | b, A → B | c | d, B → d
3. Eliminar A → B.
Gramática: S → A | b, A → c | d, B → d
4. Para S → A: A → c y A → d, así que añadir S → c y S → d.
Gramática: S → A | b | c | d, A → c | d, B → d
5. Eliminar S → A.
Gramática final: S → b | c | d, A → c | d, B → d.

Como se puede observar, este proceso expande las derivaciones a través de variables intermedias, eliminando la necesidad de los pasos unitarios.
Paso 3: Eliminar Símbolos Inútiles
Un símbolo inútil es aquel que nunca puede generar una cadena de terminales (no generador) o que nunca puede aparecer en una derivación de una cadena del lenguaje (no alcanzable desde el símbolo de inicio).
- Eliminar Símbolos No Generadores: Un símbolo
Xes generador siX → αyαconsiste enteramente de terminales o de símbolos ya conocidos como generadores. Se eliminan todas las producciones que contienen símbolos no generadores y luego los propios símbolos. - Eliminar Símbolos No Alcanzables: Un símbolo
Xes alcanzable si hay una derivaciónS ⇒* αXβ, dondeSes el símbolo de inicio. Se eliminan todas las producciones que contienen símbolos no alcanzables y luego los propios símbolos.
Es importante realizar la eliminación de no generadores primero, y luego la de no alcanzables. Si se hace al revés, se podrían eliminar símbolos que en realidad son generadores, pero que temporalmente parecen no alcanzables debido a la presencia de otros símbolos no generadores.
Paso 4: Convertir las Producciones Restantes a FNC
Después de los pasos anteriores, las producciones restantes deben ser transformadas para que cumplan estrictamente con las formas A → BC o A → c.
- Eliminar Terminales en Producciones con Múltiples Símbolos: Si una producción tiene la forma
A → aBoA → Ba, dondeaes un terminal yBes una variable, se introduce una nueva variable para cada terminal. Por ejemplo, si tenemosA → aB, creamos una nueva producciónXa → ay reemplazamos la producción original conA → XaB. Esto asegura que solo haya un terminal por producción o que todas las partes sean variables. - Romper Producciones Largas: Si una producción tiene más de dos variables en su lado derecho (ej.,
A → BCD), se introduce una nueva variable para agrupar las últimas variables. Por ejemplo,A → BCDse convierte enA → BX1yX1 → CD. Este proceso se repite hasta que cada producción tenga exactamente dos variables en su lado derecho.
Tabla Comparativa de Formas de Producción
| Forma Original | Transformación a FNC | Descripción |
|---|---|---|
A → ε | Eliminar o permitir S → ε | Eliminación de producciones vacías. |
A → B | Reemplazar con producciones de B | Eliminación de producciones unitarias. |
A → aB | Xa → a, A → XaB | Reemplazo de terminales con variables auxiliares. |
A → BCD | A → BX1, X1 → CD | Descomposición de producciones largas. |
A → c | Permitido | Ya está en FNC. |
A → BC | Permitido | Ya está en FNC. |
Preguntas Frecuentes (FAQs) sobre la Forma Normal de Chomsky
¿Todas las gramáticas libres de contexto pueden convertirse a FNC?
Sí, cualquier gramática libre de contexto puede ser convertida a una forma equivalente en FNC. Esto significa que la gramática resultante generará exactamente el mismo lenguaje que la gramática original.
¿Es la FNC única para una gramática dada?
No, la FNC de una gramática no es única. El proceso de conversión puede implicar la introducción de nuevas variables auxiliares, y diferentes elecciones en el nombramiento o la agrupación de estas variables pueden llevar a gramáticas en FNC estructuralmente diferentes, pero funcionalmente equivalentes.
¿Qué significa que un símbolo sea 'útil'?
Un símbolo es útil si es tanto generador como alcanzable. Un símbolo generador puede derivar a una cadena de terminales. Un símbolo alcanzable puede ser alcanzado desde el símbolo de inicio de la gramática. La eliminación de símbolos inútiles es un paso de simplificación importante antes de convertir a FNC.
¿Cuál es la diferencia entre la Forma Normal de Chomsky y la Forma Normal de Greibach?
Ambas son formas normales para gramáticas libres de contexto. En la Forma Normal de Greibach (FNG), todas las producciones son de la forma A → aα, donde a es un terminal y α es una cadena de cero o más variables. La principal diferencia es que la FNG garantiza que cada derivación comienza con un terminal, lo que es útil para ciertos tipos de analizadores descendentes. La FNC es más restrictiva en la longitud del lado derecho (máximo dos símbolos) y no requiere que el primer símbolo sea un terminal.
¿Por qué no se permiten terminales en las producciones A → BC?
La restricción de que B y C deben ser variables en A → BC es clave para la uniformidad de la FNC. Permite que algoritmos como CYK asuman que cada paso de derivación que no genera un terminal directamente siempre reemplaza una variable por exactamente dos variables, simplificando la lógica de las tablas de parsing y las pruebas de propiedades.
Conclusión
La Forma Normal de Chomsky es un concepto fundamental en la teoría de lenguajes formales y la computación. Aunque el proceso de conversión puede parecer tedioso debido a sus múltiples pasos, cada uno de ellos contribuye a una gramática más estructurada y manejable. Comprender la FNC y cómo transformar gramáticas a esta forma no solo es vital para el estudio académico, sino que también proporciona una base sólida para el diseño e implementación de herramientas de procesamiento de lenguajes, como compiladores y analizadores sintácticos. Dominar la FNC es, sin duda, un paso crucial para cualquiera que desee profundizar en el fascinante mundo de las gramáticas y los lenguajes formales.
Si quieres conocer otros artículos parecidos a Desentrañando la Forma Normal de Chomsky puedes visitar la categoría Cálculos.
