Esta es una reformulación de ¿Son los programas de gramáticas? previamente preguntado por Vag y con muchas sugerencias de los comentaristas.
¿De qué manera puede verse una gramática que especifica un modelo de cálculo? Si, por ejemplo, tomamos una gramática simple sin contexto, como
G ::= '1' -> '0' '+' '1'
'1' -> '1' '+' '0'
'2' -> '2' '+' '0'
'2' -> '1' '+' '1'
'2' -> '0' '+' '2'
'3' -> '3' '+' '0'
'3' -> '2' '+' '1'
'3' -> '1' '+' '2'
'3' -> '1' '+' '2'
Suponiendo que el analizador no distingue entre símbolos terminales y no terminales como he demostrado aquí, entonces es posible realizar una aritmética simple para números hasta 3.
Por ejemplo, toma la cuerda
"2 + 0 + 1"
Ejecutar un analizador LR (1) en esta cadena debería darnos el siguiente árbol de sintaxis concreta donde el resultado del cálculo se almacena en la raíz del árbol:
'3'
/ | \
/ | \
'2' '+' '1'
/ | \
/ | \
'2' '+' '0'
Por lo tanto, si consideramos que una gramática es un programa y un generador de analizadores para ser un compilador , ¿podríamos ver el lenguaje de especificación gramatical como un lenguaje de programación ?
Además, ¿podríamos construir programas completos de Turing especificando gramáticas similares a cómo podría construir programas completos de Turing con autómatas celulares o el cálculo lambda ?
En otras palabras, se sabe que, en el sentido de reconocer un idioma, los lenguajes regulares corresponden a autómatas de estado finito , los lenguajes libres de contexto corresponden a autómatas de empuje y los lenguajes sensibles al contexto corresponden a autómatas lineales . Sin embargo, si consideramos las gramáticas como dispositivos computacionales (es decir, programas en el sentido del ejemplo anterior), ¿cómo clasificamos la fuerza computacional de cada clase de gramáticas en la jerarquía de Chomsky?
- Gramáticas regulares
- Gramáticas libres de contexto
- Gramáticas sensibles al contexto
- Gramáticas sin restricciones (para lenguajes recursivamente enumerables )
Además, ¿qué hay de las subclases menos conocidas de gramáticas como
- Gramáticas deterministas sin contexto (también LR (k) / LL (k) / SLR / LALR, etc.)
- Gramáticas de palabras anidadas
- Gramáticas adyacentes a los árboles
- Gramáticas indexadas
EDITAR: Por cierto, este es un punto crítico en mi propia pregunta, pero no mencioné que no di ningún símbolo de inicio para la gramática de ejemplo y agité a mano la necesidad de distinguir entre terminales y no terminales. Técnica o tradicionalmente creo que la gramática probablemente debería escribirse en una forma más complicada como esta (donde S es el símbolo de inicio y $ representa el terminal de fin de flujo):
G ::= S -> R0 '$'
S -> R1 '$'
S -> R2 '$'
R0 -> '0'
R0 -> R0 '+' '0'
R1 -> '1'
R1 -> R0 '+' '1'
R1 -> '1' '+' R0
R1 -> R0 '+' '1' '+' R0
R2 -> '2'
R2 -> R0 '+' '2'
R2 -> '2' '+' R0
R2 -> R0 '+' '2' '+' R0
R2 -> R1 '+' '1'
R2 -> R1 '+' '1' '+' R0
... no es que realmente cambie nada, pero pensé que debería mencionarlo.
EDITAR: Algo más que me vino a la mente cuando leí la respuesta de Gasche es que cada rama en el árbol en mi ejemplo representa un sub-cálculo. Si observa cada regla de producción como una función donde el LHS representa el resultado y el RHS representa sus argumentos, entonces la estructura de la gramática determina cómo se componen las funciones.
En otras palabras, el contexto del analizador junto con su mecanismo de búsqueda anticipada ayuda a determinar no solo qué funciones aplicar ('un poco' como el polimorfismo paramétrico) sino cómo deben componerse juntas para formar nuevas funciones.
Al menos, supongo que podrías verlo de esta manera para CFG inequívocos, para otras gramáticas, la gimnasia mental es demasiado para mí en este momento.