Phasen des Compilers mit Beispiel

Inhaltsverzeichnis:

Anonim

Was sind die Phasen des Compiler-Designs?

Der Compiler arbeitet in verschiedenen Phasen. Jede Phase transformiert das Quellprogramm von einer Darstellung in eine andere. Jede Phase nimmt Eingaben von ihrer vorherigen Stufe und speist ihre Ausgaben in die nächste Phase des Compilers ein.

Ein Compiler besteht aus 6 Phasen. Jede dieser Phasen hilft bei der Konvertierung der übergeordneten Sprache in den Maschinencode. Die Phasen eines Compilers sind:

  1. Lexikalische Analyse
  2. Syntaxanalyse
  3. Semantische Analyse
  4. Zwischencode-Generator
  5. Code-Optimierer
  6. Code Generator
Phasen des Compilers

Alle diese Phasen konvertieren den Quellcode, indem sie in Token unterteilt, Analysebäume erstellt und den Quellcode durch verschiedene Phasen optimiert werden.

In diesem Tutorial lernen Sie:

  • Was sind die Phasen des Compiler-Designs?
  • Phase 1: Lexikalische Analyse
  • Phase 2: Syntaxanalyse
  • Phase 3: Semantische Analyse
  • Phase 4: Zwischencodegenerierung
  • Phase 5: Codeoptimierung
  • Phase 6: Codegenerierung
  • Symboltabellenverwaltung
  • Fehlerbehandlungsroutine:

Phase 1: Lexikalische Analyse

Die lexikalische Analyse ist die erste Phase, in der der Compiler den Quellcode scannt. Dieser Vorgang kann zeichenweise von links nach rechts erfolgen und diese Zeichen zu Token gruppieren.

Hier wird der Zeichenstrom aus dem Quellprogramm durch Identifizieren der Token in sinnvollen Sequenzen gruppiert. Es nimmt die entsprechenden Tickets in die Symboltabelle auf und übergibt dieses 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, reservierte Wörter und geben Sie sie in verschiedene Tabellen ein. Kommentare im Quellprogramm werden ignoriert
  • Identifizieren Sie das Token, das nicht Teil der Sprache ist

Beispiel :

x = y + 10

Token

X. Kennung
= Aufgabenverwalter
Y. Kennung
+ Additionsoperator
10 Nummer

Phase 2: Syntaxanalyse

Bei der Syntaxanalyse geht es darum, die Struktur im Code zu ermitteln. Es bestimmt, ob ein Text dem erwarteten Format folgt oder nicht. Das Hauptziel dieser Phase ist es 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 mit Hilfe von Token erstellt wird. Es bestimmt auch die Struktur der Ausgangssprache und die Grammatik oder Syntax der Sprache.

Hier ist eine Liste der Aufgaben, die in dieser Phase ausgeführt werden:

  • Beziehen Sie Token vom lexikalischen Analysator
  • Überprüft, ob der Ausdruck syntaktisch korrekt ist oder nicht
  • Alle Syntaxfehler melden
  • Erstellen Sie eine hierarchische Struktur, die als Analysebaum bezeichnet wird

Beispiel

Jede Kennung / Nummer ist ein Ausdruck

Wenn x ein Bezeichner und y + 10 ein Ausdruck ist, dann ist x = y + 10 eine Aussage.

Betrachten Sie den Analysebaum für das folgende Beispiel

(a+b)*c

Im Analysebaum

  • Innenknoten: Datensatz mit einem Operator und zwei Dateien für Kinder
  • Blatt: Datensätze mit 2 / mehr Feldern; eine für Token und andere Informationen über das Token
  • Stellen Sie sicher, dass die Komponenten des Programms sinnvoll zusammenpassen
  • Sammelt Typinformationen und prüft die Typkompatibilität
  • Überprüfungsoperanden sind in der Ausgangssprache zulässig

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. Es wird auch geprüft, ob der Code eine angemessene Bedeutung hat.

Semantic Analyzer sucht nach Typinkongruenzen, inkompatiblen Operanden, einer mit falschen Argumenten aufgerufenen Funktion, einer nicht deklarierten Variablen usw.

Funktionen der semantischen Analysephase sind:

  • Hilft Ihnen, gesammelte Typinformationen zu speichern und in einer Symboltabelle oder einem Syntaxbaum zu speichern
  • Ermöglicht die Typprüfung
  • Im Fall einer Typfehlanpassung, bei der es keine genauen Typkorrekturregeln 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 Ausgangssprache die Operanden zulässt oder nicht

Beispiel

float x = 20.2;float y = x*30;

Im obigen Code typisiert der semantische Analysator die Ganzzahl 30 vor der Multiplikation auf float 30.0

Phase 4: Zwischencodegenerierung

Sobald die semantische Analysephase über dem Compiler abgeschlossen ist, wird ein Zwischencode für die Zielmaschine generiert. Es repräsentiert ein Programm für eine abstrakte Maschine.

Der Zwischencode befindet sich zwischen der Hochsprache und der Maschinensprache. Dieser Zwischencode muss so generiert werden, dass er leicht in den Zielmaschinencode übersetzt werden kann.

Funktionen zur Erzeugung von Zwischencode:

  • 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 es Ihnen, die Rangfolge der Ausgangssprache beizubehalten
  • Es enthält die korrekte Anzahl von Operanden der Anweisung

Beispiel

Zum Beispiel,

total = count + rate * 5

Zwischencode mit Hilfe der Adresscode-Methode ist:

t1 := int_to_float(5)t2 := rate * t1t3 := count + t2total := t3

Phase 5: Codeoptimierung

Die nächste Phase ist die Codeoptimierung oder der Zwischencode. Diese Phase entfernt unnötige Codezeilen und ordnet die Reihenfolge der Anweisungen an, um die Ausführung des Programms zu beschleunigen, 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 beansprucht.

Die Hauptfunktionen dieser Phase sind:

  • Es hilft Ihnen, einen Kompromiss zwischen Ausführung und Kompilierungsgeschwindigkeit herzustellen
  • Verbessert die Laufzeit des Zielprogramms
  • Erzeugt optimierten Code, der sich noch in der Zwischendarstellung befindet
  • Nicht erreichbaren Code entfernen und nicht verwendete Variablen entfernen
  • Entfernen von Anweisungen, die nicht geändert wurden, aus der Schleife

Beispiel:

Betrachten Sie den folgenden Code

a = intofloat(10)b = c * ad = e + bf = d

Kann werden

b =c * 10.0f = 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. Ziel dieser Phase ist es, 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. Diese Phase deckt den Optimierungs- oder Zwischencode in die Zielsprache ab.

Die Zielsprache ist der Maschinencode. Daher werden während dieser Phase auch alle Speicherplätze und Register ausgewählt und zugewiesen. Der von dieser Phase generierte Code wird ausgeführt, um Eingaben zu übernehmen und erwartete Ausgaben zu generieren.

Beispiel:

a = b + 60,0

Würde möglicherweise in Register übersetzt.

MOVF a, R1MULF #60.0, R2ADDF R1, R2

Symboltabellenverwaltung

Eine Symboltabelle enthält einen Datensatz für jeden Bezeichner mit Feldern für die Attribute des Bezeichners. Diese Komponente erleichtert dem Compiler das Durchsuchen des Bezeichnerdatensatzes und das schnelle Abrufen. Die Symboltabelle hilft Ihnen auch bei der Bereichsverwaltung. Die Symboltabelle und der Fehlerhandler interagieren entsprechend mit allen Phasen und der Aktualisierung der Symboltabelle.

Fehlerbehandlungsroutine:

Im Compiler-Designprozess können in allen unten angegebenen Phasen Fehler auftreten:

  • Lexikalischer Analysator: Falsch geschriebene Token
  • Syntaxanalysator: Fehlende Klammern
  • Intermediate Code Generator: Nicht übereinstimmende Operanden für einen Operator
  • Code Optimizer: Wenn die Anweisung nicht erreichbar ist
  • Codegenerator: Nicht erreichbare Anweisungen
  • Symboltabellen: Fehler mehrerer deklarierter Bezeichner

Die häufigsten Fehler sind ungültige Zeichenfolgen beim Scannen, ungültige Token-Sequenzen beim Typ, Bereichsfehler und Parsen bei der semantischen Analyse.

Der Fehler kann in einer 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 an den Fehlerbehandler 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 transformiert das Quellprogramm von einer Darstellung in eine andere
  • Sechs Phasen des Compiler-Designs sind 1) Lexikalische Analyse 2) Syntaxanalyse 3) Semantische Analyse 4) Zwischencodegenerator 5) Codeoptimierer 6) Codegenerator
  • Die lexikalische Analyse ist die erste Phase, in der der Compiler den Quellcode scannt
  • Bei der Syntaxanalyse geht es darum, Strukturen im Text zu entdecken
  • Die semantische Analyse überprüft die semantische Konsistenz des Codes
  • Sobald die semantische Analysephase über dem Compiler abgeschlossen ist, generieren Sie Zwischencode für die Zielmaschine
  • Die Codeoptimierungsphase entfernt unnötige Codezeilen und ordnet die Reihenfolge der Anweisungen an
  • Die Codegenerierungsphase erhält Eingaben aus der Codeoptimierungsphase und erzeugt als Ergebnis den Seitencode oder Objektcode
  • Eine Symboltabelle enthält einen Datensatz für jeden Bezeichner mit Feldern für die Attribute des Bezeichners
  • Die Fehlerbehandlungsroutine behandelt Fehler und Berichte in vielen Phasen