Parser - wie aufbauen?
-
Mahlzeit,
ich schreibe gerade an einer Skriptsprache und bin am Überlegen, wie ich den Parser am besten realisiere. Er braucht auf jeden Fall zwei Durchläufe, weil ich Forward-Deklarationen vermeiden will.
Ansatz 1 wäre, beim ersten Durchlauf einen kompletten Strukturbaum zu erstellen, alle Bezeichner zu vermerken und im zweiten dann den Strukturbaum zu übersetzen.
Die andere Idee war, einfach zweimal über die Tokens zu laufen.Die erste Möglichkeit hätte den Vorteil, dass ich recht einfach andere Sprachdialekte zusätzlich implementieren könnte. Bei der zweiten würde ich mir dagegen den kompletten Strukturbaum sparen, was den Compiler natürlich ordentlich beschleunigen würde.
Der Code sollte möglichst kompakt und wartbar bleiben.
Wozu würdet ihr mir raten?Grüße
trion
-
Betrifft zwar nicht direkt dein Problem, aber als Parserframework könntest du dir vielleicht Boost.Spirit anschauen (wegen Kompaktheit und Wartbarkeit). Hier gibt es zwei Artikel dazu:
Boost::Spirit – Eine Einführung
Ein Überblick über Spirit2
-
Danke für den Tipp, aber mir ist es aus Übersichtsgründen lieber, den kompletten Compiler inkl. Standardbibliothek selbst zu schreiben. Die STL bzw. Boost ist mir generell nicht sehr sympathisch, ich bin einfach den Bibliotheks-"Stil" von .NET gewöhnt.
Der Tokenizer ist mittlerweile komplett, und vom Parser ist auch schon ein beträchtlicher Teil geschrieben, ein Parsergenerator kommt für mich also nicht in Frage.
-
Da hast du dir aber was vorgenommen
Compilerbau
Sehr interessant was Ben04 da geschrieben hat. Am Ende kann man sogar Funktionen, If-Abfragen und Schleifen benutzen.
-
trion schrieb:
Die STL bzw. Boost ist mir generell nicht sehr sympathisch, ich bin einfach den Bibliotheks-"Stil" von .NET gewöhnt.
Damit rennst du über kurz oder lang nur gegen Wände. In jeder Sprache programmiert man anders. Probiere nicht in Sprache x wie in Sprache y zu programmieren. Das betrifft auch den Aufbau von Bibliotheken.
Sowas braucht Zeit, man muss sich umgewöhnen, aber man sollte dies so schnell wie möglich tun und probieren ins kalte Wasser zu springen. Aus eigener Erfahrung kann ich dir sagen, dass es einem deutlich mehr bringt.Grüssli
-
trion schrieb:
Der Tokenizer ist mittlerweile komplett...
Du wirst du eine Ewigkeit fehler finden und dran rumbauen bis es dann komplett genannt werden darf. Kann man auch aus dem Weg gehen indem man fertige Lösungen nimmt, die von tausenden Entwicklern getestet und benutzt werden.
Aber manche Leute haben ja Spaß an sowastrion schrieb:
Die STL bzw. Boost ist mir generell nicht sehr sympathisch
Sympathie bedarf es eben erstmal einer richtigen Kennenlernphase. Seine besten Freunde lernt man auch nicht im Vorbeigehen kennen.
-
Gewisse Boost-Bibliotheken sind sicher nicht jedermanns Sache, man sollte sie auch keinem C++-Programmierer aufzwingen. Hingegen gehört die STL zur Standardbibliothek und zu jenen Werkzeugen, die man tagtäglich braucht und die einem enorm viel Arbeit abnehmen. Mit der Standard Template Library sollte man sich schon früher oder später anfreunden, wenn man produktiv C++ programmiert.
-
Dravere schrieb:
trion schrieb:
Die STL bzw. Boost ist mir generell nicht sehr sympathisch, ich bin einfach den Bibliotheks-"Stil" von .NET gewöhnt.
Damit rennst du über kurz oder lang nur gegen Wände. In jeder Sprache programmiert man anders. Probiere nicht in Sprache x wie in Sprache y zu programmieren.
Dann wundert's mich aber, wie es sein kann, das fast jedes größere Projekt eine eigene Bibliothek beinhaltet und nicht die STL verwendet.
brotbernd schrieb:
Du wirst du eine Ewigkeit fehler finden und dran rumbauen bis es dann komplett genannt werden darf.
Genau das Rumbauen ist der Grund dafür, dass ich ihn selber schreib.
brotbernd schrieb:
Aber manche Leute haben ja Spaß an sowas
Jo, ich z.B.
Ich werd für meine Arbeit so und so nicht bezahltDas ist jetzt aber mal schwer OT.
Ohne unhöflich wirken zu wollen, aber das hat mit meinem Thema wirklich nichts zu tun. Mir gings in dem Thread einzig und allein um die Frage in Post #1, nicht um meinen Programmierstil.
Ich erlaube mir zu behaupten, dass ich genug Erfahrung habe, um solche Glaubensfragen selbst zu beantworten.Danke Freaky für den Link, ich werd mir das durchlesen.
-
Du kannst einen Parserbaum inkl. Symboltabelle und Co aufbauen und diese bei der Codegenerierung überprüfen lassen. Zu diesem Zeitpunkt müssten auch später deklarierte Funktionen, etc. in der Symboltabelle vollständig eingetragen sein.
Der Nachteil bei diesem Prozess ist, dass Fehler erst zu einem späteren Zeitpunkt entdeckt werden, nämlich bei der Codegenerierung oder bei einer interpretrierten Sprache zur Ausführungszeit. Letzteres sollte man auf keinen Fall anstreben, da wäre es dann sogar sinnvoller erst Zwischencode zu erzeugen.
-
Mit flex sowie yacc/bison kannst du dir autom. einen Parser bauen lassen den du nur noch deinem Programm hinzulinken musst.
MfG SideWinder
-
.... schrieb:
Du kannst einen Parserbaum inkl. Symboltabelle und Co aufbauen und diese bei der Codegenerierung überprüfen lassen. Zu diesem Zeitpunkt müssten auch später deklarierte Funktionen, etc. in der Symboltabelle vollständig eingetragen sein.
Das war mein erster Gedanke.
.... schrieb:
Der Nachteil bei diesem Prozess ist, dass Fehler erst zu einem späteren Zeitpunkt entdeckt werden, nämlich bei der Codegenerierung oder bei einer interpretrierten Sprache zur Ausführungszeit.
Die Codegenerierung (Bytecode) folgt bei mir eigentlich direkt auf das Parsen. Ich hab mir das so vorgestellt, dass erst vom Quellcode und allen Abhängigkeiten Symboltabellen erstellt werden und anschließend der Code selbst übersetzt wird.
Die Frage ist halt, ob ein Parserbaum überhaupt sinnvoll ist? Bringt es Nachteile, den Sourcecode beim Parsen (2. Durchlauf) direkt zu übersetzen?
-
@SideWinder: Wurde davor schon diskutiert, trotzdem danke.
-
.... schrieb:
Der Nachteil bei diesem Prozess ist, dass Fehler erst zu einem späteren Zeitpunkt entdeckt werden, nämlich bei der Codegenerierung oder bei einer interpretrierten Sprache zur Ausführungszeit.
Die Codegenerierung (Bytecode) folgt bei mir eigentlich direkt auf das Parsen. Ich hab mir das so vorgestellt, dass erst vom Quellcode und allen Abhängigkeiten Symboltabellen erstellt werden und anschließend der Code selbst übersetzt wird.
Die Frage ist halt, ob ein Parserbaum überhaupt sinnvoll ist? Bringt es Nachteile, den Sourcecode beim Parsen (2. Durchlauf) direkt zu übersetzen?[/quote]
Ja, du kannst schlecht bis gar nicht optimieren. In der Regel lohnt sich der Aufbau eines solchen Baus immer. Du trennst den Prozess des Parsings von der Codegenerierung. Das wirkt sich auch positiv auf die Wartbarkeit und auch Übersichtlichkeit aus. Du kannst besser optimieren und letztendlich kannst du auch dein Problem mit der Forward Declaration lösen. Ich sehe da nur Vorteile.
-
Stimmt. Dann werde ich das wohl so machen.
Danke!