Phasen des Compilers mit Beispiel: Kompilierungsprozess und -schritte
Was sind die Phasen des Compiler-Designs?
Compiler arbeitet in verschiedenen Phasen. Jede Phase transformiert das Quellprogramm von einer Darstellung in eine andere. Jede Phase übernimmt Eingaben aus der vorherigen Phase und gibt ihre Ausgabe an die nächste Phase des Compilers weiter.
Es gibt 6 Phasen in einem Compiler. Jede dieser Phasen hilft bei der Konvertierung der Hochsprache in den Maschinencode. Die Phasen eines Compilers sind:
- Lexikalische Analyse
- Syntaxanalyse
- Semantische Analyse
- Zwischencodegenerator
- Code-Optimierer
- Code Generator

Alle diese Phasen konvertieren den Quellcode, indem sie ihn in Token aufteilen, Parse-Bäume erstellen und den Quellcode in verschiedenen Phasen optimieren.
Phase 1: Lexikalische Analyse
Die lexikalische Analyse ist die erste Phase, in der der Compiler den Quellcode scannt. Dieser Vorgang kann Zeichen für Zeichen von links nach rechts erfolgen und diese Zeichen in Token gruppieren.
Hierbei wird der Zeichenstrom aus dem Quellprogramm durch die Identifizierung der Token in sinnvolle Sequenzen gruppiert. Es führt den Eintrag der entsprechenden Tickets in die Symboltabelle durch und übergibt diesen Token an die nächste Phase.
Die Hauptfunktionen dieser Phase sind:
- Identifizieren Sie die lexikalischen Einheiten in einem Quellcode
- Klassifizieren Sie lexikalische Einheiten in Klassen wie Konstanten und reservierte Wörter und geben Sie sie in verschiedene Tabellen ein. Kommentare im Quellprogramm werden ignoriert
- Identifizieren Sie ein Token, das nicht Teil der Sprache ist
Beispiel:
x = y + 10
Tokens
X | Kennzeichnung |
= | Aufgabenverwalter |
Y | Kennzeichnung |
+ | Additionsoperator |
10 | Nummer |
Phase 2: Syntaxanalyse
Bei der Syntaxanalyse geht es darum, die Struktur im Code zu entdecken. Es bestimmt, ob ein Text dem erwarteten Format folgt oder nicht. Das Hauptziel dieser Phase besteht darin, sicherzustellen, dass der vom Programmierer geschriebene Quellcode korrekt ist oder nicht.
Die Syntaxanalyse basiert auf den Regeln, die auf der spezifischen Programmiersprache basieren, indem der Analysebaum mithilfe von Token erstellt wird. Es bestimmt auch die Struktur der Ausgangssprache und die Grammatik oder Syntax der Sprache.
Hier ist eine Liste der in dieser Phase ausgeführten Aufgaben:
- Erhalten Sie Token vom lexikalischen Analysator
- Überprüft, ob der Ausdruck syntaktisch korrekt ist oder nicht
- Melden Sie alle Syntaxfehler
- Konstruieren Sie eine hierarchische Struktur, die als Parse-Baum bezeichnet wird.
Beispiel
Jeder Bezeichner/jede Zahl ist ein Ausdruck
Wenn x ein Bezeichner und y+10 ein Ausdruck ist, dann ist x= y+10 eine Anweisung.
Betrachten Sie den Parse-Baum für das folgende Beispiel
(a+b)*c
Im Analysebaum
- Innerer Knoten: Datensatz mit einem Operatorfeld und zwei Dateien für untergeordnete Elemente
- Blatt: Datensätze mit 2/mehr Feldern; eine für Token und andere Informationen über den Token
- Stellen Sie sicher, dass die Programmbestandteile sinnvoll zusammenpassen
- Sammelt Typinformationen und prüft die Typkompatibilität
- Überprüft, ob Operanden in der Quellsprache zulässig sind
Phase 3: Semantische Analyse
Die semantische Analyse überprüft die semantische Konsistenz des Codes. Es verwendet den Syntaxbaum der vorherigen Phase zusammen mit der Symboltabelle, um zu überprüfen, ob der angegebene Quellcode semantisch konsistent ist. Außerdem wird geprüft, ob der Code eine angemessene Bedeutung vermittelt.
Der semantische Analysator sucht nach Typkonflikten, inkompatiblen Operanden, einer mit falschen Argumenten aufgerufenen Funktion, einer nicht deklarierten Variable usw.
Die Funktionen der Phase der semantischen Analyse sind:
- Hilft Ihnen, gesammelte Typinformationen zu speichern und in einer Symboltabelle oder einem Syntaxbaum zu speichern
- Ermöglicht die Durchführung einer Typprüfung
- Im Falle einer Typ-Nichtübereinstimmung, bei der es keine genauen Typ-Korrekturregeln gibt, die die gewünschte Operation erfüllen, wird ein semantischer Fehler angezeigt
- Sammelt Typinformationen und prüft die Typkompatibilität
- Überprüft, ob die Quellsprache die Operanden zulässt oder nicht
Beispiel
float x = 20.2; float y = x*30;
Im obigen Code wandelt der Semantikanalysator die Ganzzahl 30 vor der Multiplikation in Float 30.0 um
Phase 4: Zwischencodegenerierung
Sobald die Phase der semantischen Analyse abgeschlossen ist, generiert der Compiler Zwischencode für den Zielcomputer. Es stellt ein Programm für eine abstrakte Maschine dar.
Der Zwischencode liegt zwischen der Hochsprache und der Maschinensprache. Dieser Zwischencode muss so generiert werden, dass er leicht in den Zielmaschinencode übersetzt werden kann.
Funktionen zur Zwischencodegenerierung:
- Es sollte aus der semantischen Darstellung des Quellprogramms generiert werden
- Enthält die während des Übersetzungsprozesses berechneten Werte
- Hilft Ihnen, den Zwischencode in die Zielsprache zu übersetzen
- Ermöglicht Ihnen, die Rangfolge der Ausgangssprache beizubehalten
- Es enthält die richtige Anzahl von Operanden der Anweisung
Beispiel
Zum Beispiel,
total = count + rate * 5
Der Zwischencode mit Hilfe der Adresscode-Methode lautet:
t1 := int_to_float(5) t2 := rate * t1 t3 := count + t2 total := t3
Phase 5: Codeoptimierung
Die nächste Phase ist die Codeoptimierung oder der Zwischencode. In dieser Phase werden unnötige Codezeilen entfernt und die Anweisungsfolge so angeordnet, dass die Ausführung des Programms beschleunigt wird, ohne Ressourcen zu verschwenden. Das Hauptziel dieser Phase besteht darin, den Zwischencode zu verbessern, um einen Code zu generieren, der schneller ausgeführt wird und weniger Platz einnimmt.
Die Hauptfunktionen dieser Phase sind:
- Es hilft Ihnen, einen Kompromiss zwischen Ausführungs- und Kompilierungsgeschwindigkeit zu finden
- Verbessert die Laufzeit des Zielprogramms
- Erzeugt optimierten Code noch in Zwischendarstellung
- Entfernen von nicht erreichbarem Code und Entfernen nicht verwendeter Variablen
- Entfernen von Anweisungen, die nicht geändert werden, aus der Schleife
Ejemplo:
Betrachten Sie den folgenden Code
a = intofloat(10) b = c * a d = e + b f = d
Kann werden
b =c * 10.0 f = e+b
Phase 6: Codegenerierung
Die Codegenerierung ist die letzte und letzte Phase eines Compilers. Es erhält Eingaben aus Codeoptimierungsphasen und erzeugt als Ergebnis den Seitencode oder Objektcode. Das Ziel dieser Phase besteht darin, Speicher zuzuweisen und verschiebbaren Maschinencode zu generieren.
Außerdem werden Speicherplätze für die Variable zugewiesen. Die Anweisungen im Zwischencode werden in Maschinenanweisungen umgewandelt. In dieser Phase wird der Optimierungs- oder Zwischencode in die Zielsprache umgewandelt.
Die Zielsprache ist der Maschinencode. Daher werden in dieser Phase auch alle Speicherplätze und Register ausgewählt und zugewiesen. Der in dieser Phase generierte Code wird ausgeführt, um Eingaben entgegenzunehmen und erwartete Ausgaben zu generieren.
Beispiel
a = b + 60.0
Würde möglicherweise in Register übersetzt.
MOVF a, R1 MULF #60.0, R2 ADDF R1, R2
Symboltabellenverwaltung
Eine Symboltabelle enthält für jeden Bezeichner einen Datensatz mit Feldern für die Attribute des Bezeichners. Diese Komponente erleichtert es dem Compiler, den Bezeichnerdatensatz zu durchsuchen und ihn schnell abzurufen. Die Symboltabelle hilft Ihnen auch bei der Scope-Verwaltung. Die Symboltabelle und der Fehlerhandler interagieren mit allen Phasen und die Symboltabelle wird entsprechend aktualisiert.
Fehlerbehandlungsroutine
Im Compiler-Designprozess können in allen unten aufgeführten Phasen Fehler auftreten:
- Lexikalischer Analysator: Falsch geschriebene Token
- Syntaxanalysator: Fehlende Klammer
- Zwischencodegenerator: Nicht übereinstimmende Operanden für einen Operator
- Code-Optimierer: Wenn die Anweisung nicht erreichbar ist
- Code Generator: Wenn der Speicher voll ist oder nicht die richtigen Register zugewiesen sind
- Symboltabellen: Fehler bei mehreren deklarierten Bezeichnern
Die häufigsten Fehler sind ungültige Zeichenfolgen beim Scannen, ungültige Tokensequenzen beim Typ, Bereichsfehler und Parsing bei der semantischen Analyse.
Der Fehler kann in jeder der oben genannten Phasen auftreten. Nachdem Fehler gefunden wurden, muss sich die Phase mit den Fehlern befassen, um mit dem Kompilierungsprozess fortzufahren. Diese Fehler müssen dem Fehlerhandler gemeldet werden, der den Fehler behandelt, um den Kompilierungsprozess durchzuführen. Im Allgemeinen werden die Fehler in Form einer Nachricht gemeldet.
Zusammenfassung
- Der Compiler arbeitet in verschiedenen Phasen. Jede Phase wandelt das Quellprogramm von einer Darstellung in eine andere um.
- Sechs Phasen von Compiler-Design sind 1) Lexikalische Analyse 2) Syntaxanalyse 3) Semantische Analyse 4) Zwischencodegenerator 5) Code-Optimierer 6) Code Generator
- Die lexikalische Analyse ist die erste Phase, in der der Compiler den Quellcode scannt
- Bei der Syntaxanalyse geht es darum, die Struktur eines Textes zu entdecken
- Die semantische Analyse überprüft die semantische Konsistenz des Codes
- Sobald die semantische Analysephase abgeschlossen ist, generiert der Compiler Zwischencode für den Zielcomputer
- Die Codeoptimierungsphase entfernt unnötige Codezeilen und ordnet die Reihenfolge der Anweisungen
- Die Codegenerierungsphase ruft Eingaben aus der Codeoptimierungsphase ab und erzeugt als Ergebnis den Seitencode oder Objektcode
- Eine Symboltabelle enthält für jeden Bezeichner einen Datensatz mit Feldern für die Attribute des Bezeichners
- Die Fehlerbehandlungsroutine verarbeitet Fehler und Berichte in vielen Phasen