Gramática independiente del contexto

Las gramáticas independientes de contexto (GICs) son un modelo de computación que representa lenguajes independientes de contexto.

Una GIC está formada por

* Un alfabeto de símbolos terminales
* Un conjunto de variables no terminales
* Un conjunto de reglas de producción de la forma A→α, donde A es un símbolo no terminal y α una cadena de símbolos terminales y no terminales.
* Una variable destacada inicial.

Se dice que una cadena de símbolos terminales pertenece a cierta gramática si existe una secuencia de producciones que convierten la variable inicial en dicha cadena.

Las GICs son equivalentes a los APs.

## Árboles de derivación

Los árboles de derivación son una representación en árbol de la derivación de una palabra perteneciente a una GIC. Representan la estructura sintáctica de acuerdo a la gramática de la palabra. Para distinguir cuando dos cadenas de derivaciones representan una estructura sintáctica distinta (ie a dos árboles de derivación distintos) nos restringimos a derivaciones a la izquierda, en las que siempre elegimos sustituir la variable más a la izquierda.

## Gramáticas ambiguas

Una GIC es ambigua si existen dos árboles de derivación distintos (equivalentemente, dos cadenas de derivaciones a la izquierda) asociados a una palabra concreta de la gramática.

A veces es posible eliminar la ambigüedad de un GIC forzando una precedencia de operaciones (por ejemplo en la aritmética), lo cual nos da un GIC equivalente no ambiguo.

Un lenguaje es inherentemente ambiguo si toda GIC que lo genera es ambigua.

## Formas normales de un LIC

=== Simplificación de una GIC ===

Para simplificar una GIC procedemos a:

1. Eliminar producciones ε (A→ε)

Toda variable derivable en ε es anulable. Las anulables se pueden marcar explícitamente en las reglas de producción (ej: si A es anulable y B→AC entonces podemos sustituir la regla por B→AC | C) y luego eliminar la producción ε.
Esto no es posible hacerlo en lenguajes que contienen a ε

2. Eliminar producciones unitarias (A→B, con B variable) utilizando el algoritmo de pares unitarios.

3. Eliminamos los símbolos no generadores, que identificamos con una búsqueda en árbol a partir de las reglas que resultan en símbolos terminales.

4. Eliminamos los símbolos no alcanzables, que identificamos con una búsqueda en árbol que parte del símbolo inicial.

==== Forma normal de Chomsky (FNC) ====

Una GIC está en FNC si todas sus producciones son de la forma A→BC ó A→a.

Para convertir una GIC en FCN:

1. Realizamos las simplificaciones del apartado anterior para eliminar producciones épsilon, producciones unitarias y símbolos inútiles.
2. Por cada variable terminal:
	1. Creamos una variable X\_a y una regla de producción X\_a → a.
	2. Reemplazamos el resto de las apariciones de a en las reglas de producción por X\_a.
3. Reemplazamos cada producción A→B\_1...B\_k por A→B\_1 C\_1, C\_1→B\_2 C\_2, etc.

### Algoritmo CYK

Dada una gramática en FNC, podemos usar el algoritmo CYK para decidir si la gramática puede una cadena dada.

Consideramos una string a\_1...a\_n. Queremos computar dinámicamente X\_{i,j}, el conjunto de variables tales que es posible derivar X\_{i,j}\rightarrow a\_i...a\_j.

Primero inicializamos X\_{i,i} usando las reglas de producción de la forma $A\rightarrow a\_i$.

A continuación, para cada 1\le k \le n, calculamos X\_{i, i+k}, usando las reglas de producción de la forma $A\rightarrow BC$, donde $B\in X\_{i, i+z}$, $C\in X\_{i+z, i+k}.

Finalmente comprobamos si $X\_{1,n}$ es vacio.