Convertir código Fortran 77 a C #

14

Estoy intentando convertir un programa Fortan77 a C #. Tengo una subrutina con aproximadamente 650 líneas de código y declaraciones GOTO horribles por todas partes. Estoy teniendo muchos problemas incluso para comenzar a visualizar el flujo de la subrutina para averiguar 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?

    
pregunta user643192 30.11.2011 - 07:03
fuente

10 respuestas

10

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 entender el código en un nivel alto.

Vea si puede reemplazar lógicamente los GOTOs con bucles o llamadas de función; Si el diagrama resultante tiene la forma de una estructura de árbol, es relativamente fácil convertirlo a C # sin tener que recurrir a GOTOs. Sin embargo, al final, deberá comprender el código íntimamente para poder mantener y utilizar el resultado con confianza.

    
respondido por el Daniel B 30.11.2011 - 07:11
fuente
12

Además de lo que Daniel B escribió anteriormente, diría lo siguiente:

Primero, haga que su código de Fortran funcione con Fortran para DotNet. No si no puede "llegar a ninguna parte con la reprogramación", sino antes de intentar cualquier reprogramación. Será un pequeño paso, pero en la dirección correcta.

Luego, escribe 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 la misma entrada, la prueba debería tener éxito, por supuesto.

Luego, mientras está reescribiendo el código en C #, ejecutará su código en el conjunto de pruebas y le dirá si su código funciona correctamente o no, es decir, si está produciendo exactamente el mismo resultado. Como el código de Fortran da la misma entrada. Sin él, estarás perdido.

No estoy de acuerdo con @ SK-logic, NO deberías usar ningún gotos en tu código C #.

(Pero, con suerte, una vez que haya hecho funcionar el código Fortran bajo DotNet, no verá ninguna razón para continuar perdiendo el tiempo convirtiendo un código de espagueti en C #).

    
respondido por el Mike Nakis 30.11.2011 - 09:11
fuente
3

Tu tarea es complicada. Realmente necesitas conocer bien a Fortran. Debe tener cuidado con la forma en que Fortran realiza cálculos similares y las reglas de truncamiento y redondeo que se aplican. Además, debes tener cuidado con los tipos primitivos que significan en C # y Fortran.

Otro enfoque de lo que se ha sugerido (no necesariamente uno mejor, es solo otro):

A: considere volver a escribir el código en C # según el conocimiento del negocio y la función, use el código Fortran solo como referencia

B: considere utilizar una herramienta comercial que realice 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 solucionará.

Si lo anterior no lo corta, responde esta pregunta:

¿Necesito optimizar el código o simplemente hacer que se ejecute? En otras palabras, ¿cuál es el valor comercial de gastar 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 habrá terminado.

Si esto todavía no es bueno, entonces:

0-Convierte el código de Fortran línea por línea en C # (o usa Fortan CLR)

1-Haz una prueba rápida para asegurarte de que se ejecuta

2-Usa una re-factorización (hay herramientas comerciales disponibles) para ayudarte a escribir el código de una manera más optimizada.

Buena suerte.

    
respondido por el NoChance 30.11.2011 - 09:48
fuente
2

Una forma sencilla de recodificar cosas con muchos gotos es dibujar un diagrama de flujo y estirar la cuerda. A veces, los programas F77 son programas antiguos F66 o incluso programas FII peores. F66 no tenía una construcción if-then-else, por lo que eran necesarias las fotos. Todo lo que necesitas hacer es invertir la condición para obtener un if-then.

F66 tampoco tuvo un do-while, pero F77 sí. Depende de si el codificador fue un converso de F66 a F77 (como muchos de ellos hoy en día son de C a C ++ o de C ++ a C #), donde utilizan F77 como F66. Si puede detectar los patrones, en la codificación, es mucho más fácil de convertir.

    
respondido por el cup 17.04.2012 - 06:52
fuente
1

Antes de comenzar, haga una serie de pruebas para probar el código existente. Sea muy cuidadoso ya que esto ayudará a aclarar el comportamiento. Luego puede usar este paquete para medir la efectividad de su conversión.

Más allá de eso, sea metódico , no se apure y use mucho papel para rastrear la funcionalidad.

    
respondido por el Bryan Oakley 30.11.2011 - 14:16
fuente
1

Esta es la forma en que realmente hice para traducir el código a C #. Ya que .NET es compatible con las declaraciones goto, primero tomé todo el código de Fortran y lo pegué como está en un nuevo método, bueno, tantos métodos como rutinas y subrutinas de Fortran.

El compilador produjo un millón de errores, en su mayoría sobre variables no declaradas y formato de enunciado de bloque incorrecto, que eliminé uno por uno. También tuve que volver a escribir algunos de los códigos específicos de Fortran, como sentencias de E / S y cosas por el estilo. Cuando se hizo eso, tuve 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 goto una por una.

A partir de esta experiencia, debo decir que hay algunos casos en los que las declaraciones 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 usando métodos y métodos. llamando a los repetidos.

También utilicé la versión gratuita de Silverfrost para compilar el código original y realizar comprobaciones periódicas en mi código reformateado para asegurar que el cambio de formato no produjera errores.

    
respondido por el user643192 07.09.2012 - 02:19
fuente
0

Un enfoque genérico para "descompilar" tal código sería el siguiente:

  • primero compílelo en una forma de nivel inferior (por ejemplo, LLVM)
  • realice una SSA-transform en él (le ayudará a limpiar sus variables locales)
  • split el flujo de control irreducible (si existe)
  • detecte los bucles y los ifs y sustitúyalos por las construcciones de alto nivel adecuadas

El propio backend C de LLVM puede proporcionarle un primer borrador.

    
respondido por el SK-logic 30.11.2011 - 07:53
fuente
0

La mejor manera, sin duda, es reescribir / refactorizar primero el código FORTRAN de una manera mejor estructurada y lógica. Esto te obligará a entender la lógica original antes de intentar portarla a C #.

Así es como lo abordaría:

  • Comprenda el código existente y, si es necesario, refactorice e incluso vuelva a escribirlo en FORTRAN para que pueda probar fácilmente que funciona.
  • Transfiera el código refactorizado a C #

No pierdas el tiempo con un convertidor de código automático que acabará con el mismo lío de declaraciones goto que el FORTRAN original, ya que C # admite gotos y etiquetas, al igual que C.

    
respondido por el dodgy_coder 10.04.2012 - 08:06
fuente
0

Si falla algo más, puede usar goto sentencias en C # .

  

La declaración goto transfiere el control del programa directamente a una declaración etiquetada.

     

Un uso común de goto es transferir el control a una etiqueta de caja de interruptores específica o la etiqueta predeterminada en una declaración de interruptor .

     

La declaración goto también es útil para salir de bucles profundamente anidados ...

    
respondido por el Wyatt Barnett 07.09.2012 - 03:22
fuente
-2

Para convertir cualquier código FORTRAN antiguo a un nuevo idioma, alguien debería seguir algunos pasos básicos en su código heredado  (1) para la verificación de tipo estático, convierta el código a "IMPLICIT NONE"  (2) convertir todos los comunes truncados en comunes completos  (3) Eliminar la equivalencia  (4) convertir común a Módulo de FORTRAN 90

Luego puedes intentar convertir a otros idiomas.

    
respondido por el Debiprasad Ghosh 22.01.2015 - 08:07
fuente

Lea otras preguntas en las etiquetas