Compiler

Im Computer, a Compiler ist ein Computer Programm das Übersetzt Computercode in einem geschrieben Programmiersprache (das Quelle Sprache) in eine andere Sprache (die Ziel Sprache). Der Name "Compiler" wird hauptsächlich für Programme verwendet, die übersetzt werden Quellcode von einem Programmiersprache auf hoher Ebene zu einem Sprache niedrigerer Ebene (z.B. Montagesprache, Objektcode, oder Maschinensprache) um eine zu erstellen ausführbar Programm.[1][2]: P1[3]

Es gibt viele verschiedene Arten von Compilern, die in verschiedenen nützlichen Formen Ausgang erzeugen. EIN Cross-Compiler erzeugt Code für einen anderen Zentralprozessor oder Betriebssystem als derjenige, auf dem der Cross-Compiler selbst läuft. EIN Bootstrap -Compiler ist oft ein temporärer Compiler, der zum Kompilieren eines dauerhafteren oder besser optimierten Compilers für eine Sprache verwendet wird.

Zu den verwandten Software gehören ein Programm, das von einer Sprache auf niedriger Ebene bis zu einer höheren Stufe eins übersetzt wird, ist a Dekompiler; ein Programm, das zwischen hochrangigen Sprachen übersetzt, normalerweise als a Source-to-Source-Compiler oder Transpiler. Eine Sprache Rewritriter ist normalerweise ein Programm, das die Form von übersetzt Ausdrücke ohne Sprachwechsel. EIN Compiler-Compiler ist ein Compiler, der einen Compiler (oder einen Teil von einem) erzeugt, oft generisches und wiederverwendbares, um viele unterschiedliche Compiler herzustellen.

Ein Compiler wird wahrscheinlich einige oder alle folgenden Operationen ausführen, die häufig als Phasen bezeichnet werden: Vorverarbeitung, lexikalische Analyse, Parsing, Semantische Analyse (Syntax-gerichtete Übersetzung), Konvertierung von Eingabeprogrammen zu einem Zwischendarstellung, Codeoptimierung und Codegenerierung. Compiler implementieren diese Phasen im Allgemeinen als modulare Komponenten und fördern effizientes Design und Richtigkeit von Transformationen der Quelleingabe in die Zielausgabe. Programmfehler, die durch ein falsches Verhalten des Compiler verursacht werden, können sehr schwer aufzuspüren und zu arbeiten. Daher investieren Compiler -Implementierer erhebliche Anstrengungen, um sicherzustellen Compiler Korrektheit.[4]

Compiler sind nicht der einzige Sprachprozessor, der zur Transformation von Quellprogrammen verwendet wird. Ein Dolmetscher ist Computersoftware, die die angegebenen Vorgänge verwandelt und dann ausführt.[2]: P2 Der Übersetzungsprozess beeinflusst die Gestaltung von Computersprachen, was zu einer Präferenz der Zusammenstellung oder Interpretation führt. Theoretisch kann eine Programmiersprache sowohl einen Compiler als auch einen Dolmetscher haben. In der Praxis werden Programmiersprachen in der Regel nur mit einem (einem Compiler oder einem Dolmetscher) in Verbindung gebracht.

Geschichte

Ein Diagramm des Betrieb

Theoretische Computerkonzepte, die von Wissenschaftlern, Mathematikern und Ingenieuren entwickelt wurden, bildeten die Grundlage für die Entwicklung der digitalen modernen Computer im Zweiten Weltkrieg. Primitive binäre Sprachen entwickelten sich, da digitale Geräte nur die und Nullen und die Schaltungsmuster in der darunter liegenden Maschinenarchitektur verstehen. In den späten 1940er Jahren wurden Assemblersprachen erstellt, um eine praktikablere Abstraktion der Computerarchitekturen zu bieten. Begrenzt Erinnerung Die Kapazität früherer Computer führte zu erheblichen technischen Herausforderungen, als die ersten Compiler entworfen wurden. Daher musste der Zusammenstellungsprozess in mehrere kleine Programme unterteilt werden. Die Front -End -Programme produzieren die Analyseprodukte, die von den Back -End -Programmen verwendet werden, um Zielcode zu generieren. Da Computertechnologie mehr Ressourcen bereitstellte, könnten Compiler -Designs besser mit dem Zusammenstellungsprozess übereinstimmen.

Für einen Programmierer ist es normalerweise produktiver, eine Sprache auf hoher Ebene zu verwenden, sodass die Entwicklung hochrangiger Sprachen natürlich aus den von digitalen Computern angebotenen Funktionen folgte. Hochrangige Sprachen sind formelle Sprachen das werden streng von ihrer Syntax und durch ihre Syntax definiert Semantik die die hochrangige Spracharchitektur bilden. Zu den Elementen dieser formalen Sprachen gehören:

  • Alphabet, alle endlichen Satz von Symbolen;
  • Saiteeine endliche Abfolge von Symbolen;
  • Sprache, alle Saiten auf einem Alphabet.

Die Sätze in einer Sprache können durch eine Reihe von Regeln definiert werden, die als Grammatik bezeichnet werden.[5]

Backus -Naur -Form (BNF) beschreibt die Syntax von "Sätzen" einer Sprache und wurde für die Syntax von Algol 60 verwendet John Backus.[6] Die Ideen stammen aus dem Kontextfreie Grammatik Konzepte von Noam Chomsky, ein Linguist.[7] "BNF und seine Erweiterungen sind zu Standardwerkzeugen zur Beschreibung der Syntax von Programmiernotationen geworden, und in vielen Fällen werden Teile von Compilern automatisch aus einer BNF -Beschreibung generiert."[8]

In den 1940er Jahren, Konrad Zuse entwarf eine algorithmische Programmiersprache namens namens Plankalkül ("Plan Kalkül"). Während bis in die 1970er Jahre keine tatsächliche Umsetzung auftrat, präsentierte sie später Konzepte in Apl Entworfen von Ken Iverson Ende der 1950er Jahre.[9] APL ist eine Sprache für mathematische Berechnungen.

Hochrangiger Sprachdesign während der prägenden Jahre des digitalen Computers lieferte nützliche Programmierwerkzeuge für eine Vielzahl von Anwendungen:

  • Forran (Formelübersetzung) für Ingenieur- und Wissenschaftsanwendungen wird als erste hochrangige Sprache angesehen.[10]
  • Cobol (Gemeinsame geschäftorientierte Sprache) entwickelt sich aus A-0 und Fließen matisch Die dominierende hochrangige Sprache für Geschäftsanwendungen zu werden.[11]
  • LISPELN (Listenprozessor) für eine symbolische Berechnung.[12]

Die Compiler-Technologie entwickelte sich aus der Notwendigkeit einer streng definierten Umwandlung des hochrangigen Quellprogramms in ein Zielprogramm auf niedrigem Niveau für den digitalen Computer. Der Compiler könnte als Front -End angesehen werden, um mit der Analyse des Quellcode und einem Back -End umzugehen, um die Analyse in den Zielcode zu synthetisieren. Die Optimierung zwischen dem Frontend und dem hinteren Ende könnte einen effizienteren Zielcode erzeugen.[13]

Einige frühe Meilensteine ​​bei der Entwicklung der Compiler -Technologie:

  • 1952: Ein Autocode Compiler entwickelt von Alick Glennie für die Manchester Mark i Der Computer an der Universität von Manchester wird von einigen als die erste kompilierte Programmiersprache angesehen.
  • 1952: Grace HopperTeam mit Remington Rand schrieb den Compiler für die A-0 Programmiersprache (und prägte den Begriff Compiler es beschreiben),[14][15] Obwohl der A-0-Compiler eher als Lader oder Linker als als moderner Begriff eines vollständigen Compilers fungierte.
  • 1954–1957: Ein Team angeführt von John Backus bei IBM aufgetreten Forran Dies wird normalerweise als erste hochrangige Sprache angesehen. 1957 absolvierten sie einen FORTRAN -Compiler, der allgemein als den ersten eindeutig vollständigen Compiler zugeschrieben wird.
  • 1959: Die Konferenz über Data Systems Language (CODASYL) initiierte die Entwicklung von Cobol. Das COBOL-Design zog sich auf A-0 und flow-Matic. In den frühen 1960er Jahren wurde Cobol auf mehreren Architekturen zusammengestellt.
  • 1958–1962: John McCarthy bei MIT entworfen LISPELN.[16] Die Symbolverarbeitungsfunktionen lieferten nützliche Merkmale für die Forschung für künstliche Intelligenz. Im Jahr 1962 stellte LISP 1.5 einige Werkzeuge fest: ein Dolmetscher von Stephen Russell und Daniel J. Edwards, einem Compiler und Assembler von Tim Hart und Mike Levin.[17]

Frühe Betriebssysteme und Software wurden in Montagesprache geschrieben. In den 1960er und frühen 1970er Jahren war die Verwendung von Sprachen auf hoher Ebene für die Systemprogrammierung aufgrund von Ressourcenbeschränkungen immer noch umstritten. Mehrere Forschungs- und Branchenbemühungen begannen jedoch die Verlagerung in Richtung hochrangiger Systemprogrammiersprachen beispielsweise. BCPL, WONNE, B, und C.

BCPL (Grundlegende kombinierte Programmiersprache) 1966 entworfen von 1966 von Martin Richards An der Universität von Cambridge wurde ursprünglich als Compiler -Schreibwerkzeug entwickelt.[18] Mehrere Compiler wurden implementiert, Richards 'Buch bietet Einblicke in die Sprache und ihren Compiler.[19] BCPL war nicht nur eine Programmiersprache für einflussreiche Systeme, die noch in der Forschung verwendet wird[20] bildete aber auch eine Grundlage für die Gestaltung von B- und C -Sprachen.

WONNE (Basic-Sprache für die Implementierung von Systemsoftware) wurde für einen PDP-10-Computer der Digital Equipment Corporation (DEC) von W.A. WULFs Carnegie Mellon University (CMU) -Schiffel-Team entwickelt. Das CMU-Team entwickelte 1970 ein Jahr später ein Bliss-11-Compiler.

Mehrheit (Multiplexed Information and Computing Service), ein Time-Sharing-Betriebssystemprojekt, beteiligt MIT, Bell Labs, General Electric (später Honeywell) und wurde von angeführt Fernando Corbató vom MIT.[21] Multics wurde in der geschrieben Pl/i Sprache entwickelt von IBM und IBM User Group.[22] Das Ziel von IBM war es, die Anforderungen an die Geschäfts-, Wissenschafts- und Systemprogrammieranforderungen zu erfüllen. Es gab andere Sprachen, die in Betracht gezogen werden können, aber PL/ich bot die vollständigste Lösung an, obwohl sie nicht implementiert worden war.[23] In den ersten Jahren des Multics -Projekts konnte eine Untergruppe der Sprache mit dem frühen PL/I (EPL) -Kompiler von Doug McIlory und Bob Morris von Bell Labs mit dem frühen PL/I -Compiler zusammengestellt werden.[24] EPL unterstützte das Projekt, bis ein Start-Strapp-Compiler für die vollständige PL/ich entwickelt werden konnte.[25]

Bell Labs verließ das Multics -Projekt 1969 und entwickelte eine Systemprogrammiersprache B basierend auf BCPL -Konzepten, geschrieben von von Dennis Ritchie und Ken Thompson. Ritchie erstellte einen Start-Strapp-Compiler für B und schrieb Unics (Uniplexed Information and Computing Service) Betriebssystem für ein PDP-7 in B. Unics wurde schließlich als UNIX geschrieben.

Bell Labs begann die Entwicklung und Erweiterung von C Basierend auf B und BCPL. Der BCPL -Compiler wurde von Bell Labs zu Multics transportiert und BCPL war eine bevorzugte Sprache in Bell Labs.[26] Anfangs wurde ein Front-End-Programm zum B-Compiler von Bell Labs verwendet, während ein C-Compiler entwickelt wurde. 1971 stellte ein neues PDP-11 die Ressource zur Definition von Erweiterungen zu B und dem Umschreiben des Compilers zur Verfügung. Bis 1973 war das Design der C-Sprache im Wesentlichen abgeschlossen und der Unix-Kernel für einen PDP-11 wurde in C. Steve Johnson umgeschrieben, um die Entwicklung eines tragbaren C-Compilers (PCC) zur Unterstützung des Retargetierens von C-Compilern auf neue Maschinen zu unterstützen.[27][28]

Objekt orientierte Programmierung (OOP) bot einige interessante Möglichkeiten für die Entwicklung und Wartung von Anwendungen. Oop -Konzepte gehen weiter zurück, waren aber Teil von LISPELN und Simula Sprachwissenschaft.[29] Bei Bell Labs die Entwicklung von C ++ interessierte sich für OOP.[30] C ++ wurde erstmals 1980 für die Systemprogrammierung verwendet. Das anfängliche Design nutzte C -Programmierfunktionen für C -Sprachsysteme mit Simula -Konzepten. Objektorientierte Einrichtungen wurden 1983 hinzugefügt.[31] Das CFRONT-Programm hat ein C ++-Front-End für C84-Sprachkompiler implementiert. In den folgenden Jahren wurden mehrere C ++ - Compiler entwickelt, als C ++ Popularität zunahm.

In vielen Anwendungsbereichen hat sich die Idee, eine Sprache auf höherer Ebene zu verwenden, schnell auf. Aufgrund der wachsenden Funktionalität, die von neuer unterstützt wird Programmiersprachen und die zunehmende Komplexität von Computerarchitekturen, Compiler wurden komplexer.

DARPA (Defense Advanced Research Projects Agency) hat 1970 ein Compiler-Projekt mit dem CMU-Forschungsteam von WULF gesponsert. Der Compiler-Kompiler der Produktion Qualitätsqualität PQCC Das Design würde einen Produktionsqualitäts Compiler (PQC) aus formalen Definitionen der Quellsprache und des Ziels erzeugen.[32] PQCC versuchte, den Begriff Compiler-Compiler über die traditionelle Bedeutung als Parser-Generator hinaus zu erweitern (z. B.,,, Yacc) ohne viel Erfolg. PQCC könnte besser als Compiler -Generator bezeichnet werden.

Bei der PQCC-Forschung zum Codegenerierungsprozess wurde ein wirklich automatisches Compiler-Schreibsystem erstellt. Die Anstrengung entdeckte und entwarf die Phasenstruktur des PQC. Der Bliss-11-Compiler lieferte die anfängliche Struktur.[33] Die Phasen umfassten Analysen (Frontend), Zwischenübersetzung in die virtuelle Maschine (Mittelend) und die Übersetzung zum Ziel (Back End). TCOL wurde für die PQCC -Forschung entwickelt, um mit sprachspezifischen Konstrukten in der Zwischendarstellung umzugehen.[34] Variationen von TCOL unterstützten verschiedene Sprachen. Das PQCC -Projekt untersuchte Techniken des automatisierten Compiler -Bauwerks. Die Designkonzepte erwiesen sich als nützlich für die Optimierung von Compilern und Compilern für die (seit 1995, objektorientierte) Programmiersprache Ada.

Die ada STEINMANN Dokumentierte die Programmunterstützungsumgebung (APSE) zusammen mit dem Kernel (Kapse) und minimaler (MAPSE). Ein ADA -Dolmetscher NYU/ED unterstützte Entwicklungs- und Standardisierungsbemühungen mit dem American National Standards Institute (ANSI) und der International Standards Organization (ISO). Zu den ersten ADA -Compiler -Entwicklung durch die US -Militärdienste gehörten die Compiler in eine vollständige integrierte Designumgebung im Rahmen der Sicht der STEINMANN dokumentieren. Army und Navy arbeiteten am ADA Language System (ALS) -Projekt, das auf die DEC/VAX -Architektur abzielte, während die Luftwaffe in der ADA Integrated Environment (AIE) begann, die auf die IBM 370 -Serie abzielte. Während die Projekte nicht die gewünschten Ergebnisse lieferten, trugen sie zu den allgemeinen Anstrengungen zur ADA -Entwicklung bei.[35]

Andere Bemühungen des ADA -Compilers wurden in Großbritannien an der Universität von York und in Deutschland an der Universität von Karlsruhe durchgeführt. In den USA lieferte Verdix (später von Rational erworben) das Verdix ADA Development System (VADS) der Armee. VADS lieferte eine Reihe von Entwicklungstools, darunter ein Compiler. UNIX/VADs könnten auf einer Vielzahl von UNIX -Plattformen wie DEC Ultrix und dem Sun 3/60 Solaris in einer Armee -Cecom -Bewertung auf Motorola 68020 veranstaltet werden.[36] Es gab bald viele ADA -Compiler, die die ADA -Validierungstests bestanden haben. Das Free Software Foundation GNU -Projekt entwickelte das GNU Compiler -Sammlung (GCC), das eine Kernfähigkeit bietet, mehrere Sprachen und Ziele zu unterstützen. Die ADA -Version MÜCKE ist einer der am häufigsten verwendeten ADA -Compiler. GNAT ist kostenlos, aber es gibt auch kommerzielle Unterstützung, beispielsweise Adacore, wurde 1994 gegründet, um kommerzielle Softwarelösungen für ADA bereitzustellen. GNAT Pro enthält den GNU GCC -basierten Gnat mit einer Werkzeugsuite, um eine bereitzustellen integrierte Entwicklungsumgebung.

Hochrangige Sprachen förderten die Compiler-Forschung und -entwicklung weiter. Zu den Fokusbereichen gehörten Optimierung und automatische Codegenerierung. Trends in Programmiersprachen und Entwicklungsumgebungen beeinflussten die Compiler -Technologie. Weitere Compiler wurden in Sprachverteilungen (Perl, Java Development Kit) und als Bestandteil einer IDE (VADS, Eclipse, ADA Pro) aufgenommen. Die Wechselbeziehung und die gegenseitige Abhängigkeit von Technologien wuchsen. Das Aufkommen von Webdiensten förderte das Wachstum von Websprachen und Skriptsprachen. Skripte zeichnen zu den frühen Tagen der Befehlszeilenschnittstellen (CLI) zurück, in denen der Benutzer Befehle eingeben kann, die vom System ausgeführt werden können. Benutzer -Shell -Konzepte, die mit Sprachen entwickelt wurden, um Shell -Programme zu schreiben. Frühe Windows -Designs boten eine einfache Batch -Programmierfunktion. Die konventionelle Transformation dieser Sprache verwendete einen Dolmetscher. Obwohl sie nicht weit verbreitet sind, wurden Bash- und Batch -Compiler geschrieben. In jüngerer Zeit wurden anspruchsvolle interpretierte Sprachen Teil des Entwickler -Tool -Kits. Zu den modernen Skriptsprachen gehören PHP, Python, Ruby und Lua. (LUA wird in der Spielentwicklung häufig eingesetzt.) Alle diese Unterstützung und Compiler -Unterstützung.[37]

"Als das Kompilierfeld Ende der 50er Jahre begann, war sein Fokus auf die Übersetzung von Sprachprogrammen auf hoher Ebene in den Maschinencode beschränkt ... Das Compiler-Feld ist zunehmend mit anderen Disziplinen mit der Computerarchitektur, Programmiersprachen, formalen Methoden, miteinander verflochten. Software -Engineering und Computersicherheit. "[38] In dem Artikel "Compiler Research: The Next 50 Jahre" wurde die Bedeutung objektorientierter Sprachen und Java festgestellt. Sicherheits- und Parallelcomputer wurden unter den zukünftigen Forschungszielen zitiert.

Compiler -Konstruktion

Ein Compiler implementiert eine formale Transformation von einem hochrangigen Quellprogramm zu einem Zielprogramm auf niedrigem Niveau. Das Compiler-Design kann eine End-to-End-Lösung definieren oder eine definierte Teilmenge mit anderen Kompilierungstools, z. Präprozessoren, Abgeordnete, Linker. Die Entwurfsanforderungen umfassen streng definierte Schnittstellen sowohl intern zwischen Compiler -Komponenten als auch extern zwischen Support -Toolsets.

In den frühen Tagen wurde der Ansatz zum Compiler -Design direkt von der Komplexität der zu verarbeitenden Computersprache, der Erfahrung der von der Person entworfenen Person und den verfügbaren Ressourcen beeinflusst. Ressourcenbeschränkungen führten dazu, dass die Quellcode mehr als einmal durchlaufen werden musste.

Ein Compiler für eine relativ einfache Sprache, die von einer Person geschrieben wurde, könnte eine einzige monolithische Software sein. Wenn die Quellsprache in der Komplexität wächst, kann das Design jedoch in eine Reihe von voneinander abhängigen Phasen aufgeteilt werden. Separate Phasen bieten Designverbesserungen, die die Entwicklung auf die Funktionen im Zusammenstellungsprozess konzentrieren.

Einpass- und Mehrpass-Compiler

Die Klassifizierung von Compilern nach Anzahl der Pässe hat den Hintergrund in den Hardware -Ressourcenbeschränkungen von Computern. Durch das Kompilieren wurde viel Arbeit ausgeführt und frühe Computer hatten nicht genügend Speicher, um ein Programm zu enthalten, das all diese Arbeiten erledigte. Daher wurden Compiler in kleinere Programme aufgeteilt, die jeweils einen Pass über die Quelle (oder einige Darstellungen) machten, die einige der erforderlichen Analysen und Übersetzungen durchführten.

Die Fähigkeit, in a zu kompilieren Einzelpass wurde klassisch als Vorteil gesehen Multi-Pass-Compiler. Somit wurden teilweise von den Ressourcenbeschränkungen früherer Systeme bestimmt, so dass viele frühe Sprachen speziell so konzipiert wurden, dass sie in einem einzigen Pass zusammengestellt werden konnten (z. B.,, Pascal).

In einigen Fällen muss ein Compiler für das Design einer Sprachfunktion mehr als einen Durchgang über die Quelle ausführen. Betrachten Sie beispielsweise eine Erklärung, die in Zeile 20 der Quelle erscheint, die die Übersetzung einer Erklärung in Zeile 10 beeinflusst. In diesem Fall muss der erste Durchgang Informationen über Erklärungen sammeln Während eines nachfolgenden Pass.

Der Nachteil der Zusammenstellung in einem einzigen Pass ist, dass es nicht möglich ist, viele der Raffinierten durchzuführen Optimierungen benötigt, um hochwertige Code zu generieren. Es kann schwierig sein, genau zu zählen, wie viele Pässe ein optimierender Compiler macht. Beispielsweise können verschiedene Optimierungsphasen einen Ausdruck um ein Vielfaches analysieren, jedoch nur einmal einen anderen Expression analysieren.

Die Aufteilung eines Compilers in kleine Programme ist eine Technik, die von Forschern verwendet wird, die an der Herstellung von nachweislich korrekten Compilern interessiert sind. Das Nachweis der Richtigkeit einer Reihe kleiner Programme erfordert häufig weniger Aufwand als die Richtigkeit eines größeren, einzelnen, äquivalenten Programms.

Dreistufe Compiler-Struktur

Compiler -Design

Unabhängig von der genauen Anzahl der Phasen im Compiler -Design können die Phasen einer von drei Stufen zugeordnet werden. Die Bühnen umfassen ein Frontend, ein Mittelende und ein hinteres Ende.

  • Das Frontend scannt die Eingabe und überprüft Syntax und Semantik gemäß einer bestimmten Quellsprache. Zum Statisch getippte Sprachen Es führt Geben Sie die Überprüfung ein durch Sammeln von Typinformationen. Wenn das Eingabeprogramm syntaktisch falsch ist oder einen Typfehler aufweist, generiert es Fehler- und/oder Warnmeldungen, wobei der Speicherort im Quellcode, an dem das Problem erkannt wurde, normalerweise identifiziert. In einigen Fällen kann der tatsächliche Fehler (viel) früher im Programm sein. Zu den Aspekten des Frontends gehören lexikalische Analyse, Syntaxanalyse und semantische Analyse. Das Frontend verwandelt das Eingabeprogramm in eine Zwischendarstellung (IR) zur weiteren Verarbeitung bis zum Mittelende. Dieser IR ist normalerweise eine niedrigere Darstellung des Programms in Bezug auf den Quellcode.
  • Das Mittelend führt Optimierungen für das IR durch, die unabhängig von der CPU -Architektur sind. Dieser Quellcode-/Maschinencode -Unabhängigkeit soll ermöglichen, generische Optimierungen zwischen den Versionen des Compilers zu teilen, das verschiedene Sprachen und Zielprozessoren unterstützt. Beispiele für mittlere Endoptimierungen sind die Entfernung von nutzloser (Dead-Code-Eliminierung) oder unerreichbarer Code (Erreichbarkeitsanalyse), Entdeckung und Ausbreitung konstanter Werte (Konstante Ausbreitung), Umzug der Berechnung in einen weniger häufig ausgeführten Ort (z. B. aus einer Schleife) oder die Spezialisierung der Berechnung basierend auf dem Kontext, wodurch schließlich das "optimierte" IR erzeugt wird, das vom Back -End verwendet wird.
  • Das Back End Nimmt den optimierten IR vom Mittelende. Es kann mehr Analysen, Transformationen und Optimierungen durchführen, die für die Ziel -CPU -Architektur spezifisch sind. Das hintere Ende generiert den zielabhängigen Montagecode, der ausgeführt wird Zuteilung registrieren dabei. Das hintere Ende führt aus Anweisungsplanung, welche Anweisungen ermittelt, um parallel zu bleiben Ausführungseinheiten beschäftigt durch Füllen Verzögerung von Slots. Obwohl die meisten Optimierungsprobleme sind Np-harte, Heuristik Techniken zur Lösung von ihnen sind gut entwickelt und derzeit in Produktionsfaktoren in Produktionsqualität implementiert. In der Regel ist die Ausgabe eines Back -Ends der Maschinencode spezialisiert für einen bestimmten Prozessor- und Betriebssystem.

Dieser Vorder-/Mittel-/Back-End-Ansatz ermöglicht es, die Frontenden für verschiedene Sprachen mit Rückenenden für verschiedene zu kombinieren CPUs während der Optimierungen des Mittelende teilen.[39] Praktische Beispiele für diesen Ansatz sind die GNU Compiler -Sammlung, Klang (Llvm-basierend C/C ++ Compiler),[40] und die Amsterdam Compiler Kit, die mehrere Frontendungen, gemeinsame Optimierungen und mehrere Rückenlendungen haben.

Frontend

Lexer und Parser Beispiel für C. Ausgehend von der Abfolge der Zeichen "if (net> 0,0) insgesamt+= net*(1,0+steuer/100,0);"Der Scanner besteht eine Sequenz von Tokenund kategorisiert jedes von ihnen, zum Beispiel als Kennung, reserviertes Wort, Zahl buchstäblich, oder Operator. Die letztere Sequenz wird vom Parser in a transformiert Syntaxbaum, was dann von den verbleibenden Compiler -Phasen behandelt wird. Der Scanner und der Parser behandeln die regulär und richtig kontextfrei Teile des Grammatik für c, beziehungsweise.

Das Front -End analysiert den Quellcode, um eine interne Darstellung des Programms zu erstellen, die genannt wird Zwischendarstellung (Ir). Es verwaltet auch die Symboltabelle, eine Datenstruktur, die jedes Symbol im Quellcode auf zugehörige Informationen wie Standort, Typ und Umfang zuordnet.

Während das Frontend eine einzige monolithische Funktion oder ein einzelnes Programm sein kann, wie in a Scannerloser ParserEs wurde traditionell als mehrere Phasen implementiert und analysiert, die nacheinander oder gleichzeitig ausgeführt werden können. Diese Methode wird aufgrund ihrer Modularität bevorzugt und Trennung von Bedenken. Am häufigsten ist das Frontend heute in drei Phasen unterteilt: lexikalische Analyse (auch als Lexing oder Scannen bezeichnet), Syntaxanalyse (auch als Scannen oder Parsen bezeichnet) und Semantische Analyse. Lexing und Parsen umfassen die syntaktische Analyse (Wortsyntax bzw. Phrase -Syntax), und in einfachen Fällen können diese Module (Lexer und Parser) automatisch aus einer Grammatik für die Sprache erzeugt werden, obwohl diese in komplexeren Fällen manuelle Änderungen erfordern . Die lexikalische Grammatik und die Phrase -Grammatik sind normalerweise Kontextfreie Grammatiken, was die Analyse erheblich vereinfacht, wobei die Kontextsensitivität in der semantischen Analysephase behandelt wird. Die semantische Analysephase ist im Allgemeinen komplexer und von Hand geschrieben, kann aber teilweise oder vollständig automatisiert werden Grammatiken zuschreiben. Diese Phasen selbst können weiter aufgeschlüsselt werden: Lexen als Scannen und Bewertungen und Parsen als Gebäude a Betonsyntaxbaum (CST, analysieren Sie Baum) und dann in eine verwandeln Zusammenfassung Syntaxbaum (AST, Syntaxbaum). In einigen Fällen werden insbesondere zusätzliche Phasen verwendet Zeilenrekonstruktion und Vorverarbeitung, Aber diese sind selten.

Die Hauptphasen des Frontends umfassen Folgendes:

  • Zeilenrekonstruktion Konvertiert die Eingangszeichensequenz in eine kanonische Form, die für den Parser bereit ist. Sprachen welche Strop Ihre Schlüsselwörter oder erlauben beliebige Räume innerhalb von Kennern diese Phase. Das von oben nach unten, rekursives Abzent, tabellangesteuerte Parser, die in den 1960er Jahren verwendet wurden, lesen typischerweise den Quellcharakter gleichzeitig und benötigten keine separate Tokenisierungsphase. Atlas Autocode und Imp (und einige Implementierungen von Algol und Koralle 66) sind Beispiele für gestürzte Sprachen, deren Compiler eine haben würden Zeilenrekonstruktion Phase.
  • Vorverarbeitung Unterstützung Makro Substitution und Bedingte Zusammenstellung. Typischerweise tritt die Präprozessierungsphase vor der syntaktischen oder semantischen Analyse auf; z.B. Im Fall von C manipuliert der Präprozessor eher lexikalische Token als syntaktische Formen. Einige Sprachen wie Planen Unterstützen Sie Makro -Substitutionen basierend auf syntaktischen Formen.
  • Lexikalische Analyse (auch bekannt als Lexing oder Tokenisierung) zerlegt den Quellcode -Text in eine Abfolge kleiner Stücke, die genannt werden lexikalische Token.[41] Diese Phase kann in zwei Phasen unterteilt werden: die Scannen, der den Eingabetxt in syntaktische Einheiten unterteilt Lexeme und weist ihnen eine Kategorie zu; und die Bewertung, der Lexeme in einen verarbeiteten Wert umwandelt. Ein Token ist ein Paar, das aus a besteht Token -Name und ein optionales Token -Wert.[42] Gemeinsame Token -Kategorien können Kennungen, Schlüsselwörter, Separatoren, Operatoren, Literale und Kommentare umfassen, obwohl die Anzahl der Token -Kategorien unterschiedlich unterschiedlich ist Programmiersprachen. Die Lexeme -Syntax ist normalerweise a Regelmäßige Sprache, so a Finite State Automaton gebaut aus a regulären Ausdruck kann verwendet werden, um es zu erkennen. Die Software, die lexikalische Analyse durchführt, wird als a bezeichnet Lexikalanalysator. Dies ist möglicherweise kein separater Schritt - er kann mit dem Parsen -Schritt in Kombination kombiniert werden Scannerloser ParsenIn diesem Fall erfolgt die Parsen auf der Charakterebene, nicht auf der Token -Ebene.
  • Syntaxanalyse (auch bekannt als Parsing) beinhaltet Parsing Die Token -Sequenz, um die syntaktische Struktur des Programms zu identifizieren. Diese Phase baut normalerweise a Baum analysieren, was die lineare Sequenz von Token durch eine Baumstruktur ersetzt formelle Grammatik die die Syntax der Sprache definieren. Der Parsebaum wird oft analysiert, erweitert und durch spätere Phasen im Compiler transformiert.[43]
  • Semantische Analyse fügt semantische Informationen zu der hinzu Baum analysieren und baut die Symboltabelle. Diese Phase führt semantische Überprüfungen aus, z. Geben Sie die Überprüfung ein (Überprüfung auf Typfehler) oder Objektbindung (Assoziieren von Variablen und Funktionsreferenzen mit ihren Definitionen) oder bestimmte Zuordnung (Erfordern Sie, dass alle lokalen Variablen vor der Verwendung initialisiert werden.), Ablehre falsche Programme oder Warnungen ausstellen. Die semantische Analyse erfordert normalerweise einen vollständigen Parse -Baum, was bedeutet, dass diese Phase logischerweise dem folgt Parsing Phase und geht logischerweise dem voraus Codegenerierung Phase, obwohl es häufig möglich ist, mehrere Phasen in einem Compiler -Implementierung in einen Pass über den Code zu falten.

Mittelend

Das Mittelende, auch bekannt als Optimierer, führt Optimierungen für die Zwischendarstellung durch, um die Leistung und die Qualität des produzierten Maschinencodes zu verbessern.[44] Das mittlere End enthält die Optimierungen, die unabhängig von der CPU -Architektur sind.

Die Hauptphasen des Mittelende umfassen Folgendes:

Die Compiler -Analyse ist die Voraussetzung für jede Compiler -Optimierung, und sie arbeiten eng zusammen. Zum Beispiel, Abhängigkeitsanalyse ist entscheidend für Schleifentransformation.

Der Umfang der Compiler -Analyse und -Optimierungen variieren stark; Ihr Umfang kann vom Betrieb innerhalb von a reichen Grundblock, zu ganzen Verfahren oder sogar das gesamte Programm. Es besteht ein Kompromiss zwischen der Granularität der Optimierungen und den Zusammenstellungskosten. Zum Beispiel, Pephole -Optimierungen sind während der Zusammenstellung schnell durchzuführen, beeinflussen jedoch nur ein kleines lokales Fragment des Code und können unabhängig von dem Kontext durchgeführt werden, in dem das Codefragment erscheint. Im Gegensatz, Interprocedurale Optimierung Benötigt mehr Kompilierungszeit und Speicherplatz, ermöglicht jedoch Optimierungen, die nur möglich sind, indem das Verhalten mehrerer Funktionen gleichzeitig berücksichtigt werden.

Interprocedurale Analysen und Optimierungen sind in modernen kommerziellen Compilern aus häufig HP, IBM, SGI, Intel, Microsoft, und Sun Microsystems. Das gratis Software GCC wurde für lange Zeit dafür kritisiert, dass es mangelnde leistungsstarke interprocedurale Optimierungen fehlte, sich jedoch in dieser Hinsicht ändert. Ein weiterer Open -Source -Compiler mit vollständiger Analyse- und Optimierungsinfrastruktur ist Open64, die von vielen Organisationen für Forschung und kommerzielle Zwecke verwendet wird.

Aufgrund der zusätzlichen Zeit und des für die Compiler -Analyse und -Optimierungen erforderlichen Platzes überspringen einige Compiler sie standardmäßig. Benutzer müssen Kompilierungsoptionen verwenden, um dem Compiler explizit mitzuteilen, welche Optimierungen aktiviert werden sollten.

Back End

Das Back -End ist verantwortlich für die CPU -Architekturspezifischen Optimierungen und für Codegenerierung[44].

Die Hauptphasen des hinteren Endes umfassen Folgendes:

  • Maschinenabhängige Optimierungen: Optimierungen, die von den Details der CPU -Architektur abhängen, die der Compiler abzielt.[45] Ein herausragendes Beispiel ist Pephole -Optimierungen, die kurze Sequenzen von Assembler -Anweisungen in effizientere Anweisungen umschreiben.
  • Codegenerierung: Die transformierte Zwischensprache wird in die Ausgangssprache übersetzt, normalerweise die Native Maschinensprache vom System. Dies beinhaltet Ressourcen- und Speicherentscheidungen, z. B. die Entscheidung, in welche Variablen passen, Register und Erinnerung und die Auswahl und Planung von entsprechenden Maschinenanweisungen zusammen mit ihren zugehörigen Adressierungsmodi (siehe auch Sethi -Ullman -Algorithmus). Debug -Daten müssen möglicherweise auch generiert werden, um zu erleichtern Debuggen.

Compiler Korrektheit

Compiler Korrektheit ist der Zweig der Software -Engineering, der sich mit dem Versuch befasst, zu zeigen, dass sich ein Compiler nach seinem Verhalten verhält Sprachspezifikation. Zu den Techniken gehört die Entwicklung des Compilers mithilfe Formale Methoden und Verwendung strenger Tests (häufig als Compiler -Validierung bezeichnet) auf einem vorhandenen Compiler.

Kompiliert gegen interpretierte Sprachen

Aufgeordnete Programmiersprachen erscheinen normalerweise mit einer Art von Art von Übersetzung Denken Sie an: Entweder als gestaltet als kompilierte Sprache oder Interpretierte Sprache. In der Praxis gibt es jedoch selten etwas über eine Sprache, die erfordert Es wird ausschließlich kompiliert oder ausschließlich interpretiert, obwohl es möglich ist, Sprachen zu entwerfen, die zur Wiederinterpretation zur Laufzeit beruhen. Die Kategorisierung spiegelt normalerweise die beliebtesten oder am weitesten verbreiteten Implementierungen einer Sprache wider - zum Beispiel, BASIC wird manchmal als interpretierte Sprache bezeichnet, und c ein kompiliert, trotz der Existenz von grundlegenden Compilern und C -Dolmetschern.

Die Interpretation ersetzt die Kompilierung nicht vollständig. Es verbirgt es nur vor dem Benutzer und macht es allmählich. Auch wenn ein Dolmetscher selbst interpretiert werden kann, wird irgendwo am Ende des Ausführungsstapels ein direkt ausgeführtes Programm benötigt (siehe Maschinensprache).

Darüber hinaus können für Optimierungs Compiler Interpreter -Funktionen enthalten, und Dolmetscher können im Voraus Time Compilation -Techniken einbeziehen. Wenn beispielsweise ein Ausdruck während der Zusammenstellung ausgeführt werden kann und die in das Ausgabeprogramm eingefügten Ergebnisse verhindert, dass er jedes Mal neu berechnet werden muss, wenn das Programm ausgeführt wird, kann das endgültige Programm erheblich beschleunigt werden. Moderne Trends in Richtung Just-in-Time-Zusammenstellung und Bytecode -Interpretation Manchmal verwischen die traditionellen Kategorisierungen von Compilern und Dolmetschern noch weiter.

Einige Sprachspezifikationen berichten über diese Implementierungen muss eine Zusammenstellung einschließen; zum Beispiel, Common Lisp. Es gibt jedoch nichts in der Definition von Common Lisp inhärent, das verhindert, dass es interpretiert wird. Andere Sprachen haben Funktionen, die in einem Dolmetscher sehr einfach zu implementieren sind, aber es erschweren das Schreiben eines Compilers viel schwieriger. zum Beispiel, Apl, Snobol4und viele Scripting -Sprachen ermöglichen es Programmen, einen beliebigen Quellcode zur Laufzeit mit regulären String -Vorgängen zu erstellen und diesen Code dann auszuführen, indem er ihn an eine Spezialübergabeteilung übergibt Bewertungsfunktion. Um diese Funktionen in einer kompilierten Sprache zu implementieren, müssen Programme normalerweise mit a versendet werden Laufzeitbibliothek Dazu gehören eine Version des Compilers selbst.

Typen

Eine Klassifizierung von Compilern ist von der Plattform auf die ihr generierter Code ausgeführt wird. Dies ist als die bekannt Zielplattform.

A einheimisch oder bereitgestellt Der Compiler ist einer, dessen Ausgabe direkt auf demselben Computertyp und Betriebssystem ausgeführt wird, auf dem der Compiler selbst ausgeführt wird. Die Ausgabe von a Cross Compiler ist so konzipiert, dass er auf einer anderen Plattform ausgeführt wird. Cross -Compiler werden häufig bei der Entwicklung von Software für verwendet eingebettete Systeme Das ist nicht dazu gedacht, eine Softwareentwicklungsumgebung zu unterstützen.

Die Ausgabe eines Compilers, der Code für a erstellt virtuelle Maschine (VM) kann auf derselben Plattform wie der Compiler ausgeführt werden, der es produziert hat. Aus diesem Grund werden solche Compiler normalerweise nicht als native oder Cross Compiler eingestuft.

Die Sprache der unteren Ebene, die das Ziel eines Compilers ist, kann selbst a sein Programmiersprache auf hoher Ebene. C, die von einigen als eine Art tragbare Montagesprache betrachtet wird, ist häufig die Zielsprache solcher Compiler. Zum Beispiel, CFRONT, der ursprüngliche Compiler für C ++, verwendet C als Zielsprache. Der von einem solchen Compiler generierte C -Code soll normalerweise nicht von Menschen lesbar sein und gepflegt werden. Eingerichteter Stil Und das Erstellen von hübschem C -Zwischencode wird ignoriert. Einige der Merkmale von C, die es zu einer guten Zielsprache machen #Linie Richtlinie, die vom Compiler zur Unterstützung erzeugt werden kann Debuggen der ursprünglichen Quelle und der breiten Plattformunterstützung, die mit C -Compilern erhältlich ist.

Während ein gängiger Compiler -Maschinencode ausgibt, gibt es viele andere Typen:

  • Source-to-Source-Compiler sind eine Art von Compiler, der eine hochrangige Sprache als Eingabe nimmt und eine Sprache auf hoher Ebene ausgibt. Zum Beispiel eine automatische Parallelisierung Der Compiler nimmt häufig ein hochrangiges Sprachprogramm als Eingabe auf und transformiert dann den Code und kommentiert ihn mit parallelen Code-Anmerkungen (z. OpenMP) oder Sprachkonstrukte (z. B. Forran's's ALLES MACHEN Aussagen). Andere Begriffe für Quell-zu-Source-Compiler sind Sprachübersetzer, Sprachwandler oder Sprache Rewritriter. Der letzte Begriff wird normalerweise auf Übersetzungen angewendet, die keine Sprachänderung beinhalten.[46]
  • Bytecode Compiler kompilieren wie einige zur Montagesprache einer theoretischen Maschine Prolog Implementierungen
  • Just-in-Time-Compiler (JIT -Compiler) Verschiebung der Kompilierung bis zur Laufzeit. JIT -Compiler existieren für viele moderne Sprachen, einschließlich Python, JavaScript, Smalltalk, Java, Microsoft .NETZ's Gemeinsame Zwischensprache (Cil) und andere. Ein JIT -Compiler läuft im Allgemeinen in einem Dolmetscher. Wenn der Interpreter feststellt, dass ein Codepfad "heiß" ist, was bedeutet, dass er häufig ausgeführt wird, wird der JIT -Compiler aufgerufen und den "Hot" -Coder für eine erhöhte Leistung zusammengestellt.
    • Für einige Sprachen, wie z. Zwischendarstellung. Ein Bytecode -Interpreter führt den Bytecode aus, der JIT -Compiler übersetzt jedoch den Bytecode in den Maschinencode, wenn eine erhöhte Leistung erforderlich ist.[47]
  • Hardware -Compiler (Auch als Synthese -Tools bekannt) sind Compiler, deren Eingabe a ist Hardware -Beschreibung Sprache und deren Ausgabe eine Beschreibung in Form von a ist Netzliste oder anderweitig einer Hardwarekonfiguration.
    • Die Ausgabe dieser Compiler zielen auf Computerhardware auf sehr niedrigem Niveau zum Beispiel a Feldprogrammierbares Gate-Array (FPGA) oder strukturiert Anwendungsspezifische integrierte Schaltung (ASIC).[48] Solche Compiler sollen Hardware -Compiler sind, da der Quellcode, den sie kompilieren, die endgültige Konfiguration der Hardware und der Funktionsweise effektiv steuert. Die Ausgabe der Kompilierung ist nur eine Verbindung von Transistoren oder Nachschlagetabellen.
    • Ein Beispiel für den Hardware -Compiler ist XST, das zum Konfigurieren von FPGAs verwendete Xilinx -Synthese -Tool.[49] Ähnliche Tools sind bei Altera erhältlich,[50] Synplität, Synopsys und andere Hardwareanbieter.
  • Ein Assembler ist ein Programm, das menschliche lesbare kompiliert Montagesprache zu Maschinensprache, Die tatsächlichen Anweisungen, die von Hardware ausgeführt werden. Das inverse Programm, das den Maschinencode in die Montagesprache übersetzt Disassembler.
  • Ein Programm, das von einer Sprache auf niedriger Ebene bis zu einer höheren Stufe eins ist, ist a Dekompiler.[51]
  • Ein Programm, das sich in ein Objektcode -Format übersetzt, das nicht auf der Kompilierungsmaschine unterstützt wird Cross Compiler und wird häufig verwendet, um Code für eingebettete Anwendungen vorzubereiten.[Klarstellung erforderlich]
  • Ein Programm, das den Objektcode wieder in denselben Objektcode -Typen umschreibt, während Optimierungen und Transformationen angewendet werden, ist a Binärverkompiler.

Siehe auch

Verweise

  1. ^ "Enzyklopädie: Definition von Compiler". Pcmag.com. Abgerufen 2. Juli 2022.{{}}: CS1 Wartung: URL-Status (Link)
  2. ^ a b Compiler: Prinzipien, Techniken und Werkzeuge von Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman - Zweite Ausgabe, 2007
  3. ^ Sudarsanam, Ashok; Malik, Sharad; Fujita, Masahiro (2002). "Eine maschinelle Kompilierungsmethode für eingebettete digitale Signalprozessoren unter Verwendung einer maschinellabhängigen Codeoptimierungsbibliothek". Messwerte in Hardware/Software-Co-Design. Elsevier. S. 506–515. doi:10.1016/b978-155860702-6/50045-4. ISBN 9781558607026. Ein Compiler ist ein Computerprogramm, das ein Programm übersetzt in einer hochrangigen Sprache (HLL) wie C in ein äquivalentes Assembler-Sprachprogramm [2].
  4. ^ Sonne, Chengian; Le, Vu; Zhang, Qirun; Su, Zhendong (2016). "Um Compiler -Fehler in GCC und LLVM zu verstehen". ACM. ISSTA 2016: 294–305. doi:10.1145/2931037.2931074. ISBN 9781450343909. S2CID 8339241.
  5. ^ Vorlesungsnotizen Compiler: Prinzipien, Techniken und Werkzeuge Jing-Shin Chang Abteilung für Informatik & Informationstechnik National Chi-Nan University
  6. ^ Naur, P. et al. "Bericht über Algol 60". Kommunikation der ACM 3 (Mai 1960), 299–314.
  7. ^ Chomsky, Noam; Lightfoot, David W. (2002). Syntaktische Strukturen. Walter de Gruyter. ISBN 978-3-11-017279-9.
  8. ^ Gries, David (2012). "Anhang 1: backus-naur-Form". Die Wissenschaft der Programmierung. Springer Science & Business Media. p. 304. ISBN 978-1461259831.
  9. ^ Iverson, Kenneth E. (1962). Eine Programmiersprache. John Wiley & Sons. ISBN 978-0-471430-14-8.
  10. ^ Backus, John. "Die Geschichte von Forran I, II und III" (PDF). Geschichte der Programmiersprachen. SoftwarePeservation.org.
  11. ^ Porter Adams, Vicki (5. Oktober 1981). "Captain Grace M. Hopper: Die Mutter von Cobol". InfoWorld. 3 (20): 33. ISSN 0199-6649.
  12. ^ McCarthy, J.; Brayton, R.; Edwards, D.; Fox, P.; Hodes, L.; Luckham, D.; Maling, K.; Park, D.; Russell, S. (März 1960). "LISP I Programmierer Handbuch" (PDF). Boston, Massachusetts: Künstliche Intelligenzgruppe, M.I.T. Berechnungszentrum und Forschungslabor.
  13. ^ Compiler -Prinzipien, Techniken und Tools 2. Ausgabe von AHO, Lam, Sethi, Ullman ISBN0-321-48681-1
  14. ^ Hopper, Grace Murray (1952). "Die Ausbildung eines Computers". Verfahren des ACM National Meeting von 1952 (Pittsburgh): 243–249. doi:10.1145/609784.609818. S2CID 10081016.
  15. ^ Ridgway, Richard K. (1952). "Routinen zusammenstellen". Verfahren des ACM National Meeting von 1952 (Toronto): 1–5. doi:10.1145/800259.808980. S2CID 14878552.
  16. ^ "Rekursive Funktionen symbolischer Ausdrücke und ihrer Berechnung nach Maschine", Kommunikation der ACM, April 1960
  17. ^ McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I. (1965). LISP 1.5 Programmiererhandbuch. Die MIT -Presse. ISBN 9780262130110.
  18. ^ "BCPL: Ein Werkzeug für das Schreiben von Compiler und die Systemprogrammierung"M. Richards, Universitätsmathematischer Labor Cambridge, England 1969
  19. ^ BCPL: Die Sprache und ihr Compiler, M Richards, Cambridge University Press (erstmals veröffentlicht am 31. Dezember 1981)
  20. ^ Der BCPL Cintsys und Cintpos User Guide, M. Richards, 2017
  21. ^ Corbató, F. J.; Vyssotsky, V. A. "Einführung und Übersicht über das Mehrschichtsystem". 1965 Herbst Joint Computer Conference. Multiders.org.
  22. ^ Bericht II des Anteilsabgeschwächtes Sprachentwicklungskomitee, 25. Juni 1964
  23. ^ Multiys.org "Die Wahl des PL /I" -Aktels, Herausgeber /Tom van Vleck
  24. ^ "PL/I als Instrument zur Systemprogrammierung", F.J. Corbato, DataMation 6 Mai 1969 Ausgabe
  25. ^ "Der Multics PL/1 Compiler", R. A. Freiburghouse, GE, Herbst Joint Computer Conference 1969
  26. ^ Dennis M. Ritchie, "Die Entwicklung der C -Sprache", ACM Second History of Programming Languages ​​Conference, April 1993
  27. ^ S. C. Johnson, "Ein tragbarer C -Compiler: Theorie und Praxis", 5. ACM Popl Symposium, Januar 1978
  28. ^ A. Snyder, Ein tragbarer Compiler für die Sprache c, Mit, 1974.
  29. ^ K. Nygaard, Universität Oslo, Norwegen, "Grundlegende Konzepte in der objektorientierten Programmierung", Sigplan bemerkt V21, 1986
  30. ^ B. Stroustrup: "Was ist objektorientierte Programmierung?" Proceedings 14. ASU -Konferenz, 1986.
  31. ^ Bjarne Strousstrup, "Ein Überblick über die C ++ - Programmiersprache", Handbuch der Objekttechnologie (Editor: Saba Zamir, ISBN0-8493-3135-8)
  32. ^ Leverett, Cattell, Hobbs, Newcomer, Reiner, Schatz, WULF: "Ein Überblick über das Produktionsqualitäts Compiler-Compiler-Projekt", CMU-CS-89-105, 1979
  33. ^ W. Wulf, K. Nori, "Verzögerte Bindung in PQCC -erzeugten Compilern", CMU Research Showcase-Bericht, CMU-CS-82-138, 1982
  34. ^ Joseph M. Newcomer, David Alex Lamb, Bruce W. Leverett, Michael Tighe, William A. Wulf - Carnegie -Mellon University und David Levine, Andrew H. Reinerit - Intermetrics: "TCOL ADA: Überarbeiteter Bericht über eine Zwischendarstellung für den Dod Standard -Programmiersprache ", 1979
  35. ^ William A. Whitaker, "ADA - Das Projekt: The Dod High Order Working Group", ACM Sigplan Notices (Band 28, Nr. 3, März 1991)
  36. ^ CECOM Center for Software Engineering Advanced Softwaretechnologie, "Abschlussbericht-Bewertung der ACEC-Benchmark-Suite für Echtzeitanwendungen", AD-A231 968, 1990
  37. ^ P. Biggar, E. de Vries, D. Gregg, "Eine praktische Lösung für Skriptsprachkompiler", Einreichung der Wissenschaft des Computerprogramms, 2009
  38. ^ M.Hall, D. Padua, K. Pingali, "Compiler Research: Die nächsten 50 Jahre", ACM Communications 2009 Vol 54 #2
  39. ^ Cooper und Torczon 2012, p. 8
  40. ^ Lattner, Chris (2017). "LLVM". In Brown, Amy; Wilson, Greg (Hrsg.). Die Architektur von Open Source -Anwendungen. Archiviert Aus dem Original am 2. Dezember 2016. Abgerufen 28. Februar 2017.
  41. ^ Aho, Lam, Sethi, Ullman 2007, p. 5-6, 109-189
  42. ^ Aho, Lam, Sethi, Ullman 2007, p. 111
  43. ^ Aho, Lam, Sethi, Ullman 2007, p. 8, 191-300
  44. ^ a b Blindell, Gabriel Hjort (3. Juni 2016). Auswahl der Anweisungen: Prinzipien, Methoden und Anwendungen. Schweiz. ISBN 9783319340197. OCLC 951745657.
  45. ^ Cooper und Toczon (2012), p. 540
  46. ^ "Sprachübersetzer Tutorial" (PDF). Washington University.
  47. ^ Aycock, John (2003). "Eine kurze Geschichte der Just-in-Time". ACM Comput. Überleben. 35 (2, Juni): 93–113. doi:10.1145/857076.857077. S2CID 15345671.
  48. ^ Swartz, Jordan S.; Betz, Vaugh; Rose, Jonathan (22. bis 25. Februar 1998). "Ein schneller Routabilitätsrouter für FPGAs" (PDF). FPGA '98 Proceedings des ACM/SIGDA Sechsten internationalen Symposiums von 1998 auf Feldprogrammiergate -Arrays. Monterey, CA: ACM: 140–149. doi:10.1145/275107.275134. ISBN 978-0897919784. S2CID 7128364. Archiviert (PDF) Aus dem Original am 9. August 2017.
  49. ^ Xilinx Staff (2009). "XST -Syntheseübersicht". Xilinx, Inc. Archiviert Aus dem Original am 2. November 2016. Abgerufen 28. Februar 2017.
  50. ^ Altera Staff (2017). "Spectra-Q ™ Motor". Altera.com. Archiviert von das Original am 10. Oktober 2016. Abgerufen 28. Februar 2017.
  51. ^ "Dekompiler - ein Überblick | ScienceDirect -Themen". www.sciencedirect.com. Abgerufen 12. Juni 2022.

Weitere Lektüre

Externe Links