Estoy tratando de convertir un programa Fortan77 a C #. Tengo una subrutina con aproximadamente 650 líneas de código y horribles declaraciones GOTO por todo el lugar. Tengo muchos problemas incluso para comenzar a visualizar el flujo de la subrutina para descubrir qué hace.
¿Hay alguien con experiencia en este tipo de cosas que pueda darme algún consejo sobre cómo obtener una visión general de esta subrutina? ¿Hay algunas herramientas disponibles para acelerar o facilitar este tipo de conversión?
Respuestas:
En mi experiencia, una buena manera de hacerlo es crear un diagrama de flujo del código Fortran. Intente separar los objetivos de las declaraciones GOTO en bloques separados, y use el diagrama para tratar de comprender el código en un nivel alto.
Vea si puede reemplazar lógicamente los GOTO con bucles o llamadas a funciones; Si el diagrama resultante tiene la forma de una estructura de árbol, es relativamente fácil convertir a C # sin recurrir a GOTO. Al final, sin embargo, deberá comprender el código íntimamente para poder mantener y utilizar el resultado con confianza.
fuente
goto
es algo extremadamente útil si se aplica con prudencia. No implementaría un autómata de estado grande y eficiente sin ungoto
. Ciertamente, también los necesitará en su código generado.Además de lo que Daniel B escribió anteriormente, diría lo siguiente:
Primero, obtenga su código Fortran para trabajar con Fortran para DotNet. No si "no puede llegar a ningún lado con la reprogramación", sino antes de intentar cualquier reprogramación. Será un pequeño paso, pero en la dirección correcta.
Luego, escriba un conjunto de pruebas en C # que alimente el código Fortran con cualquier entrada que se haya hecho para masticar y almacene la salida. Ejecute el conjunto de pruebas una vez y guarde la salida. Luego, extienda el conjunto de pruebas para probar la salida producida contra la salida guardada. Suponiendo que el código Fortran siempre produce la misma salida cuando se alimenta con la misma entrada, la prueba, por supuesto, debe tener éxito.
Luego, mientras reescribe el código en C #, ejecutará su código en el conjunto de pruebas y le indicará si su código funciona correctamente o no, es decir, si está produciendo exactamente la misma salida que el Fortran código dado la misma entrada. Sin ella, estarás perdido.
No estoy de acuerdo con @ SK-logic, NO debería tener que usar ningún gotos en su código C #.
(Pero con suerte, una vez que haya hecho que el código Fortran funcione en DotNet, no verá ninguna razón para seguir perdiendo el tiempo convirtiendo una pieza de código de espagueti a C #).
fuente
goto
también puede hacer que el código sea muy difícil de comprender en algunos casos (y una máquina de estados es el ejemplo más importante de tal caso). Simplemente no puedo soportar esta estúpida religión de goto-bashing: la gente sigue repitiendo la misma BS sin sentido sin siquiera tratar de entender la razón por la cual se considera que goto es dañino.Tu tarea es complicada. Realmente necesitas conocer bien a Fortran. Debe tener cuidado con la forma en que Fortran hace cálculos similares / diferentes y qué reglas de truncamiento y redondeo se aplican. Además, debe tener cuidado con los tipos primitivos que significan en C # y Fortran.
Otro enfoque de lo que ha sido sugerencia (no necesariamente una mejor, es solo otra):
A - Considere volver a escribir el código en C # basado en el conocimiento del negocio y la función, use el código Fortran solo como referencia
B - Considere usar una herramienta comercial que realiza el trabajo de conversión - Ejemplo: DataTek
Si la rutina representa una función estándar o una función para la que puede comprar una dll preparada (como la integración numérica), use la función estándar o el producto comercial en lugar de la traducción manual, y su problema se resolverá.
Si lo anterior no es suficiente, responda esta pregunta:
¿Necesito optimizar el código o simplemente hacer que se ejecute? En otras palabras, ¿cuál es el valor comercial de pasar 500 horas para mejorar el código?
Si no hay valor en la optimización, traduzca el código línea por línea y ya está.
Si esto todavía no es bueno, entonces:
0-Convierta el código Fortran línea por línea en C # (o use Fortan CLR)
1-Haz una prueba rápida asegúrate de que se ejecute
2-Use una refactorización (hay herramientas comerciales disponibles) para ayudarlo a escribir el código de una manera más optimizada.
Buena suerte.
fuente
Una forma sencilla de recodificar cosas con muchos gotos es dibujar un diagrama de flujo y tirar de la cuerda recta. A veces, los programas F77 son solo programas F66 antiguos o incluso peores programas FII. F66 no tenía una construcción if-then-else, por lo que los gotos eran necesarios. Todo lo que necesita hacer es invertir la condición para obtener un if-then.
F66 tampoco tuvo un do-while, pero sí F77. Depende de si el codificador se convirtió de F66 a F77 (como muchos hoy en día son C a C ++ o C ++ a C #) donde están usando F77 como F66. Si puede detectar los patrones, en la codificación, es mucho más fácil convertir.
fuente
Antes de comenzar, haga un conjunto de pruebas para probar el código existente. Sea muy cuidadoso ya que esto ayudará a arrojar luz sobre el comportamiento. Luego puede usar esta suite para medir la efectividad de su conversión.
Más allá de eso, sea metódico , no se apresure y use mucho papel para rastrear la funcionalidad.
fuente
Esta es la forma en que realmente traduje el código a C #. Como .NET admite declaraciones de goto, primero tomé todo el código Fortran y lo pegué como está en un nuevo método, bueno, tantos métodos como rutinas y subrutinas Fortran.
Al compilador se le ocurrió un millón de errores, principalmente sobre variables no declaradas y formato incorrecto de instrucciones de bloque, que eliminé uno por uno. También tuve que volver a escribir parte del código específico de Fortran, como las declaraciones de E / S y cosas por el estilo. Cuando se hizo eso, tenía una réplica exacta del código original.
Gracias al buen formato de Visual Studio, los bloques lógicos fueron mucho más fáciles de identificar que en el código original. Y podría comenzar a desentrañar las declaraciones de goto una por una.
De esta experiencia tengo que decir que hay algunos casos en los que las declaraciones de goto son realmente MUY útiles para evitar tener que volver a escribir el mismo código una y otra vez, aunque en muchos casos se puede lograr lo mismo utilizando métodos y llamando repetidamente .
También utilicé la versión gratuita de Silverfrost para compilar el código original y realizar verificaciones regulares en mi código reformateado para asegurar que el formateo no produjera errores.
fuente
Un enfoque genérico para "descompilar" dicho código sería el siguiente:
El propio backend C de LLVM puede proporcionarle un primer borrador.
fuente
La mejor forma, sin duda, es reescribir / refactorizar primero el código FORTRAN en una forma mejor estructurada y lógica. Esto lo obligará a comprender la lógica original antes de intentar portarlo a C #.
Así es como lo abordaría:
No pierda su tiempo con un convertidor de código automático que terminará con el mismo desorden de declaraciones goto que el FORTRAN original, ya que C # admite gotos y etiquetas, al igual que C.
fuente
Al fallar cualquier otra cosa, puede usar declaraciones goto en C # .
fuente
Para convertir cualquier código FORTRAN antiguo a un nuevo idioma, alguien debe seguir algunos pasos básicos en su código heredado (1) para la verificación de tipo estático, convertir el código a "IMPLICIT NONE" (2) convertir todos los comunes truncados a comunes completos (3) Eliminar conversión de equivalencia (4) común al módulo de FORTRAN 90
Entonces puedes intentar convertir a otros idiomas.
fuente