Speicherverwaltung



  • Mh gut möglich :/. Wie würdest du die genannte Situation umsetzen?



  • skNiNe schrieb:

    Mh gut möglich :/. Wie würdest du die genannte Situation umsetzen?

    Ich plane vielleicht weniger, sondern tippe einfach drauf los. Ich versuche schon dafür zu sorgen, daß Erweiterungen später möglich sind und nicht wie nachträglich drangeschraubt aussehen. Aber ich schreibe auch nur, was benötigt wird.

    - Soll Position ein Template sein? Evtl kann man somit den Typ von line und column angeben.
    Wozu? int32_t reicht doch.

    - Mach ich den Scanner als abstrakte Klasse?
    Wozu? Klingt langsam ohne weiteren Vorteil.

    - Wenn ich Scanner als abstrakte Klasse mache, wäre auch eine Überlegung, ob ich Document als Template mach.
    Wozu?

    - Evtl. könnte ich im Document noch den char-Typen angeben (char, wchar_t) ... Wozu? Entscheidi Dich für utf8 oder sowas und gut ist's.

    - Evtl. zerlege ich die Schnittstelle Document noch in zwei Teile: Read- und Writable (noch flexibler).
    Wozu?



  • Mh ja wäre evtl ne Idee ^^.

    Hier mal der Hintergrund des ganzen:

    Irgendwo hier im Forum fliegt ein Thread "C++ parsen" von mir rum. Im Moment probiere ich mich an einem C-Parser. Bisher bin ich einige konzeptionelle Sachen durchgegangen und mittlerweile fang ich des tippeln an ^^.

    Bei C/C++ rumpelt der Präprozessor über den Code und bearbeitet ihn bevor die tatsächliche Analyse stattfindet. Ich möchte jedoch nicht alle Änderungen in eine separate Datei schreiben und die vom C-Analyzer einlesen sondern möchte alle Änderungen intern auflösen. Damit soll folgendes verhindert werden:

    - Erneutes Laden der Datei
    - Wenn eine Datei von mehreren Dateien eingebunden werden muss, muss diese nicht immer neu analysiert und bearbeitet werden sondern existiert schon in bearbeiteter Form im Programm.

    Also angenommen ich hab eine Datei (Document) in der folgendes drin steht:

    ??=include "header.h"
    

    wird daraus nach dem ersten Durchlauf des Präprozessors ein

    #include "header.h"
    

    und im zweiten wird die Stelle durch den Inhalt von header.h ersetzt.

    Also kann ich im Endeffekt an Hand bestimmter Aktionen (löschen, ersetzen, hinzufügen, und in Datei springen) die vom Präprozessor bearbeitete Datei wie folgt simulieren (von unten angefangen):

    `in Datei header.h springen


    (ersetzen)


    ??=include "header.h"`

    Also ich kann für bestimmte Position-Ranges Aktionen hinterlegen, und je nach Durchlauf der Translation-Phase soll der Scanner eben diese Aktionen berücksichtigen (an Hand eines Mappings).

    Aus diesem Grund hab ich über einen abstrakten Scanner nachgedacht. Einen der ein Document pur liest, und einer der bspw. die Aktionen berücksichtigt. Wenn ich den Scanner als template deklarieren würde könnte ich sogar noch den Tokenizer drauf setzen (dass er mir kein char sondern ein Token liefert). Tokenizer liest aus ActionScanner und der wiederum aus dem normalen Scanner.

    Also ist meine Idee.



  • #ifdef __WIN32__
        #ifndef NDEBUG
            #define NO_MIN_MAX //ändert Verhalten von <windows.h>!
        #endif
        #include <windows.h>
    #else
        #ifdef __linux__
            #include <usistd.h>
        #else
            #define TEST zeile1\
            zeile2
        #endif
    #endif
    

    macht mir jetzt ein wenig Angst.

    Warum nicht einfach verschiedene Prozessoren bauen, die jeweils einen Zeichenstrom lesen und einen schreiben? Als Strom kannste dann eine Pipe nehmen und mußt nichts in teuren Dateien zwischenspeichern. Präcompilat zwischenspeichern darfste eigentlich nur, wenn alle Makrodefinitionen und alle Deklarationen vorher gleich waren.



  • Also mit meinem genannten Beispiel bin ich hauptsächlich mal auf das Handling von Dateien bzgl. des Scanners eingegangen. Sicher sitzt intern dahinter noch ein Präprozessor der die Grammatik aus dem Standard implementiert und dort eben Symbole definiert, wieder rauswirft usw. ... Dementsprechend werden an bestimmten Stellen auch Aktionen zum springen in Dateien hinterlegt (so nach dem erklärten Prinzip).

    Wenn du mir das mit den verschiedenen Prozessoren, lesen und schreiben usw. nochmal genauer erklären könntest wäre ich dir sehr dankbar :). Klingt schon mal gut, aber kann ich im Moment nicht genau nachvollziehen.

    EDIT:
    Jetzt weiss ich warums dir Angst macht ^^. Im Endeffekt wäre es dann so, dass ich zwar das Dokument nur einmal laden bräuchte, aber die Aktionen die ich hinterlege müssen für einen kompletten Translation-Unit gelten und nicht für die Datei selbst. Schon allein aus der Tatsache dass ich eine einzelne Datei garnicht verarbeiten kann.



  • Hintereinanderhängen im Prinzip wie

    dir c:\windows | sort /+20 | more
    

    Und benutzt wird wohl http://msdn.microsoft.com/en-us/library/aa365781(v=vs.85).aspx
    bzw daraus streambuf machen und einen istream und ostream dranbasteln. Falls man nicht alles selber zeichenweise lesen will (ich würde selber lesen wollen).

    ifstream eingabe("c:\test.cpp");
    ofstream ausgabe("c:\test.obj");
    pipe p1;
    pipe p2;
    
    compilefunc(p2.istream,ausgabe);//diese drei aber als Threads
    preprocessorfunc(p1.istream,p2.ostream);//absetzen und quasi gleichzeitig 
    bitrigraphfunc(eingabe,p1.ostream);//laufen lassen. Die Pipes 
    //synchronisieren den Ablauf schon.
    


  • Nach dem Prinzip verlier ich aber leider die Positionszuordnung. Wollte mir irgendwann wenn das Ding steht mal nen kleinen Editor zusammenbauen um mit dem Parser interaktiv Code aus dem Editor zu analysieren. Demnach müsste ich nach jeder Änderung den kompletten Code neu analyisieren.



  • skNiNe schrieb:

    Demnach müsste ich nach jeder Änderung den kompletten Code neu analyisieren.

    Das wird wohl leider oft genug vorkommen. Wenigstens, daß Du den kompletten Code hinter der Änderung neu analysieren mußt. Quellcodezeilennummern kann man sich in dem selber erfundenen Streamformat natürlich mitschicken.



  • Theoretisch müsste es auch ohne kompletter erneuten Analyse funktionieren. Schließlich hab ich am Ende nach der syntaktischen Prüfung einen AST. Darin sind alle Produktionen und letztendlich auch alle Tokens. Zu den Tokens gehört eine Referenz auf eine Position. An zentraler Stelle werden die Positionen gespeichert und aktualisiert wenn der Benutzer bspw. whitespace einfügt usw. ... Wenn ich nun in einer Funktion einen Ausdruck bearbeite, muss nur des Scope in dem der Ausdruck ist (in der Funktion) neu analysiert werden. Erst wenn die Funktion auch ungültig wird müssen alle Stellen im AST die auf die Funktion referenzieren (in welcher Form auch immer) neu analysiert werden ...

    Hab ich irgendwas nicht berücksichtigt was deiner Meinung nach dazu führen könnte, dass ich alles neu analysieren muss?

    Klingt nach nen harten Broken programmierarbeit. Aber im Moment bin ich ja eh noch mit den Sachen ganz am Anfang beschäftigt.



  • skNiNe schrieb:

    Theoretisch müsste es auch ohne kompletter erneuten Analyse funktionieren. Schließlich hab ich am Ende nach der syntaktischen Prüfung einen AST. Darin sind alle Produktionen und letztendlich auch alle Tokens.

    In ein PST ja aber eigentlich nicht im AST.



  • skNiNe schrieb:

    müssen alle Stellen im AST

    Stimmt. Wenn eine Deklaration sich ändert oder den Verschwindibus macht, kann sie im AST jeden benachrichtigen, der sie verwendet hat.

    Wobei auch das Hinzukommen von Deklarationen, using-Direktiven, Makros das spätere Verhalten ändern kann. Hier mal eine weitere Überladung von f und schon ist h anders als g.

    #include <iostream>
    using namespace std;
    
    void f(...){
        cout<<"hello ";
    }
    
    void g(){
        f(0);
    }
    
    void f(void*){
        cout<<"world!\n";
    }
    
    void h(){
        f(0);
    }
    
    int main(){
        g();
        h();
    }
    

    Also auch für Überladungen die Namenslisten führen und wie war das nochmal mit dem König-Lookup http://de.wikipedia.org/wiki/Argument_dependent_name_lookup ?

    Klingt nach nen harten Broken programmierarbeit.

    Jup.



  • Aber im Endeffekt sind die nötigen Informationen irgendwo in irgendeiner Form vorhanden.


Anmelden zum Antworten