Wie kann man einen Compiler programmieren?

8 Antworten

Man Müsste ja beim ersten Compiler programmieren eine Prgrammiersprache und die Maschienensprache beherrschen oder nicht?

Korrekt. Das muss man aber auch bei modernen Compilern noch beides können!

Wie funktioniert das?

Bei modernen Programmiersprachen besteht die Toolkette aus mehreren Programmen (Compiler, Assembler, Linker). Es ist jedoch auch möglich, einen Compiler zu schreiben, der direkt (ohne Assembler und Linker) ein lauffähiges Programm erzeugt.

Ein Compiler liest eine Quellcodedatei ein und schreibt die entsprechenden Maschinencode-Instruktionen in die Binärdatei hinein. (Ich selbst habe mehrere Compiler geschrieben.) Das Ganze ist wirklich nicht so einfach.

Ich bin bis jetzt immer rekursiv vorgegangen. Beispiel:

meineFunktion1(1, 2, meineFunktion2(3), 4);

Ich schreibe eine Funktion zum Compilieren von Ausdrücken. Beim oben stehenden Ausdruck wird sich die Funktion viermal sich selbst aufrufen, um die Ausdrücke "1", "2", "meineFunktion2(3)" und "4" zu compilieren. Für den dritten Ausdruck wird die Funktion sich ebenfalls selbst aufrufen, um "3" zu compilieren. Am Schluss wird der Maschinencode für den eigentlichen Funktionsaufruf geschrieben.

Je nach dem, wie die Calling-Convention (z.B. "Pascal-Convention") aussieht, ist es dann recht einfach, das entsprechende Äquivalent zum Programmcode als Maschinencode zu finden.

So entspricht ein einfaches Ganzzahl-Argument nur einer "pushl $n"-Instruktion. Ein Funktionsaufruf einem "call Funktionsname" und falls der Rückgabewert der Funktion weiterverwendet wird muss noch ein "push %eax" dazu.

Dadurch würde der oben von mir beschriebene Ansatz zu folgendem Assembler-Code führen:

pushl $1
pushl $2
pushl $3
call meineFunktion2
push %eax
pushl $4
call meineFunktion1

Beim Assembler-Code entspricht eine Zeile genau einer Anweisung in Maschinencode, so dass es auch möglich wäre, direkt Maschinencode zu schreiben.

Da hat sich mir die Frage gestellt wie wird sowas den programmiert.

Falls nun die Frage nach dem allerersten Compiler aufkommt:

Bei modernen Betriebssystemen sind die Dateiformate (z.B. .EXE bei Windows) so komplex, dass es wohl nicht möglich gewesen wäre, den "ersten Compiler" zu schreiben. Man hat den ersten Compiler für Windows also unter MS-DOS (mit einem Compiler für MS-DOS) geschrieben, den ersten Compiler für MS-DOS mit einem älteren Betriebssystem und einem Compiler, der auf dem älteren Betriebssystem lief usw.

Die ersten Computer hatten Lochstreifen als Eingabemedium. Solche Streifen hat man bereits bei Fernschreibern benutzt, bevor es Computer gab. Man konnte die Streifen also mit einem Fernschreiber beschreiben. Die Computer waren so gebaut, dass die Maschinensprache-Befehle als Textdatei schreibbar waren. So hat der Text "A12345" dem Befehl "Addiere 12345" entsprochen. (Bei Computern mit Prozessoren ist dies nicht mehr so!) Man konnte also direkt mit dem Fernschreiber Maschinensprache-Befehle tippen! Irgendwer hat dann einen Compiler (in Maschinensprache) geschrieben.

Ich habe da noch eine Frage:

Ich bin am Anfang und bringe mir grad selber C# bei. Mit welcher Sprachart lässt sich die Maschinensprache mit menschlich(en) Sprachen/Spracharten vergleichen (wie jetzt z.B. Blindenschrift, oder ähnliches)?

Selber kann man das nicht so leicht machen , jedenfalls nicht als Anfänger

Ich hab auch nicht geschrieben das ich einen programmieren will

Franz1957  28.01.2014, 13:04

Deine Frage ist ja trotzdem berechtigt. Überhaupt sollte jeder, der programmiert, wenigstens in Grundzügen versteht, wie Compiler "denken". So kommt man leichter mit ihnen zurecht, z.B. auch mit ihren Fehlermeldungen.

0
Man Müsste ja beim ersten Compiler programmieren eine Prgrammiersprache und die Maschienensprache beherrschen oder nicht?

Korrekt. Wir hatten das an der FH als 2-Semester-Arbeit. Der Prof hatte eine fiktive Sprache vorgegeben. Nichts allzu Schwieriges, nur ein paar Befehle zum Addieren, Substrahieren, Multiplizieren, Werte speichern, Werte laden, Eingabe und Ausgabe etc.

Als Ergebnis sollte aus einem Programm dieser fiktiven Sprache ein korrektes Pascalprogramm entstehen, welches nicht nur das korrekte Ergebnis liefert sondern auch intern exakt die Rechen- und Speicheroperationen des Programm der fiktiven Sprache abbildet.

Ein wichtiger Teil ist ein Parser, der das Programm in der ersten Sprache in seine einzelnen Bestandteile zerlegt (Da gibt es so manche Tücke, v.a. wenn es um verschachtelte mathematische Ausdrücke geht). Diese werden dann in entsprechende Konstrukte der Zielsprache übersetzt / kompiliert.

So ähnlich funktioniert das auch mit richtigen Compilern, welche eine Hochsprache in Maschinensprache übersetzen.

Frischmilch  28.01.2014, 08:53

Ich nehme an, ihr habt ein "Cross-Compiler" gebastelt. Haben wir damals auch gemacht, Zielsprache war bei uns tatsächlich auch Pascal.

Und um es sich noch etwas einfacher zu machen, haben wir LEX (oder FLEX) und YACC (oderBison) eingesetzt. Mein Tipp für Compilerbau: Automaten (vor allem Kellerautomaten) und Grammatiken (natürlich von Computersprachen ;-)) anschauen. Allerdings würde ich empfehlen, erst nach dem "Grundkurs" einer Sprache damit anzufangen. Dann tut man sich warscheinlich etwas leichter, weil man schon erste Erfahrungen mit einer Computersprache hat.

0
CSANecromancer  28.01.2014, 11:49
@Frischmilch

Ich nehme an, ihr habt ein "Cross-Compiler" gebastelt.

Jup.

Mein Tipp für Compilerbau: ...

Vielen Dank, aber davon habe ich mich schon lange verabschiedet und mich mehr den Datenbanken zugewandt. :)

0