Lernen, einen Compiler zu schreiben [geschlossen]

699

Bevorzugte Sprachen : C / C ++, Java und Ruby.

Ich suche nach hilfreichen Büchern / Tutorials, wie Sie Ihren eigenen Compiler nur zu Bildungszwecken schreiben können. Ich bin mit C / C ++, Java und Ruby am besten vertraut, daher bevorzuge ich Ressourcen, die eine dieser drei beinhalten, aber jede gute Ressource ist akzeptabel.

Anton
quelle
ANTLR den ganzen Weg. Alle unten vorgeschlagenen Ressourcen sehen für mich wie ein Overkill aus. ANTLR ist immer ein bester Freund des Compiler-Designers. A
A_Var
Wenn Ihr Hauptaugenmerk darauf liegt, zu lernen, wie das Kompilieren von Ideen im Allgemeinen funktioniert, können Sie die auf Schema (Liste) basierende strukturierte Interpretation von Computerprogrammen überprüfen und mit SICP abkürzen, aber die allgemeinen Prinzipien vermitteln. mitpress.mit.edu/sicp . Mir wurde dieses Buch von einem Veteranen empfohlen, der für ein Unternehmen arbeitet und diese Werke für seinen Lebensunterhalt zusammenstellt und interpretiert!
Nishant
Ein schamloser Stecker: meine Antwort auf eine ähnliche Frage .
9000
Ich habe in meinem Blog einen Artikel über das Erstellen eines Compilers geschrieben: orangejuiceliberationfront.com/how-to-write-a-compiler Er konzentriert sich auf die Grundlagen und die ersten Schritte . Dort gibt es eine Reihe weiterer Artikel zum Thema Compiler / Codegen / Parser / Sprachdesign.
uliwitness

Antworten:

1084

Große Liste von Ressourcen:

Legende:

  • ¶ Link zu einer PDF-Datei
  • $ Link zu einem gedruckten Buch
Anton
quelle
22
Ich habe die Serie Let's Build a Compiler[ compilers.iecc.com/crenshaw/] gelesen , es ist wirklich eine schöne Zusammenfassung und ein guter Ausgangspunkt.
TheVillageIdiot
5
Ich denke, eine erwähnenswerte ist Courseras Compilerkurs. Es hat schöne Videos und geht durch die Erstellung einer Java-ähnlichen Sprache / einfachen Compiler. Coursera Compilers Link
QuantumKarl
1
Ich wollte diese Antwort so original wie möglich halten, deshalb habe ich beschlossen, diese Referenz hier zu veröffentlichen: tutorialspoint.com/compiler_design/index.htm Was mir an dieser Site gefallen hat, ist, dass sie sich nicht mit dem eigentlichen Schreiben von Code befasst um einen Compiler zu erstellen, aber er zerlegt den Compiler in seine Teile: Phasen und Stufen. Es beschreibt den logischen und algorithmischen Entwurfsansatz ohne ein spezifisches Sprachparadigma, da es die Notationen einer beliebigen Sprache und eines beliebigen Alphabets ausdrückt. Es ist eine schnelle Lektüre, gibt Ihnen aber die Konzepte, was für jedes Teil benötigt wird.
Francis Cugler
70

Das ist eine ziemlich vage Frage, denke ich; nur wegen der Tiefe des Themas. Ein Compiler kann jedoch in zwei separate Teile zerlegt werden. eine obere Hälfte und eine untere. Die obere Hälfte nimmt im Allgemeinen die Ausgangssprache und konvertiert sie in eine Zwischendarstellung, und die untere Hälfte kümmert sich um die plattformspezifische Codegenerierung.

Eine Idee für eine einfache Herangehensweise an dieses Thema (die wir zumindest in meiner Compiler-Klasse verwendet haben) besteht darin, den Compiler in den beiden oben beschriebenen Teilen zu erstellen. Insbesondere erhalten Sie eine gute Vorstellung vom gesamten Prozess, indem Sie nur die obere Hälfte erstellen.

Wenn Sie nur die obere Hälfte ausführen, können Sie den lexikalischen Analysator und den Parser schreiben und einen "Code" (die von mir erwähnte Zwischendarstellung) generieren. Es wird also Ihr Quellprogramm nehmen und es in eine andere Darstellung konvertieren und einige Optimierungen vornehmen (wenn Sie möchten), was das Herz eines Compilers ist. Die untere Hälfte nimmt dann diese Zwischendarstellung und generiert die Bytes, die zum Ausführen des Programms auf einer bestimmten Architektur erforderlich sind. In der unteren Hälfte wird beispielsweise Ihre Zwischendarstellung verwendet und eine ausführbare PE-Datei generiert.

Einige Bücher zu diesem Thema, die ich besonders hilfreich fand, waren Compilers Principles and Techniques (oder das Dragon Book, aufgrund des niedlichen Drachen auf dem Cover). Es hat eine großartige Theorie und deckt definitiv kontextfreie Grammatiken auf wirklich zugängliche Weise ab. Zum Erstellen des lexikalischen Analysators und Parsers werden Sie wahrscheinlich die * nix-Tools lex und yacc verwenden. Und uninteressant genug, das Buch " Lex and Yacc " hat dort angefangen, wo das Drachenbuch für diesen Teil aufgehört hat .

mrduclaw
quelle
55

Ich denke, die moderne Compiler-Implementierung in ML ist der beste einführende Compiler, der Text schreibt. Es gibt eine Java-Version und eine C-Version , die aufgrund Ihres Sprachhintergrunds möglicherweise leichter zugänglich sind. Das Buch enthält viele nützliche Grundmaterialien (Scannen und Parsen, semantische Analyse, Aktivierungsdatensätze, Anweisungsauswahl, native RISC- und x86-Codegenerierung) und verschiedene "erweiterte" Themen (Kompilieren von OO- und Funktionssprachen, Polymorphismus, Speicherbereinigung, Optimierung und einzelnes statisches Zuweisungsformular) auf relativ wenig Platz (~ 500 Seiten).

Ich bevorzuge die Modern Compiler-Implementierung gegenüber dem Dragon-Buch, da die Modern Compiler-Implementierung weniger Feldforschung betreibt - stattdessen werden alle Themen, die Sie zum Schreiben eines seriösen, anständigen Compilers benötigen, wirklich solide abgedeckt. Nachdem Sie dieses Buch durchgearbeitet haben, können Sie Forschungsarbeiten bei Bedarf direkt vertiefen.

Ich muss gestehen, dass ich eine ernsthafte Schwäche für Niklaus Wirths Compilerkonstruktion habe. Es ist online als PDF verfügbar . Ich finde Wirths Programmierästhetik einfach wunderschön, aber einige Leute finden seinen Stil zu minimal (zum Beispiel bevorzugt Wirth rekursive Abstiegsparser, aber die meisten CS-Kurse konzentrieren sich auf Parsergenerator-Tools; Wirths Sprachdesigns sind ziemlich konservativ.) Die Compilerkonstruktion ist eine sehr prägnante Destillation von Wirths Grundideen, ob Sie nun seinen Stil mögen oder nicht, ich empfehle dringend, dieses Buch zu lesen.

Dominic Cooney
quelle
Compilerkonstruktion PDF ethoberon.ethz.ch/WirthPubl/CBEAll.pdf
matepal297
Ich empfehle dringend, gegen die C-Version von "Modern Compiler Implementation" vorzugehen, da sie aufgrund von C durch Details auf niedriger Ebene verkrüppelt ist. Sie macht das Buch völlig unübersichtlich. Java 1st ist nicht allzu gut, da sein OO-Design schlecht ist. In Java 2nd Ed geht es nicht mehr um die Tiger-Sprache. Ich empfehle daher dringend die ML: Es ist nicht notwendig, fließend ML zu sprechen, um sie zu verstehen. ML ist definitiv gut für den Job geeignet.
Akim
44

Ich stimme der Referenz zum Drachenbuch zu. IMO, es ist der endgültige Leitfaden für die Compilerkonstruktion. Machen Sie sich jedoch bereit für eine Hardcore-Theorie.

Wenn Sie ein Buch suchen, das theoretisch leichter ist, ist Game Scripting Mastery möglicherweise das bessere Buch für Sie. Wenn Sie ein absoluter Neuling in der Compilertheorie sind, bietet dies eine sanftere Einführung. Es werden keine praktischeren Parsing-Methoden behandelt (die sich für einen nicht prädiktiven rekursiven Abstieg entscheiden, ohne das LL- oder LR-Parsing zu diskutieren), und wie ich mich erinnere, wird nicht einmal irgendeine Optimierungstheorie diskutiert. Anstatt zu Maschinencode zu kompilieren, wird zu einem Bytecode kompiliert, der auf einer VM ausgeführt werden soll, die Sie auch schreiben.

Es ist immer noch eine anständige Lektüre, besonders wenn Sie es günstig bei Amazon kaufen können. Wenn Sie nur eine einfache Einführung in Compiler wünschen, ist Game Scripting Mastery kein schlechter Weg. Wenn Sie im Vorfeld Hardcore spielen möchten, sollten Sie sich mit nichts weniger als dem Drachenbuch zufrieden geben.

user316
quelle
1
Game Scripting Mastery ist eine großartige Lernressource, denn wenn Sie fertig sind, haben Sie ein spielbares, skriptfähiges 2D-Abenteuerspiel. Dadurch konzentriert sich jede Übung auf einen bestimmten Zweck und motiviert den Leser.
Dour High Arch
1
Dragon konzentriert sich etwas zu sehr auf grammatikalisches Parsen. Wenn Sie nicht versuchen, etwas schier Unmögliches wie C ++ oder so mit Parser-Generatoren zu analysieren, sondern beispielsweise eine handgefertigte LL-Grammatik verwenden können, sollten Sie nach etwas Ausschau halten, das andere Compilerfelder mit einem höheren Prozentsatz als Grammatiktransformation und -beweis behandelt
Marco van de Voort
27

"Let's Build a Compiler" ist großartig, aber etwas veraltet. (Ich sage nicht, dass es dadurch noch ein bisschen weniger gültig wird.)

Oder schauen Sie sich SLANG an . Dies ähnelt "Let's Build a Compiler", ist jedoch eine viel bessere Ressource, insbesondere für Anfänger. Dies wird mit einem PDF-Tutorial geliefert, das einen 7-stufigen Ansatz zum Unterrichten eines Compilers verfolgt. Hinzufügen des Quora-Links, da er die Links zu allen verschiedenen Ports von SLANG in C ++, Java und JS enthält, sowie Interpreter in Python und Java, die ursprünglich mit C # und der .NET-Plattform geschrieben wurden.

RBz
quelle
5
Ich bin damit einverstanden, dass diese Serie etwas veraltet ist, obwohl sie immer noch nützlich ist. Mein größter Kritikpunkt ist jedoch die Tatsache, dass versucht wird, direkt in die Assemblersprache auszugeben, anstatt irgendeine Art von Analysebaum zu erstellen, was bedeutet (im Gegensatz zu dem, was im ersten Artikel angegeben ist), dass es für das Schreiben nicht sehr nützlich ist ein Dolmetscher.
a_m0d
23

Wenn Sie leistungsstarke Tools auf höherer Ebene verwenden möchten, anstatt alles selbst zu erstellen, ist es eine gute Option, die Projekte und Lesungen für diesen Kurs durchzugehen . Es ist ein Sprachkurs des Autors der Java-Parser-Engine ANTLR. Sie können das Buch für den Kurs als PDF von den Pragmatic Programmers erhalten .

Der Kurs behandelt die Standard-Compiler-Compiler-Inhalte, die Sie an anderer Stelle sehen würden: Parsen, Typen- und Typprüfung, Polymorphismus, Symboltabellen und Codegenerierung. Das einzige, was nicht behandelt wird, sind Optimierungen. Das endgültige Projekt ist ein Programm, das eine Teilmenge von C kompiliert . Da Sie Tools wie ANTLR und LLVM verwenden, ist es möglich, den gesamten Compiler an einem einzigen Tag zu schreiben (ich habe einen Existenznachweis dafür, obwohl ich ~ 24 Stunden meine). Es ist schwer für die praktische Technik mit modernen Werkzeugen, ein bisschen leichter für die Theorie.

LLVM ist übrigens einfach fantastisch. In vielen Situationen, in denen Sie normalerweise bis zur Assembly kompilieren, ist es viel besser, stattdessen die Zwischenrepräsentation von LLVM zu kompilieren . Es ist übergeordnet, plattformübergreifend und LLVM ist ziemlich gut darin, daraus eine optimierte Montage zu generieren.

Peter Burns
quelle
Der erste Link ist tot.
Lynn
20

Wenn Sie wenig Zeit haben, empfehle ich Niklaus Wirths "Compiler Construction" (Addison-Wesley. 1996) , eine winzige kleine Broschüre, die Sie an einem Tag lesen können, die jedoch die Grundlagen erklärt (einschließlich der Implementierung von Lexern, rekursiven Abstiegsparsern, und Ihre eigenen stapelbasierten virtuellen Maschinen). Wenn Sie danach tief tauchen möchten, führt kein Weg an dem Drachenbuch vorbei, wie andere Kommentatoren vorschlagen.

Matthieu
quelle
Wenn Sie nicht viel Zeit haben, schreiben Sie keinen Compiler.
Ingo
17

Vielleicht möchten Sie sich Lex / Yacc ansehen (oder Flex / Bison, wie auch immer Sie sie nennen möchten). Flex ist ein lexikalischer Analysator, der die semantischen Komponenten ("Token") Ihrer Sprache analysiert und identifiziert. Mit Bison wird definiert, was passiert, wenn jedes Token analysiert wird. Dies könnte sein, ist aber definitiv nicht darauf beschränkt, C-Code für einen Compiler auszudrucken, der zu C kompiliert werden würde, oder die Anweisungen dynamisch auszuführen.

Diese FAQ soll Ihnen helfen, und dieses Tutorial sieht sehr nützlich aus.

Zachary Murray
quelle
17

Im Allgemeinen gibt es kein fünfminütiges Tutorial für Compiler, da es ein kompliziertes Thema ist und das Schreiben eines Compilers Monate dauern kann. Sie müssen Ihre eigene Suche durchführen.

Python und Ruby werden normalerweise interpretiert. Vielleicht möchten Sie auch mit einem Dolmetscher beginnen. Es ist im Allgemeinen einfacher.

Der erste Schritt besteht darin, eine formale Sprachbeschreibung zu schreiben, die Grammatik Ihrer Programmiersprache. Dann müssen Sie den Quellcode, den Sie gemäß der Grammatik kompilieren oder interpretieren möchten, in einen abstrakten Syntaxbaum umwandeln, eine interne Form des Quellcodes, den der Computer versteht und verarbeiten kann. Dieser Schritt wird normalerweise als Parsing bezeichnet, und die Software, die den Quellcode analysiert, wird als Parser bezeichnet. Oft wird der Parser von einem Parser-Generator generiert, der eine formale Grammatik in Quell- oder Maschinencode umwandelt. Für eine gute, nicht mathematische Erklärung des Parsens empfehle ich Parsing Techniques - A Practical Guide. Wikipedia bietet einen Vergleich von Parser-Generatoren, aus denen Sie den für Sie geeigneten auswählen können. Abhängig vom gewählten Parser-Generator

Das Schreiben eines Parsers für Ihre Sprache kann sehr schwierig sein, dies hängt jedoch von Ihrer Grammatik ab. Daher schlage ich vor, Ihre Grammatik einfach zu halten (im Gegensatz zu C ++). Ein gutes Beispiel dafür ist LISP.

Im zweiten Schritt wird der abstrakte Syntaxbaum von einer Baumstruktur in eine lineare Zwischendarstellung umgewandelt. Als gutes Beispiel hierfür wird häufig der Bytecode von Lua angeführt. Aber die Zwischendarstellung hängt wirklich von Ihrer Sprache ab.

Wenn Sie einen Interpreter erstellen, müssen Sie lediglich die Zwischendarstellung interpretieren. Sie können es auch just-in-time kompilieren. Ich empfehle LLVM und libjit für die Just-in-Time-Kompilierung. Um die Sprache nutzbar zu machen, müssen Sie auch einige Eingabe- und Ausgabefunktionen und möglicherweise eine kleine Standardbibliothek enthalten.

Wenn Sie die Sprache kompilieren, wird es komplizierter. Sie müssen Backends für verschiedene Computerarchitekturen schreiben und Maschinencode aus der Zwischendarstellung in diesen Backends generieren. Ich empfehle LLVM für diese Aufgabe.

Es gibt einige Bücher zu diesem Thema, aber ich kann keines für den allgemeinen Gebrauch empfehlen. Die meisten von ihnen sind zu akademisch oder zu praktisch. Es gibt kein "Bringen Sie sich das Schreiben von Compilern in 21 Tagen bei" und Sie müssen daher mehrere Bücher kaufen, um ein gutes Verständnis für dieses gesamte Thema zu erhalten. Wenn Sie im Internet suchen, werden Sie auf einige Online-Bücher und Vorlesungsunterlagen stoßen. Vielleicht gibt es in Ihrer Nähe eine Universitätsbibliothek, in der Sie Bücher über Compiler ausleihen können.

Ich empfehle auch gute Hintergrundkenntnisse in theoretischer Informatik und Graphentheorie, wenn Sie Ihr Projekt ernst nehmen wollen. Ein Abschluss in Informatik wird ebenfalls hilfreich sein.

user141335
quelle
++ Sie haben Recht, dass es gut ist, all diese Dinge zu wissen, und es kann eine große Aufgabe sein, aber ich habe auch von einigen Experten gelernt, wie man Dinge nicht zu einer großen Sache macht. Es ist gut, Dinge zu wissen, und es ist noch besser zu wissen, wann man sie nicht benutzt, was die meiste Zeit der Fall ist.
Mike Dunlavey
11

Ein Buch, das noch nicht vorgeschlagen, aber sehr wichtig ist, ist "Linkers and Loaders" von John Levine. Wenn Sie keinen externen Assembler verwenden, benötigen Sie eine Möglichkeit, eine Objektdatei auszugeben, die mit Ihrem endgültigen Programm verknüpft werden kann. Selbst wenn Sie einen externen Assembler verwenden, müssen Sie wahrscheinlich die Verschiebungen und die Funktionsweise des gesamten Programmladevorgangs verstehen, um ein funktionierendes Tool zu erstellen. Dieses Buch sammelt viele zufällige Informationen über diesen Prozess für verschiedene Systeme, einschließlich Win32 und Linux.

Ben Combee
quelle
10

Das Dragon Book ist definitiv das "Building Compiler" -Buch, aber wenn Ihre Sprache nicht ganz so kompliziert ist wie die aktuelle Sprachgeneration, sollten Sie sich das Interpreter-Muster aus Design Patterns ansehen .

Das Beispiel im Buch entwirft eine Sprache, die einem regulären Ausdruck ähnelt, und ist gut durchdacht, aber wie es im Buch heißt, ist es gut, um den Prozess zu durchdenken, aber es ist wirklich nur bei kleinen Sprachen wirksam. Es ist jedoch viel schneller, einen Interpreter für eine kleine Sprache mit diesem Muster zu schreiben, als sich mit den verschiedenen Arten von Parsern, Yacc und Lex usw. vertraut zu machen.

Chris Bunch
quelle
10

Wenn Sie bereit sind, LLVM zu verwenden, lesen Sie dies: http://llvm.org/docs/tutorial/ . Es zeigt Ihnen, wie Sie einen Compiler mit dem LLVM-Framework von Grund auf neu schreiben, und setzt nicht voraus, dass Sie über Kenntnisse zu diesem Thema verfügen.

Das Tutorial schlägt vor, dass Sie Ihren eigenen Parser und Lexer usw. schreiben, aber ich rate Ihnen, sich mit Bison und Flex zu befassen, sobald Sie die Idee haben. Sie machen das Leben so viel einfacher.

wvdschel
quelle
Aber die Dokumentation zum Einrichten von Visual Studio ist schlecht geschrieben, plus keine Beispiele
SpicyWeenie
10

Ich fand das Dragon-Buch viel zu schwer zu lesen, mit zu viel Fokus auf Sprachtheorie, die nicht wirklich erforderlich ist, um einen Compiler in der Praxis zu schreiben.

Ich würde das Oberon- Buch hinzufügen, das die vollständige Quelle eines erstaunlich schnellen und einfachen Oberon-Compilers Project Oberon enthält .

Alt-Text

Lothar
quelle
10

Ich erinnere mich, dass ich diese Frage vor ungefähr sieben Jahren gestellt habe, als ich noch ziemlich neu in der Programmierung war.

Ich war sehr vorsichtig, als ich fragte, und überraschenderweise bekam ich nicht so viel Kritik wie Sie hier. Sie haben mich jedoch in Richtung des " Drachenbuchs " geführt, das meiner Meinung nach ein wirklich großartiges Buch ist, das alles erklärt, was Sie wissen müssen, um einen Compiler zu schreiben (Sie müssen natürlich ein oder zwei Sprachen beherrschen. Je mehr Sprachen, die Sie kennen, desto besser.).

Und ja, viele Leute sagen, dass das Lesen dieses Buches verrückt ist und Sie nichts daraus lernen werden, aber ich bin damit nicht einverstanden.

Viele Leute sagen auch, dass das Schreiben von Compilern dumm und sinnlos ist. Es gibt eine Reihe von Gründen, warum die Compilerentwicklung nützlich ist:

  • Weil es Spaß macht.
  • Es ist lehrreich, wenn Sie lernen, wie man Compiler schreibt, lernen Sie viel über Informatik und andere Techniken, die beim Schreiben anderer Anwendungen nützlich sind.
  • Wenn niemand Compiler schreiben würde, würden die vorhandenen Sprachen nicht besser werden.

Ich habe nicht sofort meinen eigenen Compiler geschrieben, aber nachdem ich gefragt hatte, wusste ich, wo ich anfangen sollte. Und jetzt, nachdem ich viele verschiedene Sprachen gelernt und das Drachenbuch gelesen habe, ist das Schreiben kein so großes Problem. (Ich studiere auch Computertechnik atm, aber das meiste, was ich über Programmierung weiß, ist Autodidakt.)

Zusammenfassend ist das Drachenbuch ein großartiges "Tutorial". Aber verbringen Sie einige Zeit damit, ein oder zwei Sprachen zu beherrschen, bevor Sie versuchen, einen Compiler zu schreiben. Erwarten Sie jedoch nicht, in den nächsten zehn Jahren ein Compiler-Guru zu sein.

Das Buch ist auch gut, wenn Sie lernen möchten, wie man Parser / Dolmetscher schreibt.

Pandafox
quelle
9

"... Lass uns einen Compiler bauen ..."

Ich würde http://compilers.iecc.com/crenshaw/ von @sasb unterstützen . Vergessen Sie für den Moment, mehr Bücher zu kaufen.

Warum? Werkzeuge & Sprache.

Die erforderliche Sprache ist Pascal und wenn ich mich richtig erinnere, basiert sie auf Turbo-Pascal. Es passiert einfach so, wenn Sie zu http://www.freepascal.org/ gehen und den Pascal-Compiler herunterladen. Alle Beispiele funktionieren direkt von der Seite ~ http://www.freepascal.org/download.var Das Schöne an Free Pascal ist, dass Sie es fast jeden Prozessor oder jedes Betriebssystem verwenden können, für das Sie sich interessieren.

Wenn Sie die Lektionen gemeistert haben, probieren Sie das fortgeschrittenere " Dragon Book " ~ http://en.wikipedia.org/wiki/Dragon_book

Bootload
quelle
9

Ich beschäftige mich mit dem gleichen Konzept und habe diesen vielversprechenden Artikel von Joel Pobar gefunden.

Erstellen Sie einen Sprachcompiler für .NET Framework - nicht sicher, wohin dies geführt hat

Erstellen Sie einen Sprachcompiler für die .NET Framework - PDF-Kopie des Originaldokuments

Er diskutiert ein übergeordnetes Konzept eines Compilers und erfindet seine eigene Sprache für das .Net-Framework. Obwohl es auf das .Net Framework abzielt, sollten viele der Konzepte reproduzierbar sein. Der Artikel umfasst:

  1. Langauge Definition
  2. Scanner
  3. Parser (das bisschen interessiert mich hauptsächlich)
  4. Targeting des .Net Frameworks
  5. Code Generator

Es gibt andere Themen, aber Sie bekommen die gerechte.

Es richtet sich an Anfänger, geschrieben in C # (nicht ganz Java)

HTH

Knochen

dbones
quelle
Was bedeutet "nicht ganz Java"?
Hejazzman
haha, sorry, ich meinte es ist geschrieben für .Net, das im Prinzip Java ähnlich ist. Beide sind JIT im Stil. :)
dbones
8

Eine einfache Möglichkeit, einen Compiler zu erstellen, besteht darin, Bison und Flex (oder ähnliches) zu verwenden, einen Baum (AST) zu erstellen und Code in C zu generieren. Das Generieren von C-Code ist der wichtigste Schritt. Durch das Generieren von C-Code funktioniert Ihre Sprache automatisch auf allen Plattformen mit einem C-Compiler.

Das Generieren von C-Code ist so einfach wie das Generieren von HTML (verwenden Sie einfach print oder ein gleichwertiges Element), was wiederum viel einfacher ist als das Schreiben eines C-Parsers oder HTML-Parsers.

Peter Stuifzand
quelle
8

Aus den häufig gestellten Fragen zu comp.compilers :

"Programmieren eines Personal Computers" von Per Brinch Hansen Prentice-Hall 1982 ISBN 0-13-730283-5

Dieses leider betitelte Buch erklärt das Design und die Erstellung einer Einzelbenutzer-Programmierumgebung für Mikros unter Verwendung einer Pascal-ähnlichen Sprache namens Edison. Der Autor präsentiert den gesamten Quellcode und Erklärungen für die schrittweise Implementierung eines Edison-Compilers und eines einfachen unterstützenden Betriebssystems, die alle in Edison selbst geschrieben sind (mit Ausnahme eines kleinen unterstützenden Kernels, der in einem symbolischen Assembler für PDP 11/23 geschrieben ist; Die vollständige Quelle kann auch für den IBM PC bestellt werden.

Die interessantesten Dinge an diesem Buch sind: 1) seine Fähigkeit zu demonstrieren, wie ein vollständiges, in sich geschlossenes, sich selbst wartendes, nützliches Compiler- und Betriebssystem erstellt werden kann, und 2) die interessante Diskussion über Sprachdesign- und Spezifikationsprobleme und Handel - Offs in Kapitel 2.

"Brinch Hansen on Pascal Compilers" von Per Brinch Hansen Prentice-Hall 1985 ISBN 0-13-083098-4

Ein weiteres leichtes, theoretisches und pragmatisches Buch ist das How-to-Code-It-Buch. Der Autor präsentiert das Design, die Implementierung und den vollständigen Quellcode für einen Compiler und einen P-Code-Interpreter für Pascal- (Pascal "minus"), eine Pascal-Teilmenge mit booleschen und ganzzahligen Typen (aber keine Zeichen, Reals, untergeordneten oder aufgezählten Typen). , Konstanten- und Variablendefinitionen sowie Array- und Datensatztypen (jedoch keine gepackten, Varianten-, Mengen-, Zeiger-, namenlosen, umbenannten oder Dateitypen), Ausdrücke, Zuweisungsanweisungen, verschachtelte Prozedurdefinitionen mit Wert- und Variablenparametern, if-Anweisungen, while-Anweisungen, und Anfang-Ende-Blöcke (aber keine Funktionsdefinitionen, Prozedurparameter, goto-Anweisungen und Beschriftungen, case-Anweisungen, Wiederholungsanweisungen, für Anweisungen und mit Anweisungen).

Der Compiler und der Interpreter sind in Pascal * (Pascal "Stern") geschrieben, einer Pascal-Teilmenge, die um einige Funktionen im Edison-Stil zum Erstellen von Softwareentwicklungssystemen erweitert wurde. Ein Pascal * -Compiler für den IBM-PC wird vom Autor verkauft, aber es ist einfach, den Pascal-Compiler des Buches auf jede bequeme Pascal-Plattform zu portieren.

Dieses Buch macht das Design und die Implementierung eines Compilers einfach. Mir gefällt besonders, wie sich der Autor mit Qualität, Zuverlässigkeit und Tests befasst. Der Compiler und der Interpreter können leicht als Grundlage für ein komplexeres Sprach- oder Compilerprojekt verwendet werden, insbesondere wenn Sie schnell etwas zum Laufen bringen müssen.

Joe Snyder
quelle
8

Sie sollten sich Darius Bacons " Ichbins " ansehen , einen Compiler für einen kleinen Lisp-Dialekt, der auf C abzielt , auf etwas mehr als 6 Seiten Code. Der Vorteil gegenüber den meisten Spielzeug-Compilern besteht darin, dass die Sprache so vollständig ist, dass der Compiler darin geschrieben ist. (Der Tarball enthält auch einen Interpreter, um das Ding zu booten.)

Es gibt mehr Dinge darüber, was ich nützlich fand, um zu lernen, wie man einen Compiler auf meiner Ur-Scheme- Webseite schreibt .

Kragen Javier Sitaker
quelle
8
  1. Dies ist ein großes Thema. Unterschätzen Sie diesen Punkt nicht. Und unterschätze meinen Standpunkt nicht, ihn nicht zu unterschätzen.
  2. Ich höre das Drachenbuch ein (der?) Ausgangspunkt ist, zusammen mit der Suche. :) Werden Sie besser in der Suche, irgendwann wird es Ihr Leben sein.
  3. Das Erstellen einer eigenen Programmiersprache ist eine absolut gute Übung! Aber wissen Sie, dass es am Ende niemals für einen praktischen Zweck verwendet wird. Ausnahmen gibt es nur wenige und sehr weit voneinander entfernt.
280Z28
quelle
4
Wenn Sie das Drachenbuch nicht gelesen haben. Bitte empfehlen Sie es nicht. Haben Sie jemals einen Compiler implementiert?
Ja, wie der Name schon sagt, ist das Drachenbuch ein Monster. Sehr ausführlich, aber dennoch eine sehr gute Ressource. Ich würde es jedoch nicht für Anfänger empfehlen ...
Zachary Murray
2
@Neil: Du hast mich nicht googelt, oder? lol. blog.280z28.org Aber nein, ich habe das Buch nicht gelesen.
Sam Harwell
Ich lese es gerade (das Drachenbuch) und gleichzeitig Lex / Yacc. Ich finde das Buch ziemlich gut. Persönlich.
Simeon Pilgrim
1
Um fair zu sein, habe ich "Ich höre ..." vorangestellt. :) # 1 und # 3 sind die Punkte, die meiner Meinung nach extrem wichtig sind, aber nicht so oft erwähnt werden.
Sam Harwell
8

Der LCC-Compiler ( Wikipedia ) ( Projekthomepage ) ( github.com/drh/lcc ) von Fraser und Hanson ist in ihrem Buch "A Retargetable C Compiler: Design and Implementation" beschrieben. Es ist gut lesbar und erklärt den gesamten Compiler bis hin zur Codegenerierung.

mfx
quelle
Dies scheint eine sehr gute Ressource zu sein, danke.
Gideon
7

Python wird mit einem in Python geschriebenen Python-Compiler geliefert. Sie können den Quellcode sehen und er umfasst alle Phasen, vom Parsen über den abstrakten Syntaxbaum bis hin zum Ausgeben von Code usw. Hacken Sie ihn.

Yeruham
quelle
7

Entschuldigung, es ist auf Spanisch, aber dies ist die Bibliographie eines Kurses namens "Compiladores e Intérpretes" (Compiler und Dolmetscher) in Argentinien.

Der Kurs war von der formalen Sprachtheorie bis zur Compilerkonstruktion, und dies sind die Themen, die Sie benötigen, um zumindest einen einfachen Compiler zu erstellen:

  • Compiler Design in C.
    Allen I. Holub

    Prentice-Hall. 1990.

  • Compiladores. Teoría y Construcción.
    Sanchís Llorca, FJ, Galán Pascual, C. Editorial Paraninfo. 1988.

  • Compilerkonstruktion.
    Niklaus Wirth

    Addison-Wesley. 1996.

  • Lenguajes, Gramáticas y Autómatas. Un enfoque práctico.
    Pedro Isasi Viñuela, Paloma Martínez Fernández, Daniel Borrajo Millán. Addison-Wesley Iberoamericana (España). 1997.

  • Die Kunst des Compilerdesigns. Theorie und Praxis.
    Thomas Pittman, James Peters.

    Prentice-Hall. 1992.

  • Objektorientierte Compilerkonstruktion.
    Jim Holmes.
    Prentice Hall, Englewood Cliffs, NJ 1995

  • Compiladores. Conceptos Fundamentales.
    B. Teufel, S. Schmidt, T. Teufel.

    Addison-Wesley Iberoamericana. 1995.

  • Einführung in die Automatentheorie, Sprachen und Berechnung.

    John E. Hopcroft. Jeffref D. Ullman.
    Addison-Wesley. 1979.

  • Einführung in formale Sprachen.
    György E. Révész.

    Mc Graw Hill. 1983.

  • Analysetechniken. Ein praktischer Leitfaden.
    Dick Grune, Ceriel Jacobs.
    Impreso por los autores. 1995
    http://www.cs.vu.nl/~dick/PTAPG.html

  • Yacc: Noch ein Compiler-Compiler.
    Stephen C. Johnson
    Computer Science Technischer Bericht Nr. 32, 1975. Bell Laboratories. Murray Hill, New
    Jersey.

  • Lex: Ein Lexical Analyzer Generator.
    ME Lesk, E. Schmidt. Computing Science Technical Report Nr. 39, 1975. Bell Laboratories. Murray Hill, New Jersey.

  • lex & yacc.
    John R. Levine, Tony Mason und Doug Brown.
    O'Reilly & Associates. 1995.

  • Elemente der Berechnungstheorie.
    Harry R. Lewis, Christos H. Papadimitriou. Segunda Edición. Prentice Hall. 1998.

  • Un Algoritmo Eficiente para la Construcción del Grafo de Dependencia de Control.
    Salvador V. Cavadini.
    Trabajo Finale de Grado für obtener el Título de Ingeniero en Computación.
    Facultad de Matemática Aplicada. UCSE 2001.

eKek0
quelle
6

Kein Buch, sondern ein technisches Dokument und eine enorm unterhaltsame Lernerfahrung, wenn Sie mehr über Compiler (und Metacompiler) erfahren möchten ... Diese Website führt Sie durch den Aufbau eines vollständig eigenständigen Compilersystems, das sich selbst und andere Sprachen kompilieren kann:

Tutorial: Metacompiler Teil 1

Dies alles basiert auf einem erstaunlichen kleinen 10-seitigen technischen Papier:

Val Schorre META II: Eine syntaxorientierte Compiler-Schreibsprache

Ich habe 1970 gelernt, wie man Compiler daraus baut. Es gibt einen atemberaubenden Moment, in dem man endlich darüber nachdenkt, wie sich der Compiler selbst regenerieren kann ...

Ich kenne den Website-Autor aus meiner College-Zeit, habe aber nichts mit der Website zu tun.

Ira Baxter
quelle
Wie andere sagen, ist BIG Argument, ich denke, Sushi eine Aufgabe ist eine letzte Arbeit für Bachelor, es erfordert eine Menge von Konzepten der Mathematik, Informatik und so weiter.
Ingconti
Wenn Sie diese Themen nicht kennen, sollten Sie nicht wirklich versuchen, einen seriösen Compiler zu erstellen. Wenn Sie jedoch 2-3 Jahre Informatik-Grundausbildung (Programmierung, Datenstrukturen, Assemblersprache) haben, funktioniert das MetaII-Papier für Sie.
Ira Baxter
5

Ich mochte das Crenshaw-Tutorial auch, weil es absolut klar macht, dass ein Compiler nur ein anderes Programm ist, das einige Eingaben liest und einige ausgegebene ausgibt.

Lies es.

Arbeiten Sie daran, wenn Sie möchten, und schauen Sie sich dann eine andere Referenz an, wie größere und vollständigere Compiler wirklich geschrieben sind.

Lesen Sie On Trusting Trust , um einen Hinweis auf die nicht offensichtlichen Dinge zu erhalten, die in diesem Bereich getan werden können.

dmckee
quelle
5

Wenn Sie daran interessiert sind, einen Compiler für eine funktionale Sprache (und nicht für eine prozedurale) zu schreiben, ist Simon Peyton-Jones und David Lesters " Implementieren funktionaler Sprachen: ein Tutorial " eine hervorragende Anleitung.

Die konzeptionellen Grundlagen der Funktionsweise der Funktionsbewertung werden anhand von Beispielen in einer einfachen, aber leistungsstarken Funktionssprache namens "Core" geleitet. Zusätzlich wird jeder Teil des Core Language Compilers mit Codebeispielen in Miranda (einer reinen Funktionssprache, die Haskell sehr ähnlich ist) erklärt.

Es werden verschiedene Arten von Compilern beschrieben, aber selbst wenn Sie nur dem sogenannten Template-Compiler für Core folgen, haben Sie ein hervorragendes Verständnis dafür, wie funktionale Programmierung funktioniert.

Mark Reid
quelle
5

Sie können BCEL verwenden von der Apache Software Foundation verwenden. Mit diesem Tool können Sie Assembler-ähnlichen Code generieren, aber es ist Java mit der BCEL-API. Sie können lernen, wie Sie Zwischensprachencode (in diesem Fall Bytecode) generieren können.

Einfaches Beispiel

  1. Erstellen Sie eine Java-Klasse mit dieser Funktion:

    public String maxAsString(int a, int b) {
        if (a > b) {
            return Integer.valueOf(a).toString();
        } else if (a < b) {
            return Integer.valueOf(b).toString();
        } else {
            return "equals";
        }
    }
    

Führen Sie nun BCELifier mit dieser Klasse aus

BCELifier bcelifier = new BCELifier("MyClass", System.out);
bcelifier.start();

Sie können das Ergebnis auf der Konsole für die gesamte Klasse sehen (wie der Bytecode MyClass.java erstellt wird). Der Code für die Funktion lautet:

private void createMethod_1() {
  InstructionList il = new InstructionList();
  MethodGen method = new MethodGen(ACC_PUBLIC, Type.STRING, new Type[] { Type.INT, Type.INT }, new String[] { "arg0", "arg1" }, "maxAsString", "MyClass", il, _cp);

  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load first parameter to address 1
  il.append(InstructionFactory.createLoad(Type.INT, 2)); // Load second parameter to adress 2
    BranchInstruction if_icmple_2 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPLE, null); // Do if condition (compare a > b)
  il.append(if_icmple_2);
  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load value from address 1 into the stack
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_13 = il.append(InstructionFactory.createLoad(Type.INT, 1));
  il.append(InstructionFactory.createLoad(Type.INT, 2));
    BranchInstruction if_icmpge_15 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPGE, null); // Do if condition (compare a < b)
  il.append(if_icmpge_15);
  il.append(InstructionFactory.createLoad(Type.INT, 2));
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_26 = il.append(new PUSH(_cp, "equals")); // Return "equals" string
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  if_icmple_2.setTarget(ih_13);
  if_icmpge_15.setTarget(ih_26);
  method.setMaxStack();
  method.setMaxLocals();
  _cg.addMethod(method.getMethod());
  il.dispose();
}
timaschew
quelle
5

Hier gibt es viele gute Antworten, daher dachte ich, ich würde der Liste nur noch eine hinzufügen:

Ich habe vor mehr als einem Jahrzehnt ein Buch namens Project Oberon bekommen, das einen sehr gut geschriebenen Text auf dem Compiler enthält. Das Buch zeichnet sich wirklich dadurch aus, dass die Quelle und die Erklärungen sehr praktisch und lesbar sind. Der vollständige Text (Ausgabe 2005) wurde als PDF zur Verfügung gestellt, sodass Sie ihn jetzt herunterladen können. Der Compiler wird in Kapitel 12 erläutert:

http://www.ethoberon.ethz.ch/WirthPubl/ProjectOberon.pdf

Niklaus Wirth, Jürg Gutknecht

(Die Behandlung ist nicht so umfangreich wie sein Buch über Compiler)

Ich habe mehrere Bücher über Compiler gelesen, und ich kann das Drachenbuch unterstützen. Die Zeit, die ich für dieses Buch aufgewendet habe, ist sehr lohnenswert.

tovare
quelle
4

Dieses Buch ist bisher nicht in der Liste enthalten:

Grundlagen des Compilerdesigns (Torben Mogensen) (Fakultät für Informatik, Universität Kopenhagen)

Ich bin auch daran interessiert, etwas über Compiler zu lernen und plane, in den nächsten Jahren in diese Branche einzusteigen. Soweit ich sehen kann, ist dieses Buch das ideale Theoriebuch, um Compiler zu lernen. Es ist KOSTENLOS zu kopieren und zu reproduzieren, sauber und sorgfältig geschrieben und wird Ihnen in einfachem Englisch ohne Code zur Verfügung gestellt, präsentiert aber dennoch die Mechanik anhand von Anweisungen und Diagrammen usw. Einen Blick wert.

magneto12321
quelle
Fügte es der Liste hinzu danke :)
Anton