Für diejenigen, die POJ (Pascal auf der JVM) nicht befolgen: Es handelt sich um einen Compiler, der eine Teilmenge von Pascal in JASM umwandelt ( Java Assembly), damit wir die JVM als Ausführungsumgebung verwenden können.
Im letzten Beitrag haben wir einige wichtige Fehler behoben, insbesondere bei der Generierung der Assembly. In diesem Beitrag werden wir darüber sprechen, wie man die Assembly für verschachtelte Sätze korrekt generiert.
Während wir für die JVM kompilieren, ist es notwendig, die Funktionsweise verschiedener Punkte dieser unglaublichen virtuellen Maschine im Detail zu beschreiben. Daher erläutere ich an verschiedenen Stellen die interne Funktionsweise der JVM sowie einige ihrer Anweisungen (Opcodes).
Eine der notwendigen Funktionen für den korrekten Umgang mit verschachtelten Sätzen ist die Möglichkeit, im Parser mehrere Kontexte zu haben. Dies liegt daran, dass, wenn der Parser nur einen Kontext annimmt, verschachtelte Kontrollsätze, die Beschriftungen und Sprünge generieren (wie if, for, while und repeat) würden eine falsche Sprungadressierung erzeugen.
Es gibt zwei Möglichkeiten, mit Kontexten umzugehen:
Normalerweise würde ich den rekursiven Parser-Ansatz verwenden. Um jedoch einen rekursiven Parser mit ANTLR zu implementieren, wäre es aufgrund der Art und Weise, wie die Grammatik in POJ strukturiert war, notwendig, Code direkt in die Grammatik einzufügen, ein Ansatz, der nicht empfohlen wird. Aus diesem Grund haben wir uns für den Ansatz des Stapelns von Kontexten entschieden.
Da es bereits eine Stack-Implementierung gab, die die Typen überwachte, die der Parser in der JVM gestapelt/entstapelt hat, haben wir beschlossen, einen zu erstellen, um keinen weiteren Stapel für einen bestimmten Typ erstellen zu müssen 🎜 >Stack generisch in dieser PR. Ich kann diese Implementierung nicht nur später nutzen, sondern auch den alten Code umgestalten und den vorhandenen spezifischen Stack entfernen.
In diesem Commit wurde der Parser geändert, um Funktionskontexte korrekt zu stapeln/entstapeln. Grundsätzlich wird am Anfang des Parsers einer Funktion der Kontext gestapelt und am Ende wird der Kontext entstapelt.
Kontrollsätze wie if, for, while und repeat funktionierten korrekt. Wenn es jedoch verschachtelte Sätze gab, speicherte POJ den Kontext nicht und generierte fälschlicherweise Beschriftungen und Sprünge. Hier und hier wurde diskutiert, wie die Generierung der Assembly für diese Kontrollsätze funktioniert.
Für das folgende Beispiel, das ein if enthält, das in einem anderen verschachtelt ist, hat POJ fälschlicherweise die Beschriftungen und die erforderlichen Sprünge generiert:
program NestedIfs; begin if (1 > 2) then if (2 > 3 ) then writeln('1 > 2 and 2 > 3') else writeln('1 > 2 and 2 <= 3') else writeln('1 <= 2'); end.
Dieser Fehler war bekannt und ich habe beschlossen, ihn zu beheben, als der Parser Kontexte unterstützte.
In diesem Commit wurde die LabelsContext-Struktur erstellt, die die folgenden Labels enthält:
Um die korrekte Generierung der Assembly zu validieren, wurden Tests erstellt, um verschachtelte ifs, verschachtelte repeats, verschachtelte whiles sowie fors zu validieren verschachtelt. Hier wurden Tests erstellt, um die Generierung der Assembly bei rekursiven Funktionen zu validieren. Darüber hinaus war es notwendig, die erwartete Zusammenstellung aller vorhandenen Tests zu aktualisieren. Schließlich wurde in dieser PR der Parser aktualisiert, um die neue Kontextstruktur zu verwenden.
Hier ist die vollständige PR dieser Änderungen. Hier haben wir das Commit, das die Änderungen für die korrekte Funktionsweise des if-Satzes enthält, hier das Commit, das sich auf die Wiederholung bezieht das commit bezieht sich auf while und hier das commit bezieht sich auf for.
Im nächsten Beitrag werden wir über die Dateneingabe sprechen. Jetzt dauert es nicht mehr lange, bis wir eines der Ziele dieses Projekts erreichen: eine Zahl aus der Standardeingabe lesen und ihre Fakultät berechnen.
Das Repository mit dem vollständigen Code und der Dokumentation des Projekts finden Sie hier.
Das obige ist der detaillierte Inhalt vonVerschachtelte Sätze. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!