Conversion du code Fortran 77 en C #


14

J'essaie de convertir un programme Fortan77 en C #. J'ai un sous-programme avec environ 650 lignes de code et d'horribles instructions GOTO partout. J'ai beaucoup de mal à même commencer à visualiser le flux du sous-programme pour comprendre ce qu'il fait.

Y a-t-il quelqu'un ayant de l'expérience dans ce genre de choses qui pourrait me donner des conseils sur la façon d'avoir un aperçu de ce sous-programme? Existe-t-il des outils pour accélérer ou faciliter ce type de conversion?


1
Comme cette question est plus ouverte et demande des conseils, elle serait plus appropriée sur Programmers SE

4
avez-vous envisagé de simplement le compiler dans .NET à l'aide de silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx , puis de simplement référencer l'assembly?

@Shaun, c'est une bonne idée Shaun. Je regarderai cela si je ne peux pas arriver à quelque chose avec la reprogrammation.
user643192

2
Je suis désolé pour toi ...
Marko

1
J'ai été à ta place. Ce furent les pires jours de ma carrière.
utilisateur

Réponses:


10

D'après mon expérience, une bonne façon de procéder consiste à créer un organigramme du code Fortran. Essayez de séparer les cibles des instructions GOTO en blocs séparés et utilisez le diagramme pour essayer de comprendre le code à un niveau élevé.

Voyez si vous pouvez logiquement remplacer les GOTO par des boucles ou des appels de fonction; si le diagramme résultant se présente sous la forme d'une arborescence, il est relativement facile de le convertir en C # sans recourir à GOTO. En fin de compte, vous devrez comprendre le code intimement pour pouvoir maintenir et utiliser le résultat en toute confiance.


Bonne suggestion, merci! Les déclarations GOTO devraient être interdites.
user643192

6
@ user643192, gotoest une chose extrêmement utile si elle est appliquée judicieusement. Vous n'iriez pas implémenter un automate à grand état efficace sans goto. Vous en aurez certainement aussi besoin dans votre code généré.
SK-logic

3
Il existe des outils qui peuvent dessiner des organigrammes à partir du code Fortran. Exemple: home.comcast.net/~lchen223621
NoChance

OP: Vous ne pouvez pas interdire rétroactivement. @EmmadKareem: suggestion très utile.
Kris

J'ai fini par faire ce que Daniel B a suggéré ici et j'ai fait une version bloc du code Fortran. Cela a beaucoup aidé, alors merci pour cela. Pour SK-logic, vous avez probablement raison sur les GOTO. Mon commentaire a été fait après mon premier après-midi en regardant le code ... et il y a BEAUCOUP de GOTO dedans: o (
user643192

12

En plus de ce que Daniel B a écrit ci-dessus, je dirais ce qui suit:

Tout d'abord, faites fonctionner votre code Fortran avec Fortran pour DotNet. Pas si vous "n'arrivez à rien avec la reprogrammation", mais avant de tenter une reprogrammation. Ce sera un petit pas, mais dans la bonne direction.

Ensuite, écrivez une suite de tests en C # qui alimente le code Fortran avec n'importe quelle entrée sur laquelle il a été créé et stocke la sortie. Exécutez la suite de tests une fois et enregistrez la sortie. Ensuite, étendez la suite de tests pour tester la sortie produite par rapport à la sortie enregistrée. En supposant que le code Fortran produit toujours la même sortie lorsqu'il est alimenté par la même entrée, le test doit bien sûr réussir.

Ensuite, pendant que vous réécrivez le code en C #, vous exécuterez votre code sous la suite de tests, et il vous dira si votre code fonctionne correctement ou non, c'est-à-dire s'il produit exactement la même sortie que le Fortran. code donné la même entrée. Sans cela, vous serez perdu.

Je ne suis pas d'accord avec @ SK-logic, vous ne devriez PAS du tout utiliser de gotos dans votre code C #.

(Mais j'espère qu'une fois que vous aurez fait fonctionner le code Fortran sous DotNet, vous ne verrez aucune raison de continuer à perdre votre temps à convertir un morceau de code spaghetti en C #.)


1
l'esprit explique, pourquoi "vous ne devriez pas"? Des arguments rationnels , outre "tout le monde pense que c'est mal"? J'ai nommé deux cas extrêmement importants où vous devez utiliser goto, sinon vous finirez par écrire du code illisible ou inefficace (ou les deux).
SK-logic

@ SK-logic Je n'ai pas écrit "tu ne devrais PAS", j'ai écrit "tu ne devrais PAS avoir à". Dans tous les cas, c'est parti: les instructions goto rendent le code très difficile à comprendre et à vérifier son exactitude dans presque toutes les circonstances, et leurs avantages supposés en termes d'efficacité sont quelque chose entre un mythe et une idée fausse. Bien sûr, ceux-ci pourraient être clarifiés davantage, mais évitons de le faire, ce n'est pas le lieu de cette discussion. Laissez-nous simplement accepter d'être en désaccord.
Mike Nakis

2
une absence de gotostatemens peut également rendre le code très difficile à comprendre dans certains cas (et une machine d'état est l'exemple le plus important d'un tel cas). Je ne supporte pas cette stupide religion de dénigrement des goto - les gens continuent de répéter les mêmes BS sans signification sans jamais essayer de comprendre la raison pour laquelle le goto est considéré comme nocif.
SK-logic

Vous faites partie de ces gens qui ne peuvent tout simplement pas le supporter s'ils n'ont pas le dernier mot, hein? C -: =
Mike Nakis

1
@ ridecar2, j'écris des machines à bon état tout le temps. J'utilise des énumérations et des instructions switch, et je laisse le compilateur écrire les GOTO dans le langage machine généré. Je n'ai en fait jamais vu d'exemple de machine à états explicitement écrite avec GOTO. Vous souhaitez publier un pointeur sur un exemple?
John R. Strohm

3

Votre tâche est délicate. Vous devez vraiment bien connaître Fortran. Vous devez faire attention à la façon dont Fortran est similaire / différent aux calculs et aux règles de troncature et d'arrondi qui s'appliquent. En outre, vous devez faire attention aux types primitifs signifiant en C # et Fortran.

Une autre approche de ce qui a été suggéré (pas nécessairement une meilleure, c'est juste une autre):

A - Envisagez de réécrire le code en C # sur la base des connaissances métier et de la fonction, utilisez le code Fortran comme référence

B - Envisagez d'utiliser un outil commercial qui effectue le travail de conversion - Exemple: DataTek

Si la routine représente une fonction standard ou une fonction pour laquelle vous pouvez acheter une DLL prête à l'emploi (telle qu'une intégration numérique), utilisez la fonction standard ou le produit commercial au lieu de la traduction manuelle, et votre problème est résolu.

Si ce qui précède ne suffit pas, répondez à cette question:

Dois-je optimiser le code ou simplement le faire fonctionner. En d'autres termes, quelle est la valeur commerciale de 500 heures pour améliorer le code?

s'il n'y a aucune valeur dans l'optimisation, traduisez le code ligne par ligne et vous avez terminé.

Si ce n'est toujours pas bon, alors:

0-Convertissez le code Fortran ligne par ligne en C # (ou utilisez Fortan CLR)

1-Faites un test rapide pour vous assurer qu'il fonctionne

2-Utilisez une refactorisation (des outils commerciaux sont disponibles) pour vous aider à écrire le code de manière plus optimisée.

Bonne chance.


2

Un moyen simple de recoder des trucs avec beaucoup de gotos est de dessiner un organigramme et de tirer la chaîne directement. Parfois, les programmes F77 ne sont que de vieux programmes F66 ou pire encore des programmes FII. F66 n'avait pas de construction if-then-else, donc des gotos étaient nécessaires. Tout ce que vous avez à faire est d'inverser la condition pour obtenir un si-alors.

Le F66 n'a pas eu de temps libre non plus, mais le F77 en a un. Cela dépend si le codeur était un converti de F66 en F77 (comme beaucoup aujourd'hui sont C en C ++ ou C ++ en C #) où ils utilisent F77 comme F66. Si vous pouvez repérer les motifs, dans le codage, il est beaucoup plus facile de convertir.


1

Avant de commencer, créez une suite de tests pour tester le code existant. Soyez très minutieux car cela aidera à faire la lumière sur le comportement. Vous pouvez ensuite utiliser cette suite pour évaluer l'efficacité de votre conversion.

Au-delà de cela, soyez méthodique , ne vous précipitez pas et utilisez beaucoup de papier pour tracer la fonctionnalité.


1

Voici la façon dont j'ai réellement traduit le code en C #. Étant donné que .NET prend en charge les instructions goto, j'ai d'abord pris tout le code Fortran et l'ai collé tel quel dans une nouvelle méthode, ainsi, autant de méthodes qu'il y avait de routines et de sous-programmes Fortran.

Le compilateur a trouvé un million d'erreurs, principalement sur les variables non déclarées et le formatage incorrect des instructions de bloc, que j'ai effacées une par une. J'ai également dû réécrire une partie du code spécifique à Fortran, comme les instructions d'E / S et des trucs comme ça. Lorsque cela a été fait, j'avais une réplique exacte du code d'origine.

Grâce au formatage agréable de Visual Studio, les blocs logiques étaient beaucoup plus faciles à identifier que dans le code d'origine. Et je pourrais commencer à démêler les déclarations goto une par une.

D'après cette expérience, je dois dire qu'il y a des cas où les instructions goto sont en fait TRÈS utiles pour éviter d'avoir à réécrire le même code encore et encore, bien que dans de nombreux cas, la même chose puisse être obtenue en utilisant des méthodes et en les appelant à plusieurs reprises .

J'ai également utilisé la version gratuite de Silverfrost pour compiler le code d'origine et effectuer des vérifications régulières sur mon code reformaté pour m'assurer que le reformatage ne produisait pas d'erreurs.


0

Une approche générique pour «décompiler» un tel code serait la suivante:

  • compilez-le d'abord dans un formulaire de niveau inférieur (par exemple, LLVM)
  • effectuer une transformation SSA dessus (cela vous aidera à nettoyer vos variables locales)
  • diviser le flux de contrôle irréductible (le cas échéant)
  • détecter les boucles et les ifs et les remplacer par les constructions de haut niveau appropriées

Le propre backend C de LLVM peut vous fournir une première version.


0

La meilleure façon sans aucun doute est de réécrire / refactoriser d'abord le code FORTRAN de manière plus structurée et logique. Cela vous obligera à comprendre la logique d'origine avant d'essayer de la porter en C #.

Voici comment je l'aborderais:

  • Comprenez le code existant et si nécessaire refactorisez-le et même réécrivez-le dans FORTRAN pour pouvoir tester facilement son fonctionnement.
  • Portez le code refactorisé en C #

Ne perdez pas votre temps avec un convertisseur de code automatique qui se retrouvera avec le même désordre d'instructions goto que le FORTRAN d'origine puisque C # prend en charge les gotos et les étiquettes, tout comme C le fait.


0

A défaut d'autre chose, vous pouvez utiliser les instructions goto en C # .

L' instruction goto transfère le contrôle de programme directement dans une instruction étiquetée.

Une utilisation courante de goto consiste à transférer le contrôle à une étiquette de boîtier de commutation spécifique ou à l'étiquette par défaut dans une instruction switch .

L' instruction goto est également utile pour sortir des boucles profondément imbriquées ...


-2

Pour convertir n'importe quel ancien code FORTRAN dans une nouvelle langue, quelqu'un devrait suivre certaines étapes de base de votre code hérité (1) pour la vérification du type statique convertir le code en "IMPLICITE AUCUN" (2) convertir tous les tronconiques communs en pleins communs (3) Supprimer l'équivalence (4) convertit le commun en module de FORTRAN 90

Ensuite, vous pouvez essayer de convertir dans d'autres langues.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.