2010-05-24 19 views
8

Solía ​​usar OPENÇ ++ (http://opencxx.sourceforge.net/opencxx/html/overview.html) para llevar a cabo la generación de código como:marco compilador-Fuente-fuente quería

Fuente:

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

Generado:

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

Este tipo de la generación de código coincide directamente con el caso de uso en el tutorial de OpenC++ (http://www.csg.is.titech.ac.jp/~chiba/opencxx/tutorial.pdf) al escribir un programa de meta-nivel para manejar "MyKeyword", "inarg" y "outarg" y performin g la generación de código. Sin embargo, OpenC++ está algo desactualizado e inactivo ahora, y mi generador de código solo puede funcionar en g ++ 3.2 y desencadena un error al analizar los archivos de cabecera de g ++ de la versión superior.

He examinado VivaCore, pero no proporciona la infraestructura para compilar el programa de meta niveles. También estoy mirando LLVM, pero no puedo encontrar la documentación que me tutorice para calcular mi uso de compilación fuente a fuente. También conozco el marco del compilador ROSE, pero no estoy seguro de si se adapta a mi uso, y si su binario front-end C++ patentado se puede usar en un producto comercial, y si hay una versión de Windows disponible.

Cualquier comentario y consejos para el tutorial específico/papel/documentación son muy apreciados.

+1

No puede usar el marco Rose en un contexto comercial sin obtener su propia licencia para la interfaz EDG. No sé si Rose tiene una versión de Windows. –

Respuesta

3

No sé de cualquier solución lista para su uso, pero se puede construir su propia con un esfuerzo relativamente pequeño. Una posible opción es el analizador Elsa C++, un poco desactualizado, pero fácil de usar y extensible. Otra opción es alterar los AST XML producidos por Clang ++. Usé ambos enfoques en diferentes escenarios.

+0

Muchas gracias por responder al problema. Elas y Clang ++ son información muy útil. –

+1

Clang es lo que recomendaría encarecidamente. LLVM está muy abajo en la ruta del compilador para sus necesidades, pero Clang está en el lugar correcto. –

+0

El sitio de Elsa parece no haber tenido ninguna actualización desde 2005; pretende intentar analizar C++ 2003. –

0

¿Conoces la práctica de la metaprogramación de plantillas? Si no lo ha usado antes, es la aplicación del preprocesador C++ para crear metaprogramas extraños que se sienten más como LISP que C++. La idea es la misma que la anterior: tener un paso de precompilación que genera código repetido basado en ciertas entradas. Sin embargo, todo se ejecuta en tiempo de compilación (mientras que parece que OpenC++ hace varias cosas en tiempo de ejecución).

Considerando que parece que estás dispuesto a aprender uno nuevo independientemente, ¿estarías dispuesto a utilizarlo como un "idioma" de reemplazo?

Boost proporciona una biblioteca que utiliza esta técnica para proporcionar una fácil serialización, como la mostrada anteriormente. 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

Gracias por la idea de usar el preprocesador. Sin embargo, algunos problemas de legado y compatibilidad me limitan a cambiar demasiado el uso actual. –

1

Puede considerar nuestro DMS Software Reengineering Toolkit. DMS es una base general para analizar texto fuente en lenguajes arbitrarios para las estructuras de datos del compilador (AST, tablas de símbolos, gráficos de flujo de control, gráficos de flujo de datos dependiendo de qué tan lejos lo tome).

DMS es un propósito general Source-to-source program transformation system. Puede aplicar transformaciones de fuente a fuente, o escribir transformaciones de procedimiento (como OpenC++), y luego regenerar el texto fuente compilable correspondiente al programa transformado.

DMS se parametriza mediante definiciones de lenguaje explícitas, y maneja C, C#, COBOL, Java, Python, javascript, Fortran.

Tiene un total de C++ Front End que maneja muchos dialectos reales de C++ (ANSI, GNU, MS), con nombre completo y resolución de tipo.DMS con la interfaz de C++ puede llevar a cabo transformaciones controladas por "metaprogramas" dentro y a través de múltiples unidades de compilación. Se ha utilizado con enojo para hacer reorganizaciones radicales de los sistemas de software C++, incluida la reconstrucción masiva de software de aviónica de misión (ver documentos en el sitio web), que finalmente se utiliza en vehículos aéreos no tripulados.

DMS se ejecuta en Windows.

EDITAR 2/3/2011: DMS parece funcionar bien en Wine on Linux y Solaris, también. Pruebas en curso para DMS en Wine bajo OSX.

EDITAR 01/03/2011: DMS parece ejecutarse en Wine para OSX, también.

EDITAR 21/2/2013: La interfaz de C++ ahora maneja ANSI C++ 11, así como las versiones MS y GNU de C++ 11.

EDITAR 24/2/2015: Ahora maneja C++ 14 en ANSI, MS y sabores GNU.