Conversione del codice Fortran 77 in C #

14

Sto provando a convertire un programma Fortan77 in C #. Ho una subroutine con circa 650 linee di codice e dichiarazioni GOTO orribili dappertutto. Sto avendo un sacco di problemi anche iniziando 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?

    
posta user643192 30.11.2011 - 07:03
fonte

10 risposte

10

Nella mia esperienza, un buon modo per farlo è creare un diagramma di flusso del codice Fortran. Cerca di separare gli obiettivi delle istruzioni GOTO in blocchi separati e usa il diagramma per cercare di capire il codice ad un livello elevato.

Verifica se è possibile 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 capire il codice intimamente per poter mantenere e usare il risultato con sicurezza.

    
risposta data 30.11.2011 - 07:11
fonte
12

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

Innanzitutto, fai in modo che il tuo codice Fortran funzioni 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, scrivi una suite di test in C # che alimenta il codice Fortran con qualsiasi input sia stato creato per masticare e memorizza l'output. Esegui la suite di test una volta e salva l'output. Quindi, estendere la suite di test per verificare l'output prodotto rispetto all'output salvato. Supponendo che il codice Fortran produca sempre lo stesso output quando viene alimentato lo stesso input, il test dovrebbe ovviamente riuscire.

Quindi, mentre stai riscrivendo il codice in C #, eseguirai il tuo codice sotto la suite di test e ti dirà se il tuo codice funziona correttamente o meno, cioè se sta producendo esattamente lo stesso output come il codice Fortran dato lo stesso input. Senza di esso, ti perderai.

Non sono d'accordo con @ SK-logic, NON dovresti usare alcun goto nel tuo codice C #.

(Ma spero che una volta che hai 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 #.)

    
risposta data 30.11.2011 - 09:11
fonte
3

Il tuo compito è complicato. Hai davvero bisogno di conoscere bene Fortran. Devi stare attento a come Fortran similare / diverso fa i calcoli e quali sono le regole di troncamento e arrotondamento. Inoltre, devi fare attenzione ai tipi primitivi che significano in C # e Fortran.

Un altro approccio da ciò che è stato suggerito (non necessariamente uno migliore, è solo un altro):

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

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

Se la routine rappresenta una funzione standard o una funzione che è possibile acquistare una dll già pronta per (come l'integrazione numerica), utilizzare la funzione standard o il prodotto commerciale invece della 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 rendere il codice migliore?

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

Se ciò non va ancora bene, allora:

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

1-Fai un test rapido assicurandoti che funzioni

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

Buona fortuna.

    
risposta data 30.11.2011 - 09:48
fonte
2

Un modo semplice per ricodificare cose con un sacco di gotos è disegnare un diagramma di flusso e tirare dritto la corda. A volte, i programmi F77 sono solo vecchi programmi F66 o programmi peggiori di FII. F66 non aveva un costrutto if-then-else quindi era necessario il gotos. Tutto quello che devi fare è invertire la condizione per ottenere un if-then.

F66 non ha avuto un do-while, ma F77 lo fa. Dipende se il codificatore è stato convertito da F66 a F77 (come molti oggi sono C in C ++ o C ++ in C #) dove stanno usando F77 come F66. Se riesci a individuare i modelli, nella codifica, è molto più facile da convertire.

    
risposta data 17.04.2012 - 06:52
fonte
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. Puoi quindi utilizzare questa suite per valutare l'efficacia della tua conversione.

Oltre a ciò, sii metodico , non affrettarti e usa un sacco di carta per rintracciare la funzionalità.

    
risposta data 30.11.2011 - 14:16
fonte
1

Questo è il modo in cui sono effettivamente andato a tradurre il codice in C #. Poiché .NET supporta le istruzioni goto, ho preso per la prima volta l'intero codice Fortran e l'ho incollato come è in un nuovo metodo, beh, come molti metodi quanti erano le routine e le subroutine Fortran.

Il compilatore ha generato un milione di errori, principalmente su variabili non dichiarate e formattazione errata delle istruzioni di blocco, che ho risolto uno per uno. Ho anche dovuto riscrivere alcuni dei codici specifici di Fortran, come le dichiarazioni I / O e cose del genere. Quando ciò è stato fatto ho avuto una replica esatta del codice originale.

Grazie alla buona formattazione di Visual Studio, i blocchi logici erano molto più facili da identificare rispetto al codice originale. E potrei iniziare a sbrogliare 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 chiamarli ripetutamente.

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

    
risposta data 07.09.2012 - 02:19
fonte
0

Un approccio generico alla "decompilazione" di tale codice sarebbe il seguente:

  • prima compila in un modulo di livello inferiore (ad es., LLVM)
  • esegui un trasformazione SSA su di esso (ti aiuterà a ripulire le tue variabili locali)
  • dividi il flusso di controllo irriducibile (se presente)
  • rileva loop e if e li sostituisce con i costrutti di alto livello appropriati

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

    
risposta data 30.11.2011 - 07:53
fonte
0

Il modo migliore è quello di riscrivere / rifare il codice FORTRAN in un modo meglio strutturato e logico. Questo ti costringerà a capire la logica originale prima di provare a portarla su C #.

Ecco come vorrei affrontarlo:

  • Comprendi il codice esistente e se necessario refactoring e persino riscrivilo in FORTRAN in modo da poter verificare facilmente che funzioni.
  • Porta il codice refactored in C #

Non perdere tempo con un convertitore di codice automatico che finirà con lo stesso pasticcio di istruzioni goto del FORTRAN originale dato che C # supporta goto ed etichette, proprio come fa C.

    
risposta data 10.04.2012 - 08:06
fonte
0

Se non ci riesci, puoi utilizzare istruzioni goto in C # .

The goto statement transfers the program control directly to a labeled statement.

A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.

The goto statement is also useful to get out of deeply nested loops...

    
risposta data 07.09.2012 - 03:22
fonte
-2

Per convertire qualsiasi vecchio codice FORTRAN in una nuova lingua, qualcuno dovrebbe eseguire alcuni passaggi di base nel codice legacy  (1) per il controllo del tipo statico convertire il codice in "IMPLICIT NONE"  (2) converti tutto il comune troncato in pieno comune  (3) Rimuovere l'equivalenza  (4) convertire comune in Module of FORTRAN 90

Quindi puoi provare a convertire in altre lingue.

    
risposta data 22.01.2015 - 08:07
fonte

Leggi altre domande sui tag