Was ist ein Compiler-Design? Typen, Bauwerkzeuge, Beispiel
โก Intelligente Zusammenfassung
Die Phasen des Compilers beschreiben die sechs Stufen, die Quellcode in Maschinencode umwandeln: lexikalische Analyse, Syntaxanalyse, semantische Analyse, Zwischencodegenerierung, Codeoptimierung und Codegenerierung, unterstรผtzt durch Symboltabellenverwaltung und Fehlerbehandlung.
Was sind die Phasen des Compiler-Designs?
A Compiler Der Compiler arbeitet in verschiedenen Phasen, wobei jede Phase das Quellprogramm von einer Darstellungsform in eine andere transformiert. Jede Phase verarbeitet die Eingaben der vorherigen Phase und leitet ihre Ausgabe an die nรคchste Phase weiter. Ein Compiler besteht aus sechs Phasen. Jede dieser Phasen trรคgt zur รbersetzung der Hochsprache in Maschinencode bei. Die Phasen eines Compilers sind:
- Lexikalische Analyse
- Syntaxanalyse
- Semantische Analyse
- Zwischencodegenerator
- Code Optimierer
- Code Generator
Phasen des Compilers
In all diesen Phasen wird der Quellcode umgewandelt, indem er in Tokens unterteilt, Syntaxbรคume erstellt und der Quellcode durch verschiedene Phasen optimiert wird.
Phase 1: Lexikalische Analyse
Die lexikalische Analyse ist die erste Phase, in der der Compiler den Quellcode durchsucht. Dieser Prozess kann von links nach rechts, Zeichen fรผr Zeichen, erfolgen und gruppiert diese Zeichen zu Token.
Hier wird der Zeichenstrom aus dem Quellprogramm durch die Identifizierung der Token in sinnvolle Sequenzen gruppiert. Die entsprechenden Token werden in die Symboltabelle eingetragen und an die nรคchste Phase รผbergeben.
Die Hauptfunktionen dieser Phase sind:
- Identifizieren Sie die lexikalischen Einheiten in einem Quellcode.
- Lexikalische Einheiten werden in Klassen wie Konstanten und reservierte Wรถrter eingeteilt und in verschiedene Tabellen eingetragen. Kommentare im Quellprogramm werden dabei ignoriert.
- Identifizieren Sie ein Token, das nicht Teil der Sprache ist.
Ejemplo: x = y + 10
| Token | Typ |
|---|---|
| X | Kennzeichnung |
| = | Aufgabenverwalter |
| Y | Kennzeichnung |
| + | Additionsoperator |
| 10 | Nummer |
Phase 2: Syntaxanalyse
Bei der Syntaxanalyse geht es darum, die Struktur von Code zu erkennen. Sie ermittelt, ob ein Text dem erwarteten Format entspricht. Hauptziel dieser Phase ist es, sicherzustellen, dass der vom Programmierer geschriebene Quellcode korrekt ist.
Die Syntaxanalyse basiert auf den Regeln der jeweiligen Programmiersprache und erstellt mithilfe von Token einen Syntaxbaum. Sie bestimmt auรerdem die Struktur der Quellsprache sowie deren Grammatik bzw. Syntax.
Hier ist eine Liste der in dieser Phase durchgefรผhrten Aufgaben:
- Tokens vom lexikalischen Analysator abrufen.
- Prรผfen Sie, ob der Ausdruck syntaktisch korrekt ist oder nicht.
- Alle Syntaxfehler melden.
- Erstellen Sie eine hierarchische Struktur, die als Syntaxbaum 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 Syntaxbaum fรผr das folgende Beispiel:
(a+b)*c
Im Syntaxbaum:
- Innerer Knoten: Datensatz mit einem Operatorfeld und zwei Feldern fรผr untergeordnete Elemente.
- Blatt: Datensรคtze mit 2 oder mehr Feldern; eines fรผr das Token und weitere Informationen รผber das Token.
- Stellen Sie sicher, dass die Programmkomponenten sinnvoll zusammenpassen.
- Sammelt Typinformationen und prรผft auf Typkompatibilitรคt.
- Die Quellsprache erlaubt Prรผfoperanden.
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 prรผft auf Typenkonflikte, inkompatible Operanden, Funktionsaufrufe mit unzulรคssigen Argumenten, nicht deklarierte Variablen usw.
Die Funktionen der semantischen Analysephase sind:
- Hilft Ihnen dabei, gesammelte Typinformationen zu speichern und in der Symboltabelle oder im Syntaxbaum abzulegen.
- Ermรถglicht die Durchfรผhrung von Typรผberprรผfungen.
- Im Falle einer Typenabweichung, bei der es keine exakten Typkorrekturregeln gibt, die die gewรผnschte Operation erfรผllen, wird ein semantischer Fehler angezeigt.
- Sammelt Typinformationen und prรผft auf Typkompatibilitรคt.
- Prรผft, ob die Quellsprache die Operanden zulรคsst oder nicht.
Beispiel
float x = 20.2; float y = x*30;
Im obigen Code wird der semantische Analysator den Integer 30 vor der Multiplikation in float 30.0 umwandeln.
Phase 4: Mittelstufe Code Generation
Sobald die semantische Analysephase abgeschlossen ist, generiert der Compiler Zwischencode fรผr die Zielmaschine. Dieser reprรคsentiert ein Programm fรผr eine bestimmte Zielgruppe.tract-Maschine.
Der Zwischencode bildet die Schnittstelle zwischen der Hochsprache und der Maschinensprache. Dieser Zwischencode muss so generiert werden, dass er sich leicht in den Zielmaschinencode รผbersetzen lรคsst.
Funktionen von Zwischen Code Generation:
- Sie sollte aus der semantischen Reprรคsentation des Quellprogramms generiert werden.
- Speichert die wรคhrend des รbersetzungsprozesses berechneten Werte.
- Hilft Ihnen dabei, den Zwischencode in die Zielsprache zu รผbersetzen.
- Ermรถglicht es Ihnen, die Rangfolge der Quellsprache beizubehalten.
- Es enthรคlt die korrekte Anzahl an Operanden der Anweisung.
Beispiel
Beispielsweise:
total = count + rate * 5
Der Zwischencode, der mithilfe der Adresscodemethode erstellt wurde, lautet:
t1 := int_to_float(5)
t2 := rate * t1
t3 := count + t2
total := t3
Phase 5: Code Optimierung
Die nรคchste Phase ist die Codeoptimierung des Zwischencodes. Dabei werden unnรถtige Codezeilen entfernt und die Abfolge der Anweisungen so angeordnet, dass die Programmausfรผhrung beschleunigt und gleichzeitig Ressourcen geschont werden. Hauptziel dieser Phase ist die Verbesserung des Zwischencodes, um einen schnelleren und speicherschonenderen Code zu generieren.
Die Hauptfunktionen dieser Phase sind:
- Es hilft Ihnen, einen Kompromiss zwischen Ausfรผhrungs- und Kompilierungsgeschwindigkeit zu finden.
- Verbessert die Laufzeit des Zielprogramms.
- Erzeugt weiterhin in Zwischenreprรคsentation รผbersichtlichen Code.
- Nicht erreichbaren Code entfernen und ungenutzte Variablen lรถschen.
- Anweisungen, die nicht verรคndert werden, werden aus der Schleife entfernt.
Ejemplo: Betrachten Sie den folgenden Code:
a = intofloat(10)
b = c * a
d = e + b
f = d
Kann werden zu:
b = c * 10.0
f = e + b
Phase 6: Code Generation
Code Die Generierung ist die letzte Phase eines Compilers. Sie erhรคlt Eingaben aus der Codeoptimierungsphase und erzeugt als Ergebnis den Seitencode oder Objektcode. Ziel dieser Phase ist die Speicherzuweisung und die Generierung von verschiebbarem Maschinencode.
Auรerdem werden Speicherplรคtze fรผr die Variablen reserviert. Die Anweisungen im Zwischencode werden in Maschinenbefehle umgewandelt. In dieser Phase wird der optimierte oder Zwischencode in die Zielsprache รผbersetzt.
Die Zielsprache ist der Maschinencode. Daher werden in dieser Phase auch alle Speicheradressen und Register ausgewรคhlt und zugewiesen. Der in dieser Phase generierte Code wird ausgefรผhrt, um Eingaben zu verarbeiten und die erwarteten Ausgaben zu erzeugen.
Beispiel
a = b + 60.0 kรถnnte mรถglicherweise wie folgt in Register รผbersetzt werden:
MOVF a, R1 MULF #60.0, R2 ADDF R1, R2
Symboltabellenverwaltung
Eine Symboltabelle enthรคlt fรผr jeden Bezeichner einen Eintrag mit Feldern fรผr dessen Attribute. Diese Komponente erleichtert dem Compiler die Suche nach dem Bezeichnereintrag und ermรถglicht dessen schnellen Abruf. Die Symboltabelle unterstรผtzt zudem die Bereichsverwaltung. Symboltabelle und Fehlerbehandlung 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 die richtigen Register nicht zugewiesen sind.
- Symboltabellen: Fehler: Mehrere Bezeichner wurden deklariert.
Die hรคufigsten Fehler sind ungรผltige Zeichenketten beim Scannen, ungรผltige Token-Sequenzen beim Typisieren, Bereichsfehler und Parsing-Fehler bei der semantischen Analyse.
Der Fehler kann in jeder der oben genannten Phasen auftreten. Nach dem Auffinden eines Fehlers muss die jeweilige Phase diesen behandeln, um den Kompilierungsprozess fortsetzen zu kรถnnen. Diese Fehler mรผssen an die Fehlerbehandlungsroutine gemeldet werden, die den Fehler behandelt, um den Kompilierungsprozess fortzusetzen. In der Regel werden die Fehler in Form einer Fehlermeldung ausgegeben.



