dynamischen AST aus token stream erzeugen
-
Hallo,
ich entwickel derzeit ein System um Codebäume einer C++ ähnlichen Syntax zu erzeugen jedoch nicht Objektorientiert. Den Tokenizer habe ich bereits gebaut und dieser funktioniert auch, ich hänge jetzt allerdings beim Erzeugen des Syntaxbaums an einigen Logikproblemen fest. Dabei ist das weniger der Sprache geschuldet als eher der ganzen Macromechanik.
Zuerst einmal die Frage wie der Parser arbeitet und ob der AST bereits den Vorverarbeiteten code enthält oder ob dieser erst in der Erzeugung des Bytecodes in die jeweilige Bahn gelenkt wird.
Ist es sinnvoll vorverarbeitete AST zu speichern oder sollte ich die ASTs lieber direkt auch schon mit den jeweiligen Weichen fest erzeugen, sodass ein Umschalten der ein oder anderen Bedingung noch bei der Weiterverarbeitung möglich ist?
Nehmen wir an es gibt eine Codezeile
#ifdef XY int func1(int x, int y) { if(x == 0 || y == 0) return -1; #else int func1(int x) { #endif /*.. code here ..*/ return x; }sollte das bereits verarbeitet sein oder kann sowas auch als dynamischen Baum abspeichern?
Wenn ja, wie müsste ich das von der Datenhaltung her Anstellen?
Schonmal herzlichen Dank für konstruktive Beiträge!
-
Kalaeido schrieb:
Zuerst einmal die Frage wie der Parser arbeitet und ob der AST bereits den Vorverarbeiteten code enthält oder ob dieser erst in der Erzeugung des Bytecodes in die jeweilige Bahn gelenkt wird.
Versteh ich nicht. Bezieht sich das jetzt auf die "Macros" in deiner Sprache, die du parsen willst?
Die Frage ist im Endeffekt, ob du einen AST aufbaust, der den kompletten Code, inklusive "Präprozessordirektiven" enthält, oder nur den Code, der nach dem Präprozessorlauf rauskommt?
Wenn ja, dann kommts drauf an, ob diese Macros in irgendeiner Form dynamisch sind oder sein sollten. Wenn die statisch sind, würde ich die nicht in den AST aufnehmen. Je weniger nutzlose Informationen der enthält, desto besser. Wenn du aber aus irgendeinem Grund die Informationen doch haben willst, dann musst du das eben selber wissen
Ich denke, der Parser kann die Macros auswerten und dann dementsprechend den AST generieren.
-
Hallo Mechanics,
Macros sein jetzt mal so dahingestellt, es geht mir in erster Linie um diese #if/#ifdef/#ifndef/#elif/#else codeweichen die man ja dann doch ganz gerne mal benutzt.
Konkret, das soll ein Präparser für GlSl Shadercode sein, von daher wäre es schon ganz nützlich wenn man z.b. so sachen hätte wie
#if AMD ... #if NVidia ...usw, da der Weg Klartext -> Tokenizer -> Parser -> Optimizer -> GL API deutlich weiter (und zeitaufwändiger ist als z.b. AST -> Optimizer -> GL API und auch die Dateigröße eines vorverarbeiteten AST kleiner ist als es bei Klartext der fall sein würde.
Da das aber im Momment absolut außerhalb meines Wissensgebietes liegt ist ersteinmal die generelle Frage
- Wie handhaben das andere Compiler/Parser/Sprachen wie etwa C/C++ die GlSl sehr ähneln
und dann natürlich wieviel Aufwand das wäre, welche Ansatze es da gäbe das so zu machen etc.
Macrosupport stelle ich jetzt ersteinmal hinten an, Hauptaugenmerk liegt im Momment auf den Präprozessordirektiven #if und konsorten so wie #include
Eben weil ich mich damit aktuell erst beschäftige die Frage ob das überhaupt sinnvoll ist und ob das einen so großen Vorteil bringt zur Laufzeit des Programms noch einzelne Parameter ändern zu können. Spontan fallen mir da Platformen und Quallity-settings ein wobei man diese auch mit separaten Dateien lösen könnte

-
Ob das Macros, oder #if #else sind ist eigentlich egal, ich bezog mich ja auf den Präprozessor.
Es kommt hier hauptsächlich drauf an, was dein "Compiler" erzeugen soll und wann diese Informationen ausgewertet werden. Es kann durchaus beides Sinn machen. Wenn dein Programm auf dem Zielsystem übersetzt wird, weißt du schon, ob das AMD oder NVIDIA ist, da brauchst du die Informationen nicht im AST und kannst einen kleineren AST generieren. Wenn du aber auf irgendeinem System vorher dein Programm vorkompilierst, dann steht die Information erst auf dem Zielsystem zur Verfügung und es müssen beide Varianten im AST (oder in dem Code, der daraus generiert wird) enthalten sein.
Konkret bei C und C++ kümmert sich der Präprozessor um sowas, der richtige Parser sieht das gar nicht mehr.
-
Hat sich erledigt, Danke!
Habe die Macro-Maker jetzt als tokens in den Baum geladen ohne diese in der Struktur separat zu verankern, daher läuft das Validieren jetzt über den Generator.
--closed--