C++ parsen



  • @phlox81
    Für welche Sprachen und aus welchen Grund hast du schon Parser geschrieben? Die Motivation anderer Leute die auch schonmal einen Parser geschrieben haben finde ich interessant :). Den Lexer an sich finde ich eigtl nicht unbedingt so schwer, das Problem liegt meiner Meinung nach in der Überprüfung der Semantik.

    @Th69
    Danke für die Informationen :). Vorallem den Thread bei gamedev finde ich interessant. Leider wurde es ja bisher noch nicht geschafft, einen C++-Parser an Hand von boost::spirit zu entwickeln. Wie auch in gamedev schon beschrieben steht, läuft es darauf hinaus, dass man es doch selbst entwickeln muss.

    Edit:
    Ich habe mir nun folgendes Buch gegönnt. Ich hoffe mal, dass es sein Geld wert ist.
    http://www.amazon.de/Compiler-Prinzipien-Techniken-Pearson-Studium/dp/3827370973/ref=sr_1_1?ie=UTF8&qid=1295098835&sr=8-1



  • skNiNe schrieb:

    @phlox81
    Für welche Sprachen und aus welchen Grund hast du schon Parser geschrieben? Die Motivation anderer Leute die auch schonmal einen Parser geschrieben haben finde ich interessant :). Den Lexer an sich finde ich eigtl nicht unbedingt so schwer, das Problem liegt meiner Meinung nach in der Überprüfung der Semantik.

    Das ist immer die Frage was man machen will, ich habe mich eigentlich immer darauf beschränkt, nur Code zu generieren, und bedingt auch zu parsen (statt 10 Editboxen eine).
    Schwierig wirds natürlich wenn man auch den eigentlichen Logikcode parsen will, ansonsten kann man relativ einfach eine Regel bauen die den inhalt zwischen zwei {} in einen String schreibt.

    Ich habe 2 Parser für TTCN3 geschrieben, unter anderem dort auch die Aufrufe später überprüft. Und Parser für diverse andere Dinge.



  • wieviele jahre bist du denn bereit dafür zeit zu investieren? das ist fast ne lebensaufgabe



  • skNiNe schrieb:

    Leider wurde es ja bisher noch nicht geschafft, einen C++-Parser an Hand von boost::spirit zu entwickeln. Wie auch in gamedev schon beschrieben steht, läuft es darauf hinaus, dass man es doch selbst entwickeln muss.

    Es ist nicht so, dass es ganz von Hand einfacher wäre als mit Boost.Spirit. Aber vielleicht musst du zu einem mächtigeren Lexer-/Parserframework (z.B. Flex/Bison-Kombination) greifen.



  • Nexus schrieb:

    skNiNe schrieb:

    Leider wurde es ja bisher noch nicht geschafft, einen C++-Parser an Hand von boost::spirit zu entwickeln. Wie auch in gamedev schon beschrieben steht, läuft es darauf hinaus, dass man es doch selbst entwickeln muss.

    Es ist nicht so, dass es ganz von Hand einfacher wäre als mit Boost.Spirit. Aber vielleicht musst du zu einem mächtigeren Lexer-/Parserframework (z.B. Flex/Bison-Kombination) greifen.

    lol. Tschuldigung, aber spirit ist mächtig genug, und ich kann mir nicht vorstellen, was Flex/Bison besser als Spirit könnte.
    Evtl. interessant könnte hier der Quellcode von LLVM/clang sein, die haben ja einen kompletten Kompiler neu gebaut, also müssten sie auch einen Parser haben.
    Dieser ist zumindest Opensource, evtl. sogar unter einer BSD ähnlichen Lizenz (also nich GPL).



  • phlox81 schrieb:

    lol. Tschuldigung, aber spirit ist mächtig genug, und ich kann mir nicht vorstellen, was Flex/Bison besser als Spirit könnte.

    Ich kenne die Frameworks zu wenig, um das zu beurteilen. Jedoch hat g++ meines Wissens früher auf Bison basiert. Das muss natürlich nichts heissen (ausser dass man sich vielleicht eher an einer existierenden Implementierung orientieren kann).

    Das mit dem "mächtiger" habe ich schon ein paar Male gehört, aber offenbar zu Unrecht. Danke für die Anmerkung.



  • Ich verwende in einigen Programmen als Skriptsprache AngelScript.
    http://www.angelcode.com/angelscript/
    Das ist auch OpenSource und benutzt als Sprache eine Mischung aus C++ und Python.
    Ist OpenSource, daher vielleicht ganz interessant mal zum reinschauen.
    HTH ein wenig.
    rya.



  • Guten Tag,

    ich bin seit gestern nach wie vor am überlegen, womit ich anfangen könnte, um mir diverses Wissen dafür anzueignen. Letztens habe ich hier schonmal einen Thread geöffnet (sogar hier im falschen Forum dafür), welcher sich um GNU make handelte. Mir ist nun in den Sinn gekommen, dass ich ein kleines make-Programm schreiben könnte, welches einfacher zu bedienen und dennoch flexibler als das traditionelle make ist. Meiner Meinung nach gibt es vorallem Probleme mit z. B. Qt. Woher will make wissen, welche Header-Dateien zunächst von moc kompiliert werden müssen. qmake finde ich auch nicht unbedingt gut, da dieser (wie viele andere Alternativen zu make) zunächst ein Makefile erstellt, in dem die ganzen Sourcen und Abhängigkeiten statisch (bedeutet: nicht automatisch ermittelt werden) eingetragen werden, welches wiederrum erstmal ausgeführt werden muss, um letztendlich eine ausführbare Datei zu erstellen.

    Was haltet ihr von der Idee, ein make-Programm zu erstellen, welches auf einer (sehr) vereinfachten Syntax von C/C++ basiert, um seine eigenen Funktionen zu definieren. Des Weiteren stehen bereits sämtliche Funktionen (die u. a. auch in make vertreten sind) schon im vornherein zur Verfügung. Ein solches Makefile wird von diesem make interpretiert und ausgeführt (ohne ein traditionelles Makefile zu erstellen). Um dennoch die Kompatibilität zum alten make zu bewahren, könnte es ein Feature geben, um ein Makefile in ein traditionelles Makefile zu konvertieren (demnach wird dann auch alles statisch eingetragen (wie in qmake usw.)).

    Falls diese Idee Anhang finden würde, wäre es durchaus ein sinnvolles Projekt, welches zugleich eine gute Einführung ins parsen und interpretieren gibt.

    Ich wäre sehr dankbar für Meinungen zu dieser Idee.

    Hier noch der Link zum Make-Thread von mir:
    http://www.c-plusplus.net/forum/279038

    Viele Grüße 🙂



  • skNiNe schrieb:

    Falls diese Idee Anhang finden würde

    Kennst du schon alle Build-Systeme?
    Die Sache mit dem make ist halt die, dass make so ziemlich überall installiert werden kann und oft auch ist. Wenn ich ein Projekt mit deinem SMake (ich nenn es jetzt einfach mal so) schreiben würde, müsste jeder Nutzer erst einmal das README durchlesen, dann SMake installieren, dann nachschauen wie es aufgerufen werden soll, dann die Fehlermeldungen verstehen und beheben, ... Ansonsten hätte er einfach ./configure && make && sudo make install auszuführen und das kennt er schon.



  • libclang hat noch keiner vorgeschlagen... liegt sicher daran, dass c++'ler boost mit der muttermilch aufnehmen. für alle nicht verblendeten wärs evtl. nen blick wert!

    @edit: 5.130 ergebnisse sind in webdimensionen ja auch fast wie die nadel im heuhaufen - gerne hab ich bei der suche geholfen 😉



  • Ich kenne einige Build-Systeme (mehr oder weniger gut). Aber gibt es denn die oben genannte Möglichkeit bspw. in eine Header-Datei zu schauen, um zu überprüfen ob diese zunächst vom MOC kompiliert werden muss? Ich will und kann natürlich kein perfektes make erstellen. Aber man könnte ja eine große Basis an Standardfunktionalität bieten, auf welcher man eine beliebige Anzahl an eigenen Funktionen aufbauen kann.

    Das von dir genannte Problem bzgl. Einarbeitung in make-Programme wäre ja im Endeffekt mit der Konvertierung in ein übliches Makefile behoben. Diesen Vorgang würde man dann zu jedem Release durchführen, sodass der Benutzer des Programms oder Bibliothek nur noch sein gewohntes Makefile hat. Nur der Entwickler müsste einmal initial sein spezifischen Makefile schreiben bzw. anwenden können.



  • So, ich melde mich mal wieder :). Ich hab mich die letzten Monate mit der Materie auseinandergesetzt (Dragonbook), mich mit verschiedenen Parsertechniken (hauptsächlich rekursiv absteigend und LALR) beschäftigt. In nächster Zeit (nach meiner FIAE Abschlussprüfung anfang Mai) werde ich wohl mal einen C-Parser angehen. Wie im Verlauf des Threads schon kenntlich gemacht wurde, geht es mir nicht nur rein ums parsen, sondern um einen Parser, der eher wie eine Code-Completion arbeitet. Änderungen im Source-Code direkt nachdem diese durchgeführten wurden entsprechend parsen und den AST aktualisieren. Nun zu meiner eigentlichen Frage. Gibt es bereits Techniken, wie man so einen, ich sag mal "Live-Parser" implementieren kann?

    Viele Grüße



  • Hat niemand eine Idee?



  • Ich denke die wenigsten haben schon einmal einen Live-Parser geschrieben.
    Was hindert dich daran, einen schon bestehenden anzuschauen? Mal angefangen mit man: ctags (oder vllt. Geany), dann weiter zu KDevelop oder anderen IDEs.

    Genau darum gibt es Open Source.



  • Das richtige Stichwort heißt Incremental Compiler.

    Für weitere Infos dann einfach google bemühen (ggf. Google Scholar).



  • Ich rate dir noch kleiner anzufangen. Ich bin selber momentan dran eine kleine Skriptsprache zu basteln un das is wirklich nicht in 1 oder 2 wochen gemacht.
    Ich empfehl dir ein Zwischencode zu erstellen und dann zu parsen, am besten einen im hex style oder nach deiner wahl. Das kann das parsen um einiges schneller machen.



  • life schrieb:

    Das richtige Stichwort heißt Incremental Compiler.

    Für weitere Infos dann einfach google bemühen (ggf. Google Scholar).

    Exakt nach dem Stichwort hab ich gesucht. Vielen Dank!

    @gamebuntu: Danke für den Rat. Jedoch bin ich von meinem wuchtigen Ziel eines C++-Parsers zu einen C-Parser abgestiegen ^^. Grammatikalisch ist C relativ leicht zu parsen. Bei der semantischen Analyse wird mir wohl noch das eine oder andere Problem übern Weg laufen, aber da führt bei allen Skript- oder Programmiersprachen kein Weg dran vorbei.

    An dieser Stelle nochmal ein großes Danke an alle hier :).

    Viele Grüße



  • Guten Morgen,

    ich hab mich nun mal etwas mit der inkrementellen Übersetzung beschäftigt. Des Weiteren hab ich schonmal ein Gropkonzept aufgesetzt, wie sowas umsetzbar wäre. Jedoch habe ich bei der ganzen Sache noch ein Problem, welches ich nicht zu lösen weiss. Ich übersetze jeweils den Teil im Source-Code neu, der aktualisiert wurde, und alles was damit zusammenhängt. Bspw. Es wird im Bereich einer Funktion oder eines Block-Statements etwas geändert, so muss die Funktion in der dieser Block existiert ebenfalls neu validiert werden. Im Falle der Funktion müssen alle aufrufenden bzw. referenzierenden Stellen validiert werden. Wenn ich nun am Anfang einmal initial den kompletten Source-Code übersetze (parsen + semantische Überprüfung) habe ich nun erstmal einen Abstract-Syntax-Tree (AST). Wenn ich nun an einer beliebigen Funktion oder sonstigen Elementen im Source-Code etwas ändere, brauch ich dazu den Verweis auf die Stelle im AST. Jedoch weiss ich nicht wie ich das ordentlich abgebildet bekomme. Theoretisch könnte ich bei der lexikalschen Analyse für jedes Token die Stelle im Source (Row, Column) speichern. Jedoch wird es ziemlich unflexibel wenn ich mitten im Code etwas ändere und sich somit der komplette nachfolgende Code verschiebt, oder einfach nur weitere Newlines zwischen Funktionen einfüge.

    Kennt jemand für dieses Probleme eine bewährte bzw. praktikable Lösung?

    Viele Grüße



  • skNiNe schrieb:

    Wenn ich nun an einer beliebigen Funktion oder sonstigen Elementen im Source-Code etwas ändere, brauch ich dazu den Verweis auf die Stelle im AST. Jedoch weiss ich nicht wie ich das ordentlich abgebildet bekomme. Theoretisch könnte ich bei der lexikalschen Analyse für jedes Token die Stelle im Source (Row, Column) speichern.

    Wieso Row/Column? Auf den ersten Wurf würde ich eine Symboltabelle erstellen, in denen zu den Symbolen Verweise auf die AST-Knoten liegen, in denen das Symbol definiert/deklariert oder verwendet wird.

    Wenn jetzt irgendwo ein Symbol neu verwendet wird bzw. die Verwendung geändert wird, kannst du über die Tabelle die vorhandenen Deklarationen finden und prüfen, ob die Verwendung passt.

    Wenn die Deklaration eines Symbols verändert, gelöscht oder hinzugefügt wird, findest du über die Tabelle die Knoten, in denen sie verwendet wird und kannst die Knoten neu evaluieren.



  • Nabend,

    grundsätzlich eine gute Idee. Jedoch muss ich beachten, dass in der Symboltabelle in der Regel ja erstmal nur Identifier gespeichert werden (bspw. für Objekte oder Funktionen). Grundsätzlich kann ein Identifier an verschiedenen Stellen bzw. Scopes auftreten bzw. deklariert werden. Wenn ich nun an bestimmter Stelle den Code ändere, muss ich ja an dieser Stelle schon wissen, welches Element in der Symboltabelle gemeint ist um erstmal meinen Verweis auf den AST-Knoten zu bekommen. Des Weiteren könnte ich ja bspw. einfach eine Klammer irgendwo hinzufügen oder entfernen. Für so eine Änderung gibt es in der Symboltabelle kein Element, somit wüsste ich auch nicht, an welcher Stelle neu evaluiert werden müsste.

    Btw: Bezüglich inkrementeller Übersetzung lassen sich nur schwer detailierte Informationen beschaffen. Beim "normalen" parsen hätte ich solche Probleme nicht. Theoretisch könnte ich direkt erstmal mit dem Parser usw. beginnen, jedoch möchte ich im vornherein einige Einzelheiten planen, um später eine saubere Implementierung zu haben.

    Ich bin für jede Hilfe dankbar :).

    Viele Grüße


Anmelden zum Antworten