Warum C ++, um einen Compiler zu schreiben?


15

Ich habe mich gefragt, warum C ++ eine gute Wahl ist, um einen Compiler zu schreiben. Natürlich ist C auch für diesen Zweck gut, da viele Compiler entweder in C oder C ++ geschrieben sind, aber ich bin diesmal mehr an C ++ interessiert. Irgendwelche guten Gründe? Das habe ich im Internet gesucht, aber ich kann keine guten Gründe finden.


3
"Viele Compiler sind [...] in C ++ geschrieben" - irgendwelche Referenzen? Welche? Was lässt Sie glauben, dass C ++ häufiger für die Compilerkonstruktion verwendet wird als andere gängige Sprachen?
Doc Brown

4
@DocBrown Nun, Clang und MSVC sind größtenteils in C ++ geschrieben, gcc enthält jetzt ein bisschen C ++, Java JVM ist in C ++ geschrieben. Stackoverflow.com/questions/410320/what-is-java-written-in und auch superuser . com / questions / 136136 /…
Klaim

@DocBrown DMD Der Referenz-Compiler für D ist in C ++ geschrieben
Ratschenfreak

3
Wer sagt, dass es eine gute Wahl ist?
Phil

1
@Phil Glaubst du, sie haben diese Wahl getroffen, ohne Alternativen in Betracht zu ziehen? Es ist keine "gute" Wahl, es ist eine "effiziente" Wahl.
Klaim

Antworten:


21

C ++ hat zwei Seiten. Es hat eine Low-Level-Entwicklungsseite, die es wie eine natürliche Sprache erscheinen lässt, um Low-Level-Aufgaben wie die Codegenerierung auszuführen. Es hat auch eine High-Level-Seite (was C nicht tut), mit der Sie eine komplexe Anwendung (wie einen Compiler) auf logische, objektorientierte Weise strukturieren können, ohne die Leistung zu beeinträchtigen. Da es sowohl Low- als auch High-Level-Aspekte aufweist, ist es eine gute Wahl für große Anwendungen, die Low-Level-Funktionen oder -Leistung erfordern.


9
Soweit ich weiß, ist ein Großteil der Logik in einem Compiler funktionaler Natur (Umwandlung komplexer Datenstrukturen in andere Datenstrukturen). Daher bin ich mir nicht sicher, ob objektorientierte Funktionen (die mehr auf die Programmierung im großen Maßstab abzielen) verfügbar sind , architektonische Aspekte) bringen einen echten Vorteil für die Compilerkonstruktion in Bezug auf einen prozeduralen Programmierstil. Nur meine 2 Cent.
Giorgio

5
@Giorgio Objekte zu haben, hilft in vielen anderen Aspekten des Compiler-Schreibens. Beispielsweise muss ein Compiler bei der Optimierung eine Menge Status berücksichtigen, und solche Dinge eignen sich gut für OOP. Auch OOP und funktionale Programmierung können sehr komplementär sein. Nur weil die Algorithmen größtenteils funktionsfähig sind, bedeutet dies nicht, dass Objekte nicht helfen.
Oleksi

3
@ Giorgio und Oleksi: Ich kann euch beide bestätigen. Ich habe mit Haskell einen Compiler für eine reale Sprache geschrieben. Es war eine wirklich gute Passform. Aber manchmal habe ich etwas OO verpasst. Wenn ich einen anderen Compiler schreiben müsste, würde ich definitiv Haskell wählen, aber das ist wirklich ein Sonderfall. Ich würde Haskell nicht ohne zu zögern für andere Arten von Projekten wählen.
Narbenkühlschrank

23
Warum brauchen Sie eine Sprache mit einer "Low-Level-Seite", um Code zu generieren? Ich kann nicht sehen, wie diese beiden in irgendeiner Weise verbunden sind.
phant0m

5
Sie brauchen keine "Low-Level-Seite", um Code zu generieren , genauso wenig wie Sie Unicode- Bezeichner benötigen , um japanischen Text in eine Datei schreiben zu können.
Dan04

11

Meine Erfahrung stimmt hier nicht mit Ihrer Prämisse überein. Tatsächlich ist es bei allgemeinen Hochsprachen üblich, den Compiler in derselben Sprache wie die Ausgangssprache (die zu kompilierende Sprache) zu schreiben . Beispielsweise:

  • Der Java-Compiler von Sun ist in Java geschrieben
  • Der Scala-Compiler ist in Scala geschrieben
  • Monos C # -Compiler ist in C # geschrieben
  • Squicks Smalltalk-Compiler ist in Smalltalk geschrieben
  • ... und viele mehr

Eine Ausnahme bilden Compiler-Frontends, die für vorhandene Compiler-Frameworks wie GCC, LLVM oder Polyglot geschrieben wurden und dann in der Sprache des Frameworks geschrieben wurden, oder Compiler, die auf vorhandenen Parser-Generatoren wie Yacc basieren. Da GCC, LLVM und Yacc gängige, in C und C ++ geschriebene Tools sind, bieten sie den Compiler-Autoren einen Anreiz, sie zu verwenden, was dazu führen kann, dass C und C ++ einen großen Anteil an der Verteilung der Compiler-Implementierungssprache haben.


2
Ich denke, das hat viel mehr damit zu tun, dass die Leute, die den Compiler schreiben, die Sprache, für die sie einen Compiler schreiben, gut kennen und mögen, als aus objektiven technischen Gründen.
Thomas Bonini

1
@Krelp Ich bin damit einverstanden, dass es sich nicht um einen objektiven technischen Grund handelt, aber es ist auch nicht wirklich "sympathisch" - es wird nur als Übergangsritus für eine Sprache angesehen - "ist es ausgereift genug, um als eigene Implementierungssprache dienen zu können Compiler ".
Oak

1
Der Java-Compiler von Sun ist in C ++ geschrieben: stackoverflow.com/questions/410320/what-is-java-written-in
Klaim

10
@ Behaupten Sie, Sie verwechseln hier zwei Produkte. Einer davon ist der Java-Compiler ( javacBefehlszeile) von Sun , mit dem Java in Java-Bytecode kompiliert wird. Es ist in Java geschrieben - ich habe es selbst oft modifiziert und Sie können die Java-Quellen online durchsuchen . Der andere ist der in die Hotspot-JVM eingebettete Just-in-Time-Compiler, der Java- Bytecode in systemeigenen Maschinencode kompiliert. Wie die meisten JVMs ist es in C ++ geschrieben, aber es ist kein Java-Compiler - tatsächlich weiß es nichts über die Java-Sprache.
Oak

@Oak, absolut richtig! Mit anderen Worten, JVM! = Javac
Paul Draper

5

Um was zu was zu kompilieren? Ein Compiler transformiert einen Quellcode von einer Sprache (Quellsprache) in eine andere (Zielsprache), was nichts über die niedrige Ebene der Zielsprache aussagt.

  • CoffeeScript in JavaScript kompiliert, wobei der Compiler in CoffeeScript geschrieben wird.
  • Skript# kompiliert C # in JavaScript, wobei der Compiler geschrieben wird, wenn ich mich recht erinnere, C #.
  • etc.

Die Sprache, die Sie zum Schreiben eines Compilers auswählen, hängt vom Kontext ab.Bei der Arbeit an einem Projekt, das eine von PHP abgeleitete Sprache in einen nativen PHP-Code übersetzt, habe ich zum Schreiben des Compilers eine Mischung aus PHP und C # verwendet, da dies für mich aufgrund meiner Fähigkeiten am sinnvollsten war. Eine andere Person würde Python oder Java und PHP oder C ++ mit etwas JavaScript oder was auch immer auswählen.

C oder C ++ ist aufgrund der Unterstützung von Compiler-bezogenen Tools (siehe die Antwort von Telastyn) und der Tatsache, dass diese beiden Sprachen es Ihnen ermöglichen, wirklich muttersprachlich zu werden, eine beliebte Wahl. Aber es ist nichts Falsches daran, eine andere Sprache zu wählen.

Beachten Sie, dass , um mehr zu sein geeky , können Sie die Quellsprache wählen Sie den Compiler selbst zu schreiben. Genau das ist beim CoffeeScript-Compiler und vielen anderen Compilern passiert. Es ist auch bei den IDEs beliebt: Eines der ersten Visual Studios wurde mit demselben Visual Studio erstellt.


4
Selfhosting ist kein Geeky, sondern eine wichtige Eigenschaft für die Portierung eines Compilers.

4
Der Grund dafür ist, dass der Compiler selbst sofort ein Testprogramm sein kann. Es wird höchstwahrscheinlich auch das größte Programm für diesen Compiler für eine Weile sein.

5

Ich neige dazu, die grundlegende Prämisse hier in Frage zu stellen. Während C und C ++ hervorragend zum Schreiben von Compilern geeignet sind, scheinen einige andere Sprachen für diese Aufgabe ebenfalls hervorragend geeignet zu sein.

Ein bisschen hängt jedoch von der Sprache ab, die Sie kompilieren. Für kleine, einfache Sprachen funktionieren C und Pascal ganz gut. Wenn Sie etwas Großes und Komplexes kompilieren, wird Ihr Compiler auch groß und komplex - in diesem Fall sind die zusätzlichen Funktionen von C ++ zum Organisieren und Arbeiten mit größeren Programmen offensichtlich nützlich. Das ist jedoch nicht sehr spezifisch für das Kompilieren, sondern bietet nur nützliche Funktionen für größere Programme im Allgemeinen.

Ich denke, es lohnt sich auch, einen weiteren Punkt zu erwähnen. Anfänger (scheinen) denken, dass Compiler hauptsächlich Textmanipulationen ausführen. Sie denken also, dass Perl eine große Hilfe beim Schreiben von Compilern sein wird. In Wirklichkeit beginnen die meisten interessanten Teile der Kompilierung erst, nachdem Sie Ihren AST erstellt haben. Obwohl ich sicher bin, dass Perl die Aufgabe perfekt erledigen kann, bringt seine Textmanipulationsfähigkeit auch keinen großen Vorteil (die Textmanipulation liegt hauptsächlich im Lexer, und Lexer-Generatoren für Dinge wie C unterstützen sowieso alle REs).


2
AST = Abstract Syntax Tree, RE = Reguläre Ausdrücke
chaotisches Gleichgewicht

5

Compiler können in jeder modernen Sprache implementiert werden. Eine der wichtigsten Anforderungen an einen Compiler ist jedoch, schnell zu sein.

C ++ hat hier einen klaren Vorteil. Optimierung in C ++ ist nicht billig. Aufgrund der niedrigen Ebene dieser Sprache ist es jedoch möglich, C ++ - Code mehr manuell zu optimieren als in jeder anderen Sprache (mit Ausnahme von Assembly, die nicht portierbar ist).


9
Eine weitere wichtige Voraussetzung ist, dass der generierte Code korrekt ist. Ich hätte lieber einen langsamen Compiler, dem ich vertrauen kann, als einen schnellen, der falschen Code generiert.

1
Zwar ist es sicherlich möglich , C ++ sehr stark zu optimieren, aber es gibt eine Menge von eher… na ja… weniger als optimalem C ++ - Code.
Donal Fellows

2
@DonalFellows Umgekehrt: Es ist möglich, in jeder Sprache weniger als optimalen Code zu schreiben, aber es gibt Optimierungen, die in anderen Sprachen als C ++ (außer Assembler) nicht möglich sind. Ich füge C aus Mangel nicht hinzu von Strukturen auf hoher Ebene, die ein stärkeres Inlining ermöglichen).
Klaim

2

Ich vermute, dass der Hauptgrund für ihre Verwendung darin besteht, dass die Lex / Yacc / Bison-Ausgabe (hauptsächlich) in C liegt. Da dies seit so langer Zeit der Standard ist, hat sie Schwung.

Nicht, dass das besonders gute Gründe wären ...


Eigentlich befriedigt es mich nicht, aber danke für den Versuch.
Kobra

Das beantwortet nicht die Frage "Warum C ++ anstelle von C für die Compilerkonstruktion wählen".
Doc Brown

2
Das ist überhaupt kein guter Grund. Analoge Tools zu Lex und Yacc gibt es für viele Plattformen. Zum Beispiel PLY und ANTLR.
user16764

Darüber hinaus verwenden die meisten populären Compiler der realen Welt (ich bin mir ziemlich sicher, dass Clang und GCC es sind) handgeschriebene Parser.

@delnan: Ja, aber sie haben wahrscheinlich mit einer generierten angefangen, um die Dinge in Gang zu bringen. Die Handgenerierung des Parsers ist ein Optimierungsschritt, den Sie erst dann durchführen möchten, wenn Sie nachweisen können, dass andere Dinge funktionieren.
Martin York
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.