WikiDer > Compiler

Compiler

EIN Compiler (buchstäblich Compiler oder Baumeister) ist ein Computer Programm das eins in eins Ausgangssprache geschriebenes Programm in ein semantisch äquivalentes Programm in einer Zielsprache übersetzt.

Die Übersetzung oder Konvertierung wird Kompilieren oder Kompilieren genannt. Ein Compiler bezieht sich in erster Linie auf ein Programm, das ein Programm in eine höhere . übersetzt Programmiersprache übersetzt in eine niedrigere Programmiersprache, normalerweise Assemblersprache oder Maschinensprache. Der Hauptgrund für das Kompilieren von Quellcode besteht darin, ausführbaren Code zu erstellen.

Wenn das kompilierte Programm auf einem Computer mit einem anderen Zentralprozessor oder ein anderes Betriebssystem als der Rechner, auf dem der Compiler selbst läuft, spricht man von a Cross-Compiler. Ein Programm, das eine Übersetzung zwischen höheren Programmiersprachen vornimmt, wird normalerweise nicht als Compiler bezeichnet, sondern Übersetzer. Wird ein Programm von einer niedrigeren Programmiersprache in eine höhere übersetzt, heißt es a Dekompilierer.

Kompilation ist formal die Übersetzung von Ausdrücke von einem formale Eingabesprache zu Ausdrücken von a formale Ausgabesprache (oder Zielsprache).

Der Compiler prüft auch, ob die Eingabe wohlgeformt ist und ob eine korrekte Übersetzung vorgenommen werden kann, andernfalls gibt er Fehler zurück. Heutzutage arbeitet man meist interaktiv und der Compiler stoppt meist bei der ersten Fehlermeldung. Bei der klassischen Stapelverarbeitung (der Programmierer schickt sein Programm ins Rechenzentrum und erhält die Ausgabe erst Stunden später oder am nächsten Tag) untersucht der Compiler das gesamte Programm auf Fehler.

Struktur

Die Kompilierung erfolgt in mehreren Phasen, die teilweise parallel laufen. Die ersten Schritte sind für die Analyse des zu kompilierenden Quellcodes verantwortlich. Diese Phasen werden zusammen die Frontend (Vorderseite) des Compilers. Die späteren Stufen sind für die Synthese des Ergebnisses verantwortlich und befassen sich mit der Generierung und Optimierung des Ergebnisses der Kompilierung. Diese Phasen bilden zusammen die Backend (Rückseite) des Compilers. Das Frontend liefert seine Ergebnisse in Form von a . an das Backend interne Vertretung und ein Symboltabelle.

Das Frontend eines Compilers ist spezifisch für einen bestimmten Programmiersprache. Für das Kompilieren von Programmen in verschiedenen Programmiersprachen werden unterschiedliche Frontends benötigt. Das Backend ist (teilweise) unabhängig von der Programmiersprache, aber spezifisch für den Zweck, für den es kompiliert wird. Dieses Ziel kann ein bestimmter Prozessor oder ein virtuelle Maschine. Für jeden Prozessor oder jede virtuelle Maschine ist ein anderes Back-End erforderlich.

Ein Compiler mit a hinteres Ende die das Programm direkt ausführt, anstatt ausführbaren Code zu generieren, wird zu einem Dolmetscher erwähnt.

Die meisten Compiler haben die folgenden Phasen:

  • Frontend (Analyse):
    1. Das lexikalischer Scan oder lexikalische Analyse (Wortzerlegung), bei der die Symbole der Eingabe von vorne nach hinten betrachtet werden und die Eingabe in Symbolblöcke unterteilt wird, die innerhalb der Eingabesprache auf eine bestimmte Weise interpretiert werden. Im Fall von a Programmiersprache als Eingabesprache kann man sich vorstellen, Schlüsselwörter, Operatoren und Variablen aus einer Reihe von Eingabezeichen zu erkennen.
    2. Das Parsing oder syntaktische Analyse (Satzparsing, also bzgl. Grammatik), bei der geprüft wird, ob die Eingabe in die kontextfreie Grammatik der Eingabesprache. Daraus wird (teilweise) ersichtlich, ob eine Übersetzung möglich ist und wenn ja, (teilweise) wie diese Übersetzung erstellt werden soll. Im Fall einer Programmiersprache kann man sich eine Überprüfung vorstellen, dass die syntaktischen Regeln der Sprache eingehalten werden.
    3. Die Attributbewertung von semantisch Analyse. Dies ist die "Bedeutung" und bezieht sich hauptsächlich auf tippen, die prüft, ob die Eingabe den kontextsensitiven Regeln der Eingabesprache entspricht. Dies zeigt definitiv, ob eine Übersetzung möglich ist und wie sie erreicht werden soll. Bei einer Programmiersprache könnte man daran denken, die Einhaltung aller Tippregeln (Typprüfung erwähnt).
    4. Generieren von a interne Vertretung des Eingabeprogramms.
  • Backend (Synthese):
    1. Das Registerzuordnung, wobei der Compiler bestimmt, welche Daten in welchen Registern gespeichert werden.
    2. Das Codegenerierung, bei dem aus den zuvor gesammelten Informationen ein Wort aus der Zielsprache generiert wird. Im Fall einer Programmiersprache könnte beispielsweise Maschinencode generiert werden.
    3. Optimierung
Ein Diagramm der verschiedenen Phasen, aus denen die Kompilierung besteht

Der lexikalische Scan

sehen Lexikalische Analyse für den Hauptartikel zu diesem Thema.

Das lexikalischer Scan bildet die erste Analyse der Eingabe des Compilers. Dieser Eintrag ist eine Zeichenfolge aus a Alphabet, die im Sinne einer formalen Sprache ein Wort bilden können.

Die Aufgabe eines lexikalischen Scanners im Compiler besteht darin, die Eingabe in kleinere Teile, die Token genannt werden, aufzuteilen und diese Token nacheinander an den Parser. Ein Token ist dann ein Objekt, das ist Parser kann als Schlüsselwort in der formalen Sprache oder als Name erkannt und als solches behandelt werden.

analysieren

sehen Parser für den Hauptartikel zu diesem Thema.

Während der analysieren (parse) die aus der lexikalischen Analyse resultierenden Token werden in eine Baumstruktur umgewandelt, a Syntaxbaum erwähnt. Dies geschieht nach den Regeln, die in der kontextfreie Grammatik der Sprache.

Wenn der Parser auf eine Reihe von Token trifft, die keiner der Regeln der Grammatik entsprechen, gibt es a Syntax-Fehler, ein Syntaxfehler. In diesem Fall gibt der Compiler einen Fehler zurück.

Das Ergebnis des Parsings ist ein konkreter Syntaxbaum, der die Struktur des geparsten Quellcodes darstellt.

Attributbewertung

Attributbewertung ist eine Operation, die an dem Ableitungsbaum ausgeführt wird, der sich aus dem oben beschriebenen Parsing ergibt.

Das Parsen definiert eine mögliche Ableitung eines Wortes aus einer formalen Sprache im Sinne der kontextfreien Grammatik dieser Sprache. Eine solche Ableitung sagt jedoch nichts über die Richtigkeit der Ableitung im Hinblick auf die kontextsensitiven Eigenschaften der Programmiersprache aus. Ein Beispiel ist eine Regel, dass eine Variable vor ihrer Verwendung deklariert werden muss oder dass ein bestimmter Wert nur einer Variablen des richtigen Typs zugewiesen werden kann.

Der Attribut-Evaluator eines Compilers durchläuft die gesamte Ableitung noch einmal (manchmal mehr als einmal), um zu bestimmen, ob ein abgeleitetes Wort alle kontextuellen Regeln der formalen Sprache respektiert. Eine übliche Methode hierfür ist, dass der Attributauswerter Teilbäume des Baums von der Wurzel bis zu den Blättern und wieder zurück betrachtet und den Baum mit Eingabeinformationen dekoriert (kontextuelle Einschränkungen für Teilbäume, die von der Spitze des Baums aus auferlegt werden – z. B. "Variable X hat hier keinen Wert") ).

In der Informatik wird noch viel an Attributbewertungsgeneratoren gearbeitet. Es gibt mehrere Systeme, die aus einer Beschreibung einen Attributbewerter generieren können, jedoch gibt es noch keine allgemein anerkannte Lösungsmethode.

Codegenerierung

Das Code Generator ist der letzte Schritt der Kompilierung. Dieser Teil wirft einen letzten Blick auf den dekorierten Ableitungsbaum und generiert für jeden Teilbaum des Ableitungsbaums Übersetzungen in die Zielsprache. Da alle Teilbäume zusammen den gesamten Baum bilden, erzeugt dieser Vorgang die gesamte Übersetzung.

Die bei Codegeneratoren am häufigsten verwendete Methode besteht darin, dass der Codegenerator aus einer Bibliothek von "Standardübersetzungen" von Teilen des Ableitungsbaums besteht, in denen neben Treibercode Lücken auftreten. Diese Lücken werden bei der realen Codegenerierung mit kontextsensitiven Informationen gefüllt. Dazu gehört der genaue Name einer Variablen aus der Eingabe. Da die Codegenerierung auf kontextsensitiven Informationen beruht und es noch keine wirkliche Lösung für die Attributbewertung gibt, gibt es noch keinen allgemeinen Mechanismus zur Generierung von Codegeneratoren.

Darüber hinaus stehen Forscher der Codegenerierung noch vor einem weiteren Problem, nämlich dass es oft viel mehr als einen einzigen Weg gibt, einen Teilbaum in eine Zielsprache zu übersetzen und nicht jede mögliche Übersetzung immer die beste ist. Über diese Art der Codeoptimierung wird viel geforscht.

Software-Entwicklung

Compiler werden innerhalb der Computerprogrammierung. Ein Text in Form von Quellcode in einem bestimmten Programmiersprache konvertiert wird, normalerweise in eine Form, in der es direkt von einem Computer ausgeführt werden kann. Manchmal wird es so in ein Formular umgewandelt, dass es von einem anderen Programm namens a . verwendet werden kann Dolmetscher oder Laufzeitmodul, ausgeführt werden.

Ein Compiler beginnt mit 1985 oft verwendet als Teil von a Softwareentwicklungsumgebung, damit das Programm sofort getestet werden kann. Ohne eine Softwareentwicklungsumgebung erfordert das Kompilieren eine separate Aktion des Programmierers.

EIN Programmierer schreibt den Quellcode des Programms in a Texteditor (ein Textbearbeitungsprogramm, meist besonders geeignet für die zu verwendende Programmiersprache) und speichert es in einem Datei. Wenn der Programmierer den Compiler verwendet, wird er den Quellcode in eine ausführbare Datei konvertieren.

Das resultierende Objektdateien (hier nicht Objekt mit hier verwechseln) Objektorientierung) muss meistens noch verlinkt (mit z.B. Startup-Code zusammengeführt), wonach das Programm zur Ausführung bereit ist, das sogenannte ausführbar. Bei einer Variante, die noch a . hat Dolmetscher erforderlich, wird die Linkphase normalerweise übersprungen. Dies macht den Kompilierungsprozess normalerweise etwas schneller, aber die Ausführung langsamer. Ein Vorteil der interpreterbasierten Kompilierung kann darin liegen, dass die generierten Objektcode auf andere Systeme übertragbar. Der Interpreter selbst ist dann nicht portabel und kümmert sich um plattformspezifische Angelegenheiten.

Ein Compiler kann nicht sicherstellen, dass keine Fehler das Programm eingeben. Jetzt sofort Debugger solche Fehler können erkannt werden, aber danach muss der Kompilierungsvorgang erneut durchgeführt werden.

Beispiele

Beispiele für Compiler sind (in alphabetischer, nicht chronologischer Reihenfolge):

Siehe auch

Externe Links