2010-05-24 6 views
8

ich verwendet OpenC++ zu verwenden (http://opencxx.sourceforge.net/opencxx/html/overview.html) Codegenerierung wie ausführen:Source-to-Source-Compiler Rahmen wollte

Quelle:

class MyKeyword A { 
    public: 
    void myMethod(inarg double x, inarg const std::vector<int>& y, outarg double& z); 
}; 

generiert:

class A { 
    public: 
    void myMethod(const string& x, double& y); 
    // generated method below: 
    void _myMehtod(const string& serializedInput, string& serializedOutput) { 
     double x; 
     std::vector<int> y; 
     // deserialized x and y from serializedInput 
     double z; 
     myMethod(x, y, z); 
    } 
}; 

Diese Art von Die Codegenerierung stimmt direkt mit dem Anwendungsfall im Lernprogramm von OpenC++ überein (http://www.csg.is.titech.ac.jp/~chiba/opencxx/tutorial.pdf), indem ein Meta-Level-Programm geschrieben wird, das "MyKeyword", "inarg" und "outarg" verarbeitet und ausführt g die Code-Generierung. Allerdings ist OpenC++ jetzt veraltet und inaktiv, und mein Code-Generator kann nur mit g ++ 3.2 arbeiten und löst einen Fehler beim Parsen von Header-Dateien von g ++ höherer Versionen aus.

Ich habe mir VivaCore angeschaut, aber es bietet nicht die Infrastruktur zum Kompilieren von Meta-Level-Programmen. Ich schaue mir auch LLVM an, aber ich kann keine Dokumentation finden, die mich bei der Ausarbeitung meiner Source-to-Source-Kompilierung unterstützt. Ich kenne auch das ROSE-Compiler-Framework, aber ich bin mir nicht sicher, ob es meiner Verwendung entspricht und ob seine proprietäre C++ - Frontend-Binärdatei in einem kommerziellen Produkt verwendet werden kann und ob eine Windows-Version verfügbar ist.

Alle Kommentare und Hinweise auf bestimmte Tutorial/Papier/Dokumentation werden sehr geschätzt.

+1

Sie können das Rose-Framework nicht in einem kommerziellen Kontext verwenden, ohne Ihre eigene Lizenz für das EDG-Frontend zu erhalten. Weiß nicht ob Rose eine Windows Version hat. –

Antwort

3

Ich weiß nicht jede ready-to-use-Lösung, aber Sie können Ihre eigene mit relativ geringen Aufwand zu bauen. Eine mögliche Option ist Elsa C++ Parser, ein wenig veraltet, aber einfach zu bedienen und ziemlich erweiterbar. Eine weitere Möglichkeit ist die Manipulation von XML-ASTs, die von Clang ++ erstellt wurden. Ich habe beide Ansätze in verschiedenen Szenarien verwendet.

+0

Vielen Dank für die Bereitstellung von Antworten auf das Problem. Elas und Clang ++ sind sehr nützliche Informationen. –

+1

Clang ist was ich sehr empfehlen würde. LLVM ist zu weit unten im Compiler-Pfad für Ihre Bedürfnisse, aber Clang ist an der richtigen Stelle. –

+0

Die Website von Elsa scheint seit etwa 2005 keine Aktualisierungen mehr zu haben. es behauptet zu versuchen, C++ 2003 zu analysieren. –

0

Kennen Sie die Praxis der Template-Metaprogrammierung? Wenn Sie es vorher nicht benutzt haben, ist es die Anwendung des C++ - Präprozessors, um merkwürdige Meta-Programme zu erstellen, die sich eher wie LISP als C++ anfühlen. Die Idee ist die gleiche wie oben - mit einem Vorkompilierungsschritt, der basierend auf bestimmten Eingaben wiederholten Code generiert. Es wird jedoch alles zur Kompilierzeit ausgeführt (während es aussieht, als würde OpenC++ zur Laufzeit mehrere Dinge tun).

Wenn man bedenkt, dass es so aussieht, als ob Sie bereit wären, ein neues zu lernen, wären Sie bereit, das als Ersatz "Sprache" zu benutzen?

Boost stellt eine Bibliothek bereit, die diese Technik verwendet, um eine einfache Serialisierung zu ermöglichen, wie Sie oben gezeigt haben. From the tutorial in its manual:

///////////////////////////////////////////////////////////// 
// gps coordinate 
// 
// illustrates serialization for a simple type 
// 
class gps_position 
{ 
private: 
    friend class boost::serialization::access; 
    // When the class Archive corresponds to an output archive, the 
    // & operator is defined similar to <<. Likewise, when the class Archive 
    // is a type of input archive the & operator is defined similar to >>. 
    template<class Archive> 
    void serialize(Archive & ar, const unsigned int version) 
    { 
     ar & degrees; 
     ar & minutes; 
     ar & seconds; 
    } 
    int degrees; 
    int minutes; 
    float seconds; 
public: 
    gps_position(){}; 
    gps_position(int d, int m, float s) : 
     degrees(d), minutes(m), seconds(s) 
    {} 
}; 

int main() { 
    // create and open a character archive for output 
    std::ofstream ofs("filename"); 

    // create class instance 
    const gps_position g(35, 59, 24.567f); 

    // save data to archive 
    { 
     boost::archive::text_oarchive oa(ofs); 
     // write class instance to archive 
     oa << g; 
     // archive and stream closed when destructors are called 
    } 

    // ... some time later restore the class instance to its orginal state 
    gps_position newg; 
    { 
     // create and open an archive for input 
     std::ifstream ifs("filename"); 
     boost::archive::text_iarchive ia(ifs); 
     // read class state from archive 
     ia >> newg; 
     // archive and stream closed when destructors are called 
    } 
    return 0; 
} 
+0

Danke für die Idee zur Verwendung von Präprozessor. Einige Legacy- und Kompatibilitätsprobleme beschränken mich jedoch darauf, die aktuelle Nutzung zu sehr zu ändern. –

1

Sie könnten unsere DMS Software Reengineering Toolkit betrachten. DMS ist eine allgemeine Grundlage für das Parsen von Quelltext in beliebigen Sprachen zu Compilerdatenstrukturen (ASTs, Symboltabellen, Kontrollflussdiagramme, Datenflussdiagramme, abhängig davon, wie weit Sie es nehmen).

DMS ist ein allgemeiner Zweck Source-to-source program transformation system. Sie können Quell-zu-Quell-mustergesteuerte Transformationen anwenden oder prozedurale Transformationen schreiben (ähnlich wie OpenC++), und dann den kompilierbaren Quelltext entsprechend dem transformierten Programm regenerieren.

DMS ist durch explizite Sprachdefinitionen parametrisiert und behandelt C, C#, COBOL, Java, Python, Javascript, Fortran.

Es hat eine volle C++ Front End, die viele echte Dialekte von C++ (ANSI, GNU, MS) mit voller Namen und Typ-Auflösung behandelt.DMS mit dem C++ - Frontend kann Transformationen durchführen, die von "Metaprogrammen" innerhalb und über mehrere Übersetzungseinheiten gesteuert werden. Es wurde im Zorn verwendet, um radikale Reorganisationen von C++ - Softwaresystemen durchzuführen, einschließlich der massiven Umgestaltung von Mission Avionics Software (siehe Papiere auf der Website), die schließlich in UAVs verwendet wurden.

DMS läuft unter Windows.

EDIT 2/3/2011: DMS scheint unter Wine auch unter Linux und Solaris einwandfrei zu funktionieren. Tests für DMS auf Wine unter OSX laufen.

EDIT 01.03.2011: DMS scheint auch unter Wine für OSX zu laufen.

EDIT 21.02.2013: Das C++ - Front-End verarbeitet jetzt ANSI C++ 11, sowie MS und GNU-Versionen von C++ 11.

EDIT 24.02.2015: Behandelt jetzt C++ 14 in ANSI, MS und GNU Aromen.