2010-05-24 6 views
8

Je l'habitude d'utiliser OpenC++ (http://opencxx.sourceforge.net/opencxx/html/overview.html) pour effectuer la génération de code comme:cadre du compilateur Source-source voulait

Source:

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

Generated:

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); 
    } 
}; 

Ce genre de la génération de code correspond directement au cas d'utilisation dans le tutoriel d'OpenC++ (http://www.csg.is.titech.ac.jp/~chiba/opencxx/tutorial.pdf) en écrivant un programme de méta-niveau pour gérer "MyKeyword", "inarg" et "outarg" et performin g la génération de code. Cependant, OpenC++ est en quelque sorte désuet et inactif maintenant, et mon générateur de code ne peut fonctionner que sur g ++ 3.2 et il déclenche une erreur sur les fichiers d'en-tête d'analyse de g ++ de version supérieure.

J'ai regardé VivaCore, mais il ne fournit pas l'infrastructure pour compiler le programme de méta-niveau. Je suis aussi en train de regarder LLVM, mais je ne trouve pas de documentation pour m'enseigner l'utilisation de la compilation source-source. Je suis également conscient du framework de compilateur ROSE, mais je ne suis pas sûr que cela corresponde à mon utilisation, et que son binaire frontal C++ propriétaire puisse être utilisé dans un produit commercial, et si une version Windows est disponible.

Tous les commentaires et les pointeurs vers un tutoriel/papier/documentation spécifique sont très appréciés. Connaissez-vous la pratique de la métaprogrammation de modèle?

+1

Vous ne pouvez pas utiliser le framework Rose dans un contexte commercial sans avoir votre propre licence sur le frontal EDG. Dunno si Rose a une version Windows. –

Répondre

3

Je ne connais pas de solution prête à l'emploi, mais vous pouvez construire votre propre avec un effort relativement peu. Une option possible est l'analyseur Elsa C++, un peu dépassé, mais facile à utiliser et assez extensible. Une autre option consiste à altérer les AST XML produites par Clang ++. J'ai utilisé les deux approches dans différents scénarios.

+0

Merci beaucoup d'avoir fourni des réponses au problème. Elas et Clang ++ sont des informations très utiles. –

+1

Clang est ce que je recommande fortement. LLVM est trop loin dans le chemin du compilateur pour vos besoins, mais Clang est au bon endroit. –

+0

Le site Elsa semble n'avoir eu aucune mise à jour depuis environ 2005; il prétend essayer d'analyser C++ 2003. –

0

Si vous ne l'avez pas déjà utilisé, c'est l'application du préprocesseur C++ pour créer des méta-programmes bizarres qui ressemblent plus à LISP qu'à C++. L'idée est la même que ci-dessus - avoir une étape de pré-compilation qui génère un code répété basé sur certaines entrées. Cependant, tout est exécuté au moment de la compilation (alors qu'il semble que OpenC++ fasse plusieurs choses à l'exécution). Considérant qu'il semble que vous êtes prêt à en apprendre un nouveau, seriez-vous prêt à l'utiliser comme un «langage» de remplacement? Boost fournit une bibliothèque qui utilise cette technique pour fournir une sérialisation facile, comme ce que vous avez montré ci-dessus. 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

Merci pour l'idée d'utiliser le préprocesseur. Cependant, certains problèmes hérités et de compatibilité me limitent de modifier trop l'utilisation actuelle. –

1

Vous pouvez envisager notre DMS Software Reengineering Toolkit. DMS est une base générale pour analyser le texte source dans des langages arbitraires pour compiler des structures de données (ASTs, tables de symboles, graphiques de flux de contrôle, graphiques de flux de données en fonction de quelle distance vous le prenez).

DMS est un usage général Source-to-source program transformation system. Vous pouvez appliquer des transformations de source à source, ou écrire des transformations procédurales (comme OpenC++), , puis régénérer le texte source compilable correspondant au programme transformé. DMS est paramétré par des définitions de langage explicites et gère C, C#, COBOL, Java, Python, javascript, Fortran.

Il a un C++ Front End complet qui gère beaucoup de vrais dialectes de C++ (ANSI, GNU, MS), avec le nom complet et la résolution de type.Le DMS avec le frontal C++ peut effectuer des transformations contrôlées par des "métaprogrammes" au sein et entre plusieurs unités de compilation. Il a été utilisé dans la colère pour faire des réorganisations radicales des systèmes logiciels C++, y compris la réarchitecture massive des logiciels avioniques de mission (voir les articles sur le site Web), finalement utilisé dans les drones. DMS fonctionne sous Windows.

EDIT 2/3/2011: DMS semble fonctionner correctement avec Wine sous Linux et Solaris. Tests en cours pour DMS sur Wine sous OSX.

EDIT 3/1/2011: DMS semble également fonctionner sous Wine pour OSX.

EDIT 21/02/2013: Le frontal C++ gère désormais ANSI C++ 11, ainsi que les versions MS et GNU de C++ 11.

EDIT 2/24/2015: gère maintenant C++ 14 dans les saveurs ANSI, MS et GNU.