Skip to content
Simon Johannes Engelhardt edited this page Feb 24, 2025 · 12 revisions

Projektdokumentation "AlmanAssemblierer"

Alman ist eine in vielen Sprachen gebräuchliche neutrale Bezeichnung für Deutsche. Im deutschen Sprachraum wird es mitunter als Slangbegriff verwendet, mit dem mehrheitlich Menschen mit Migrationshintergrund sich über klischeehaft „deutsches Verhalten“ [...] lustig machen. - Wikipedia

Einführung

Das Projekt "AlmanAssemblierer" ist die Abgabe für den Kurs "Compilerbau" an der Hochschule Rhein Main. Ziel der Abgabe ist, einen Compiler zu schreiben, der von einer Quellsprache mithilfe einer Implementierungssprache in eine Zielsprache übersetzt. In meinem Projekt handelt es sich bei der Quellsprache um eine eigens entwickelte Sprache, die "Alman"-Sprache. Eine Sprache bei der alle sonst geläufigen Programmierwörter in die deutsche Sprache übersetzt wurden. Mehr zur "Almn"-Sprache

Die Quellsprache ist x86 Assembly und die Implementierungssprache ist Java. Der Assembly Code kann nach der Generierung mit Tools wie gcc in Machine Code assembliert werden und dann direkt auf dem System ausgeführt werden. Um aber bis zu Machine Code zu kommen, sind einige Schritte nötig. Und da aller Anfang schwer ist, fängt man auch erst simpel an und arbeitet sich dann langsam hoch. Der erste Schritt ist der Lexer.

Lexer (Tokenizer)

Ein*e Programmierer*in hat Code in der "Alman"-Sprache geschrieben. Diese Datei soll jetzt in die Zielsprache übersetzt werden. Dafür wird die Datei als Character Stream eingelesen und an einen Lexer bzw. Tokenizer übergeben, der mithilfe von regulären Ausdrücken zusammengehörende Zeichen zu Tokens zusammen gruppiert. Diese Tokens werden in einem Token Stream übergeben an den Parser.

Parser

Der Parser führt eine syntaktische Analyse der Tokens durch und erkennt, welche Tokens in welcher Relation zusammengehören. Daraus generiert der Parser dann einen AST (Abstract Syntax Tree). In meinem Projekt wird der Lexer und Parser mit der Bibliothek ANTLR umgesetzt. Mit dieser Bibliothek ist es möglich, mit regulären Ausdrücken ähnelnden Definitionen sowohl den Lexer als auch den Parser zu erstellen. ANTLR generiert dann mehrere Dateien in der Implementierungssprache, die genutzt werden können, um einen eigenen AST zu erstellen und diesen zu durchlaufen.

AST

Der AST besteht aus vielen Knoten, die einzelne Elemente der Quellsprache repräsentieren. Diese Knoten sind miteinander verbunden und können mit dem Visitor Pattern durchlaufen werden. Es werden in diesem Projekt verschieden Visitor eingesetzt, die den AST anreichern und Strukturen überprüfen.

Eval Visitor

Der Eval Visitor ist als ein minimalistischer Interpreter gedacht. Anfangs wurde damit versucht, die komplette Sprache zu evaluieren, dies ist aber mit steigender Komplexität nicht mehr möglich gewesen. Jetzt ist der Eval Visitor vor allem dafür da, komplexe Ausdrücke bei der Deklaration von globalen Variablen zu evaluieren.

Pretty Printer

Der Pretty Printer durchläuft den kompletten AST und generiert daraus wieder die Quellsprache. Hier wird vor allem darauf geachtet, dass die Einrückungen und weitere Syntax in einem einheitlichen Format wieder ausgegeben wird.

TypeCheck Visitor

Der TypeCheck Visitor durchläuft den AST und stellt sicher, dass die Typinformationen an allen Stellen stimmen. Eine Funktion muss tatsächlich den Wert zurückgeben, den sie angibt, zurückzugeben. Außerdem müssen die Typen bei Variablendefinitionen stimmen und bei Operationen. Mehr zum Typsystem

GenAssembly Visitor

Der GenAssembly Visitor durchläuft den AST und generiert die x86 Instruktionen. Diese werden zuerst in einen StringBuilder geschrieben und letztlich auch in eine .s Datei, um dann weiter kompiliert zu werden. Der Visitor generiert auch eine .c und .h Datei, damit die generierten Funktionen auch in C aufgerufen werden können. Mehr zur Assembly Generierung

TailCall Visitor

Der TailCall Visitor durchläuft Funktionsdefinitionen und prüft, ob diese nach dem Tail Call Muster vereinfacht werden können. Falls es möglich ist, wird ein Attribut an dem Knoten der Funktionsdefinition gesetzt und beim GenAssembly Visitor wird dann statt eines rekursiven Aufrufs eine while-Schleife in Assembly generiert.

Weiterführende Wikieinträge:

Das Buildsystem Testen Limitationen

Weitere Links:

Installations- und Ausführungsanweisungen Projekt Repository ANTLR