¿Por qué la flexibilidad de Forth hace que una gramática sea inapropiada para ella?

10

Recientemente he emprendido la tarea de escribir un lenguaje de programación basado en pila. Sin embargo, antes de comenzar a diseñar mi lenguaje, pensé que sería una buena idea leer y experimentar con los lenguajes basados ​​en pila existentes.

Esto me lleva al tema de esta publicación. Estaba leyendo el artículo de Wikipedia sobre Forth , un lenguaje basado en pila que usa expresiones de estilo postfix. En el artículo, vi la siguiente declaración:

La flexibilidad de Forth hace que una gramática BNF estática sea inapropiada y no tiene un compilador monolítico. Ampliar el compilador solo requiere escribir una nueva palabra, en lugar de modificar una gramática y cambiar la implementación subyacente.

Según tengo entendido, en la jerga de Forth, el término "palabra" parece ser básicamente sinónimo de "subrutina". Dado esto, la declaración anterior parece extraña. ¿Por qué exactamente la capacidad de crear nuevas funciones en Forth haría inapropiada una gramática formal para Forth? ¿Por qué necesitaría volver a escribir la gramática para cada nueva subrutina que defina? ¿Cómo escribir una nueva palabra en el entorno constituye extender el compilador? La afirmación anterior parece similar a decir que una gramática formal es inapropiada para Python porque puede definir nuevas funciones.

De hecho, decidí intentar escribir una gramática de estilo BNF para un subconjunto simple de Forth a continuación:

program        ::= stmt+
stmt           ::= func | expr
func           ::= ':' expr+ ';'
expr           ::= INTEGER | word
word           ::= ('+' | '-' | '*' | '/' )

La gramática anterior parecería cubrir un subconjunto válido de declaraciones Forth, y no parece tan difícil de extender para cubrir todas las declaraciones válidas en el lenguaje Forth. Además, si el analizador de un compilador implementa la gramática anterior, no veo cómo se ampliará el compilador. El compilador simplemente agregará cualquier palabra nueva a su entorno . Solo se cambia el entorno. Casi parece que el extracto anterior de Wikipedia está combinando el código subyacente que compone el compilador (que no cambia) con el entorno del compilador (que sí cambia).

En resumen, ¿por qué la capacidad de Forth para definir nuevas palabras (subrutinas) es inapropiada para una gramática escrita?

Christian Dean
fuente
1
"Inapropiado" es una palabra fuerte en este contexto. Una palabra mejor probablemente sería "innecesaria".
Robert Harvey
1
Oh, está bien @RobertHarvery. Sin embargo, si ese fuera el caso, entonces el extracto que cité parecería aplicarse a la mayoría de los idiomas. Técnicamente, nunca se necesita una gramática , pero es bueno tenerla, especialmente cuando se escriben analizadores a mano.
Christian Dean
Pero en la mayoría de los idiomas, el analizador no es una simple biblioteca de tiempo de ejecución que se puede cambiar por código de usuario, lo que afecta la forma en que se analiza la siguiente línea.
Jörg W Mittag

Respuestas:

10

Una palabra "normal" es prácticamente una subrutina.

... pero puede escribir una palabra de definición definida por el usuario , que cambia el funcionamiento del compilador. Por ejemplo, una definición normalmente comienza con dos puntos (":") y termina con un punto y coma (";"). Pero si lo desea, puede (por ejemplo) cambiar lo que hace los dos puntos y, en el proceso, cambiar cómo se "compila" una definición de palabra, cambiando así el funcionamiento del compilador y la gramática del lenguaje que se reconoce.

Es por eso que dice que una gramática es inapropiada: la gramática puede literalmente cambiar de una parte del programa a otra. Cargar un diccionario puede cambiar no solo las subrutinas cuyos nombres se reconocen actualmente, sino también la gramática que se analiza cuando define una nueva palabra.

Jerry Coffin
fuente
2
¿Estás seguro de que esta propiedad de Forth realmente cambia la gramática y no solo la semántica?
Doc Brown
@DocBrown: a la mayoría de las personas que usan Forth les gusta bastante, por lo que generalmente solo realizan los cambios mínimos necesarios para la tarea en cuestión. Alguien que fuera lo suficientemente ambicioso (y loco) podría cambiar la sintaxis por completo si quisieran, como usar la notación infija en lugar de postfix, si quisieran lo suficiente.
Jerry Coffin
@DocBrown ¿Qué tipo de gramática podrías escribir que me permitiría escribir un intérprete de C en Forth y luego cambiar de repente a C en el medio del programa?
user253751
@immibis: bueno, mi pregunta es: ¿Forth realmente permite algo como esto? De ese artículo vinculado, esto no es inherentemente claro para mí.
Doc Brown
@DocBrown Sí, lo hace. Puede ejecutar su código en tiempo de compilación, eso significa que si lo desea puede hacerse cargo del compilador. Básicamente puede ejecutar su compilador / intérprete de C en el medio del compilador / intérprete de Forth. (si desea regresar a Forth o no, depende de usted)
usuario253751
3

En Forth, puede ejecutar código en tiempo de compilación.

En particular, puede ejecutar código que consume palabras de la entrada. Por ejemplo, podría escribir un compilador de C en Forth, y luego llamarlo en tiempo de compilación, y luego escribir el resto de su programa en C.

Más comúnmente, puede definir palabras que leen argumentos del código fuente. Tradicionalmente, usted leería palabras de la misma manera que el compilador, pero no es obligatorio.

Por ejemplo, la ."palabra (que imprime una cadena) no se lee hasta el siguiente espacio, se lee hasta el siguiente ". Si intenta analizar el código : PRINTHELLO ." Hello ; : func2 world!" ;sin un caso especial .", encontrará que no se analiza correctamente.

Por supuesto que puede añadir un caso especial para ."que su gramática, pero la gramática todavía será incorrecto si el programador define su propia palabra como ."- por ejemplo, aquí está uno: : MY_PRINT POSTPONE ." ; IMMEDIATE. Esta palabra es equivalente a ."; Puedo escribir MY_PRINT Hello ; world! "y tu gramática necesita poder analizarla. Buena suerte con eso.

usuario253751
fuente