Wie schreibe ich einen... Compiler? Interpreter?
-
Hallo
Keine Angst, ich will nicht noch eine Sprache entwickeln, dazu bin ich noch viel zu schlecht, aber ich frage mal interessenhalber (nach Links oder so).
Wie schreibt man einen Compiler? Ich habe generell keine Ahnung in was da jetzt übersetzt wird, Assembly? Oder wie das gespeichert wird.Wie schreibt man einen Interpreter? Da gibt es ja dutzende Möglichkeiten, aber die meisten werden wohl kaum performant genug sein, gibt es da irgendwelche Optimale, die bereits ermittelt wurden? Wie kann man so etwas effizient programmieren?
-
sehr einfach geschrieben und gut nachvollziehbar für den einstieg:
ein artikel aus dem magazin zum thema compilerbau.
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Generell zum Thema:
http://www.python-forum.de/topic-12711.html
http://www.python-forum.de/topic-13027.html
-
Den windner aus dem ersten Thread kenne ich recht gut und weiß aus zuverläßiger Quelle, daß er alle Antworten im wizard book gefunden hat. Und noch viel mehr.
-
Da gibt es ja dutzende Möglichkeiten, aber die meisten werden wohl kaum performant genug sein, gibt es da irgendwelche Optimale, die bereits ermittelt wurden? Wie kann man so etwas effizient programmieren? [über Interpreter]
Da fällt mir Knuth ein: premature optimization is the root of all evil.
Natürlich sollte man keinen Unsinn im Architektur-Entwurf machen, aber am Anfang zu viele Gedanken an die Laufzeit zu verschwenden kann auch schlecht sein.
Nehmen wir als Beispiel eine Sprache X, die wir soeben erfunden haben. X sei interpretierbar und (für Registermaschinen) kompilierbar. Also müssen wir einen Interpreter und einen Compiler schreiben.
Meine Lieblingsstrategie geht dann so:
Wir schreiben zuerst einen Interpreter. Dazu brauchen wir eine Sprache, die es schon gibt, sagen wir: C. Das ist nicht weiter schwierig, wenn wir uns bemühen, einfach nur richtig auszuwerten. Die Laufzeit wird freilich eine Obergrenze haben, die nicht an C-Programme heran kommt.Wenn der Interpreter läuft, können wir uns an den Compiler machen. Dazu brauchen wir eine Registermaschine. Wir können entweder unseren Prozesser nehmen (da werden wir eben beim Testen viele System-Abstürze produzieren), oder wir nehmen ein Programm, das einen Prozessor simuliert. Ist dann wiederum langsamer, aber einfacher zu testen. Auch in SICP Kap. 5 wird eine einfache Registermaschine entworfen.
Dann schreiben wir den Compiler, und zwar in X (!). Wenn der Compiler fertig ist, laden wir den Interpreter, führen den Compiler aus und geben ihm seinen eigenen Quellcode als Eingabe (das ist der Moment, an dem Sussman den Hut aufsetzt). Das Ergebnis ist ein kompilierter Compiler, der sehr schnell läuft und sehr schnelle Programme erzeugt.
Jetzt können wir mit Optimierungen anfangen, und wenn wir brav sind, stellen wir die "Mutter"-Sprache C bald in den Schatten.
-
bgdnoy schrieb:
Jetzt können wir mit Optimierungen anfangen, und wenn wir brav sind, stellen wir die "Mutter"-Sprache C bald in den Schatten.
lol, sehr schön ausgedrückt
aber ich denke ist einfacher basic in den schatten zu stellen
-
bgdnoy schrieb:
Da fällt mir Knuth ein: premature optimization is the root of all evil.
Ob man das hier aber anwenden soll weiß ich aber nicht. Der Satz sagt ja etwas über das Programm das man schreibt aus und nicht über das welches man übersetzt. Wenn du da nicht von Anfang an mit denkst kommst du schnell in eine Situation in welcher eine Gewisse Optimierung gar nicht mehr oder nur noch mit erheblichem Aufwand implementiert werden können.
bgdnoy schrieb:
Wir können entweder unseren Prozesser nehmen (da werden wir eben beim Testen viele System-Abstürze produzieren),
Solange dein BS etwas taubt und du über einen Prozessor mit Segmentierung und geschützten Modus verfügst (so gut wie alle Desktoprechner heutzutage erfüllen diese Vorraussetzung) solltest du keinen einen System-Absturz erleben.
bgdnoy schrieb:
Das Ergebnis ist ein kompilierter Compiler, der sehr schnell läuft und sehr schnelle Programme erzeugt.
Wo du das jetzt draus schlussfolgerst hab ich nicht verstanden. Wieso ist ein Compiler mit der Vorgehensweise immer schnell und produziert immer schnelle Programme? Das hängt immer noch einzig und alleine von dem ab was du programmierst.
-
Ben04 schrieb:
Wo du das jetzt draus schlussfolgerst hab ich nicht verstanden. Wieso ist ein Compiler mit der Vorgehensweise immer schnell und produziert immer schnelle Programme? Das hängt immer noch einzig und alleine von dem ab was du programmierst.
Gemeint ist wohl, dass der Compiler ja nun übersetzt wurde und damit nicht mehr nur interpretiert. Was das allerdings an der Qualität der damit übersetzten Programme ändert ist mir auch nicht klar.
btw: belated pessimization is the leaf of no good. -- Performance ist eine Designfrage und nichts was man nachher noch dazubasteln kann.
-
Performance ist eine Designfrage und nichts was man nachher noch dazubasteln kann.
Ich würde sagen die Möglichkeit zu guter Performance ist eine Designfrage. Die erste Implementierung muss deswegen aber lange noch nicht performant sein.
-
Hier: Etwas Theorie zum Thema. (Zwar für Haskell aber das ändert ja am Prinzip nichts)
-
-
Das Ergebnis ist ein kompilierter Compiler, der sehr schnell läuft und sehr schnelle Programme erzeugt.
Wo du das jetzt draus schlussfolgerst hab ich nicht verstanden. Wieso ist ein Compiler mit der Vorgehensweise immer schnell und produziert immer schnelle Programme? Das hängt immer noch einzig und alleine von dem ab was du programmierst.
So tiefgründig hab ich das gar nicht gemeint. Ich hab gemeint, daß, wenn man *ein* Programm hat, man sich entscheiden muss, ob man es im Interpreter laufen lässt oder vorher übersetzt. Ganz naiv habe ich jenes als "langsam" und dieses als "schnell" angesprochen.