Compiler
Ein Compiler (auch Kompilierer oder Zersetzer) ist ein Computerprogramm, das ein in einer Quellsprache geschriebenes Programm - genannt Quellprogramm - in ein semantisch äquivalentes Programm einer Zielsprache (Zielprogramm) umwandelt. Üblicherweise handelt es sich dabei um die Übersetzung eines von einem Programmierer in einer Programmiersprache geschriebenen Quelltextes in Assemblersprache, Bytecode oder Maschinensprache. Das Übersetzen eines Quellprogramms in ein Zielprogramm durch einen Compiler wird als Kompilierung oder auch als Übersetzung bezeichnet.
Der Compilerbau, also die Programmierung eines Compilers, ist eine eigenständige Disziplin innerhalb der Informatik. Er gilt als das älteste Gebiet der praktischen Informatik.
Die Bezeichnungen Compiler (engl. to compile: zusammenstellen) ist eigentlich irreführend. Ursprünglich bezeichnete das Wort Compiler Programme die Unterprogramme zusammenfügen (etwa mit heutigen Linkern vergleichbar)[1]. Dies geht an der heutigen Kernaufgabe eines Compilers vorbei.
Verwandt mit einem Compiler ist ein Interpreter, der ein Programm nicht in die Zielsprache übersetzt, sondern Schritt für Schritt direkt ausführt.
Aufbau eines Compilers

Compiler werden in verschiedene Phasen gegliedert, die jeweils verschiedene Teilaufgaben das Compilers übernehmen. Sie werden sequentiell ausgeführt. Im Wesentlichen lassen sich zwei Phasen unterscheiden: das Frontend (auch Analysephase), das den Quelltext analysiert und daraus einen attributierten Syntaxbaum erzeugt, sowie das Backend (auch Synthesephase), das daraus das Zielprogramm erzeugt.
Frontend (auch „Analysephase“)
Im Frontend wird der Code analysiert, strukturiert und auf Fehler geprüft. Es ist auch selbst wieder in Phasen gegliedert:
Lexikalische Analyse
Die lexikalische Analyse zerteilt den eingelesenen Quelltext in zusammengehörende Token verschiedener Klassen, z. B. Schlüsselwörter, Bezeichner, Zahlen und Operatoren. Dieser Teil des Compilers heißt Scanner oder Lexer.
Ein Scanner benutzt gelegentlich einen separaten Screener, um Whitespace (Leerraum, also Leerzeichen, Zeilenenden, usw.) und Kommentare zu überspringen.
Syntaktische Analyse
Die syntaktische Analyse überprüft, ob der eingelesene Quellcode tatsächlich ein Programm der zu übersetzenden Quellsprache ist, d. h. der Syntax (Grammatik) der Quellsprache entspricht. Dabei wird die Eingabe in einen Syntaxbaum umgewandelt. Dieser Teil wird auch als Parser bezeichnet.
Semantische Analyse
Die semantische Analyse überprüft die statische Semantik, also über die syntaktische Analyse hinausgehende Bedingungen an das Programm. Zum Beispiel muss eine Variable deklariert worden sein, bevor sie verwendet wird, und Zuweisungen müssen mit kompatiblen (verträglichen) Datentypen erfolgen. Dies kann mit Hilfe von Attributgrammatiken realisiert werden. Dabei werden die Knoten des vom Parser generierten Ableitungsbaums mit Attributen versehen, die Informationen enthalten. So kann zum Beispiel eine Liste aller deklarierten Variablen erstellt werden. Die Ausgabe der semantischen Analyse nennt man dann dekorierter oder attributierter Syntaxbaum.
Backend (auch „Synthesephase“)
Das Backend erzeugt aus dem vom Frontend erstellten attributierten Syntaxbaum den Programmcode der Zielsprache.
Zwischencodeerzeugung
Viele moderne Compiler erzeugen aus dem Syntaxbaum einen Zwischencode, der schon relativ maschinennah sein kann und führen auf diesem Zwischencode z. B. Programmoptimierung durch. Das bietet sich besonders bei Compilern an, die mehrere Quellsprachen oder verschiedene Zielplattformen unterstützen. Hier kann der Zwischencode auch ein Austauschformat sein.
Programmoptimierung
Der Zwischencode ist Basis vieler Programmoptimierungen. Siehe Programmoptimierung.
Codegenerierung
Bei der Codegenerierung wird entweder direkt aus dem Syntaxbaum oder aus dem Zwischencode der Programmcode der Zielsprache erzeugt. Falls die Zielsprache eine Maschinensprache ist, kann das Ergebnis direkt ein ausführbares Programm sein oder eine so genannte Objektdatei, die durch das Linken mit der Laufzeitbibliothek und evtl. weiteren Objektdateien zu einer Bibliothek oder einem ausführbaren Programm führt.
Einordnung verschiedener Arten
- Native Compiler
- Compiler, der Programmcode für die Plattform erzeugt, auf der er selbst läuft.
- Compiler, der auf einer Plattform ausgeführt wird und Programmcode für eine andere Plattform, z. B. ein anderes Betriebssystem oder eine andere Prozessorarchitektur, erzeugt.
- Eine typische Anwendung ist die Erstellung von Programmen für ein eingebettetes System, das selbst keine oder keine guten Werkzeuge zur Softwareerstellung enthält, sowie die Erstellung oder Portierung eines Betriebssystems auf einer neuen Plattform.
- Single-pass-Compiler
- Compiler, der in einem einzigen Durchlauf aus dem Quellcode den Zielcode erzeugt (im Gegensatz zum Multi-pass-Compiler). Üblicherweise ist ein derartiger Compiler sehr schnell, aber kann nur einfache Optimierungen durchführen. Nur für bestimmte Programmiersprachen, z. B. Pascal, kann ein Single-Pass-Compiler erstellt werden.
- Multi-pass-Compiler
- Bei diesem Compilertyp wird der Quellcode in mehreren Schritten in den Zielcode übersetzt. Während in den Anfangszeiten des Compilerbaus der Übersetzungsprozess noch hauptsächlich deshalb meist in mehrere, oft viele Durchläufe zerlegt wurde, weil die Kapazität früherer Computer oft nicht ausreichte, um den vollständigen Compiler und das zu übersetzende Programm gleichzeitig im Hauptspeicher zu halten, dient ein Multi-pass-Compiler heutzutage vor allem dazu, Vorwärtsreferenzen aufzulösen (einige Programmiersprachen lassen die Deklaration eines Bezeichners nach dessen erster Verwendung zu) und aufwendige Optimierungschritte auf dem vollständigen Syntaxbaum des Programms ausführen zu können.
Sonderformen
- Bei einem Transcompiler (auch als Transpiler bezeichnet) handelt es sich um einen speziellen Compiler, der Quellcode von einer Programmiersprache in den Quellcode einer anderen Programmiersprache übersetzt, z. B. von Pascal in C.
Da jedoch viele Programmiersprachen besondere Eigenschaften und Leistungsmerkmale besitzen, die nur in den seltensten Fällen von Transcompilern berücksichtigt werden, kommt es häufig zu Effizienzverlusten. Oft ist auch eine manuelle Nachbearbeitung des Codes nötig, da die automatische Übersetzung nicht in allen Fällen zu hundert Prozent funktioniert.
- Compiler-Compiler und Compilergeneratoren sind Hilfsprogramme zur automatischen Generierung von Compilerteil
- ↑ Bauer, F.L. and Eickel, J. Compiler Construction: An Advanced Course. Springer-Verlag. 1975