PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie baut man einen Compiler für beliebige Sprachen?


mekakic
2008-07-29, 14:28:45
Hallo,

ich stehe aktuell vor einem Problem, daß ich für die Eingabesprachen A und B eben eine Art Compiler bauen muß, der die Worte und Grammatik für die jeweilige Sprache in die Ausgabesprachen C, D, oder E überführt. Da es sich alles um Maschinensprachen/Kommandos handelt, ist die Grammatik vergleichsweise einfach bzw. lange nicht so komplex wie in Programmiersprachen oder menschlichen Sprachen, der Hauptteil dabei ist die Umsetzung eines Wortes in eine entsprechend andere Sprache.

Wenn ich jetzt für jedes Kommando eine Klasse habe, wird das Riesengroß und schlecht anzupassen und zu warten. Ich habe da überlegt, ob man mit Techniken aus dem Compilerbau da nicht weiterkommt. Eben diese Übergänge zwischen den Sprachen vergleichsweise abstrakt zu beschreiben und nicht stumpf für jede Sprachkombination Eingangs-Wort in ein Übersetztes-Wort zu überführen. Eben mit dem Ziel auch in Zukunft die Sprachen zu erweitern und weitere Sprachen vergleichsweise einfach dem System hinzuzuführen.

Jetzt also die Preisfrage: wie baue ich mir bloß einen abstrakten Compiler für beliebige Sprachen?

Der_Donnervogel
2008-07-29, 16:18:56
Ich bin da auf dem Gebiet auch kein Experte, kann also sein dass es noch viel bessere Möglichkeiten gibt. Eine Idee wäre eine Zwischensprache einzuführen, in die alle anderen Sprachen übersetzen (also wie zB die .Net-Sprachen alle auf die CIL abbilden), bzw. aus der diese erzeugt werden können. Auf diese Art kann man auch neue Sprachen recht einfach ergänzen, da man dann nur einen Compiler braucht der von der Sprache in die Zwischensprache übersetzt (bzw. umgekehrt).

Das ganze kann man vermutlich noch etwas erleichtern, wenn man sich die Parser zB mit Yacc oder JavaCC generieren lässt (vor allem beim Weg Zwischensprache -> Zielsprache). Das Hauptproblem an dem Ansatz ist wohl eine geeignete Zwischensprache zu definieren, die einerseits mächtig genug ist alle Fälle abzudecken, gleichzeitig aber möglichst einfach sein sollte. :ugly:

Trap
2008-07-29, 17:39:22
Grundsätzlich sieht es immer so aus:
A -> B (-> B) -> C

Mit A als Quellsprache, C als Zielsprache und B als "intermediate representation". Für die IR gibt es meist keine Textrepräsentation, sondern es sind wie du schon probiert hast Klassen oder structs, die Bäume oder Graphen bilden. Der Schritt B->B sind irgendwelche zielunabhängigen Optimierungen, die werden bei allen sinnvollen Compilern nur in der IR-Form durchgeführt.

GCC ist so ein Compiler, der verschiedene Quell- und Zielsprachen unterstützt. C, C++, Objective-C, Fortran, Java und Ada als Quellsprachen und dutzende mögliche Maschinensprachen als Zielsprachen.
Die Dokumentation zur intermediate representation von GCC (http://gcc.gnu.org/onlinedocs/gccint/index.html#toc_Tree-SSA ) zeigt schnell, dass du nicht der einzige bist, bei dem die IR sehr komplex wird.

Für die Ein- und Ausgabesprachen braucht man nicht unbedingt eine explizite Darstellung im Programm, die braucht man nur für komplexere Umformungen, also höchstens für die Ausgabesprachen (wenn man Maschinencodeoptimierung machen möchte).