S.E.P. S.E.S. D.G.E.S.T. Centro Nacional de Investigación y Desarrollo Tecnológico cenidet Estudio empírico para la transformación gramatical de código en lenguaje COBOL hacia lenguaje JAVA TESIS Que para obtener el grado de MAESTRO EN CIENCIAS EN CIENCIAS DE LA COMPUTACIÓN Presenta: Mireya Flores Pichardo Director de Tesis Dr. René Santaolaya Salgado Co-Director de Tesis M.C. Olivia G. Fragoso Díaz Cuernavaca, Morelos Junio de 2006 Dedicatorias A mi madre: Irma Por haberme dado la vida, y con ello la fortuna de vivir diferentes experiencias y alegrías que contribuyen a mi felicidad A mi tío Benjamín Por haberme dado todo su apoyo, y haberme brindado sus cuidados y consejos desde que aparecí en su vida A mis hermanos: Leonor, Margarito, Alfonso y Graciela Por su amor, su apoyo y su compañía. Por todo lo que hemos vivido juntos. Los quiero A ti mi Paco Por ser mi pequeño gran campeón y porque tu presencia me motiva a mejorar. No vaciles en lograr lo que desees. Te amo con todo mi corazón A ti mi Andrea Por haber llegado nuestro hogar a llenarnos de sonrisas y amor Deseo que seas una triunfadora Te amo con todo mi corazón A ti Franco Porque has hecho mi vida tan maravillosa Por que con tu apoyo y tu amor he librado grandes batallas Por que siempre estas conmigo Te amo Que Dios los bendiga Agradecimientos Al COSNET y a la SEP, por brindarme su apoyo económico como becaria, ya que sin su ayuda no hubiera sido posible la terminación de esta tesis de Maestría. Al Centro Nacional de Investigación y Desarrollo Tecnológico CENIDET; y a todo el personal que en esta institución labora, por permitirme formar parte de esta gran familia. A mi Director de Tesis, Dr. René Santaolaya Salgado y a mi Codirectora M.C. Olivia Graciela Fragoso Díaz, por sus valiosas experiencias y conocimientos y porque siempre estuvieron al tanto mío y de todos mis compañeros para que brindaramos lo mejor de nosotros y lograramos nuestra meta. Al Comité de Revisión: M.C. Mario Guillén Rodríguez, M.C. Humberto Hernández García y M.C. Reynaldo Alanís Cantú, por su disposición en la revisión de este trabajo de tesis y por sus comentarios y sugerencias que contribuyeron a mejorarlo. A Rocío, a la Lic. Olivia, a Anita por brindarme siempre su apoyo en cualquier trámite referente a mi situación escolar; a Don Mario, por las facilidades otorgadas en el préstamo de material bibliográfico. A mis compañeros de generación: Sonia, Rossy, Toño, Gabriel, Santos, Alan, Pablo, Guillermo, Marco, Tito, que en clases compartieron conmigo sus conocimientos y me ayudaron a mejorar. A mis compañeros de la especialidad de Ingeniería de Software Ariel, Homero, Mariana y Armando, por que con ustedes pasé, además de muchas horas de trabajo, alegres momentos y días felices. A mi compañera y gran amiga Erika por brindarme su amistad, por escucharme en momentos difíciles y por todos lo que compartimos. Y a todas aquellas personas que contribuyeron de alguna manera, a que pudiera convertir en realidad mi meta profesional. Gracias por siempre Tabla de Contenido Tabla de Contenido Índice de Figuras Índice de Tablas Glosario de Términos Resumen Capítulo 1. INTRODUCCIÓN i ii iii iv vi 1 Capítulo 2. ANTECEDENTES 2.1 Estado del arte: trabajos relacionados 2.2 Objetivo 2.3 Planteamiento del problema 2.4 Justificación del estudio 2.5 Alcances y límites del estudio 5 5 14 15 16 17 Capítulo 3. MARCO TEÓRICO 3.1 Paradigma Procedimental 3.2 Paradigma Orientado a Objetos 3.3 Lenguaje de programación COBOL 3.4 Lenguaje de programación Java 3.5 JavaCC 18 18 19 19 22 23 Capítulo 4. DESARROLLO DEL SISTEMA 4.1 Metodología de solución 4.1.1 Complejidad del problema 4.1.2 Metodología 4.2 Análisis del sistema 4.3 Arquitectura de la Herramienta 4.4 Codificación de la Herramienta 4.5 Herramienta C2J desarrollada 25 25 25 30 31 38 39 43 Capítulo 5. EVALUACIÓN EXPERIMENTAL 5.1 Caso de Prueba C2J-01 5.2 Caso de Prueba C2J-02 5.3 Caso de Prueba C2J-03 47 48 51 56 Capítulo 6. CONCLUSIONES Y TRABAJO FUTURO 6.1 Conclusiones 6.2 Trabajo futuro 61 61 63 Anexo A Código original y resultados del caso de prueba C2J-01 Anexo B Código original y resultados del caso de prueba C2J-02 Anexo C Código original y resultados del caso de prueba C2J-03 Bibliografía 64 68 77 88 i Índice de Fi guras 2.1 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12 5.13 5.14 5.15 5.16 5.17 5.18 Antecedente: Proyecto SR2 Metodología de Solución Diagrama Principal de Casos de Uso Diagrama del Caso de Uso 1.1 (Analizar código escrito en COBOL) Diagrama del Caso de Uso 1.4 (Realizar conversión a Java) Convertir estructuras a clases de objetos Conversión de datos globales y métodos Diagrama de Secuencia del escenario de éxito Diagrama de la arquitectura de la Herramienta Inicio de la conversión de COBOL a Java Selección de archivo a convertir Confirmación del inicio del análisis Información de la bitácora de análisis (Variables encontradas) Información de la bitácora de análisis (Métodos encontrados) Clase generada por la herramienta C2J Contenido de la clase generada por la Herramienta C2J Ejecución del código del primer caso de prueba Ejecución de la Herramienta C2J con el código del primer caso de prueba Obtención del archivo escrito en Java Ejecución del archivo escrito en Java Primera parte de la ejecución del código del segundo caso de prueba Segunda parte de la ejecución del código del segundo caso de prueba Tercera parte de la ejecución del código del segundo caso de prueba Ejecución de la Herramienta C2J con el código del segundo caso de prueba Obtención del archivo escrito en Java Ejecución del archivo escrito en Java Ejecución del archivo escrito en Java Ejecución del archivo escrito en Java Ejecución del código del tercer caso de prueba Contenido del archivo ALUMNO.dat Ejecución de la Herramienta C2J con el código del tercer caso de prueba Obtención del archivo escrito en Java Ejecución del archivo escrito en Java Contenido de la tabla creada para guardar información 7 31 32 33 36 36 37 38 39 43 44 44 45 45 46 46 48 49 50 50 51 52 52 53 54 54 55 55 56 57 58 58 59 60 ii Índice de Tablas 2.1 4.1 4.2 4.3 4.4 4.5 4.6 Tabla comparativa de los trabajos relacionados contra esta tesis Reconocimiento de variables globales y registros Reconocimiento de sentencias Reconocimiento de estructuras de control Reconocimiento de llamado a subrutinas Tabla de la identificación de las VGS Tabla de la identificación de los UDT 12 28 29 29 30 34 35 iii Glo s a rio d e T ér mi n o s COBOL Common Oriented Business Oriented Language, lenguaje común orientado a los negocios Diagrama de clase Diagrama que hace un retrato de clases, tanto de sus estructuras y operaciones internas, como de las relaciones estáticas entre ellas. Estudio de factibilidad Análisis de un problema para determinar si puede ser resuelto efectivamente. Extensibilidad Medida de la capacidad que tiene un sistema de software para aceptar nuevos comandos definidos por el usuario o desarrollador de aplicaciones. Funcionalidad Grado de funciones que posee el software para satisfacer las necesidades de un usuario. Heurístico Método de resolver problemas utilizando exploración que provee un marco para resolver el problema en contraposición con un conjunto fijo de reglas que no puede variar. Ingeniería de software Es una disciplina de ingeniería que comprende todos los aspectos de la producción de software. Interfaz Es el conjunto de todas las firmas definidas por las operaciones de un objeto. La interfaz describe el conjunto de peticiones a las cuales un objeto puede responder. JavaCC Herramienta generadora de analizadores léxicos y sintácticos. Lenguaje de procedimientos Lenguaje de programación que requiere una disciplina en programación basándose en conocimientos de programación y procesamiento de datos. Mantenimiento Grado del esfuerzo requerido para modificar, mejorar o corregir errores en el software con la intención de incrementar la eficiencia o funcionamiento del software. OO Object Oriented, orientado a objetos. Paradigma Un modelo o una forma de hacer algo. iv Paradigma Orientado a Objetos Paradigma que observa el mundo como objetos e lugar de procedimientos. Refactorizar Proceso de cambiar un sistema de software en tal forma que no se altere el comportamiento externo del código aunque mejore su estructura interna. Reuso Capacidad de utilizar toda o gran parte del mismo código de programación o diseño de sistemas en otra aplicación. SR2 Acrónimo de “Sistema de Reingeniería para Reuso”. v Resumen A través del tiempo una gran cantidad de código basado en procedimientos ha sido desarrollado para diferentes aplicaciones y dominios de problemas. El código basado en procedimientos, como es el caso del lenguaje COBOL, presenta una serie de características que dificultan su reuso y mantenimiento. Una de las características es que el código cuenta con un bajo nivel de cohesión, porque conjuntos de operaciones accesan a diferentes conjuntos de datos, esto como resultado de la estructura monolítica que caracteriza al código procedimental. Por ello es necesario desarrollar estrategias para aumentar su tiempo de vida útil mediante su recuperación y transformación. El objetivo de esta tesis es transformar código escrito en lenguaje COBOL a código escrito en lenguaje Java basándose en equivalencias gramaticales, así como en métodos heurísticos de reestructura, para facilitar su reuso, mantenimiento y futuras modificaciones para ser adaptado a nuevos requerimientos. Para cumplir con el objetivo establecido, se planteó una metodología para llevar a cabo la transformación de aplicaciones procedimentales a orientadas a objetos, la cual consiste en realizar una investigación en el área de compiladores para estudiar la factibilidad de traducción formal o heurística entre el lenguaje COBOL y el lenguaje Java para su apropiada transformación. La conclusión principal del presente trabajo de tesis se refiere a la factibilidad de llevar a cabo la transformación automática de código escrito en lenguaje COBOL-85 hacia código escrito en lenguaje Java, basándose en equivalencias gramaticales, obteniendo una aplicación con la misma funcionalidad que el código original. El alcance del presente trabajo de tesis es la transformación de variables globales simples y datos definidos por el usuario, así como un subconjunto de instrucciones con palabras reservadas que fueron consideradas para transformar de lenguaje COBOL a lenguaje Java, logrando la definición de una clase general. El trabajo correspondiente a la transformación de código escrito en COBOL que realiza acceso a archivos quedó fuera del alcance de la presente tesis, ese trabajo fue desarrollado en otra tesis. vi Abstract Across the time a large amount of code based on procedures has been developed for different applications and problems domains. The code based on procedures, as it is the case of code written in COBOL language, presents a serie of characteristics that makes difficult its reuse and maintenance. One of the characteristics is that the code presents a low level of cohesion, because sets of operations access different data sets, this is the result of a monolithic structure that characterizes procedural code. For that reason it is necessary to develop strategies to increase its useful time life through its recovery and transformation. The goal of this thesis is to transform code written in COBOL language into code written in Java language based on grammar equivalences, as well as in restructure heuristic methods, to facilitate its reuse, maintenance and future modifications in order to be adapted to new requirements. In order to accomplish the established goal, a methodology to perform the transformation of procedural into object oriented applications is presented, which consists on an investigation in the area of compilers to study the feasibility of formal or heuristic translation between COBOL language and Java language for its appropriate transformation. The most important conclusion of the present thesis work refers to the feasibility to carry out the automatic transformation of code written in COBOL-85 language into code written in Java language, based on grammar equivalences, obtaining an application with the same functionality than the original code. The scope of the present thesis work is the transformation of simple global variables and user defined data types, as well as a subgroup of sentences with reserved words that were considered to transform from COBOL language to Java language, obtaining the definition of a general class. The work corresponding to the transformation of code that access to data files was out of the scope of the present thesis; it was developed in other thesis. vii Capítulo 1. Introducción Capítulo 1) INTRODUCCIÓN Existe una constante necesidad de actualizar y renovar los sistemas en cualquier ámbito, ya sea por la existencia de nuevos requerimientos, la modernización de infraestructura, o bien, por mejora tecnológica. Por ello, en el área de Ingeniería de Software, el tema de la reingeniería (análisis y renovación de los sistemas) ha cobrado mayor importancia en la actualidad, pues las demandas de funciones de negocios y de tecnología de información que los soportan están cambiando a un ritmo impresionante y se necesita mantener el ritmo de los nuevos avances con el objeto de ampliar el tiempo de vida de los actuales sistemas de Software. A través del tiempo, mucho código ha sido desarrollado en lenguajes de procedimientos para diferentes aplicaciones, tal es el caso de sistemas construidos en lenguaje COBOL; hoy se ha hecho necesario pensar en la manera de aumentar su tiempo de vida útil mediante 1 Capítulo 1. Introducción su recuperación y transformación no sólo para continuar usándolos sino también para reusarlos. El Paradigma Procedimental de la programación fue el primer modelo que permitió al hombre crecer rápidamente en el desarrollo de aplicaciones automatizadas; es decir, las operaciones manuales complejas pudieron representarse en la computadora haciendo ágil su ejecución. Sin embargo, se observó que los sistemas implementados bajo el modelo procedimental presentaban varias desventajas. “Los Objetos nacen cuando se observó que el mantenimiento de los sistemas que se implementaron en el modelo procedimental resultaba ser costoso, y el reuso era imposible debido a la inflexibilidad del propio paradigma, además de que las funciones que implementaba el modelo procedimental no modelaban adecuadamente la complejidad de los problemas que se deseaban resolver. Los Objetos intentan representar con mayor precisión los elementos del mundo que envuelve el problema. Los Objetos se modelan como una serie de cualidades (atributos) y una serie de operaciones sobre esas cualidades (métodos), reunidos en un solo paquete (abstracción) que describe, más que a un proceso, a un elemento del dominio del problema, convirtiéndose el Objeto en una forma evolucionada de modelar soluciones a problemas informáticos.” [BAR-00] Todos esos términos son parte de un modelo conocido como el Paradigma Orientado a Objetos. Actualmente, existe una creciente necesidad de reestructurar o llevar a cabo reingeniería sobre antiguos programas implementados en paradigmas procedimentales como consecuencia de querer obtener los beneficios que proveen los nuevos paradigmas y la nueva tecnología. El proceso de reingeniería implica siempre un menor costo cuando se le compara con la opción de abandonar la aplicación existente para rediseñarla comenzando desde la obtención de requisitos. Luego entonces, se prefiere plantear la transformación de código que permita la migración de un paradigma a otro transportando su funcionalidad y sin perderla. 2 Capítulo 1. Introducción El auge del Paradigma Orientado a Objetos ha influido para que la transformación de código basado en procedimientos se plantee en términos de dirigirlo hacia arquitecturas orientadas a objetos o marcos reusables orientados a objetos. La migración de lenguajes procedimentales a lenguajes orientados a objetos se basa tanto en la traducción como en la transformación de los mismos. Los traductores traducen léxica y sintácticamente un programa de un lenguaje a otro lenguaje diferente, al mismo tiempo que conserva la arquitectura de software del sistema. Durante la traducción los artefactos de un lenguaje son expresados en otro lenguaje, sin efectuar cambios significativos a la arquitectura. [PID-98] La transformación es el proceso en el cual la organización de los componentes del sistema es modificado, basado en las relaciones entre componentes. El proceso de transformación de un lenguaje procedimental a un lenguaje orientado a objetos facilita la migración de aplicaciones existentes adaptándolas a un nuevo paradigma, resultando nuevas aplicaciones que posteriormente se pueden extender para incrementar su funcionalidad. Desde luego que para transformar programas de un lenguaje procedimental a uno orientado a objetos hay que modificar la arquitectura original. Por otra parte, para la creación de clases y arquitectura de clases es necesario el empleo de métodos establecidos después de haber realizado una investigación (métodos heurísticos) en lugar de traductores de lenguajes. En la presente tesis se realizó un estudio para la transformación de código en lenguaje procedimental COBOL hacia código orientado a objetos en lenguaje Java, que permite la obtención de métodos formales o heurísticos de traducción para lograr la recuperación y transformación de software legado. 3 Capítulo 1. Introducción El estudio mencionado permitió el desarrollo de una herramienta que permite la traducción de un subconjunto de sentencias escritas originalmente en COBOL-85 a su equivalente sentencia expresada en lenguaje Java. Organización de esta tesis A continuación se muestra un panorama de la organización de este documento que permite describir el trabajo que se realizó para llevar a cabo esta tesis. En el capítulo 2, se presenta un resumen de los trabajos de investigación y productos comerciales relacionados con este tema de investigación y se muestra un análisis comparativo de éstos con respecto al presente trabajo de tesis. Así mismo se plantea la justificación del estudio realizado, se plantea el objetivo de la tesis y se establecen los alcances y los límites de la misma. En el capítulo 3, se hace una revisión de los conceptos y temas relacionados con esta investigación, los cuales permiten mostrar su fundamento teórico. En el capítulo 4, se describe el desarrollo del sistema mostrando al análisis del sistema, la arquitectura del analizador, así como la codificación y descripción de la herramienta C2J desarrollada. En el apartado 4.3, referente a la codificación de la herramienta, se muestran algunas de las acciones semánticas escritas en el analizador de la herramienta desarrollada. En el capítulo 5, se presenta la evaluación experimental llevada a cabo con 3 casos de prueba que muestran la funcionalidad de la herramienta C2J. En el capítulo 6, se presentan las conclusiones del trabajo de tesis así como el trabajo futuro derivado de esta investigación. 4 Capítulo 2. Antecedentes Capítulo 2) ANTECEDENTES 2.1. Estado del arte: trabajos relacionados Como apoyo a la solución del problema de carencia de marcos reusables, en el CENIDET se ha planteado el proyecto denominado “SR2: Reingeniería de Software Legado para Reuso” [SAN-02] El proyecto SR2 presenta la formulación de un modelo para analizar código fuente escrito en lenguaje C y un sistema de reingeniería para la transformación de software basado en procedimientos hacia arquitecturas de marcos de trabajo de componentes reusables escritos en lenguaje C++. El modelo de reingeniería que propone el proyecto SR2 consiste en: • Analizar sistemas de software legado procedimental para construir un marco inicial orientado a objetos cuya arquitectura incluya la estructura de varios patrones de diseño. 5 Capítulo 2. Antecedentes • Madurar y enriquecer ese marco por medio de la incorporación de nuevas clases, nuevas operaciones a las clases existentes y arquitecturas completas de clases. • Refactorizar el marco inicial para refinar su arquitectura, mediante el uso de patrones de diseño. El modelo da como resultado la acumulación de componentes concretos que reducen la necesidad de incorporar nuevo código por herencia. Con lo cual el usuario puede desarrollar nuevas aplicaciones integrando los componentes. A continuación se mencionan los trabajos que forman parte del proyecto SR2 y que en conjunto integran el antecedente de este trabajo de tesis: 1.- “Modelo de Representación de Patrones de Código para la Construcción de Componentes Reusables”. Tesis Doctoral. René Santaolaya Salgado, CIC-IPN, (2002). 2.- “Factorización de Funciones en Métodos de Plantilla”. Tesis de Maestría. Laura Alicia Hernández Moreno, CENIDET, (2003). 3.- “Reestructuración de Código Legado a partir del Comportamiento para la Generación de Componentes Reutilizables”. Tesis de Maestría. César Bustamante Laos, CENIDET, (2003). 4.- “Reestructuración de Software Escrito por Procedimientos Conducido por Patrones de Diseño Composicionales”. Tesis de Maestría. Armando Méndez Morales, CENIDET, (2003). 5.- “Reestructuración de Software Legado Orientado a Objetos Aplicando el Patrón de Diseño Mediator”. Tesis de Maestría. Leonor Adriana Cárdenas Robledo, CENIDET, (2003). 6.- “Integración de la Funcionalidad de Frameworks Orientados a Objetos”. Tesis de Maestría. Juan José Rodríguez Gutiérrez, CENIDET, (2003). 7.- “Adaptación de Interfaces de Marcos de Aplicaciones Orientados a Objetos, Utilizando el Patrón de Diseño Adapter”. Tesis de Maestría. Luis Esteban Santos Castillo, CENIDET, (2003). 6 Capítulo 2. Antecedentes 8.- “Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces”. Tesis de Maestría. Manuel Alejandro Valdés Marrero, CENIDET, (2003). Los trabajos anteriores siguieron en la línea de reestructurar o refactorizar código originalmente escrito en lenguaje C. Sin embargo, existe un gran número de aplicaciones de negocios escritos en lenguaje COBOL, en las que su tiempo de vida está muy próximo a terminarse debido a los altos costos de su mantenimiento y por las adaptaciones a nuevos usos, por lo que se hace necesario pensar en que podrían actualizarse a plataformas modernas. Por ello en el presente trabajo de tesis se propuso implementar el modelo de reingeniería del proyecto SR2 para transformar código legado escrito en Lenguaje COBOL (que es procedimental) hacia Lenguaje Java (que es orientado a objetos), tal como lo muestra la Fig. 2.1, logrando con ello ampliar el tiempo de vida útil de aplicaciones que fueron desarrolladas en COBOL así como también lograr la actualización de esas aplicaciones a una plataforma moderna como lo es la plataforma J2EE. Proyecto SR2 : Software Legado para Reuso Transformación de código en lenguaje COBOL a Java Sistema de Reingeniería para transformar código en lenguaje C a C++ COBOL a Java (ESTA TESIS) Base de datos en COBOL a lenguaje SQL Fig 2.1. Antecedente: Proyecto SR2 El trabajo correspondiente a la transformación de código escrito en COBOL que realiza acceso a archivos fue desarrollado en la tesis denominada “Estudio para la transformación 7 Capítulo 2. Antecedentes de instrucciones de acceso a una base de datos escrita en lenguaje COBOL hacia instrucciones escritas en lenguaje SQL” [LOP-05]. Cabe señalar que para la obtención y refinamiento de las arquitecturas hacia marcos de componentes reusables mejorados se requerirá realizar operaciones de refactorización del código en Java obtenido como resultado final por la herramienta C2J desarrollada en esta tesis. Lo anterior permitirá que el código quede apto para extensión y proporcione facilidades en su mantenimiento y reuso. A continuación se hace una breve reseña de la investigación de trabajos relacionados con el presente trabajo de tesis que si bien se enfocan a la migración entre el paradigma procedimental y el paradigma orientados a objetos no proponen mecanismos de conversión para la transformación automática de código de lenguaje en COBOL a lenguaje Java. En [SNE-95] los autores realizan la extracción de especificaciones orientadas a objetos de un programa procedural en COBOL con ayuda de una herramienta llamada REDOC, que luego de identificar objetos en la división de datos de programas escritos en el lenguaje COBOL, permite que el usuario seleccione aquel o aquellos objetos con el que desea trabajar. La herramienta realiza la extracción automática de operaciones (mediante el seguimiento de los objetos seleccionados) y la conexión de objetos. La diferencia entre REDOC y la herramienta C2J que se presenta en este trabajo de tesis es que al final REDOC proporciona al usuario documentos y gráficas del diseño de la lógica del programa orientado a objetos, pero no proporciona la transformación ni de variables ni de sentencias que en la herramienta C2J si ocurre. Los autores de [NAG-97] desarrollaron un sistema de reestructura de sistemas denominado DORE (Data Oriented Re-engineering) que permite extraer datos base de la aplicación (entidades del mundo real: Orden_de_Compra, Cliente, etc.) y a su vez extraer operaciones fundamentales de cada dato. Como parte complementaria, los autores determinan las 8 Capítulo 2. Antecedentes unidades atómicas de acciones y condiciones relacionadas a los datos base y a sus operaciones. A diferencia de lo presentado en el presente trabajo de tesis, DORE no lleva a cabo la transformación de un sistema procedimental a uno orientado a objetos pues el resultado que proporcionan los autores es la especificación formal del nuevo sistema bajo el paradigma orientado a objetos. En [YAN-97] los autores proponen un método para aplicar ingeniería inversa a programas escritos en COBOL para la obtención de elementos reusables mediante el uso de una herramienta prototipo denominada RA (Reengineering Assistant) cuyo método traduce primero el programa en COBOL a RWSL (Reengineering Wide Spectrum Language), para luego modularizar el código y obtener los Diagramas de Relación de Entidades que se convertirán en componentes reusables, luego de haber pasado la etapa de análisis semántico. Con este método los autores logran obtener una biblioteca de componentes reusables a nivel de diseño, pero no presentan la transformación de COBOL hacia algún lenguaje orientado a objetos que en el presente trabajo de tesis sí se realiza. Los autores de [BRA--97] presentan un método general para definir la gramática de COBOL del código al que se le tiene que dar mantenimiento o se va a someter a reingeniería. Llevan a cabo dos procesos: uno para manipular el código en COBOL y otro para manipular la gramática de COBOL. Ambos procesos de manipulación están relacionados y se complementan para lograr definir una gramática de COBOL libre de construcciones sin significado y libre de ambigüedades, pero no para reestructura de lenguaje a lenguaje o de paradigma a paradigma. En [PID--98] un grupo de investigadores proponen una base conceptual para la migración de una arquitectura de software procedimental hacia otra arquitectura orientada a objetos en lo que respecta al software legado. Este trabajo enfatiza en el ciclo de vida del software, en 9 Capítulo 2. Antecedentes el cual se considera a la reingeniería/reestructura como una actividad inherente a la evolución del software. Los autores proponen métodos de transformación para la migración del comportamiento procedimental al orientado a objetos, los cuales permiten primero identificar una única gran clase que contiene a las variables globales y los métodos implementados en el software procedimental para luego reestructurar la gran clase única en varias clases hijas, las variables globales en variables de clase y ubicar los métodos que accedan a éstas, logrando así la cohesión necesaria en una arquitectura orientada a objetos. Este trabajo no provee aún la transformación a una estructura orientada a objetos, sólo logra la identificación de las clases y objetos candidatos a ser usados en tal arquitectura. En [MIL--02] los autores se enfocan a la reingeniería de código legado en COBOL. Su método consiste en convertir primero el sistema en COBOL a WSL (Wide Spectrum Language) para lograr la identificación de construcciones como if-then-else y while. Después esta representación es analizada con el propósito de identificar los objetos, sus relaciones y sus métodos. A diferencia del presente trabajo de tesis, en éste trabajo relacionado sólo se hace una representación en UML de los objetos identificados que servirá como documentación y que facilitarían una futura transformación hacia el paradigma orientado a objetos. El trabajo relacionado que tiene más parecido con éste trabajo de tesis es el presentado en [MOS--02] en la cual el autor propone un método para la traducción automatizada fuente a fuente que resuelva algunos de los problemas que usualmente se presentan en la conversión de lenguajes. Dirige su estudio a la transformación de aplicaciones implementadas bajo el paradigma procedimental hacia el paradigma orientado a objetos, tal es el caso de la transformación del lenguaje COBOL hacia lenguaje Java. Mossienko divide su trabajo de investigación en tres etapas: 10 Capítulo 2. Antecedentes • La primera etapa consiste en una transición relativamente rápida tomando en cuenta el significado de la traducción de fuente a fuente. • La segunda etapa permite cambios manuales al código generado para implementar la correcta funcionalidad del mismo. • La etapa final permite la refactorización para mejorar el código. El método permite una migración incremental porque cada fase del proceso puede completarse en un período corto de tiempo y después ser mejorado si el tiempo lo permite, pero no garantiza completamente la equivalencia funcional del código generado con el programa inicial. Este método implica también agregar nueva funcionalidad al código original y permite, de ser necesario, el reemplazo gradual y subsecuente de ese código. La diferencia principal que existe entre el trabajo de Mossienko y esta tesis radica en que en esta última, la transformación de código de COBOL a Java se lleva a cabo de forma automática, es decir, se elimina la intervención manual en el proceso mismo. El algoritmo que se desarrolló en el presente trabajo de tesis, genera una única clase contenedora, en la cual se guardan las variables y las sentencias que fueron convertidas a Java durante el proceso de traducción. Así también, como se demuestra en las pruebas que se documentan en el Capítulo 5 de esta tesis, se asegura la equivalencia funcional del código generado con el código original de la aplicación sin hacerle cambio manual alguno. A continuación se muestra una tabla comparativa que resume la comparación de los trabajos relacionados y el presente trabajo de tesis. 11 Capítulo 2. Antecedentes Trabajo Lenguaje Lenguaje origen Sneed Actividad Proceso destino COBOL No indica Documentación de la lógica del ----- programa Nagaoka General General Especificación formal del nuevo Automático sistema orientado a objetos Yang COBOL No indica Obtención de biblioteca de Automático componentes reusables Brand COBOL No indica Definición de gramática en ----- COBOL para reingeniería Millham General General Representación de objetos en ----- UML para su reestructura SR2 C C++ Reestructura Automático Mossienko COBOL Java Transforma No indica Tesis Transforma Automático COBOL Java Tabla 2.1. Tabla comparativa de los trabajos relacionados contra esta tesis Existen también algunas herramientas comerciales relacionadas con el presente trabajo de tesis, mismas que a continuación se mencionan. CORECT: COBOL Transformation Toolkit [HCS-03] Esta herramienta, de la Empresa SoftwareMining, ofrece la facilidad de transformar aplicaciones en COBOL a una variedad de lenguajes tales como Java (J2EE), C#/ASP e incluso ANSI/MF COBOL. SoftwareMining es una empresa que proporciona servicios de conversión, y promete entregar una aplicación escrita en lenguaje Java con la misma funcionalidad de la aplicación COBOL original recibida, por lo que su herramienta no esta a disposición del público. 12 Capítulo 2. Antecedentes Caravel [HCT-04] TransTOOLS proporciona Caravel, una herramienta de reingeniería especializada en la conversión automática de sistemas RPG y COBOL a Java. TransTOOLS promete entregar una aplicación escrita en lenguaje Java con la misma funcionalidad de la aplicación COBOL original, pero no es posible tener acceso a la herramienta puesto que Caravel brinda solo servicios de conversión y no sus herramientas a terceras personas. HAAS : Herramienta de Análisis Avanzado de Software [HCH-00] La empresa Lifia cuenta con la herramienta denominada HAAS, con la cual asegura mejorar aspectos clave de la actividad de reestructuración de código legado en COBOL para su transformación a Java. Todo ello con ayuda de diferentes módulos en los que la herramienta se encuentra estructurada con los que se lleva a cabo el análisis léxico y parseo de sentencias COBOL, chequeo de anomalías en el código fuente, análisis estructural, generación de diagnóstico y reportes para finalmente realizar la transformación del código fuente. La empresa Lifia tiene como actividad principal proveer de servicios de conversión por lo que su compromiso es entregar una aplicación en Java que cuente con la funcionalidad original del código fuente que se va a transformar. LeTS : Legacy eTrans-Formation Service [HCL-03] Comptramatics Corporation cuenta con un servicio para reciclar sistemas legados denominada LeTS, la cual promete proveer de un proceso automatizado que transforma los sistemas legados escritos en COBOL a código orientado a objetos en Java. Ese proceso asegura contar con los siguientes aspectos: 13 Capítulo 2. Antecedentes • Proporciona un servicio automatizado de transformación de código fuente. • Reuso y transformación de todos los aspectos de los sistemas legados. • Produce código en Java bien documentado y completamente mantenible. • El proceso de transformación de LeTS es flexible de tal manera que los módulos resultantes en Java pueden ser fácilmente integrados en ambientes existentes. • Genera código en Java fácil de mantener. Esta herramienta promete entregar una aplicación escrita en lenguaje Java con la misma funcionalidad de la aplicación COBOL original, pero como ya se mencionó, Comptramatics Corporation es un servicio de conversión. Como se puede observar, la diferencia de las herramientas comerciales ya mencionadas con el presente trabajo de tesis radica en que las empresas proveen servicios de conversión que no contemplan la disponibilidad de las herramientas que la llevan a cabo, y en el caso de esta investigación, la metodología que se planteó se implementa en una herramienta denominada C2J que realiza la transformación de forma automática. 2.2. Objetivo El objetivo de la tesis es: Hacer la transformación de código escrito en lenguaje COBOL a código escrito en lenguaje Java basándose en equivalencias gramaticales de código expresado en lenguaje COBOL y en lenguaje Java, así como en métodos heurísticos de reestructura. 2.3. Planteamiento del Problema La funcionalidad de los sistemas existentes cumple en gran medida con las necesidades de las organizaciones. La problemática radica en que ante nuevos requerimientos, cambios en los requerimientos ya existentes o las nuevas necesidades tecnológicas, las aplicaciones desarrolladas en COBOL, que ya cuenta con más de treinta años en el mercado, resulten insuficientes. Sus carencias en aspectos como interfaces gráficas, capacidades multimedia, 14 Capítulo 2. Antecedentes orientación a objetos, independencia de hardware y software resultan un problema cuando la empresa desea alcanzar las necesidades actuales. Poco a poco, los sistemas que fueron desarrollados en lenguaje COBOL van siendo sustituidos por sistemas que aportan las últimas innovaciones tecnológicas optimizando la inversión, como resultado del avance de la tecnología y de la creciente necesidad de que una empresa se mantenga actualizada para lograr así competir en el mercado. Muchas organizaciones optan por la transformación de sus sistemas puesto que ello les ofrece mantener los sistemas de información que mejor se adaptan a las necesidades de la organización y reusar el sistema en el que ha invertido. También les evita los problemas de un nuevo desarrollo (que involucra costos, plazos, fiabilidad) o de la adquisición de un nuevo paquete (con sus problemas de adaptación al nuevo software). Esta tesis proporciona una metodología que permite realizar la transformación de código escrito en COBOL (que es procedimental) hacia Java (que es orientado a objetos), así como una herramienta, denominada C2J, que realiza automáticamente esa transformación. Trabajo realizado con la finalidad de lograr la actualización de aplicaciones procedimentales a nuevas plataformas, para proveerlas de facilidades de extensión a nuevas y mejores funcionalidades sin tener que desarrollar nuevamente las aplicaciones, promoviendo su reuso y su evolución, reduciendo los costos por su mantenimiento. 2.4. Justificación del estudio Desarrollar aplicaciones computacionales bajo el paradigma orientado a objetos actualmente se está convirtiendo en un estándar en el desarrollo de software, tal es el caso de las aplicaciones que han sido desarrolladas con el lenguaje Java que soporta la programación orientada a objetos. Las aplicaciones computacionales que fueron desarrolladas en COBOL, son todavía utilizadas por las empresas que invirtieron en ellas puesto que les provee aún de funcionalidades. Sin embargo, estas aplicaciones han sufrido modificaciones, adaptaciones 15 Capítulo 2. Antecedentes y extensiones, embebidos en el mismo código, lo que ocasiona que estas mismas actividades cada vez sean más costosas cuando se les intenta adaptar a nuevas necesidades de las empresas que impliquen tecnologías actuales, así mismo con las actividades de mantenimiento, por lo cual se ha pensado en la transformación de sistemas de COBOL a Java, situación que promueve el reuso del software. La necesidad de contar con herramientas que permitan transformar la arquitectura de un sistema procedimental hacia una arquitectura orientada a objetos hace necesario plantear métodos que permitan la transformación de una arquitectura a otra conservando la funcionalidad del código o programa original y tomando en cuenta los elementos léxicos y sintácticos de ambos lenguajes así como sus equivalencias funcionales u operacionales. El código resultante de la transformación de COBOL a Java contará con las mejoras propias de la programación orientada a objetos, entre las cuales encontramos mayor cohesión, menor dependencia, menor complejidad, posibilidad de extensión de funcionalidad, adaptación a nuevos usos sin modificar el código actual, etc. El dinamismo en la evolución y transformación de las tecnologías obliga a reestructurar los sistemas que se encuentran en uso y ello hace necesaria la disposición de herramientas que faciliten esa tarea de reestructuración. 2.5. Alcances y límites del estudio A continuación se muestran los alcances del trabajo de tesis: • Análisis de la gramática del lenguaje COBOL-85. La gramática ya mencionada se encuentra especificada en el metalenguaje JavaCC. • Identificación de equivalencias gramaticales entre sentencias expresadas en COBOL y en Java. • La tesis permite el reconocimiento y transformación de: o Variables globales simples. o Registros. 16 Capítulo 2. Antecedentes • Planteamiento de mecanismos formales o heurísticos de traducción de COBOL a Java para un subconjunto de sentencias, las cuales son: o Sentencia Display. o Sentencia Accept. o Sentencia Move. o Sentencia Add completa. o Sentencia Subtract. o Sentencia Multiply. o Sentencia Divide. o Sentencia Compute. o Sentencia If (Se consideran los if anidados) o Sentencia Perform (Se observan los diversos formatos del Perform e incluye el análisis del modificador Perform THRU.) • Desarrollo e implementación de una herramienta que permita la transformación de código escrito en COBOL a código escrito en Java. Las limitaciones que tiene el presente trabajo de tesis son: • La tesis se limita al análisis de código escrito en COBOL-85 estándar, por lo que el código que requiera analizarse con la herramienta obtenida como resultado de este trabajo de tesis deberá estar escrito en esa versión. • Las instrucciones que no se analizaron son: o Sentencia Alter. o Sentencia Evaluate. o Sentencia Goto. o Sentencia Inspect. o Sentencia Search. o Sentencia String o Sentencia Unstring. • No se traducirán sentencias en COBOL que impliquen el acceso a bases de datos. Tal trabajo de traducción es parte del desarrollo de la tesis [LOP-05]. 17 Capítulo 3. Marco Teórico Capítulo 3) MARCO TEÓRICO 3.1. Paradigma Procedimental “Los lenguajes de programación consisten de dos elementos: código y datos. Un programa puede estar conceptualmente organizado en torno a su código o en torno a sus datos, es decir, algunos programas están escritos en función de “lo que está ocurriendo” y otros en función de “quién esta siendo afectado”. Estos son los dos paradigmas que gobiernan la forma en que se construye un programa.” [SCH-01] “La primera de estas formas se denomina modelo orientado al proceso o procedimental. Este enfoque describe un programa como una serie de pasos lineales. Se puede considerar el modelo orientado al proceso como un código que actúa sobre los datos. Los lenguajes basados en procedimientos tales como “C” emplean este modelo con un éxito considerable.” [SCH-01] Sin embargo, cuando se escriben programas bajo este enfoque, surgen problemas a medida que se hacen más largos y más complejos, sobre todo para su mantenimiento. 18 Capítulo 3. Marco Teórico 3.2. Paradigma Orientado a Objetos “El enfoque denominado programación orientada a objetos fue concebida para abordar la creciente complejidad de la programación procedimental. La programación orientada a objetos organiza un programa alrededor de los datos, es decir, objetos, y de un conjunto de interfaces bien definidas con esos datos. Un programa orientado a objetos se puede definir como un conjunto de datos que controlan el acceso al código.” [SCH-01] Los conceptos en los que se apoya esta técnica de programación son: • Abstracción. “Por medio de ella conseguimos no detenernos en los detalles concretos de las cosas que nos interesen en cada momento, sino generalizar y centrarse en los aspectos que permitan tener una visión global del problema.” [CEB99] • Encapsulamiento. “Esta característica permite ver un objeto como una caja negra en la que se ha introducido de alguna manera toda la información relacionada con dicho objeto. Esto nos permitirá manipular los objetos como unidades básicas, permaneciendo oculta su estructura interna.” • [CEB-99] Herencia. “Permite el acceso automático a la información contenida en otras clases”. [CEB-99] Este mecanismo permite crear clases derivadas (especialización) a partir de clases bases (generalización). • Polimorfismo. “Esta característica permite implementar múltiples formas de un mismo método”. [CEB-99] 3.3. Lenguaje de programación COBOL ¿Cómo surge COBOL? “El lenguaje COBOL (Common Organization Business Oriented Languaje), fue el resultado del desarrollo de un proyecto para crear un lenguaje de programación 19 Capítulo 3. Marco Teórico apropiado para trabajos derivados de la actividad comercial y aceptable por cualquier ordenador”. [CEB-98] El resultado de estos trabajos fue publicado en 1960, denominando a esta primera versión COBOL-60. [CEB-98] En 1968, la ANSI (American National Standard Institute), estandarizó el lenguaje COBOL, siendo revisada después en 1974, dando lugar a COBOL ANS-74. En la actualidad es COBOL-85 la última versión revisada del lenguaje COBOL. [CEB-98] ¿Qué es COBOL? Cobol es un lenguaje compilado, es decir, existe el código fuente escrito con cualquier editor de textos y el código objeto (compilado), dispuesto para su ejecución. [CSI-02] Los programas compilados se traducen ordinariamente al lenguaje máquina de la computadora antes de que comience la ejecución, y se requiere de un conjunto de rutinas de apoyo en tiempos de ejecución que simulan operaciones primitivas en el lenguaje fuente para las cuales no existe un análogo cercano en el lenguaje máquina. [CSI-02] COBOL es un lenguaje simple que no maneja apuntadores ni soporta tipos de datos abstractos, entre otras cosas. Esto influye en un mínimo esfuerzo en el estilo de programación. [CSI-02] COBOL respeta elementos gramaticales como verbos y oraciones propios del idioma Inglés. Ello ha hecho que COBOL sea un lenguaje más fácil de leer, más entendible y que sea un lenguaje de programación auto documentado. Tales atributos permiten que sea más fácil el manejo de líneas de código escritas en COBOL para su posible mantenimiento. Los programas escritos en COBOL tienen una estructura jerárquica. Cada elemento de esa jerarquía consiste de uno o más elementos subordinados. La jerarquía consiste en Divisiones, Secciones, Párrafos, Oraciones y Declaraciones. [CSI-02] 20 Capítulo 3. Marco Teórico ¿Qué hace COBOL? COBOL fue diseñado para el desarrollo de aplicaciones de negocios, típicamente aplicaciones orientadas a archivos. [CSI-02] El empleo del lenguaje COBOL es apropiado para el proceso de datos en aplicaciones comerciales, utilización de grandes cantidades de datos y obtención de resultados ya sea por pantalla o impresos. [CSI-02] ¿Qué no hace COBOL? COBOL no fue diseñado para desarrollar por ejemplo un sistema operativo o un compilador que use COBOL. [CSI-02] En contraste con otros lenguajes de programación, COBOL no se concibió para cálculos complejos matemáticos o científicos, de hecho sólo dispone de comandos para realizar los cálculos más elementales, suma, resta, multiplicación y división. [CSI-02] Algunas características de las aplicaciones en COBOL son: [CSI-02] • Las aplicaciones escritas en COBOL son usualmente muy grandes. Muchas aplicaciones en COBOL contienen más de 1 millón de líneas de código. • Las aplicaciones en COBOL son duraderas. La enorme inversión en la creación de aplicaciones que consisten en algunos millones de líneas de código en COBOL hacen que esas aplicaciones no puedan ser descartadas cuando surge algún nuevo lenguaje de programación o nueva tecnología. • Las aplicaciones en COBOL funcionan en áreas de negocios. • Las aplicaciones en COBOL manejan grandes volúmenes de información. 21 Capítulo 3. Marco Teórico 3.4. Lenguaje de programación Java El lenguaje de programación Java fue desarrollado por Sun Microsystems en 1991. [CEB-99] Java es un lenguaje de programación de alto nivel independiente de plataforma tanto en código fuente como en binario. Así que el código producido por el compilador de Java puede transportarse a cualquier plataforma que tenga instalada una máquina virtual de Java y ejecutarse. [CEB-99] Una característica importante de Java es que es un lenguaje de Programación Orientado a Objetos (POO), cuyos conceptos en los que se apoya ésta técnica de programación han sido comentados en la sección anterior. Otras características importantes del lenguaje Java son: [SCH-01] • Es Simple. No requiere de mucha capacitación para poder programar. • Es Seguro. Las aplicaciones desarrolladas en Java y ejecutadas vía Internet no pueden ser modificadas sin autorización. • Es Portable. Puede ejecutarse en diferentes plataformas, gracias a la especificación de una maquina abstracta: la máquina virtual de Java. • Es Robusto. Su manejo de memoria evita los apuntadores. • Es Multihilo. Permite a varias actividades ejecutarse concurrentemente. • Es de arquitectura neutral. El compilador Java genera "Java bytecode" el cual es un formato independiente de cualquier arquitectura, diseñado para transportar código entre diferentes plataformas de hardware y software. • Es Distribuido. Conjunta la filosofía cliente-servidor con el paso de mensajes entre objetos. 22 Capítulo 3. Marco Teórico 3.5. JavaCC JavaCC es un generador de analizadores léxico y sintácticos (parsers) escritos en lenguaje Java. Los analizadores léxicos son componentes de software que manejan secuencias de caracteres y que son incorporados a compiladores o intérpretes según se requiere. [JAV-00] El analizador léxico puede dividir una secuencia de caracteres en subsecuencias llamadas tokens así mismo clasificarlos. El analizador sintáctico analiza la sentencia de entrada de acuerdo a las reglas de un lenguaje y produce un árbol. Ambos componentes son responsables de generar mensajes de error si la entrada no es conforme a las reglas léxicas y sintácticas del lenguaje que se trate. [JAV-00] JavaCC produce analizadores léxicos y sintácticos escritos en Java. [JAV-00] El formato de entrada de JavaCC, contiene una colección de reglas léxicas y sintácticas que describen al lenguaje que va a ser reconocido y un conjunto de acciones semánticas definidas por el usuario para realizar las tareas correspondientes cuando las instrucciones de entrada sean reconocidas. [JAV-00] La salida de JavaCC incluye las siguientes clases: [LUE-02] 1. TokenMgrError. Es la excepción que se lanza cuando se detectan problemas con el reconocimiento de los tokens. También se encarga de que los mensajes de error representen suficiente información al usuario. 2. ParserException. Es la excepción que se lanza cuando el analizador sintáctico encuentra que la entrada no es válida para el parser. 3. Token. Es la clase que encapsula los símbolos terminales que se encarga de obtener el analizador léxico para suministrárselos al analizador sintáctico. 4. Parser. Clase del analizador sintáctico principal. 5. ParserTokenManager. Gestor de símbolos terminales para el analizador contenido en el parser. 23 Capítulo 3. Marco Teórico 6. ParserConstants. Clase que define las constantes utilizadas por el analizador sintáctico. 7. SimpleCharStream. Representa el conjunto de caracteres de entrada. La palabra “parser” en estas clases representa un nombre simbólico, puesto que en realidad dicho nombre es elegido por el usuario de la herramienta. [LUE-02] 24 Capítulo 4. Desarrollo del Sistema Capítulo 4) DESARROLLO DEL SISTEMA 4.1. Metodología de solución 4.1.1. Complejidad del Problema La principal complicación para realizar este trabajo de Tesis se debe a la diferencia de paradigmas de programación de los lenguajes involucrados. Esta diferencia dificulta la identificación de elementos propios de la orientación a objetos (con los que cuenta Java) en el lenguaje COBOL (que es procedimental). Aunado a esto surge un problema de acceso a archivos, debido a que los accesos a archivos en COBOL no tienen traducción directa al lenguaje Java. 25 Capítulo 4. Desarrollo del Sistema A continuación se presenta un ejemplo de la conversión formal entre la estructura gramatical de lenguaje COBOL a lenguaje Java, en el caso específico del uso de un bucle de repetición DO WHILE implementando una rutina que calcula el valor medio de la altura de los alumnos de un determinado curso y finaliza la entrada de datos con un valor 0 para la variable altura. a) En lenguaje COBOL La estructura repetitiva DO WHILE en COBOL se escribe de la siguiente forma: Inicialización de la condición DO WHILE (condición) <sentencias repetitivas> Progresión de la condición ENDDO El conjunto de sentencias puede estar formado por cualquier tipo de sentencias. El funcionamiento de esta estructura es: 1.- Se evalúa la condición. 2.- Si el resultado es CIERTO, se ejecuta el bloque de sentencias repetitivas. 3.- Si el resultado es FALSO, no se ejecuta el bloque de sentencias repetitivas y se continúa en la sentencia siguiente a ENDDO. Para el caso enunciado, la implementación en COBOL quedaría como sigue: MOVE 0 TO SUMA MOVE 0 TO NUM ACCEPT ALTURA DO WHILE (ALTURA < > 0) ADD ALTURA TO SUMA ADD 1 TO NUM ACCEPT ALTURA ENDDO DIVIDE SUMA BY NUM GIVING MEDIA DISPLAY MEDIA 26 Capítulo 4. Desarrollo del Sistema b) En lenguaje Java La estructura repetitiva DO WHILE en Java se escribe de la siguiente forma: while (condición) sentencia; Donde condición es cualquier expresión booleana y sentencia es una sentencia simple o compuesta. El funcionamiento de esta estructura es: 1.- Se evalúa la condición. 2.- Si el resultado de la evaluación es FALSO, la sentencia no se ejecuta y se pasa el control a la siguiente sentencia en el programa. 3.- Si el resultado de la evaluación es VERDADERO, se ejecuta la sentencia y el proceso descrito se repite desde el punto 1. La implementación en Java del ejemplo mencionado quedaría como sigue: suma=0; num=0; altura = System.in.read (); while (altura != 0) { suma+=altura; num++; altura = System.in.read (); } media=suma/num; System.out.println (media); En este trabajo de tesis se llevo a cabo el reconocimiento y la transformación de variables globales y registros, así como de un subconjunto de sentencias ya mencionadas en el Capítulo 2 apartado 2.5. correspondiente a los alcances del estudio. 27 Capítulo 4. Desarrollo del Sistema A continuación se presentan ejemplos del conjunto de sentencias que fueron consideradas para transformar de lenguaje COBOL a lenguaje Java, logrando la definición de una clase general sin descomposición. División DATA COBOL Java 77 Suma PIC 9 VALUE 1. 77 Total PIC 9(5)V99 VALUE ZEROS. 77 Nombre-Cliente PIC X(20) VALUE SPACES. 77 Descuento PIC V99 VALUE .25. 77 Nombre-Estudiante PIC X(6) VALUE ZEROS int Suma=1; float Total=0; String Nombre-Cliente= “ ”; float Descuento=.25; String Nombre-Estudiante=”0”; Estructura Registro public class NombreEstudiante { public String Nombre; public String Apellido; } Declaración del Registro con el nivel 01 Los campos del registro con los niveles del 02 al 49 01 DetallesEstudiante. 02 NoControl PIC 9(7). 02 NombreEstudiante. 03 Nombre PIC X (10). 03 Apellido PIC X (15). 02 FechaNac. 03 Dia PIC 99. 03 Mes PIC 99. 03 Año PIC 9(4). public class FechaNac { public int Dia; public int Mes; public int Año; } public class DetallesEstudiante { int NoControl; NombreEstudiante NombreEst NombreEstudiante(); FechaNac FechaN = new FechaNac(); } = new Tabla 4.1. Reconocimiento de variables globales y registros División PROCEDURE COBOL Java DISPLAY “ RESULTADOS: “ NO ADVANCING. DISPLAY “ A / B = ” RES1 “ B - A = ” RES2. System.out.print (“RESULTADOS: ”); System.out.println (“ A / B = “ + RES1 + “ A - B = “ + RES2); ACCEPT A. String A; InputStreamReader isr = InputStreamReader(System.in); BufferedReader entrada = new BufferedReader(isr); try { A = entrada.readLine() } catch(IOException e){} 77 NOMBRE PIC X(6) 77 NOM PIC X(3) VALUE “ANA” String Nombre; String Nom = “ANA”; MOVE NOM TO NOMBRE MOVE “ANDREA” TO NOMBRE Nombre = Nom; Nombre = “ANDREA”; new 28 Capítulo 4. Desarrollo del Sistema ADD PARCIAL TO TOTAL ADD PARCIAL 20 TO TOTAL ADD PARCIAL PARCIAL2 GIVING TOTAL TOTAL = TOTAL + PARCIAL; TOTAL = TOTAL + (PARCIAL + 20) ; TOTAL = PARCIAL + PARCIAL2 SUBTRACT IMPUESTO FROM PAGO TOTAL PAGO = PAGO – IMPUESTO; TOTAL = TOTAL – IMPUESTO; PAGO = PAGO – (IMP + PENSION + PARCIAL); NETO = PAGO – DEDUCCIONES; SUBTRACT IMP PENSION PARCIAL FROM PAGO SUBTRACT DEDUCCIONES FROM PAGO GIVING NETO MULTIPLY 10 BY TAMANO MAGNITUD MULTIPLY TOTAL PORCIENTO BY VENTAS GIVING DIVIDE 15 INTO CANTIDAD1 CANTIDAD2 DIVIDE TOTAL BY UNIDADES GIVING PROM DIVIDE 215 BY 10 GIVING X REMAINDER REM COMPUTE RESULTADO = 90 - 7 * 3 + 50 / 2 COMPUTE RES = PUNTOS / .78 TAMANO = 10 * TAMANO; MAGNITUD = 10 * MAGNITUD; TOTAL = PORCIENTO * VENTAS; CANTIDAD1 = CANTIDAD1 / 15; CANTIDAD2 = CANTIDAD2 / 15; PROM = TOTAL / UNIDADES; X = 215 / 10; REM = 215 % 10; RESULTADO = 90 - 7 * 3 + 50 / 2; RES = PUNTOS / .78; Tabla 4.2. Reconocimiento de sentencias Estructuras de Control COBOL Java IF Condition THEN { Statement Block | NEXT SENTENCE } [ ELSE { Statement Block | NEXT SENTENCE } ] [ END-IF ] if (condición) { sentencia simple; | sentencia compuesta; } [ else { sentencia simple; | sentencia compuesta; } ] IF Fila > 0 AND Fila < 26 THEN DISPLAY "OK" END-IF if ( Fila > 0 && Fila < 26 ) System.out.println (“OK” ); IF Fila > 0 AND < 26 THEN DISPLAY "OK" END-IF IF NOT Cant1 < 10 OR Cant2 = 50 AND Cant3 > 150 THEN DISPLAY "OK" END-IF if ( ! (Cant1 < 10) || ( Cant2 == 50 && Cant3 > 150 ) ) System.out.println (“OK” ); IF ( VarA < 10 ) AND ( VarB NOT > VarC ) THEN IF VarG = 14 THEN DISPLAY "Primero" ELSE DISPLAY "Segundo" END-IF ELSE DISPLAY "Tercero" END-IF if ( ( VarA < 10 ) && ( VarB <= VarC) ) { if (VarG == 14) System.out.println( "Primero"); else System.out.println("Segundo"); } else System.out.println("Tercero"); Tabla 4.3. Reconocimiento de estructuras de control 29 Capítulo 4. Desarrollo del Sistema Llamados a subrutinas COBOL Java PERFORM [ PROCESO1 ] Hacer el llamado al método que se requiera. PROCEDURE DIVISION. public static void main(String args[]) { System.out.println (“Iniciando el programa. Nivel principal” ); SigNIvel(); System.out.println(“De regreso al nivel principal”); } DISPLAY "Iniciando el programa. Nivel principal". PERFORM SigNivel. DISPLAY "De regreso al nivel principal.". STOP RUN. SigNivel. DISPLAY ">>>> Ahora en el siguiente nivel" private static void SigNIvel() { System.out.println (“>>>>Ahora en el siguiente nivel”); } PERFORM PROCESO1 RepeatCount TIMES La manera de ejecutar este tipo de declaración en Java sería llamar al método tantas veces como lo indique el identificador RepeatCount. Ya sea con un ciclo o con llamadas explícitas. 01 repeticiones PIC 9 VALUE 5. PERFORM ProcesoN repeticiones TIMES En el caso del ejemplo, el ProcesoN deberá ejecutarse 5 veces, tal como lo indica la variable repeticiones. Tabla 4.4. Reconocimiento de llamado a subrutinas 4.1.2. Metodología La metodología que se planteó para resolver el problema que se presenta en la transformación de aplicaciones procedimentales a orientadas a objetos consistió en realizar una investigación en el área de compiladores para estudiar la factibilidad de traducción formal o heurística entre el lenguaje COBOL y Java. Para poder llevar a cabo ese estudio de factibilidad se siguió la metodología que a continuación se describe: • Identificación de equivalencias gramaticales existentes entre los lenguajes COBOL y Java. • Realización de un estudio del metalenguaje JavaCC para la creación de analizadores léxicos, sintácticos y semánticos de la gramática de los lenguajes COBOL y Java. 30 Capítulo 4. Desarrollo del Sistema • Obtención de reglas formales y/o heurísticas de traducción para poder lograr la transformación de COBOL a Java. • Obtención de un algoritmo de traducción que permita llevar a cabo la transformación automática de código escrito en COBOL a lenguaje Java. • Realización de pruebas con código escrito en lenguaje COBOL para su apropiada transformación al lenguaje Java. Entrada Código escrito en COBOL Análisis de código fuente Tablas de información Acciones semánticas Código escrito en Java Salida Fig. 4.1 Metodología de solución La metodología planteada, que se muestra en la Fig. 4.1, toma como entrada código escrito en lenguaje COBOL-85 y como resultado se obtiene código escrito en lenguaje Java que cuenta con la misma funcionalidad del código original proporcionado. 4.2. Análisis del Sistema El objetivo que se persigue con la metodología aplicada en este trabajo es el de solucionar el problema que se presenta en la transformación de aplicaciones procedimentales hacia aplicaciones orientadas a objetos. Esta metodología consiste en realizar una investigación en el área de compiladores para estudiar la factibilidad de traducción formal o heurística entre el lenguaje COBOL y Java. 31 Capítulo 4. Desarrollo del Sistema La figura 4.1 muestra el reporte del análisis del sistema desarrollado en esta tesis modelado con casos de uso de UML. 1.1 <<include>> 1 1 Usuario Analizar archivo escrito en COBOL <<include>> 1.2 Realizar Transformación C2J Llenar tabla de información <<include>> <<include>> 1.3 1.4 Analizar tabla de información Realizar conversión a Java Fig. 4.2 Diagrama Prinicipal de Casos de Uso En el presente trabajo de tesis se utiliza la herramienta JavaCC para generar de forma automática el analizador, por lo que se requiere la gramática de COBOL versión 85 especificada para esa herramienta. Con la gramática del lenguaje COBOL versión 85, la herramienta JavaCC genera, de forma automática, un analizador de sintaxis de programas que han sido escritos en lenguaje COBOL versión 85, el cual se requiere para lograr la identificación de instrucciones o frases léxicas-sintácticas del lenguaje COBOL que podrán ser transformados al lenguaje Java. Para lograr estos resultados, se incluyó el código de las acciones semánticas en la especificación de la gramática del lenguaje COBOL. El analizador de sintaxis generado por JavaCC, ejecuta las acciones semánticas que han sido especificadas en la gramática y como resultado de esas acciones semánticas se logra el llenando de tablas con la información requerida para la identificación de los elementos ya mencionados. A continuación se describen los elementos de la Fig. 4.2 32 Capítulo 4. Desarrollo del Sistema Caso de Uso 1. Realizar Transformación C2J Este caso de uso, iniciado por el usuario de la herramienta C2J, producida en este trabajo de tesis, inicia el proceso de transformación de código escrito en COBOL a Java. Durante el proceso de transformación, el caso de uso principal (Realizar Transformación C2J), hará uso de forma automática de los demás casos de uso mostrados en la Fig. 4.2. Caso de Uso 1.1 Analizar archivo escrito en COBOL 1.1 Analizar archivo escrito en COBOL <<include>> <<include>> <<include>> <<include>> Identificar variables globales Identificar estructuras Identificar métodos Identificar datos usados por los métodos <<include>> <<include>> <<include>> <<include>> <<include>> Identificar Atributos 1.2 Llenar tabla de información Fig. 4.3 Diagrama del Caso de Uso 1.1 (Análizar código escrito en COBOL) En el caso de la Identificación de Variables Globales Simples (VGS) la herramienta generada extrae la información de esas variables y es necesario declarar las acciones semánticas para guardar en una tabla (Caso de Uso 1.2) los datos relativos al nombre de la variable, el tipo de la variable analizada, así como también el valor de inicio y, en el caso de que la variable maneje un rango de valores, el valor final que puede tener la variable. Luego del análisis, esa información, que será vaciada en una tabla, permitirá la transformación de esas variables a su equivalente en lenguaje Java. 33 Capítulo 4. Desarrollo del Sistema La estructura de la tabla de identificación de las VGS encontradas en el código contempla la siguiente información: Identificación de VGS Nombre del VGS Tipo de la Valor Inicial Valor Final VGS Tabla 4.5. Tabla de la identificación de las VGS En el caso de la Identificación de Tipos de Datos definidos por el Usuario (UDT) se requiere extraer información sobre los registros encontrados en el código así como la declaración de la acción semántica necesaria para guardar en una tabla (Caso de Uso 1.2) los datos relativos al nombre del registro, el tipo de dato analizado, así como también el valor de inicio y en el caso de que la variable maneje un rango de valores, el valor final que tendrá la variable correspondiente a la estructura definida por el usuario. Así también se conformaron acciones semánticas que permitieran guardar información de los componentes del registro que se está analizando. Los datos que se almacenan en la tabla de campos de una estructura son: nombre de la UDT, nombre del campo, tipo del campo (por medio de la sentencia PIC, para determinar a qué tipo de dato corresponde en Java), así como los valores inicial y final del campo. A continuación se muestra un fragmento de las acciones semánticas que se introdujeron en el archivo que contiene la gramática de COBOL para el reconocimiento de los registros encontrados en el código escrito en COBOL. void DataDescriptionEntryClause(Variable var) : {String ClausulaPIC = ""; String ClausulaUsage=""; String ClausulaRedefines=""; String ClausulaSeñal=""; String ClausulaSincronized=""; String ClausulaOccurs="";} 34 Capítulo 4. Desarrollo del Sistema { ClausulaPIC = DataPictureClause() {var.Tipo=ClausulaPIC;} | DataValueClause(var) | ClausulaUsage=DataUsageClause() {var.Usage=ClausulaUsage;} | ClausulaRedefines=DataRedefinesClause() {var.Redefine=ClausulaRedefines;} | DataExternalClause() {var.Externo="V";} | DataGlobalClause() {var.Global="V";} | ClausulaSeñal=DataSignClause() {var.Señal=ClausulaSeñal;} | ClausulaOccurs=DataOccursClause() {var.Ocurre=ClausulaOccurs;} | ClausulaSincronized=DataSynchronizedClause() {var.Sincronized=ClausulaSincronized;} | DataJustifiedClause() {var.Justified="V";} | DataBlankWhenZeroClause() {var.Blank="V";} } La estructura de la tabla de identificación de los UDT encontrados en el código se observa en la Tabla 4.6: Identificación de UDT Nombre del UDT Nombre Tipo del Valor Inicial Valor Final del Campo Campo del Campo del Campo Tabla 4.6. Tabla de la identificación de los UDT En el caso de los métodos la herramienta identifica los nombres de los párrafos (que se convertirán en los métodos que se ejecutarán cuando se traduzca a Java) así como el conjunto de sentencias que compondrán el cuerpo del método a obtener. Caso 1.4 Conversión a Java Una vez realizado el análisis del código escrito en COBOL y realizado el llenado de las tablas de símbolos correspondientes a los elementos que se transformarán a Java, la herramienta C2J comienza con el análisis de las tablas para realizar la transformación, la cual incluye los casos de uso que se muestran en la figura 4.4. 35 Capítulo 4. Desarrollo del Sistema Crear archivo de escritura Crear una única clase contenedora <<include>> <<include>> <<include>> 1.4 1.4 Convertir datos globales a variables públicas <<include>> <<include>> <<include>> 1.3 1.3 Realizar conversión a Java Convertir estructuras a clases de objetos <<include>> Analizar tabla de información <<include>> <<include>> <<include>> Declarar los métodos encontrados Realizar conversión sintáctica de instrucciones en COBOL a Java Obtener archivo en Java Fig. 4.4 Diagrama del caso de uso 1.4 (Realizar conversión a Java) A continuación se ilustran los elementos de la Fig. 4.4 que contiene los pasos que se siguen para llevar a cabo la conversión de código escrito en COBOL a Java. La figura 4.5 muestra el resultado de la conversión de una estructura, utilizada en los programas escritos en COBOL, a su equivalente en lenguaje Java. En caso de encontrar alguna estructura en el código escrito en COBOL, se incluiría su conversión a Java a la única clase contenedora que genera la herramienta para realizar la conversión a Java. Después de la conversión Antes de la conversión Programa Principal Codificación Data Division Working-Storage Section 01 Registro 02 Codigo PIC 9(4) 02 Nombre PIC X(30) 02 Direccion PIC X (15) 02 Promedio PIC 9V99 class Registro { int Codigo; String Nombre; String Dirección; float Promedio; } Registro Clase Contenedora única Nombre int Codigo; String Nombre; String Direccion; float Promedio; Fig. 4.5 Convertir estructuras a clases de objetos 36 Capítulo 4. Desarrollo del Sistema La figura 4.6 ilustra un ejemplo de conversión de COBOL a Java. La figura muestra la conversión de datos globales a variables públicas, la creación del método main que permitirá la ejecución del programa en Java, así como el resultado de la conversión de párrafos a métodos así como las sentencias que contiene cada método encontrado. Antes de la conversión Después de la conversión Programa Principal Data Division Working-Storage Section A PIC X(15) B PIC X(5) VALUE "LUNES" import java.io.*; class Principal { public static String A; public static String B="LUNES"; public static InputStreamReader isr = new InputStreamReader(System.in); public static BufferedReader entrada = new BufferedReader(isr); Procedure Division INICIO Perform Metodo1 Perform Metodo2 STOP RUN. public static void main(String[] args) { Metodo1(); Metodo2(); } Metodo1. DISPLAY "TECLEE NOMBRE" ACCEPT A DISPLAY A. public static void Metodo1() { try { System.out.println("TECLEE NOMBRE"); A = entrada.readLine(); System.out.println(A) } catch(IOException e){} } Metodo2. Perform Metodo3 DISPLAY "TECLEE DIA" ACCEPT B DISPLAY B. public static void Metodo2() { try { Metodo3(); System.out.println("TECLEE DIA"); B = entrada.readLine(); System.out.println(B) } catch(IOException e){} Metodo3. DISPLAY B. } public static void Metodo3() { System.out.println(B); } } Fig. 4.6 Conversión de datos globales y métodos Diseño Detallado del Sistema La figura 4.7 muestra el diagrama de secuencia del escenario principal de éxito de la herramienta. En ella interviene la interfaz del usuario vista como una clase (ReconocedorC2J), la clase CobolParser es el parser generado con la herramienta 37 Capítulo 4. Desarrollo del Sistema JavaCC que permite realizar el análisis del archivo origen escrito en COBOL así como la obtención de información con la cual se realizará la transformación de lenguaje COBOL a lenguaje Java al ejecutarse la clase Conversión. Reconocedor C2J : Usuario iniciar () seleccionar archivo () CobolParser Conversión Proporciona información para la conversión RealizarAnálisis () Genera la clase contenedora y la llena con las sentencias converttidas a Java Crear clase Java () Fig. 4.7. Diagrama de Secuencia del escenario de éxito 4.3. Arquitectura de la Herramienta La figura 4.8 ilustra la arquitectura de la herramienta generada, la cual permite realizar los Casos de Uso que a continuación se enlistan: a) Caso de Uso 1.1 Analizar archivo escrito en COBOL b) Caso de Uso 1.2 Llenar tablas de información La arquitectura muestra que la clase parser hace uso de la clase CobolParser, con la cual inicia el análisis del archivo escrito en COBOL. La clase CobolParser hace uso de todas las demás clases para llevar a cabo el parseo de cada token encontrado durante el análisis y muestra en determinado momento la ocurrencia de errores o excepciones que pudieron haber sido encontrados durante el proceso. Luego de hacer uso del analizador ya mencionado se continúa con el Caso de Uso 1.3 Analizar las tablas de información y el Caso de Uso 1.4 Realizar Conversión a Java haciendo uso de la Base de Datos generada por el analizador para identificar las sentencias que se transformarán de COBOL a Java. 38 Capítulo 4. Desarrollo del Sistema parser (from testparser) ColUDT _udts parse() Resultados() main() parser() handleEv ent() (from ObjetosDB) Analiza (from testparser) Registros() UDT (from ObjetosDB) _Conv ierte Conv ierte ColVariables bd (from ObjetosDB) (from ObjetosDB) Nombre : String Campo : String TipoCampo : String ValorI : String ValorF : String _v ariables $_v ariables (from testparser) $_temporal CobolParser Procesos (from testparser) (from ObjetosDB) Proceso : String LI : int LF : int $_datos GuardarPVGS() GuardarPUDT() ColDatos Variable (from ObjetosDB) Niv el : String Nombre : String Tipo : String ValorI : String ValorF : String (from ObjetosDB) Fig. 4.8 Diagrama de la arquitectura de la herramienta 4.4. Codificación de la Herramienta Una vez realizado el análisis del código escrito en COBOL y el llenado de las tablas con información correspondiente a los elementos que se transformarán a Java, se continúa con la etapa de análisis de esas tablas para transformar las variables y los registros encontrados para generar la sentencia correspondiente en lenguaje Java mediante algunas clases generadas que lo realizan de forma automática. Las acciones semánticas introducidas en el analizador permiten el reconocimiento y conversión de los elementos que a continuación se mencionan: • Variables globales simples. • Registros. • Sentencia Display. • Sentencia Accept. • Sentencia Move. • Sentencia Add completa • Sentencia Subtract 39 Capítulo 4. Desarrollo del Sistema • Sentencia Multiply • Sentencia Divide • Sentencia Compute • Sentencia If (Se consideran los if anidados) • Sentencia Perform (Se observan los diversos formatos del Perform e incluye el análisis de el modificador perform TRHU.) Enseguida se muestran ejemplos de las acciones semánticas, escritas en letras itálicas y negritas, introducidas en el archivo que contiene la gramática de COBOL 85 que se utilizó para lograr la conversión de lenguaje COBOL a Java. A continuación, se muestran de manera parcial las acciones semánticas introducidas en la gramática con la cual se trabajó para la identificación de la sentencia Divide así como de la sentencia de control IF existentes en COBOL: ColDatos DivideStatement() : { String dato1="", dato2="",sentencia=""; String res="", residuo=""; String redondeo="", tipo=""; ColDatos datos2 = new ColDatos(); ColDatos resultados = new ColDatos(); ColDatos sentencias = new ColDatos(); ColDatos redondear1 = new ColDatos(); ColDatos redondear2 = new ColDatos(); ColDatos redondear3 = new ColDatos(); int formato=0, i, decimales=0; } { <DIVIDE> ( dato1 = QualifiedDataName() | dato1 = Literal() ) ( <INTO> ( (dato2 = Identifier() [ <ROUNDED> {redondeo="si";} ] {datos2.Agregar(dato2);redondear1.AgregarSentencia(redondeo); redondeo="no";} )+ {formato=1;} | dato2 = Literal() { formato=6;} ) [ <GIVING> ( res = Identifier() [ <ROUNDED> {redondeo="si";} ] 40 Capítulo 4. Desarrollo del Sistema {resultados.Agregar(res);redondear2.AgregarSentencia(redondeo); redondeo="no";} )+ {formato=2;} ] | <BY> ( dato2 = Identifier() | dato2 = Literal() ) [ <GIVING> ( res = Identifier() [ <ROUNDED> {redondeo="si";} ] {resultados.Agregar(res);redondear3.AgregarSentencia(redondeo); redondeo="no";} )+ {formato=3;} ] ) [<REMAINDER>residuo=Identifier() {if (formato==2) formato=4; if (formato==3) formato=5;} ] ... Luego de estas acciones semánticas existen otras que permiten finalizar la conversión de determinado formato de la sentencia Divide localizada en el código analizado. ColDatos IfStatement() : { String condicion=""; String sentencia=""; ColDatos sentencias = new ColDatos(); ColDatos acciones = new ColDatos(); int i; } { <IF> {sentencia="if ";} condicion = Condition() { if ( !(condicion.startsWith("(")) ) { sentencia = sentencia + "(" + condicion + ")"; } else { sentencia = sentencia + condicion; } sentencias.AgregarSentencia(sentencia); sentencia="{ //llave de apertura de if"; sentencias.AgregarSentencia(sentencia); } [ <THEN> ] ( ( acciones = Statement() { for (i=0;i < acciones.getTotal(); i++) { sentencia = acciones.getConIndice(i); sentencias.AgregarSentencia(sentencia); } } )+ 41 Capítulo 4. Desarrollo del Sistema { acciones.Destruir(); sentencia="} //llave de cierre de if"; sentencias.AgregarSentencia(sentencia); } ... La gramática de COBOL con la que se trabajó en la presente tesis es para COBOL versión 85 por lo cual se tienen algunas restricciones para el código que se proporcionará en COBOL para su conversión, mismas que se deberán cubrir para que no sean generados errores de análisis. Las limitaciones del analizador resultante son: • No se reconocen los modificadores de la sentencia Accept, es decir, la gramática con la que se trabajó no cuenta con el formato extendido, como es el caso de situarse en una posición determinada del cursor para leer alguna variable. Por lo cual sólo se acepta la ocurrencia del Accept de la siguiente forma: Accept NombreVariable. • No se reconocen los modificadores de la sentencia Display, es decir, la gramática con la que se trabajó no cuenta con el formato extendido, como es el caso de situarse en una posición determinada del cursor para desplegar alguna información. • No se reconoce el manejo de tablas o arreglos que son accedidos mediante un índice y con cuyos valores se lleva a cabo algún tipo de operación o asignación. • La gramática que se utilizó no permite que se coloque un punto final en las sentencias en COBOL que componen un párrafo, pues ello denota el fin de las sentencias a llevar a cabo, por lo que únicamente al finalizar el párrafo se acepta la ocurrencia del punto. • La gramática sólo reconoce los comentarios que inician con un asterisco seguido de un signo de mayor que (*>). 42 Capítulo 4. Desarrollo del Sistema 4.5. Herramienta C2J desarrollada A continuación se describe el funcionamiento de la herramienta denominada C2J misma que es el resultado de este trabajo de tesis y que podrá ser utilizada por el usuario que pretenda convertir código de COBOL a Java. Al ejecutarse la herramienta, el único menú que presenta es el denominado Conversión C2J mismo que permitirá dar propiamente inicio a la conversión o bien, salir de la herramienta si así se desea. La ventana secundaria que presenta esta herramienta es la denominada Bitácora de Análisis la cual tiene como finalidad mostrar el avance de la conversión de COBOL a Java indicando la finalización de cada una de las etapas del análisis del código fuente (variables globales y registros, su conversión a Java, los procesos que se convertirán a métodos, así como la finalización de la conversión). Para iniciar la conversión de COBOL a Java se deberá dar un clic a la opción del menú llamada Conversión C2J -> Iniciar Conversión tal como se muestra en la figura 4.9 Fig. 4.9 Inicio de la conversión de COBOL a Java 43 Capítulo 4. Desarrollo del Sistema Luego de haber realizado esta acción se muestra la ventana de la figura 4.10 que permite al usuario seleccionar el archivo origen escrito en COBOL que se convertirá a Java. Fig. 4.10 Selección de archivo a convertir Una vez que se da clic en el botón Abrir la herramienta mostrará la pequeña ventana de la figura 4.11 para confirmar el inicio del análisis del archivo seleccionado. Fig. 4.11 Confirmación del inicio del análisis Después de que la herramienta lleva a cabo la Etapa de Análisis del archivo origen escrito en COBOL y realiza el llenado de las tablas de información se inicia la conversión a Java que permite la transformación del código en COBOL y permite la obtención de una clase en Java. En la ventana secundaria denominada Bitácora de Análisis, la herramienta muestra un resumen de lo realizado por la herramienta. Al hacer uso de la barra de desplazamiento, el usuario podrá observar que en la bitácora de análisis se muestra información de las variables, registros y métodos encontrados, así como también, indica la finalización de cada una de las etapas que lleva a cabo la herramienta (análisis, llenado de tablas de símbolos y conversión a Java) tal como lo muestran las figuras 4.12 y 4.13: 44 Capítulo 4. Desarrollo del Sistema Fig. 4.12 Información de la bitácora de análisis (Variables encontradas) Fig. 4.13 Información de la bitácora de análisis (Métodos encontrados) La clase generada por la herramienta queda guardada en C:\temp\, tal como lo muestra la figura 4.14, ésta consiste en una clase única contenedora de las variables y sentencias convertidas de COBOL a Java, como se muestra en la figura 4.15. Tal clase será la que 45 Capítulo 4. Desarrollo del Sistema el usuario deberá compilar para poder ejecutar y obtener la funcionalidad con que contaba el código originalmente escrito en COBOL. Fig. 4.14 Clase generada por la herramienta C2J Fig. 4.15 Contenido de la clase generada por la herramienta C2J 46 Capítulo 5. Evaluación Experimental Capítulo 5) EVALUACIÓN EXPERIMENTAL Para realizar la evaluación experimental se establecieron determinados requisitos con que deben cumplir las pruebas realizadas. Esos requisitos se describen a continuación: Objetivo de las pruebas: Evaluar la funcionalidad de la herramienta C2J para generar código escrito en lenguaje Java a partir de código escrito en lenguaje COBOL-85. Especificaciones de entrada: El código fuente debe estar libre de errores así como observar las restricciones de la gramática de COBOL-85 por lo que, el código deberá ser revisado y, en caso de que se requiera, ser sustituido de manera adecuada. Por ejemplo para la instrucción ACCEPT deberá editarse el programa para eliminar los modificadores que indiquen línea y posición de lo que se leerá a través del teclado y sólo se indique el nombre de la variable que se pretende aceptar por medio del teclado. 47 Capítulo 5. Evaluación Experimental Especificación de salida. A la salida del proceso de conversión de código escrito en COBOL a código escrito en Java se deberá tener el código escrito en lenguaje Java que corresponde a la funcionalidad del código original escrito en COBOL correspondiente al caso de prueba que se esté realizando, exceptuando la conversión de sentencias que realizan acceso a archivos puesto que quedan fuera del alcance del presente trabajo de tesis. 5.1. Caso de Prueba: C2J-01 Artículo de prueba: Average0.cbl Average0 es un programa escrito en lenguaje COBOL, el programa esta hecho para la obtención del promedio de tres calificaciones logradas por dos alumnos, así como indicar si el alumno fue aprobado o no. La figura 5.1, muestra el primer caso de prueba ejecutándose en modo MS-DOS, como funcionan las aplicaciones COBOL originales. Fig. 5.1 Ejecución del código del primer caso de prueba Especificación de entrada. La entrada al proceso de conversión de código escrito en COBOL a código escrito en Java es el código fuente del programa Average0.cbl que se muestra en el Anexo A. 48 Capítulo 5. Evaluación Experimental Resultados Obtenidos. Los resultados obtenidos se presentan en las figuras 5.2 y 5.3, mismas que muestran la ejecución de la herramienta C2J al convertir el código original del primer caso de prueba: Fig. 5.2 Ejecución de la Herramienta C2J con el código del primer caso de prueba Como resultado de la ejecución de la herramienta C2J con el archivo Average0 se obtiene un archivo escrito en Java que contiene las sentencias que se ejecutarán al compilar el archivo y que proporcionarán la funcionalidad del archivo original escrito en COBOL. 49 Capítulo 5. Evaluación Experimental Fig. 5.3 Obtención del archivo escrito en Java La figura 5.4 muestra el resultado de la ejecución del archivo escrito en Java, (luego de haberlo compilado) que se obtuvo como resultado de ejecutar la herramienta con el primer caso de prueba: Fig. 5.4 Ejecución del archivo escrito en Java Como se puede observar, la salida de la ejecución del programa tanto en COBOL como en Java no tienen un formato de posición en la pantalla, pues como ya se comentó, la versión de la gramática con la que se trabajó no permite los modificadores de posición 50 Capítulo 5. Evaluación Experimental de la sentencia DISPLAY, por lo que se eliminaron del archivo original escrito en COBOL, por lo demás, la funcionalidad es la misma. El detalle del resultado de la ejecución del primer caso de prueba se encuentra en el Anexo A de este documento de tesis. 5.2. Caso de Prueba: C2J-02 Objetivo de la prueba: Evaluar la funcionalidad de la herramienta C2J para generar código escrito en lenguaje Java a partir de código escrito en lenguaje COBOL-85. Artículo de prueba: varios.cbl varios.cbl es un programa en lenguaje COBOL, el cual es una recopilación de programas escritos en lenguaje COBOL obtenidos de [ALC-92] y de [FAG-04] que están hechos para obtener el mayor de tres números, listar los números primos menores a 50 y proporcionar los datos del sueldo mínimo y máximo de un grupo de cinco trabajadores. Esas rutinas fueron incluidas en un menú general que permitirá la ejecución de cada uno de los programas ya mencionados. Las figuras 5.5, 5.6 y 5.7 muestran el segundo caso de prueba ejecutándose en modo MS-DOS, como funcionan las aplicaciones COBOL originales. Fig. 5.5 Primera parte de la ejecución del código del segundo caso de prueba 51 Capítulo 5. Evaluación Experimental Fig. 5.6 Segunda parte de la ejecución del código del segundo caso de prueba Fig. 5.7 Tercera parte de la ejecución del código del segundo caso de prueba Especificación de entrada. La entrada al proceso de conversión de código escrito en COBOL a código escrito en Java es el código fuente del programa varios.cbl que se muestra en el Anexo B. 52 Capítulo 5. Evaluación Experimental Resultados Obtenidos. Los resultados obtenidos se presentan en la figura 5.8 y 5.9, mismas que muestran la ejecución de la herramienta C2J al convertir el código original del segundo caso de prueba: Fig. 5.8 Ejecución de la Herramienta C2J con el código del segundo caso de prueba Como resultado de la ejecución de la herramienta C2J con el archivo varios.cbl se obtiene un archivo escrito en Java que contiene las sentencias que se ejecutarán al compilar el archivo y que proporcionarán la funcionalidad del archivo original escrito en COBOL. 53 Capítulo 5. Evaluación Experimental Fig. 5.9 Obtención del archivo escrito en Java Las figuras 5.10, 5.11 y 5.12 muestran el resultado de la ejecución del archivo escrito en Java, (luego de haberlo compilado) que se obtuvo como resultado de ejecutar la herramienta con el segundo caso de prueba: Fig. 5.10 Ejecución del archivo escrito en Java 54 Capítulo 5. Evaluación Experimental Fig. 5.11 Ejecución del archivo escrito en Java Fig. 5.12 Ejecución del archivo escrito en Java Como se puede observar, la salida de la ejecución del programa tanto en COBOL como en Java no tienen un formato de posición en la pantalla, pues como ya se comentó, la versión de la gramática con la que se trabajó no permite los modificadores de posición de la sentencia DISPLAY, por lo que se eliminaron del archivo original escrito en COBOL, por lo demás, la funcionalidad es la misma. El detalle del resultado de la ejecución del segundo caso de prueba se encuentra en el Anexo B de este documento de tesis. 55 Capítulo 5. Evaluación Experimental 5.3. Caso de Prueba: C2J-03 Objetivo de la prueba: Evaluar la funcionalidad de la herramienta C2J para generar código escrito en lenguaje Java a partir de código escrito en lenguaje COBOL-85. Artículo de prueba: ALUMNO2.cbl ALUMNO2 es un programa escrito en lenguaje COBOL por Job Vega López (tal como indican los primeros comentarios del código mismo), este código fue descargado de internet y se utiliza sólo como caso de prueba. El programa esta hecho para permitir dar de alta a un archivo de organización indexada los datos generales de alumnos tal como son: Código, Nombres, Apellidos, Sexo, Edad y Estado Civil. Si bien la presente herramienta no convierte las sentencias que realicen acceso a archivos, el presente caso de prueba servirá para mostrar que la herramienta obtiene correctamente la conversión de las demás sentencias y que después de incluir manualmente la conversión a Java de las sentencias que realizan acceso a archivos, la aplicación resultante funcionaría correctamente. La figura 5.13, muestra el tercer caso de prueba ejecutándose en modo MS-DOS, como corren las aplicaciones COBOL originales. Fig. 5.13 Ejecución del código del tercer caso de prueba 56 Capítulo 5. Evaluación Experimental Los datos que captura esta aplicación por medio del teclado son guardados en un archivo denominado ALUMNO.dat. En la figura 5.14 se muestra el contenido del archivo ya mencionado luego de ejecutar la aplicación del tercer caso de prueba con los datos mostrados en la figura 5.13. Fig. 5.14 Contenido del archivo ALUMNO.dat Especificación de entrada. La entrada al proceso de conversión de código escrito en COBOL a código escrito en Java es el código fuente del programa ALUMNO2.cbl que se muestra en el Anexo C. Resultados Obtenidos. Los resultados obtenidos se presentan en la figura 5.15 y 5.16, mismas que muestran la ejecución de la herramienta C2J al convertir el código original del tercer caso de prueba: 57 Capítulo 5. Evaluación Experimental Fig. 5.15 Ejecución de la Herramienta C2J con el código del tercer caso de prueba Fig. 5.16 Obtención del archivo escrito en Java Como resultado de la ejecución de la herramienta C2J con el archivo ALUMNO2 se obtiene un archivo escrito en Java que contiene las sentencias que se ejecutarán al compilar el archivo y que proporcionarán la funcionalidad del archivo original escrito en COBOL, con excepción de las sentencias que realizan acceso a archivos por no ser parte del alcance del presente trabajo de tesis. 58 Capítulo 5. Evaluación Experimental Como se explicó antes, en el código que contiene el archivo ALUMNO2.cbl se realiza acceso a un archivo, en el presente caso de prueba se incluyó de forma manual la conversión de esas instrucciones que realizan acceso a archivos así como las variables que se encuentran en la sección SECTION FILE, solo para mostrar la funcionalidad completa de la aplicación resultante en Java. Las figuras 5.17 y 5.18 muestra el resultado de la ejecución del archivo escrito en Java, luego de haber incluido las instrucciones de acceso a archivos convertidas a Java, las variables de la sección SECTION FILE convertidas a Java así como después de haber compilado el archivo final en Java: Fig. 5.17 Ejecución del archivo escrito en Java 59 Capítulo 5. Evaluación Experimental Fig. 5.18 Contenido de la tabla creada para guardar información Como se puede observar, la salida de la ejecución del programa tanto en COBOL como en Java no tienen un formato de posición en la pantalla, pues como ya se comentó, la versión de la gramática con la que se trabajó no permite los modificadores de posición de la sentencia DISPLAY, por lo que se eliminaron del archivo original escrito en COBOL. Por lo demás, luego de haber incluido manualmente las sentencias que realizan acceso a archivos, la funcionalidad es la misma. El detalle del resultado de la ejecución del tercer caso de prueba se encuentra en el Anexo C de este documento de tesis. 60 Capítulo 6. Conclusiones y Trabajo Futuro Capítulo 6) CONCLUSIONES Y TRABAJO FUTURO 6.1. Conclusiones El presente trabajo de tesis da continuidad a los trabajos derivados del proyecto SR2 los cuales implementan métodos de reestructura para transformar código escrito en lenguaje C a código en C++, así como métodos de refactorización para mejorar la arquitectura de un marco de aplicaciones orientado a objetos. El presente trabajo de tesis implica la transformación de un lenguaje procedimental (COBOL-85) a un lenguaje orientado a objetos (Java), proceso que no se había realizado en los trabajos ya mencionados. Con este trabajo de tesis se concluye que es factible llevar a cabo la transformación automática de código escrito en lenguaje COBOL-85 hacia código escrito en lenguaje Java, obteniendo una aplicación con la misma funcionalidad que el código original, basándose en equivalencias gramaticales de código expresado en lenguaje COBOL y en lenguaje JAVA, con lo cual se cumple con el objetivo inicialmente planteado en la presente tesis. 61 Capítulo 6. Conclusiones y Trabajo Futuro La metodología que se desarrolló en el presente trabajo de tesis permite la transformación de código escrito en lenguaje COBOL-85, que es procedimental, hacia código en lenguaje Java que es un lenguaje orientado a objetos, lo cual permite contar con las facilidades de extensión y de mantenimiento de software propios del paradigma orientado a objetos. Como aportaciones de esta tesis se encuentran: • Un método de transformación de código escrito en COBOL-85 hacia código escrito en lenguaje Java. El método recibe como entrada código escrito en lenguaje COBOL-85 y obtiene como resultado una única clase contenedora de las sentencias convertidas a lenguaje Java conservando la misma funcionalidad que el código fuente en lenguaje COBOL-85. • El método de transformación que se aplicó en este trabajo de tesis podría servir de base para la transformación de algún otro lenguaje procedimental hacia un lenguaje orientado a objetos, adaptándolo a las peculiaridades del lenguaje procedimental del que quisiera realizarse la transformación. • Al aplicar el método de transformación de aplicaciones desarrolladas originalmente en lenguaje COBOL-85, éstas podrán ser convertidas a aplicaciones escritas en lenguaje Java que cuenten con facilidades de extensión y mantenimiento, lo cual promueve el reuso de aplicaciones procedimentales. • El método ya descrito se implementó en la Herramienta C2J, desarrollada para llevar a cabo la transformación de código escrito en lenguaje COBOL-85 hacia código escrito en Java. • La Herramienta C2J se desarrolló en lenguaje Java, haciendo uso de un parser o analizador sintáctico de código escrito en lenguaje COBOL-85 desarrollado con el generador de parsers JavaCC. 62 Capítulo 6. Conclusiones y Trabajo Futuro 6.2. Trabajos Futuros • Completar la gramática de COBOL-85 para JavaCC, en lo referente a los formatos aceptados en las diversas sentencias del lenguaje COBOL-85, con el propósito de realizar el análisis de código sin necesidad de editarlo para que el analizador lo acepte y así poder realizar la transformación completa de los archivos fuente. • Se podrían implementar la misma metodología del presente trabajo de tesis para diversas versiones de COBOL para generar analizadores que permitieran la transformación de ese lenguaje a Java. • Realizar el análisis de las sentencias no contempladas en esta tesis, mismas que se detallaron en el Capítulo 2 en el apartado de alcances y límites. • Integración de la herramienta C2J desarrollada en este trabajo de tesis con la herramienta que se encarga de convertir las sentencias que realizan acceso a archivos obtenida como resultado de la tesis denominada “Estudio para la transformación de instrucciones de acceso a una base de datos escrita en lenguaje COBOL hacia instrucciones escritas en lenguaje SQL” [LOP-05] , con la finalidad de lograr la conversión completa de las aplicaciones en COBOL-85 a Java. • Aplicar métodos de refactorización al código escrito en Java resultante de la ejecución de la Herramienta C2J, para obtener una mejor arquitectura orientada a objetos en lugar de una única clase que se obtiene como resultado actual de este trabajo de tesis. 63 Anexo A. Código original y resultados del caso de prueba C2J-01 ANEXO A. CÓDIGO ORIGINAL Y RESULTADOS DEL CASO DE PRUEBA C2J-01 Código original del caso de prueba C2J-01. IDENTIFICATION DIVISION. PROGRAM-ID. PROMEDIOS. AUTHOR. AVILA MELGAR ERIKA. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 77 NC PIC 9(10). 77 NOMBRE PIC A(30). 77 CALIF1 PIC 9(3). 77 CALIF2 PIC 9(3). 77 CALIF3 PIC 9(3). 77 X PIC 9(2) VALUE 8. 77 I PIC 99 VALUE 1. 77 PROMEDIO PIC 9(5). 77 PROMEDIO1 PIC 999.99. 77 A PIC X(78) VALUE ALL "&". 77 FECHA PIC 9(6). 77 CONT PIC 99 VALUE 1. 77 SUMA PIC 9(3) VALUE ZERO. PROCEDURE DIVISION. INICIO. DISPLAY " " ACCEPT FECHA FROM DATE 64 Anexo A. Código original y resultados del caso de prueba C2J-01 DISPLAY FECHA DISPLAY "REPORTE GENERAL DE PROMEDIOS" DISPLAY A DISPLAY "NO.CONTROL" DISPLAY "NOMBRE" DISPLAY "CALIF1" DISPLAY "CALIF2" DISPLAY "CALIF3" DISPLAY "PROMEDIO" DISPLAY "APROBADO" PERFORM PROMEDIOS UNTIL I > 2 STOP RUN. PROMEDIOS. ACCEPT NC ACCEPT NOMBRE ACCEPT CALIF1 ACCEPT CALIF2 ACCEPT CALIF3 COMPUTE SUMA = (CALIF1 + CALIF2 + CALIF3) COMPUTE PROMEDIO = SUMA / 3 MOVE PROMEDIO TO PROMEDIO1 DISPLAY PROMEDIO1 IF(PROMEDIO > 70) DISPLAY "SI" END-IF IF(PROMEDIO < 70) DISPLAY "NO" END-IF ADD 1 TO I ADD 1 TO X. Código en Java obtenido como resultado import java.io.*; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Date; class PROMEDIOS { public static int NC; public static String NOMBRE; public static int CALIF1; public static int CALIF2; public static int CALIF3; public static int X=8; public static int I=1; 65 Anexo A. Código original y resultados del caso de prueba C2J-01 public static int PROMEDIO; public static double PROMEDIO1; public static String A="&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"; public static int FECHA; public static int CONT=1; public static int SUMA=0; public static InputStreamReader isr = new InputStreamReader(System.in); public static BufferedReader entrada = new BufferedReader(isr); public static NumberFormat nf= NumberFormat.getInstance(); public static String temporal=""; public static Date fecha=new Date(); public static SimpleDateFormat sdf=new SimpleDateFormat("yyMMdd"); public static void main(String[] args) { System.out.println(" "); FECHA = Integer.parseInt(sdf.format(fecha)); System.out.println(FECHA); System.out.println("REPORTE GENERAL DE PROMEDIOS"); System.out.println(A); System.out.println("NO.CONTROL"); System.out.println("NOMBRE"); System.out.println("CALIF1"); System.out.println("CALIF2"); System.out.println("CALIF3"); System.out.println("PROMEDIO"); System.out.println("APROBADO"); while (!(I > 2)) { //inicia bloque a ejecutar PROMEDIOS(); } //termina bloque a ejecutar } 66 Anexo A. Código original y resultados del caso de prueba C2J-01 public static void PROMEDIOS () { try { NC = Integer.parseInt(entrada.readLine()); NOMBRE = entrada.readLine(); CALIF1 = Integer.parseInt(entrada.readLine()); CALIF2 = Integer.parseInt(entrada.readLine()); CALIF3 = Integer.parseInt(entrada.readLine()); SUMA = (CALIF1 + CALIF2 + CALIF3); PROMEDIO = SUMA / 3; PROMEDIO1 = PROMEDIO; System.out.println(PROMEDIO1); if (PROMEDIO > 70) { //llave de apertura de if System.out.println("SI"); } //llave de cierre de if if (PROMEDIO < 70) { //llave de apertura de if System.out.println("NO"); } //llave de cierre de if I = I+1; X = X+1; } catch (IOException e){} } } 67 Anexo B. Código original y resultados del caso de prueba C2J-02 ANEXO B. CÓDIGO ORIGINAL Y RESULTADOS DEL CASO DE PRUEBA C2J-02 Código original del caso de prueba C2J-02. *>---------------------------------------------------* IDENTIFICATION DIVISION. *>---------------------------------------------------* PROGRAM-ID. PRUEBA2. *>---------------------------------------------------* DATA DIVISION. *>---------------------------------------------------* WORKING-STORAGE SECTION. *>---------------------------------------------------* 77 A PIC 999. 77 B PIC 999. 77 C PIC 999. 77 MENJE PIC X(24). 77 OPCION PIC 9. 77 77 77 77 77 77 DIV PIC 999. RESIDUO PIC 999. RES PIC 999. I PIC 99. TP PIC 99 VALUE 0. J PIC 999. 77 NOMBRE PIC X(30). 77 NMAX PIC X(30). 77 NMIN PIC X(30). 68 Anexo B. Código original y resultados del caso de prueba C2J-02 77 SUELDO PIC 9(6). 77 SMAX PIC 9(6). 77 SMIN PIC 9(6). *>---------------------------------------------------* PROCEDURE DIVISION. *>---------------------------------------------------* INICIO. *>**************************************************** MOVE 0 TO OPCION PERFORM LLENAR UNTIL OPCION = 4 STOP RUN. ELMAYOR. *>**************************************************** DISPLAY " " DISPLAY "Proporcione el primer numero" ACCEPT A DISPLAY "Proporcione el segundo numero" ACCEPT B DISPLAY "Proporcione el tercer numero" ACCEPT C IF A = B AND B = C MOVE "Los tres son iguales" TO MENJE ELSE IF A > B IF A > C MOVE "A es el Mayor" TO MENJE ELSE IF C = A MOVE "A y C son los Mayores" TO MENJE ELSE MOVE "C es el Mayor" TO MENJE END-IF END-IF ELSE IF A = B IF A > C MOVE "A y B son los Mayores" TO MENJE ELSE MOVE "C es el Mayor" TO MENJE END-IF ELSE IF B > C MOVE "B es el Mayor" TO MENJE ELSE IF B = C MOVE "B y C son los Mayores" TO MENJE ELSE MOVE "C es el Mayor" TO MENJE END-IF END-IF END-IF END-IF END-IF DISPLAY MENJE. PRIMOS. *>**************************************************** 69 Anexo B. Código original y resultados del caso de prueba C2J-02 DISPLAY " " DISPLAY "LISTADO DE NUMEROS PRIMOS MENORES A 50 " PERFORM VARYING I FROM 2 BY 1 UNTIL I > 50 MOVE 1 TO RES PERFORM VARYING J FROM 2 BY 1 UNTIL J >= I COMPUTE DIV = I / J COMPUTE RESIDUO = I - (DIV * J) IF RESIDUO = 0 MOVE 0 TO RES END-IF END-PERFORM IF RES = 1 DISPLAY I ADD 1 TO TP END-IF END-PERFORM DISPLAY "Total Primos:" TP. LLENAR. *>**************************************************** MOVE 0 TO OPCION DISPLAY " " DISPLAY "ELIGA UNA DE LAS SIGUIENTES OPCIONES: " DISPLAY "1. El mayor de tres numeros " DISPLAY "2. Numeros primos menores de 50 " DISPLAY "3. Sueldo maximo y minimo " DISPLAY "4. Salir " PERFORM ACEPTAR UNTIL OPCION > 0 AND OPCION <= 4 IF OPCION = 1 PERFORM ELMAYOR END-IF IF OPCION = 2 PERFORM PRIMOS END-IF IF OPCION = 3 PERFORM SUELDOS END-IF. ACEPTAR. *>****************************************************** DISPLAY " " ACCEPT OPCION. SUELDOS. *>**************************************************** DISPLAY "NOMBRE " ACCEPT NOMBRE DISPLAY "SUELDO " ACCEPT SUELDO MOVE NOMBRE TO NMAX, NMIN MOVE SUELDO TO SMAX, SMIN PERFORM 4 TIMES DISPLAY "NOMBRE " ACCEPT NOMBRE DISPLAY "SUELDO " ACCEPT SUELDO IF SUELDO > SMAX THEN MOVE NOMBRE TO NMAX MOVE SUELDO TO SMAX ELSE IF SUELDO < SMIN THEN MOVE NOMBRE TO NMIN 70 Anexo B. Código original y resultados del caso de prueba C2J-02 MOVE SUELDO TO SMIN END-IF END-IF END-PERFORM DISPLAY "El trabajador que cobra mas es: " NMAX DISPLAY "pues gana " SMAX DISPLAY "El trabajador que cobra menos es: " NMIN DISPLAY "pues gana " SMIN . Código en Java obtenido como resultado import java.io.*; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Date; class PRUEBA2 { public static int A; public static int B; public static int C; public static String MENJE; public static int OPCION; public static int DIV; public static int RESIDUO; public static int RES; public static int I; public static int TP=0; public static int J; public static String NOMBRE; public static String NMAX; public static String NMIN; public static int SUELDO; public static int SMAX; public static int SMIN; public static InputStreamReader isr = new InputStreamReader(System.in); public static BufferedReader entrada = new BufferedReader(isr); public static NumberFormat nf= NumberFormat.getInstance(); public static String temporal=""; 71 Anexo B. Código original y resultados del caso de prueba C2J-02 public static Date fecha=new Date(); public static SimpleDateFormat sdf=new SimpleDateFormat("yyMMdd"); public static void main(String[] args) { OPCION = 0; while (!(OPCION == 4)) { //inicia bloque a ejecutar LLENAR(); } //termina bloque a ejecutar } public static void ELMAYOR () { try { System.out.println(" "); System.out.println("Proporcione el primer numero"); A = Integer.parseInt(entrada.readLine()); System.out.println("Proporcione el segundo numero"); B = Integer.parseInt(entrada.readLine()); System.out.println("Proporcione el tercer numero"); C = Integer.parseInt(entrada.readLine()); if (A == B & B == C) { //llave de apertura de if MENJE = "Los tres son iguales"; } //llave de cierre de if else { //llave de apertura de else if (A > B) { //llave de apertura de if if (A > C) { //llave de apertura de if MENJE = "A es el Mayor"; } //llave de cierre de if else { //llave de apertura de else 72 Anexo B. Código original y resultados del caso de prueba C2J-02 if (C == A) { //llave de apertura de if MENJE = "A y C son los Mayores"; } //llave de cierre de if else { //llave de apertura de else MENJE = "C es el Mayor"; } //llave de cierre de else } //llave de cierre de else } //llave de cierre de if else { //llave de apertura de else if (A == B) { //llave de apertura de if if (A > C) { //llave de apertura de if MENJE = "A y B son los Mayores"; } //llave de cierre de if else { //llave de apertura de else MENJE = "C es el Mayor"; } //llave de cierre de else } //llave de cierre de if else { //llave de apertura de else if (B > C) { //llave de apertura de if MENJE = "B es el Mayor"; } //llave de cierre de if else { //llave de apertura de else if (B == C) { //llave de apertura de if MENJE = "B y C son los Mayores"; } //llave de cierre de if else { //llave de apertura de else 73 Anexo B. Código original y resultados del caso de prueba C2J-02 MENJE = "C es el Mayor"; } //llave de cierre de else } //llave de cierre de else } //llave de cierre de else } //llave de cierre de else } //llave de cierre de else System.out.println(MENJE); } catch (IOException e){} } public static void PRIMOS () { System.out.println(" "); System.out.println("LISTADO DE NUMEROS PRIMOS MENORES A 50 "); for (I = 2;!(I > 50);I = I+1) { //inicia bloque a ejecutar RES = 1; for (J = 2;!(J >= I);J = J+1) { //inicia bloque a ejecutar DIV = I / J; RESIDUO = I - (DIV * J); if (RESIDUO == 0) { //llave de apertura de if RES = 0; } //llave de cierre de if } //termina bloque a ejecutar if (RES == 1) { //llave de apertura de if System.out.println(I); TP = TP+1; } //llave de cierre de if } //termina bloque a ejecutar System.out.println("Total Primos:" + TP); } public static void LLENAR () { OPCION = 0; 74 Anexo B. Código original y resultados del caso de prueba C2J-02 System.out.println(" "); System.out.println("ELIGA UNA DE LAS SIGUIENTES OPCIONES: "); System.out.println("1. El mayor de tres numeros "); System.out.println("2. Numeros primos menores de 50 "); System.out.println("3. Sueldo maximo y minimo "); System.out.println("4. Salir "); while (!(OPCION > 0 & OPCION <= 4)) { //inicia bloque a ejecutar ACEPTAR(); } //termina bloque a ejecutar if (OPCION == 1) { //llave de apertura de if ELMAYOR(); } //llave de cierre de if if (OPCION == 2) { //llave de apertura de if PRIMOS(); } //llave de cierre de if if (OPCION == 3) { //llave de apertura de if SUELDOS(); } //llave de cierre de if } public static void ACEPTAR () { try { System.out.println(" "); OPCION = Integer.parseInt(entrada.readLine()); } catch (IOException e){} } public static void SUELDOS () { try 75 Anexo B. Código original y resultados del caso de prueba C2J-02 { System.out.println("NOMBRE "); NOMBRE = entrada.readLine(); System.out.println("SUELDO "); SUELDO = Integer.parseInt(entrada.readLine()); NMAX = NOMBRE; NMIN = NOMBRE; SMAX = SUELDO; SMIN = SUELDO; for (int i=0; i < 4; i++) { //inicia bloque a ejecutar System.out.println("NOMBRE "); NOMBRE = entrada.readLine(); System.out.println("SUELDO "); SUELDO = Integer.parseInt(entrada.readLine()); if (SUELDO > SMAX) { //llave de apertura de if NMAX = NOMBRE; SMAX = SUELDO; } //llave de cierre de if else { //llave de apertura de else if (SUELDO < SMIN) { //llave de apertura de if NMIN = NOMBRE; SMIN = SUELDO; } //llave de cierre de if } //llave de cierre de else } //termina bloque a ejecutar System.out.println("El trabajador que cobra mas es: " + NMAX); System.out.println("pues gana " + SMAX); System.out.println("El trabajador que cobra menos es: " + NMIN); System.out.println("pues gana " + SMIN); } catch (IOException e){} } } 76 Anexo C. Código original y resultados del caso de prueba C2J-03 ANEXO C. CÓDIGO ORIGINAL Y RESULTADOS DEL CASO DE PRUEBA C2J-03 Código original del caso de prueba C2J-03. *>******************************************************************** ** *> *> PROGRAMADOR : Job Vega L¢pez *> FECHA CREACION : 07 de Septiembre de 1999 *> FECHA ACTUALIZACION : 07 de Septiembre de 1999 *> OBJETIVOS : *> *> *> *>******************************************************************** ** *>---------------------------------------------------* IDENTIFICATION DIVISION. *>---------------------------------------------------* PROGRAM-ID. EQUIPO. AUTHOR. JOBVEGA. *>---------------------------------------------------* ENVIRONMENT DIVISION. *>---------------------------------------------------* INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT ALUMNO ASSIGN TO 'c:\ALUMNO.DAT'. 77 Anexo C. Código original y resultados del caso de prueba C2J-03 *>---------------------------------------------------* DATA DIVISION. *>---------------------------------------------------* FILE SECTION. FD ALUMNO. 01 REGALUM. 02 CODALUM PIC 9(2). 88 COD VALUE 1 THRU 99. 02 NOMBRES. 03 NOMBRE PIC X(15). 03 APPAT PIC X(15). 03 APMAT PIC X(15). 02 SEXO PIC A. 88 SEX VALUE 'F' 'M'. 02 EDAD PIC 9(2). 88 EDA VALUE 17 THRU 65. 02 ESTCIVIL PIC 9. 88 ECIV VALUE 1 THRU 5. WORKING-STORAGE SECTION. *>---------------------------------------------------* 77 TECLA PIC X. 77 RESP PIC A. *>---------------------------------------------------* PROCEDURE DIVISION. *>---------------------------------------------------* INICIO. *>**************************************************** MOVE " " TO RESP PERFORM ABRIR PERFORM LLENAR UNTIL RESP = "N" PERFORM CERRAR STOP RUN. ABRIR. *>**************************************************** OPEN OUTPUT ALUMNO. CERRAR. *>**************************************************** CLOSE ALUMNO. LLENAR. *>**************************************************** MOVE " " TO RESP MOVE 0 TO CODALUM MOVE 0 TO EDAD MOVE " " TO SEXO MOVE 0 TO ESTCIVIL DISPLAY "D A T O S D E L " DISPLAY "A L U M N O" DISPLAY "-Codigo De Alumno :" DISPLAY "-Nombres :" DISPLAY "-Apellido Paterno :" DISPLAY "-Apellido Materno :" DISPLAY "-Sexo :" DISPLAY "-Edad :" DISPLAY "-Estado Civil :" 78 Anexo C. Código original y resultados del caso de prueba C2J-03 PERFORM MOSTRARCOD PERFORM VALCOD UNTIL COD PERFORM BORRARCOD ACCEPT NOMBRE ACCEPT APPAT ACCEPT APMAT PERFORM MOSTRARSE PERFORM VALSEXO UNTIL SEX PERFORM BORRARSE PERFORM MOSTRAREDAD PERFORM VALEDAD UNTIL EDA PERFORM BORRAREDAD PERFORM MOSTRAREC PERFORM VALECIVIL UNTIL ECIV PERFORM GRABAR DISPLAY "DESEA INGRESAR OTRO S/N:" PERFORM ACEPTAR UNTIL RESP = "N" OR RESP = "S". VALCOD. *>****************************************************** DISPLAY " " ACCEPT CODALUM . VALSEXO. *>****************************************************** DISPLAY " " ACCEPT SEXO. VALEDAD. *>****************************************************** DISPLAY " " ACCEPT EDAD . VALECIVIL. *>****************************************************** DISPLAY " " ACCEPT ESTCIVIL. GRABAR. *>****************************************************** WRITE REGALUM. ACEPTAR. *>****************************************************** DISPLAY " " ACCEPT RESP . MOSTRARCOD. *>****************************************************** DISPLAY "[1-99]:" . BORRARCOD. *>****************************************************** DISPLAY " " . MOSTRARSE. *>****************************************************** DISPLAY "[F/M]:" . BORRARSE. *>****************************************************** 79 Anexo C. Código original y resultados del caso de prueba C2J-03 DISPLAY " " . MOSTRAREDAD. *>****************************************************** DISPLAY "[17-65]:". BORRAREDAD. *>****************************************************** DISPLAY " ". MOSTRAREC. *>****************************************************** DISPLAY "1- CASADO." DISPLAY "2- SOLTERO." DISPLAY "3- VIUDO." DISPLAY "4- SEPARADO." DISPLAY "5- OTRO." DISPLAY "SU OPCION:" . BORRAREC. *>****************************************************** DISPLAY " " DISPLAY " " DISPLAY " " DISPLAY " " DISPLAY " " DISPLAY " " . Código en Java obtenido como resultado //Lineas incluidas para el manejo de la bd import java.sql.*; import ObjetosDB.*; import java.io.*; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Date; class EQUIPO { //Variables de FileSection NO Consideradas en esta Tesis //public static class REGALUM //{ // int CODALUM; 80 Anexo C. Código original y resultados del caso de prueba C2J-03 // int[] COD = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65 ,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,9 6,97,98,99}; // NOMBRES _NOMBRES = new NOMBRES(); // String SEXO; // String[] SEX = {"F", "M"}; // int EDAD; // int[] EDA = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,4 7,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65}; // int ESTCIVIL; // int[] ECIV = {1,2,3,4,5}; //} // //public static class NOMBRES //{ // String NOMBRE; // String APPAT; // String APMAT; //} public static String TECLA; public static String RESP; //Variables de FileSection NO Consideradas en esta Tesis public static REGALUM _REGALUM = new REGALUM(); public static Conecta conec = new Conecta(); public static Connection cn = conec.getConexion(); public static bd BD=new bd(); public static InputStreamReader isr = new InputStreamReader(System.in); public static BufferedReader entrada = new BufferedReader(isr); public static NumberFormat nf= NumberFormat.getInstance(); public static String temporal=""; public static Date fecha=new Date(); 81 Anexo C. Código original y resultados del caso de prueba C2J-03 public static SimpleDateFormat sdf=new SimpleDateFormat("yyMMdd"); public static void main(String[] args) { RESP = " "; ABRIR(); while (!(RESP.equals("N"))) { //inicia bloque a ejecutar LLENAR(); } //termina bloque a ejecutar CERRAR(); } public static void ABRIR () { //OPEN OUTPUT ALUMNO. BD.setCn(cn); } public static void CERRAR () { //CLOSE ALUMNO. } public static void LLENAR () { try { RESP = " "; //Cambio CODALUM = 0; por _REGALUM.CODALUM = 0; //Cambio EDAD = 0; por _REGALUM.EDAD = 0; //Cambio SEXO = " "; por _REGALUM.SEXO = " "; //Cambio ESTCIVIL = 0; por _REGALUM.ESTCIVIL = 0; 82 Anexo C. Código original y resultados del caso de prueba C2J-03 System.out.println("D A T O S D E L "); System.out.println("A L U M N O"); System.out.println("-Codigo De Alumno :"); System.out.println("-Nombres :"); System.out.println("-Apellido Paterno :"); System.out.println("-Apellido Materno :"); System.out.println("-Sexo :"); System.out.println("-Edad :"); System.out.println("-Estado Civil :"); MOSTRARCOD(); //Cambio while (!(COD )) por while (!(_REGALUM.CODALUM >= 1 & _REGALUM.CODALUM <= 99 )) { //inicia bloque a ejecutar VALCOD(); } //termina bloque a ejecutar BORRARCOD(); /*ACCEPT NOMBRE ACCEPT APPAT ACCEPT APMAT*/ _REGALUM._NOMBRES.NOMBRE = entrada.readLine(); _REGALUM._NOMBRES.APPAT = entrada.readLine(); _REGALUM._NOMBRES.APMAT = entrada.readLine(); MOSTRARSE(); while (!(_REGALUM.SEXO.equals("F") | _REGALUM.SEXO.equals("M") ) ) { //inicia bloque a ejecutar VALSEXO(); } //termina bloque a ejecutar BORRARSE(); MOSTRAREDAD(); 83 Anexo C. Código original y resultados del caso de prueba C2J-03 while (!(_REGALUM.EDAD >= 17 & _REGALUM.EDAD <= 65)) { //inicia bloque a ejecutar VALEDAD(); } //termina bloque a ejecutar BORRAREDAD(); MOSTRAREC(); while (!(_REGALUM.ESTCIVIL >= 1 & _REGALUM.ESTCIVIL <= 5)) { //inicia bloque a ejecutar VALECIVIL(); } //termina bloque a ejecutar GRABAR(); System.out.println("DESEA INGRESAR OTRO S/N:"); while (!(RESP.equals("N") | RESP.equals("S"))) { //inicia bloque a ejecutar ACEPTAR(); } //termina bloque a ejecutar } catch (IOException e){} } public static void VALCOD () { try { System.out.println(" "); //ACCEPT CODALUM . _REGALUM.CODALUM = Integer.parseInt(entrada.readLine()); } catch (IOException e){} } 84 Anexo C. Código original y resultados del caso de prueba C2J-03 public static void VALSEXO () { try { System.out.println(" "); //ACCEPT SEXO. _REGALUM.SEXO = entrada.readLine(); } catch (IOException e){} } public static void VALEDAD () { try { System.out.println(" "); //ACCEPT EDAD. _REGALUM.EDAD = Integer.parseInt(entrada.readLine()); } catch (IOException e){} } public static void VALECIVIL () { try { System.out.println(" "); //ACCEPT ESTCIVIL. _REGALUM.ESTCIVIL = Integer.parseInt(entrada.readLine()); } 85 Anexo C. Código original y resultados del caso de prueba C2J-03 catch (IOException e){} } public static void GRABAR() { //WRITE REGALUM. BD.Altas(_REGALUM); } public static void ACEPTAR () { try { System.out.println(" "); RESP = entrada.readLine(); } catch (IOException e){} } public static void MOSTRARCOD () { System.out.println("[1-99]:"); } public static void BORRARCOD () { System.out.println(" "); } public static void MOSTRARSE () { System.out.println("[F/M]:"); } public static void BORRARSE () 86 Anexo C. Código original y resultados del caso de prueba C2J-03 { System.out.println(" "); } public static void MOSTRAREDAD () { System.out.println("[17-65]:"); } public static void BORRAREDAD () { System.out.println(" "); } public static void MOSTRAREC () { System.out.println("1- CASADO."); System.out.println("2- SOLTERO."); System.out.println("3- VIUDO."); System.out.println("4- SEPARADO."); System.out.println("5- OTRO."); System.out.println("SU OPCION:"); } public static void BORRAREC () { System.out.println(" "); System.out.println(" "); System.out.println(" "); System.out.println(" "); System.out.println(" "); System.out.println(" "); } } 87 Bibliografía BIBLIOGRAFÍA [ALC-92] Alcalde Lanchorro, Eduardo. Metodología de la programación: Aplicaciones en COBOL y Pascal. Editorial MC-Graw-Hill. 2da edición 1992. [BAR-00] http://www.kajakgroup.com/html/poo.html [BRA-97] Brand M. , Sellink A. , Verhoef C. Obtaining a COBOL Grammar from Legacy Code for Reengineering Purposes University of Amsterdam, Programming Research Group. ACM Notices. 1997. [BUS-03] Bustamante C. “Reestructuración de Código Legado a partir del Comportamiento para la Generación de Componentes Reutilizables”. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2003. [CAR-03] Cárdenas L. A. “Reestructuración de Software Legado Orientado a Objetos Aplicando Patrón de Diseño Mediator”. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2003. [CEB-98] Ceballos F. J. Curso de Programación RM/COBOL-85 Editorial Alfa Omega 1998. [CEB-99] Ceballos F. J. Java 2 : Curso de Programación Editorial Alfa Omega 1999. [CSI-02] www.csis.ul.ie\COBOL\Course [FAG-04] www.faggella.com.ar/EjemplosCobol.htm [HCH-00] www.lifia.net/haas.htm [HCL-03] http:// www.comptramatics.com/cc-lets.html [HCS-03] http://www.cobolmining.com/index.jsp [HCT-04] http://www.transtools.com/products/es/caravel.htm [HER-03] Hernández L. A. Factorización de Funciones en Métodos de Plantilla. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2004. [JAV-00] http://www.engr.mun.ca/~theo/JavaCC-Tutorial/javacc-tutorial.pdf. [LOP-05] López Rodríguez, Ariel. “Estudio para la transformación de instrucciones de acceso a una base de datos escrita en lenguaje COBOL hacia 88 Bibliografía instrucciones escritas en lenguaje SQL”. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2005. [LUE-02] Luengo, Maria C., Desarrollo y evaluación de técnicas de construcción de procesadores de lenguaje para máquinas abstractas orientadas a objetos, http://www.di.uniovi.es/~cueva/investigacion/tesis/Candi.pdf [MEN-03] Méndez A. “Reestructuración de Software Escrito por Procedimientos Conducido por Patrones de Diseño Composicionales”. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2003. [MIL-02] Millham, R.; An investigation: reengineering sequential procedure-driven software into object-oriented event-driven software through UML diagrams Computer Software and Applications Conference, Proceedings. 26th Annual International, p.p. 731, 2002. [MOS-03] Mossienko, Maxim “Automated Cobol to Java Recycling” St. Petersburg State University, LANIT-TERCOM Seventh European Conference on Software Maintenance and Reengineering (CSMR'03) Marzo 26 - 28, 2003 [NAG-97] Nagaoka, I.; Sanou, K.; Ikeo, D.; Nagashima, T.; Akiba, S.; Tsuda, M.; A reverse engineering method and experiences for industrial COBOL system Software Engineering Conference Asia Pacific and International Computer Science Conference 1997. APSEC '97 and ICSC '97. Proceedings, p.p. 220 – 228, 1997 [PID-98] Pidaparthi S. , Zedan H. , Luker P. “Conceptual Foundations for the Transformation of Procedural Software to Object-Oriented Architecture” DeMontfort University, Leicester, UK. [ROD-03] Rodríguez J. J. “Integración de la Funcionalidad de Frameworks Orientados a Objetos”. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2003. [SAN-02] Santaolaya R. Modelo de Representación de Patrones de Código para la Construcción de Componentes Reusables. Tesis de Doctorado. Departamento de Ciencias Computacionales, Centro de Investigación en Computación, IPN, 2002. [SAT-03] Santos L. E. “Adaptación de Interfaces de Marcos de Aplicaciones Orientados a Objetos, Utilizando el Patrón de Diseño Adapter”. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2003. 89 Bibliografía [SCH-01] Schildt, Herbert. Java 2 Manual de Referencia Mc Graw-Hill, 2001. [SNE-95] Sneed, H.M.; Nyary, E. Extracting object-oriented specification from procedurally oriented programs Reverse Engineering, Proceedings of 2nd Working Conference, p.p. 217 – 226 ,1995 [SEL-99] Sellink, A.; Sneed, H.; Verhoef, C. Restructuring of COBOL/CICS legacy systems Software Maintenance and Reengineering, Proceedings of the Third European Conference, p.p. 72 – 82 ,1999 [VAL-03] Valdés M. A. “Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces”. Tesis de Maestría. Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico, 2003. [YAN-97] Yang, H.; Chu, W.C.; Sun, Y.; A practical system of COBOL program reuse for reengineering Software Technology and Engineering Practice. Proceedings., Eighth IEEE International Workshop on [incorporating Computer Aided Software Engineering] , p.p. 45 – 57, 1997 90