Conversione del codice Fortran 77 in C #


14

Sto cercando di convertire un programma Fortan77 in C #. Ho una subroutine con circa 650 righe di codice e orribili dichiarazioni GOTO dappertutto. Ho molti problemi anche a cominciare a visualizzare il flusso della subroutine per capire cosa fa.

C'è qualcuno con esperienza in questo genere di cose che potrebbe darmi qualche consiglio su come ottenere una panoramica di questa subroutine? Ci sono alcuni strumenti disponibili per accelerare o facilitare questo tipo di conversione?


1
Poiché questa domanda è più aperta e in cerca di consigli, sarebbe più appropriato su Programmers SE

4
hai pensato di compilarlo in .NET usando silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx e quindi solo fare riferimento all'assembly?

@Shaun, è una bella idea Shaun. Lo guarderò se non riesco ad arrivare da nessuna parte con la riprogrammazione.
user643192

2
Mi dispiace per te ...
marko,

1
Sono stato al tuo posto. Sono stati i giorni peggiori della mia carriera.
utente

Risposte:


10

Nella mia esperienza, un buon modo di procedere è creare un diagramma di flusso del codice Fortran. Prova a separare le destinazioni delle istruzioni GOTO in blocchi separati e usa il diagramma per cercare di capire il codice ad alto livello.

Verifica se puoi sostituire logicamente i GOTO con loop o chiamate di funzione; se il diagramma risultante ha la forma di una struttura ad albero, è relativamente facile convertire in C # senza ricorrere a GOTO. Alla fine, però, dovrai comprendere il codice intimamente per poter conservare e utilizzare il risultato con sicurezza.


Ottimo consiglio, grazie! Le dichiarazioni GOTO dovrebbero essere vietate.
user643192

6
@ user643192, gotoè estremamente utile se applicato con saggezza. Non avresti intenzione di implementare un automa statale efficiente e di grandi dimensioni senza un goto. Ne avrai sicuramente bisogno anche nel tuo codice generato.
SK-logic,

3
Esistono strumenti in grado di disegnare diagrammi di flusso dal codice Fortran. Esempio: home.comcast.net/~lchen223621
NoChance

OP: non è possibile vietare in modo retroattivo. @EmmadKareem: suggerimento molto utile.
Kris,

Ho finito per fare ciò che Daniel B ha suggerito qui e ho realizzato una versione a blocchi del codice Fortran. Mi ha aiutato molto, quindi grazie per quello. Secondo la logica SK, probabilmente hai ragione sui GOTO. Il mio commento è stato fatto dopo il mio primo pomeriggio guardando il codice ... e ci sono MOLTI GOTO in esso: o (
user643192

12

Oltre a ciò che Daniel B ha scritto sopra, direi quanto segue:

Innanzitutto, fai funzionare il tuo codice Fortran con Fortran per DotNet. Non se "non puoi arrivare da nessuna parte con la riprogrammazione", ma prima di tentare qualsiasi riprogrammazione. Sarà un piccolo passo, ma nella giusta direzione.

Quindi, scrivere una suite di test in C # che alimenta il codice Fortran con qualsiasi input sia stato fatto per sgranocchiare e memorizza l'output. Eseguire una volta la suite di test e salvare l'output. Quindi, estendere la suite di test per testare l'output prodotto sull'output salvato. Supponendo che il codice Fortran produca sempre lo stesso output quando viene alimentato lo stesso input, il test dovrebbe ovviamente avere successo.

Quindi, mentre riscrivi il codice in C #, eseguirai il codice nella suite di test e ti dirà se il tuo codice funziona correttamente o meno, il che significa che sta producendo esattamente lo stesso output di Fortran codice dato lo stesso input. Senza di essa, ti perderai.

Non sono d'accordo con la logica @ SK, NON dovresti usare alcuna goto nel tuo codice C #.

(Spero che una volta che avrai fatto funzionare il codice Fortran sotto DotNet non vedrai alcun motivo per continuare a perdere tempo a convertire un pezzo di codice spaghetti in C #.)


1
mente spiegando, perché "NON dovresti"? Qualche argomento razionale , oltre a "tutti credono che sia malvagio"? Ho chiamato due casi estremamente importanti dove dovete usare goto, altrimenti si finirà per la scrittura di codice o illeggibili o unefficient (o entrambi).
SK-logic,

@ SK-logic Non ho scritto "NON dovresti", ho scritto "NON dovresti". In ogni caso, ecco qui: le dichiarazioni goto rendono il codice molto difficile da comprendere e verificarne la correttezza in quasi tutte le circostanze, e i loro presunti benefici in termini di efficienza sono qualcosa tra un mito e un malinteso. Naturalmente questi potrebbero essere ulteriormente chiariti, ma per favore tratteniamoci dal farlo, questo non è il posto per questa discussione. Accettiamo di non essere d'accordo.
Mike Nakis,

2
un'assenza di gotostati statali può anche rendere il codice molto difficile da comprendere in alcuni casi (e una macchina a stati è l'esempio più importante di tale caso). Non riesco proprio a sopportare questa stupida religione goto-bashing: le persone continuano a ripetere la stessa insignificante BS senza mai cercare di capire il motivo per cui il goto è considerato dannoso.
SK-logic,

Sei una di quelle persone che non possono sopportarlo se non hanno l'ultima parola, eh? C -: =
Mike Nakis,

1
@ ridecar2, scrivo sempre buone macchine a stati. Uso enum e switch switch e lascio che il compilatore scriva i GOTO nel linguaggio macchina generato. In realtà non ho mai visto un esempio di una macchina a stati esplicitamente scritta con GOTO. Ti interessa pubblicare un puntatore a un esempio?
John R. Strohm,

3

Il tuo compito è complicato. Devi davvero conoscere bene Fortran. Devi fare attenzione a come Fortran è simile / diverso ai calcoli e quali regole di troncamento e arrotondamento si applicano. Inoltre, devi stare attento ai tipi primitivi che significano in C # e Fortran.

Un altro approccio da quello che è stato suggerimento (non necessariamente uno migliore, è solo un altro):

A - Valuta di riscrivere il codice in C # in base alla conoscenza e alla funzione del business, usa il codice Fortran solo come riferimento

B -Considerare l'utilizzo di uno strumento commerciale che esegue il processo di conversione - Esempio: DataTek

Se la routine rappresenta una funzione standard o una funzione per la quale è possibile acquistare una dll pronta per l'uso (come l'integrazione numerica), utilizzare la funzione standard o il prodotto commerciale anziché la traduzione manuale e il problema è risolto.

Se quanto sopra non lo taglia, rispondi a questa domanda:

Devo ottimizzare il codice o semplicemente farlo funzionare. In altre parole, qual è il valore aziendale di spendere 500 ore per migliorare il codice?

se non c'è valore nell'ottimizzazione, traduci il codice riga per riga e il gioco è fatto.

Se questo non è ancora buono, allora:

0-Converti il ​​codice Fortran riga per riga in C # (o usa Fortan CLR)

1-Fai un test rapido assicurati che funzioni

2-Usa un re-factoring (sono disponibili strumenti commerciali) per aiutarti a scrivere il codice in modo più ottimizzato.

In bocca al lupo.


2

Un modo semplice per ricodificare le cose con molte goto è disegnare un diagramma di flusso e tirare la corda dritta. A volte, i programmi F77 sono solo vecchi programmi F66 o peggio ancora programmi FII. F66 non aveva un costrutto if-then-else, quindi erano necessarie le foto. Tutto quello che devi fare è invertire la condizione per ottenere un if-then.

F66 non ha avuto neanche un attimo ma F77 lo ha. Dipende dal fatto che il programmatore sia stato un convertitore da F66 a F77 (come molti oggi sono da C a C ++ o da C ++ a C #) dove usano F77 come F66. Se riesci a individuare i motivi, nella codifica, è molto più facile da convertire.


1

Prima di iniziare, crea una suite di test per testare il codice esistente. Sii molto accurato in quanto ciò contribuirà a far luce sul comportamento. È quindi possibile utilizzare questa suite per valutare l'efficacia della conversione.

Oltre a ciò, sii metodico , non affrettarti e usa molta carta per rintracciarne la funzionalità.


1

Ecco come ho effettivamente tradotto il codice in C #. Poiché .NET supporta le dichiarazioni goto, ho prima preso l'intero codice Fortran e incollato così com'è in un nuovo metodo, quindi, tutti i metodi che c'erano routine e subroutine Fortran.

Il compilatore ha prodotto un milione di errori, principalmente su variabili non dichiarate e formattazione errata dell'istruzione di blocco, che ho eliminato uno per uno. Ho anche dovuto riscrivere parte del codice specifico di Fortran, come le istruzioni I / O e cose del genere. Fatto ciò, ho avuto una replica esatta del codice originale.

Grazie alla piacevole formattazione di Visual Studio, i blocchi logici erano molto più facili da identificare rispetto al codice originale. E potrei iniziare a svelare le dichiarazioni goto una per una.

Da questa esperienza devo dire che ci sono alcuni casi in cui le istruzioni goto sono in realtà MOLTO utili per evitare di dover riscrivere lo stesso codice più e più volte, anche se in molti casi lo stesso può essere ottenuto usando metodi e chiamandoli ripetutamente .

Ho anche usato la versione gratuita di Silverfrost per compilare il codice originale e eseguire controlli regolari sul mio codice riformattato per garantire che la riformattazione non producesse errori.


0

Un approccio generico per "decompilare" un tale codice sarebbe il seguente:

  • prima compilarlo in una forma di livello inferiore (ad esempio, LLVM)
  • eseguire una trasformazione SSA su di essa (aiuterà a ripulire le variabili locali)
  • dividere il flusso di controllo irriducibile (se presente)
  • rilevare loop e if e sostituirli con i costrutti di alto livello adeguati

Il backend C di LLVM può fornirti una prima bozza.


0

Il modo migliore senza dubbio è innanzitutto riscrivere / riformattare il codice FORTRAN in un modo strutturato e logico migliore. Questo ti costringerà a comprendere la logica originale prima di provare a portarla su C #.

Ecco come lo approccerei:

  • Comprendi il codice esistente e, se necessario, il refactor e persino riscriverlo in FORTRAN in modo da poter testare facilmente che funzioni.
  • Porta il codice refactored su C #

Non perdere tempo con un convertitore di codice automatico che finirà con lo stesso pasticcio di dichiarazioni goto dell'originale FORTRAN poiché C # supporta goto ed etichette, proprio come fa C.


0

In caso contrario, puoi usare le istruzioni goto in C # .

L' istruzione goto trasferisce il controllo del programma direttamente a un'istruzione etichettata.

Un uso comune di goto è quello di trasferire il controllo a un'etichetta switch-case specifica o all'etichetta predefinita in un'istruzione switch .

L' istruzione goto è anche utile per uscire da loop profondamente nidificati ...


-2

Per convertire qualsiasi vecchio codice FORTRAN in una nuova lingua qualcuno dovrebbe seguire alcuni passaggi di base nel codice legacy (1) per il controllo del tipo statico convertire il codice in "IMPLICIT NONE" (2) convertire tutti i comuni troncati in tutti i comuni (3) Rimuovi equivalenza (4) converti in comune a Modulo di FORTRAN 90

Quindi puoi provare a convertire in altre lingue.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.