Hauptseite | Deutsche Enzyklopädie

Compiler

Ein Compiler (auch Kompilierer oder Übersetzer) ist ein Computerprogramm, das ein in einer Quellsprache geschriebenes Programm in ein semantisch äquivalentes Programm einer Zielsprache umwandelt. Üblicherweise handelt es sich dabei um die Übersetzung eines von einem Programmierer in einer Programmiersprache geschriebenen Quelltextes nach Assemblersprache, Bytecode oder Maschinensprache. Die Anwendung eines Compilers wird als Kompilierung bezeichnet.

Der Compilerbau, also die Programmierung eines Compilers, ist eine eigenständige Disziplin innerhalb der Informatik.

Die Bezeichnungen Compiler oder Kompilierer sind eigentlich irreführend, weil sie von der Zusammenstellung von Tabellen herrühren, die der Compiler für seine interne Datenverwaltung benötigt, was aber an der Kernaufgabe eines Compilers vorbeigeht.

Verwandt mit einem Compiler ist ein Interpreter, der ein Programm nicht in die Zielsprache übersetzt, sondern Schritt für Schritt direkt ausführt.

Inhaltsverzeichnis
1 Aufbau eines Compilers
2 Sonderformen
3 Geschichte
4 Programmoptimierung (ausführlich)
5 Bekannte Compiler

Aufbau eines Compilers

Es lassen sich im Wesentlichen zwei Phasen unterscheiden: eine Analysephase, die den Quelltext analysiert und daraus einen Syntaxbaum erzeugt, sowie die Synthesephase, die daraus das Zielprogramm erzeugt.

Analysephase (auch "Frontend")

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 formal richtig 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 "logische Rahmenbedingungen". Zum Beispiel muss eine Variable deklariert worden sein, bevor sie verwendet wird, und Zuweisungen müssen mit kompatiblen (verträglichen) Datentypen erfolgen.

Synthesephase (auch "Backend")

Die Synthesephase erzeugt aus dem in der Analysephase erstellten Baum den Programmcode der Zielsprache.

Zwischencodeerzeugung

Einige Compiler erzeugen Zwischencode, der schon relativ maschinennah ist, und führen auf diesem Zwischencode z. B. die Programmoptimierung durch. Das bietet sich besonders bei Compilern an, die mehrere verschiedene Zielplattformen unterstützen.

Programmoptimierung

Die Optimierungen finden hier meist auf dem zuvor erstellten Objektcode statt. Siehe Programmoptimierung.

Codegenerierung

Bei der Codegenerierung wird endgültig aus dem Syntaxbaum der Programmcode in der Zielsprache erzeugt. Falls die Zielsprache die 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.

Sonderformen

Geschichte

Der erste Compiler (A-0) wurde 1952 von der Mathematikerin Grace Hopper entwickelt.

Programmoptimierung (ausführlich)

Üblicherweise bietet ein Compiler Optionen für verschiedene Optimierungen mit dem Ziel, die Laufzeit der einzelnen Programmschritte oder den Speicherplatzbedarf des Zielprogramms zu minimieren.

Die Optimierung erfolgt teilweise in Abhängigkeit von den Eigenschaften der Hardware, z. B. wie viele und welche Register der Prozessor des Computers zur Verfügung stellt.

Einige Optimierungen führen dazu, dass der Compiler Programmkonstrukte in semantisch äquivalente, aber günstigere Konstrukte umwandelt, die keine Entsprechung im Quellcode haben. Eine Folge ist, dass es bei Aktivierung entsprechender Optimierungen kaum noch möglich ist, den Programmablauf mit einem interaktiven Debugger zu verfolgen.

"Optimierung" bedeutet nicht, dass das Programm danach in irgendeiner Weise optimal wäre, nur besser. Es ist auch möglich, dass das Programm nachher "totoptimiert" ist, also die Optimierung über das Ziel so weit hinausgeschossen ist, dass das Programm effektiv langsamer ausgeführt wird. Das ist z. B. dadurch möglich, dass längerer Code erzeugt wird, der zwar an sich schneller ausgeführt wird, aber mehr Zeit benötigt, um erst einmal in den Cache geladen zu werden, und damit erst bei häufigerer Benutzung vorteilhaft ist.

Viele Optimierungen moderner Compiler sind solche Abwägungen zwischen dem, was möglich ist, und dem, was sinnvoll ist. Die Grenze zwischen beiden ist meist nicht klar ersichtlich und muss durch Tests (Profiling) herausgefunden werden.

Im Folgenden betrachten wir einige Optimierungsmöglichkeiten eines Compilers. Es sollte aber nicht vergessen werden, dass das größte Optimierungspotenzial oft darin besteht, den Algorithmus selbst zu verändern bzw. durch einen besseren zu ersetzen. Dieser Vorgang kann meistens nicht automatisiert werden, sondern muss durch den Programmierer erfolgen. Einfachere Optimierungen kann er dagegen an den Compiler delegieren und so den Quelltext lesbarer halten.

Einsparung von Maschinenbefehlen

Wenn man zum Beispiel in einer höheren Programmiersprache den Inhalt von 2 Variablen vertauscht, dann benötigt man eine Hilfsvariable:

Einsparung von Maschinenbefehlen
höhere
Programmiersprache
Maschinenbefehle ohne Optimierung Maschinenbefehle mit Optimierung
t = a
a --> Register 1
Register 1 --> t
a --> Register 1
a = b
b --> Register 2
Register 2 --> a
b --> Register 2
b = t
t --> Register 3
Register 3 --> b
Register 1 --> b
Register 2 --> a

Mit der Optimierung werden statt 6 nur noch 4 Assemblerbefehle benötigt, außerdem wird der Speicherplatz für die Hilfsvariable t nicht gebraucht. D.h. diese Vertauschung wird schneller ausgeführt und benötigt weniger Hauptspeicher. Dies gilt jedoch nur, wenn ausreichend Register im Prozessor zur Verfügung stehen. Die Speicherung von Daten in Registern statt im Hauptspeicher, ist eine häufig angewendete Möglichkeit der Optimierung.

Statische Formelauswertung zur Übersetzungszeit

Die Berechnung des Kreisumfangs mittels

        pi = 3.1415
        u  = 2 * pi * r
kann ein Compiler bereits zum Übersetzungszeitpunkt zu "u = 6.283 * r" auswerten. Dies spart die Multiplikation "2*pi" zur Laufzeit des erzeugten Programms. Diese Vorgehensweise wird als Konstantenfaltung (engl. "constant folding") bezeichnet.

Elimination toten Programmcodes

Wenn der Compiler erkennen kann, dass ein Teil des Programmes niemals durchlaufen wird, dann kann er diesen Teil bei der Übersetzung weglassen.

  
Beispiel:  ...   ...
          100   goto 900
          200   k=3
          900   i=7
          ...   ...
Wenn in diesem Programm niemals ein GOTO auf das Label 200 erfolgt, dann kann auf die Anweisung "200 k=3" verzichtet werden.

Erkennung von unbenutzten Variablen

Wird eine Variable nicht benötigt, so muss dafür kein Speicherplatz zugewiesen und kein Programmcode erzeugt werden.

Beispiel:  subroutine test (a,b)
          b = 2 * a
          c = 3.14 * b
          return b
Hier wird die Variable c nicht benötigt: Sie steht nicht in der Parameterliste, wird in späteren Berechnungen nicht verwendet und wird auch nicht ausgegeben. Deshalb kann die Anweisung "c = 3.14 * b" entfallen.

Optimierung von Schleifen

Insbesondere Schleifen versucht man zu optimieren, indem man z.B.:

Reduktion von Paging zur Laufzeit

Zusammenhängender Code - z. B. eine Schleife - sollte zur Laufzeit möglichst auf der gleichen "Seite" (zusammenhängend vom Betriebssystem verwalteter Speicherblock) im Hauptspeicher liegen. Dies kann man z. B. dadurch erreichen, dass man dem Programmcode geeignete Leeranweisungen ("NOPs" - No OPeration) hinzufügt. Dadurch wird der Programmcode zwar größer, aber wegen des reduzierten Pagings wird das Programm schneller ausgeführt.

Vorziehen/Verzögern von Speicherzugriffen

Durch das Vorziehen von Speicherlesezugriffen und das Verzögern von Schreibzugriffen lässt sich die Fähigkeit moderner Prozessoren zur Parallelarbeit verschiedener Funktionseinheiten ausnutzen. So kann beispielsweise bei den Befehlen: a = b * c; d = e * f; der Operand e bereits geladen werden während ein anderer Teil des Prozessors noch mit der ersten Multiplikation beschäftigt ist.

Bekannte Compiler

oder auch viele andere, die zusammen mit IDEs (Integrierte Entwicklungsumgebung) ausgeliefert werden (Visual Basic, Delphi etc.)

Siehe auch: Compilerbau



Limit search to: Body and Title Deutsche Seiten Path

Websites for Compiler
Showing page 1 (1 - 10 of 717 hits) Next »
By Aristotelis Tsirigos; designed, implemented for compiler course at NYU, goal: compiler for a subset of Algol 68 that is ... to bootstrap. By Aristotelis Tsirigos; designed, implemented for compiler course at NYU, goal: compiler for a subset of Algol 68 that is ...
Notes on compiler theory, the source code of describing actual construction of compiler in C programming language. Also compiler construction related links to books, notes, tutorials, and news groups. Notes on compiler theory, the source code of describing actual construction of compiler in C programming language. Also compiler construction ...
A listing of compiler companies, compiler research projects, benchmarks, and compiler job listings. A listing of compiler companies, compiler research projects, benchmarks, and compiler job listings.
... is a wikibook describing internals of GNU C Compiler Collection. A number of authors have contributed to ... is a wikibook describing internals of GNU C Compiler Collection. A number of authors have contributed to ...
The resource overview includes compiler construction kits, lexer and parser generators, attribute grammar ... and optimization, environment generators, infrastructure/components/tools and compiler construction with Java. The resource overview includes compiler construction kits, lexer and parser generators, attribute grammar ... and optimization, environment generators, infrastructure/components/tools and compiler construction with Java.
... C, Zorland C, Zortech C++ (first native C++ compiler), Symantec C++, Digital Mars C++; Visual Cafe Java compiler; ABEL Advanced Boolean Expression Language compiler; DMDScript ECMA 262 Script compiler/interpreter; Empire Wargame. Wrote D; Northwest Software C ... C, Zorland C, Zortech C++ (first native C++ compiler), Symantec C++, Digital Mars C++; Visual Cafe ...
ACOVEA (Analysis of Compiler Options via Evolutionary Algorithm) implements a genetic algorithm to the analysis of GNU C compiler optimization flags. ACOVEA (Analysis of Compiler Options via Evolutionary Algorithm) implements a genetic algorithm to the analysis of GNU C compiler optimization flags.
A COBOL compiler for .NET and Mono, written in C#. This compiler aims to support COBOL standards as well as ... the .NET framework and object orientation. A COBOL compiler for .NET and Mono, written in C#. This compiler aims to support COBOL standards as well as ...
Suite of optimizing compiler development tools for Intel Itanium(TM) systems running ... is the continuation of the SGI Pro64(TM) compiler suite which was released under the GNU General Public License (GPL). The Open64 compiler suite currently includes compilers for C, C++, and ... Linux ABI and API standards. Suite of optimizing compiler development tools for Intel Itanium(TM) systems running ... is the continuation of the SGI Pro64(TM) compiler suite which was released under the GNU ...
Internals of one-pass compiler by example Pascal compiler. Internals of one-pass compiler by example Pascal compiler.

Next »

Help build the largest human-edited directory on the web.
Submit a Site - Open Directory Project - Become an Editor
Free thumbnail preview by Thumbshots.org

Search for products at amazon.com:
Search:
Keywords:
amazon.com books on 'Compiler':
Search at Google.com:
Google
WebCalSky.com Enzyklopädie

Suchresultate aus unserem günstigen CalSky-Shop