| J2Cpp Converter | Program Counter |
J2Cpp Converter
En esta sección iré incluyendo noticias y documentos relativos al desarrollo de esta herramienta, que espero llegue a ser útil algún día ^_^U Su objetivo es facilitar la conversión de código Java a C++, lo cual permitiría agilizar la realización de ports de un lenguaje al otro y quizá facilitar el aprendizaje de C++, al permitir ver equivalencias entre éste y Java.
El proyecto ya se ha puesto en marcha, tras algunos problemas al dar los primeros pasos. Actualmente se está llevando a cabo la implementación del analizador léxico y sintáctico, así como de las funciones de conversión más simples.
En las siguientes líneas podrás consultar:
Seguimiento de versiones
Aún no hay ninguna versión implementada. En un principio, únicamente se realizarán conversiones básicas, como el sistema de paquetes, los import entre clases definidas por el usuario y la estructura principal de éstas: cabecera, atributos y métodos.
Quedan pendientes para versiones posteriores las equivalencias entre clases de la API de Java y la STL.
Por la propia necesidad de ir reconociendo el fichero .java para realizar la conversión, el programa se implementa como un parser con generación de código. Se utilizará la orientación a objetos, y ésta planteará como ventaja principal la independencia de cada módulo respecto a los demás, facilitando la división de tareas entre ellos.
Los elementos básicos que componen una clase, y que marcarían la división de los módulos, serían los siguientes:
- Paquetes: Si una clase se sitúa en el paquete X.Y.Z, el equivalente en C++ sería el namespace X::Y::Z. La gestión sería realizada por una clase PackageProccesor.
- Importaciones: Un import tal que import pack.subpack.class se traduciría en el correspondiente #include "class" y la sentencia using namespace pack::subpack. El proceso lo realizaría la clase ImportProcessor.
- Cabecera: Esta tarea, realizada por la clase HeaderProcessor, consistiría en convertir una cabecera de clase típica en Java como public class Clase extends Base implements Interfaz. Puesto que en C++ no existe el concepto de interfaz propiamente dicho, sino que se emplearía herencia múltiple con clases abstractas, y que en Java el único tipo de herencia es la pública, se convertiría en class Clase : public Base, public Interfaz.
- Cuerpo: Esta sección sería gestionada por una clase BodyProcessor, que delegaría parte de sus funciones en otras denominadas AttributeProcessor, MethodProcessor, etc. Ésta es una cuestión que todavía debe ser estudiada, según cómo se plantee el parsing del fichero.
- Atributos: Controlados por la clase AttributeProcessor, debería generarse código adecuado al estilo de los modificadores de acceso de C++: puesto que se realiza un agrupamiento por bloques, mostrar el mismo modificador en varios atributos consecutivos, como se hace en Java, no daría lugar a un resultado demasiado halagador. Por ello, se debe mantener un control sobre el ámbito actual -privado, protegido o público-.
- Métodos: Además de gestionar los mismos puntos expuestos en el apartado de los atributos, la clase MethodProcessor debe hacer lo propio con el tratamiento de las sentencias, delegándolo en la clase SentenceProcessor. Por su similitud con el cuerpo de la clase, aún debo estudiar cómo diseñar este apartado.
Para realizar el modelado UML se ha utilizado la herramienta Umbrello, que almacena los diagramas en formato XMI, un derivado de XML. Por ahora está disponible para descargar el diagrama provisional. Como se puede observar, el proceso completo sería controlado por una clase Converter que, presumiblemente, realizaría el parsing y proporcionaría los datos necesarios para la generación a cada clase. En este caso, BodyProcessor y MethodProcessor podrían ser suprimidas o simplificadas respectivamente, y tratarse los datos de forma más directa, sólo a través de AttributeProcessor y SentenceProcessor.
Nota: Una vez se haya tomado la decisión definitiva en relación con el diseño, se realizarán las actualizaciones pertinentes de los datos de este apartado.
Por otra parte, en el diagrama de clases se puede observar una denominada Attributes, compuesta por un map en el que insertar todo tipo de objetos identificados mediante un string. El que haya trabajado algo con el lenguaje sabrá que no cuenta con mecanismos para poder insertar tipos de datos distintos en una misma estructura si no es empleando una jerarquía de herencia. Como en este caso los tipos a guardar no tienen relación entre sí -int, ostream...-, este mecanismo es imposible. Fue por ello que decidí emplear una biblioteca ya existente: la Boost.Any, de la que se incluyen algunos datos en el último apartado de esta página.
De todas formas, finalmente esta idea es rechazada tras realizar unos cambios en el diseño, de forma que, puesto que cada componente de una clase necesita unos datos fijos, sean los procesadores de dichos componentes los que gestionen la información. Por ejemplo, el PackageProcessor almacena el código generado y los namespaces abiertos.
Fase de implementaciónUna vez resueltos los problemas relativos al almacenamiento de los datos necesarios para generar el código, se ha realizado la implementación del procesador de la sentencia package y de la cabecera de clase. Intentaré publicar lo antes posible la versión 0.0.1, donde se incluyan los analizadores léxico y sintáctico y dichos procesadores. En ese momento publicaré también los comentarios a la implementación, su funcionamiento, etcétera.
Información adicionalEsta biblioteca basa su funcionamiento en una clase any que funciona como envoltorio para cualquier tipo de dato: tipos simples, punteros, tipos definidos por el usuario, etc. Se puede consultar si el envoltorio contiene algún dato en ese momento, así como consultar el tipo de éste empleando los mecanismos de RTTI, dynamic_cast -en este caso adaptado a un any_cast- y typeid.
Quien esté interesado puede consultar el fichero de cabecera de esta biblioteca.
Flex es un generador de analizadores léxicos, y Bison un generador de analizadores sintácticos.
Por ahora no incluiré más información, pero se puede empezar consultando The Lex & Yacc Page.