Pourquoi la flexibilité de Forth rend-elle une grammaire inappropriée?

10

J'ai récemment entrepris d'écrire un langage de programmation basé sur la pile. Cependant, avant de commencer à concevoir ma langue, je pensais que ce serait une bonne idée de lire et d'expérimenter avec les langues existantes basées sur la pile.

Cela m'amène au sujet de cet article. Je lisais l'article Wikipedia sur Forth , un langage basé sur la pile qui utilise des expressions de style postfix. Dans l'article, j'ai vu la déclaration suivante:

La flexibilité de Forth rend une grammaire BNF statique inappropriée, et elle n'a pas de compilateur monolithique. L'extension du compilateur nécessite uniquement d'écrire un nouveau mot, au lieu de modifier une grammaire et de changer l'implémentation sous-jacente.

D'après ma compréhension, dans le quatrième jargon, le terme "mot" semble être fondamentalement synonyme de "sous-programme". Compte tenu de cela, la déclaration ci-dessus semble étrange. Pourquoi exactement la possibilité de créer de nouvelles fonctions dans Forth rendrait-elle inappropriée une grammaire formelle pour Forth? Pourquoi auriez-vous besoin de réécrire la grammaire pour chaque nouveau sous-programme que vous définissez? En quoi l'écriture d'un nouveau mot dans l'environnement constitue-t-elle une extension du compilateur? L'instruction ci-dessus semble s'apparenter à dire qu'une grammaire formelle n'est pas appropriée pour Python car vous pouvez définir de nouvelles fonctions.

En fait, j'ai décidé d'essayer d'écrire une grammaire de style BNF pour un simple sous-ensemble de Forth ci-dessous:

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

La grammaire ci-dessus semble couvrir un sous-ensemble valide d'instructions Forth, et ne semble pas difficile à étendre pour couvrir toutes les instructions valides dans la langue Forth. De plus, si l'analyseur d'un compilateur implémente la grammaire ci-dessus, je ne vois pas comment le compilateur serait jamais étendu. Le compilateur ajoutera simplement de nouveaux mots à son environnement . Seul l'environnement est modifié. Il semble presque que l'extrait de Wikipedia ci-dessus confond le code de soulignement qui compose le compilateur (qui ne change pas) avec l'environnement du compilateur (qui change).

En résumé, pourquoi l'aptitude de Forth à définir de nouveaux mots (sous-programmes) est-elle inappropriée pour une grammaire écrite?

Christian Dean
la source
1
"Inapproprié" est un mot fort dans ce contexte. Un meilleur mot serait probablement «inutile».
Robert Harvey
1
Oh, d'accord @RobertHarvery. Cependant, si tel était le cas, l'extrait que j'ai cité semble s'appliquer à la plupart des langues. Techniquement, une grammaire n'est jamais nécessaire , mais c'est agréable d'en avoir une - en particulier lors de l'écriture manuscrite des analyseurs.
Christian Dean
Mais dans la plupart des langues, l'analyseur n'est pas une simple bibliothèque d'exécution qui peut être modifiée par le code utilisateur, affectant ainsi la façon dont la ligne suivante est analysée.
Jörg W Mittag

Réponses:

10

Un mot «normal» est à peu près juste un sous-programme.

... mais vous pouvez écrire un mot de définition défini par l' utilisateur , qui modifie le fonctionnement du compilateur. Par exemple, une définition commence normalement par deux points (":") et se termine par un point-virgule (";"). Mais si vous le souhaitez, vous pouvez (par exemple) modifier ce que fait le signe deux-points et, dans le processus, modifier la façon dont une définition de mot est "compilée", modifiant ainsi le fonctionnement du compilateur et la grammaire de la langue reconnue.

C'est pourquoi cela dit qu'une grammaire est inappropriée - la grammaire peut littéralement changer d'une partie du programme à une autre. Le chargement d'un dictionnaire peut modifier non seulement les sous-programmes dont les noms sont actuellement reconnus, mais également la grammaire analysée lorsque vous définissez un nouveau mot.

Jerry Coffin
la source
2
Êtes-vous sûr que cette propriété de Forth change vraiment la grammaire et pas seulement la sémantique?
Doc Brown
@DocBrown: La plupart des gens qui utilisent Forth l'aiment beaucoup, donc ils n'apportent généralement que les changements les plus minimes nécessaires à la tâche à accomplir. Quelqu'un qui était assez ambitieux (et fou) pourrait changer complètement la syntaxe s'il le voulait - comme utiliser la notation infixe au lieu du suffixe, s'il le voulait assez.
Jerry Coffin
@DocBrown Quel genre de grammaire pourriez-vous éventuellement écrire qui me permettrait d'écrire un interprète C à Forth, puis de basculer soudainement en C au milieu du programme?
user253751
@immibis: eh bien, ma question est - Forth permet-il vraiment quelque chose comme ça? D'après cet article lié, ce n'est pas intrinsèquement clair pour moi.
Doc Brown
@DocBrown Oui, c'est le cas. Vous pouvez exécuter votre code au moment de la compilation, ce qui signifie que si vous le souhaitez, vous pouvez prendre entièrement le contrôle du compilateur. Fondamentalement, vous pouvez exécuter votre compilateur / interprète C au milieu du compilateur / interprète Forth. (à vous de revenir ou non à Forth)
user253751
3

Dans Forth, vous pouvez exécuter du code au moment de la compilation.

En particulier, vous pouvez exécuter du code qui consomme des mots de l'entrée. Par exemple, vous pouvez écrire un compilateur C en Forth, puis l'appeler au moment de la compilation, puis écrire le reste de votre programme en C.

Plus généralement, vous pouvez définir des mots qui lisent des arguments à partir du code source. Traditionnellement, vous lisiez les mots de la même manière que le compilateur, mais ce n'est pas obligatoire.

Par exemple, le ."mot (qui imprime une chaîne) ne lit pas jusqu'à l'espace suivant, il lit jusqu'au suivant ". Si vous essayez d'analyser le code : PRINTHELLO ." Hello ; : func2 world!" ;sans cas particulier pour .", vous constaterez qu'il n'est pas analysé correctement.

Vous pouvez certainement ajouter un cas particulier pour ."votre grammaire, mais la grammaire sera toujours incorrecte si le programmeur définit leur propre mot comme ."- par exemple, voici un: : MY_PRINT POSTPONE ." ; IMMEDIATE. Ce mot est équivalent à ."; Je peux écrire MY_PRINT Hello ; world! "et votre grammaire doit pouvoir l'analyser. Bonne chance avec ça.

user253751
la source