Warum macht Forths Flexibilität eine Grammatik dafür ungeeignet?

10

Ich habe kürzlich die Aufgabe übernommen, eine stapelbasierte Programmiersprache zu schreiben. Bevor ich jedoch anfing, meine Sprache zu entwerfen, hielt ich es für eine gute Idee, vorhandene stapelbasierte Sprachen zu lesen und damit zu experimentieren.

Dies bringt mich zum Thema dieses Beitrags. Ich habe den Wikipedia-Artikel über Forth gelesen , eine stapelbasierte Sprache, die Ausdrücke im Postfix-Stil verwendet. In dem Artikel habe ich folgende Aussage gesehen:

Die Flexibilität von Forth macht eine statische BNF-Grammatik unangemessen und es gibt keinen monolithischen Compiler. Zum Erweitern des Compilers muss nur ein neues Wort geschrieben werden, anstatt eine Grammatik zu ändern und die zugrunde liegende Implementierung zu ändern.

Nach meinem Verständnis scheint der Begriff "Wort" im Forth-Jargon im Grunde genommen gleichbedeutend mit "Unterprogramm" zu sein. Angesichts dessen erscheint die obige Aussage seltsam. Warum genau würde die Fähigkeit, neue Funktionen in Forth zu erstellen, eine formale Grammatik für Forth unangemessen machen? Warum müssen Sie die Grammatik für jede neue Unterroutine, die Sie definieren, neu schreiben? Wie stellt ein neues Wort in der Umgebung Schreiben Verlängerung des Compilers? Die obige Aussage scheint zu sagen, dass eine formale Grammatik für Python ungeeignet ist, da Sie neue Funktionen definieren können.

Tatsächlich habe ich mich entschlossen, eine Grammatik im BNF-Stil für eine einfache Teilmenge von Forth zu schreiben:

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

Die obige Grammatik scheint eine gültige Teilmenge von Forth-Anweisungen abzudecken und scheint nicht so schwer zu erweitern, um alle gültigen Anweisungen in der Forth-Sprache abzudecken. Wenn der Parser eines Compilers die obige Grammatik implementiert, sehe ich nicht, wie der Compiler jemals erweitert werden würde. Der Compiler fügt seiner Umgebung einfach neue Wörter hinzu . Nur die Umgebung wird geändert. Es scheint fast so, als würde der obige Auszug aus Wikipedia den unterstrichenen Code, aus dem der Compiler besteht (der sich nicht ändert), mit der Umgebung des Compilers (die sich ändert) zusammenführen.

Zusammenfassend lässt sich sagen, warum Forths Fähigkeit, neue Wörter (Unterprogramme) zu definieren, für eine geschriebene Grammatik ungeeignet ist.

Christian Dean
quelle
1
"Unangemessen" ist in diesem Zusammenhang ein starkes Wort. Ein besseres Wort wäre wahrscheinlich "unnötig".
Robert Harvey
1
Oh, okay @RobertHarvery. Wenn dies jedoch der Fall wäre, würde der von mir zitierte Auszug für die meisten Sprachen gelten. Technisch wird eine Grammatik nie benötigt , aber es ist schön, eine zu haben - besonders wenn man Parser von Hand schreibt.
Christian Dean
In den meisten Sprachen ist der Parser jedoch keine einfache Laufzeitbibliothek, die durch Benutzercode geändert werden kann, was sich auf die Analyse der nächsten Zeile auswirkt.
Jörg W Mittag

Antworten:

10

Ein "normales" Wort ist so ziemlich nur eine Unterroutine.

... aber Sie können ein benutzerdefiniertes definierendes Wort schreiben , das die Funktionsweise des Compilers ändert. Beispielsweise beginnt eine Definition normalerweise mit einem Doppelpunkt (":") und endet mit einem Semikolon (";"). Wenn Sie möchten, können Sie (zum Beispiel) ändern, was der Doppelpunkt tut, und dabei ändern, wie eine Wortdefinition "kompiliert" wird, wodurch die Funktionsweise des Compilers und die Grammatik der erkannten Sprache geändert werden.

Aus diesem Grund heißt es, dass eine Grammatik unangemessen ist - die Grammatik kann sich buchstäblich von einem Teil des Programms zum anderen ändern. Durch das Laden eines Wörterbuchs können nicht nur die Unterprogramme geändert werden, deren Namen derzeit erkannt werden, sondern auch die Grammatik, die beim Definieren eines neuen Wortes analysiert wird.

Jerry Sarg
quelle
2
Sind Sie sicher, dass diese Eigenschaft von Forth wirklich die Grammatik und nicht nur die Semantik ändert?
Doc Brown
@DocBrown: Die meisten Leute, die Forth verwenden, mögen es ziemlich oft, daher nehmen sie normalerweise nur die minimalsten Änderungen vor, die für die jeweilige Aufgabe erforderlich sind. Jemand, der ehrgeizig (und verrückt) genug war, konnte die Syntax komplett ändern, wenn er wollte - wie die Verwendung der Infix-Notation anstelle des Postfixes, wenn er es dringend genug wollte.
Jerry Coffin
@DocBrown Welche Art von Grammatik könnten Sie möglicherweise schreiben, um einen C-Interpreter in Forth zu schreiben und dann plötzlich mitten im Programm zu C zu wechseln?
user253751
@immibis: Nun, meine Frage ist - erlaubt Forth wirklich so etwas? Aus diesem verlinkten Artikel geht mir dies nicht von Natur aus klar.
Doc Brown
@ DocBrown Ja, das tut es. Sie können Ihren Code zur Kompilierungszeit ausführen. Wenn Sie möchten, können Sie den Compiler vollständig übernehmen. Grundsätzlich können Sie Ihren C-Compiler / Interpreter in der Mitte des Forth-Compilers / Interpreters ausführen. (ob Sie irgendwann nach Forth zurückkehren möchten oder nicht, liegt bei Ihnen)
user253751
3

In Forth können Sie Code zur Kompilierungszeit ausführen.

Insbesondere können Sie Code ausführen, der Wörter aus der Eingabe verbraucht. Sie können beispielsweise einen C-Compiler in Forth schreiben und ihn dann zur Kompilierungszeit aufrufen und dann den Rest Ihres Programms in C schreiben.

In der Regel können Sie Wörter definieren, die Argumente aus dem Quellcode lesen. Traditionell lesen Sie Wörter genauso wie der Compiler, dies ist jedoch nicht erforderlich.

Zum Beispiel ."liest das Wort (das eine Zeichenfolge druckt) erst im nächsten Leerzeichen, es liest bis zum nächsten ". Wenn Sie versuchen, den Code : PRINTHELLO ." Hello ; : func2 world!" ;ohne Sonderfall zu analysieren .", werden Sie feststellen, dass er nicht korrekt analysiert wird.

Sie können ."Ihrer Grammatik sicherlich einen Sonderfall hinzufügen , aber die Grammatik ist immer noch falsch, wenn der Programmierer sein eigenes Wort wie folgt definiert ."- zum Beispiel hier eines : : MY_PRINT POSTPONE ." ; IMMEDIATE. Dieses Wort ist äquivalent zu ."; Ich kann schreiben MY_PRINT Hello ; world! "und Ihre Grammatik muss sie analysieren können. Viel Glück damit.

user253751
quelle