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?
Réponses:
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.
la source
goto
est une chose extrêmement utile si elle est appliquée judicieusement. Vous n'iriez pas implémenter un automate à grand état efficace sansgoto
. Vous en aurez certainement aussi besoin dans votre code généré.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 #.)
la source
goto
statemens 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.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.
la source
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.
la source
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é.
la source
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.
la source
Une approche générique pour «décompiler» un tel code serait la suivante:
Le propre backend C de LLVM peut vous fournir une première version.
la source
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:
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.
la source
A défaut d'autre chose, vous pouvez utiliser les instructions goto en C # .
la source
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.
la source