Eigener Compiler
-
Ben04 schrieb:
Wenn die Signatur jeder Funktion eindeutig aus dem Aufruf hervor geht, dann kannst du die Funktion implizit deklarieren
Das sollte doch bei Funktionen mit Parametern so gut wie nie möglich sein, oder?
Selbst bei trivialen Aufrufen wiechar c; foo(c);
ist die Signatur von foo noch nicht bekannt.
-
this->that schrieb:
Ben04 schrieb:
Wenn die Signatur jeder Funktion eindeutig aus dem Aufruf hervor geht, dann kannst du die Funktion implizit deklarieren
Das sollte doch bei Funktionen mit Parametern so gut wie nie möglich sein, oder?
Bei dynamisch typisierten Sprachen (z.b. PHP, Python, ...) ist es meistens der Fall da es nur einen generischen Typ gibt. Auch frühe C Versionen kannten nur ints (damals hießen die aber noch anders). Daher rührt auch die C-Regel alles unbekannte erstmal als int anzusehen.
Wenn es keine impliziten Konvertierungen gibt welche Code erzeugen geht es auch. String nach int ist problematisch wogegen Derived* nach Base* kein Problem darstellt. Man fasst erstmal alles als Zeiger auf und kuckt nachher, wenn dann alle Funktionen vorliegen, ob es überhaupt eine passende gibt.
-
Vielen Dank für eure Antworten!
Also die Signatur lässt sich bei meiner Sprache nicht aus dem Aufruf ermitteln. Und für eine automatische Erkennung/Konvertierung sind die Datentypen leider zu unterschiedlich. Aber wenn es nicht so sehr auf die Geschwindigkeit geht, werde ich wohl den Code einfach zweimal parsen. Ist wenigstens einfach zu implementieren.
-
Wieso den Quelltext zweimal parsen? Generierst du direkt Code, baust du keinen AST auf?
-
Hm, daran habe ich noch garnicht gedacht. Bei Wikipedia habe ich mal nachgeschaut (http://en.wikipedia.org/wiki/Parse_tree), allerdings verstehe ich nicht, wie ich den Baum dann abarbeiten soll. Was soll mein Parser machen, wenn er zum Beispiel einen Knoten mit zwei Unterknoten hat?
Bisher dachte ich immer, dass ich die Tokens einfach in einer Liste speichere und die dann halt zweimal parse.
-
Ich bin ein wenig überrascht. Ich hätte jetzt gedacht, dass man von solchen Dingen Ahnung haben muss, um einen Compiler entwerfen zu können.
Wie funktioniert denn dein Compiler in etwa?
-
Du solltest Dich mal mit Compilerbau beschäftigen...
http://cs.uni-muenster.de/Studieren/Scripten/Lippe/CompilerbauI/cbI.pdf
http://users.informatik.haw-hamburg.de/~voeller/fc/comp/comp.html
-
Bashar schrieb:
Ich bin ein wenig überrascht.
du lügst doch. du bist viel zu lange hier, um davon ehrlich überrascht zu sein.
Bashar schrieb:
Ich hätte jetzt gedacht, dass man von solchen Dingen Ahnung haben muss, um einen Compiler entwerfen zu können.
man kann sich aber auch einiges zusammenreimen und neu erfinden. obs am ende gut wird, steht auf einem anderen blatt.
-
Danke für die Links!
Naja, ich bin noch nicht besonders weit mit meinem Compiler.
Ich habe im Internet schon einige "Tutorials" oder andere Informationen zum Compilerbau gefunden, allerdings werden da immer nur Sprachen behandelt, die sich in einem Pass übersetzen lassen. Mein Sprache benötigt ja mehrere Läufe, was die ganze Sache schon komplizierter macht. Außerdem weiß ich nicht, wie zum Beispiel das Prinzip der Symboltabelle aussieht. Soll schon der Lexer Einträge in die Tabelle machen oder erst der Parser? Soll ich erst den kompletten Quelltext scannen und zwischenspeichern und dann erst parsen?
Ich hoffe, jemand kann da etwas Licht ins Dunkel bringen.
-
http://magazin.c-plusplus.net/artikel/Compilerbau
Ich würde die parse_* Funktionen abwandeln welche den Rumpf der Funktionen einlesen, so dass sie einen AST zurück geben. Du erhälst so einen AST per Funktion welcher alle Informationen enthält, welche nötig sind um den ASM Code zu erzeugen.