Konvertieren von Fortran 77-Code in C #

14

Ich versuche, ein Fortan77-Programm in C # zu konvertieren. Ich habe ein Unterprogramm mit etwa 650 Codezeilen und schrecklichen GOTO-Anweisungen überall. Ich habe große Probleme damit, den Ablauf des Unterprogramms zu visualisieren, um herauszufinden, was es tut.

Gibt es jemanden mit Erfahrung in dieser Art von Dingen, der mir einen Rat geben könnte, wie ich mir einen Überblick über dieses Unterprogramm verschaffen kann? Gibt es einige Tools, um diese Art der Konvertierung zu beschleunigen oder zu erleichtern?

user643192
quelle
1
Da diese Frage offener ist und auf der Suche nach Rat ist, ist sie für Programmierer besser geeignet. SE
4
Haben Sie darüber nachgedacht, es einfach mit silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx in .NET zu kompilieren und dann einfach auf die Assembly zu verweisen?
@ Shaun, das ist eine schöne Idee, Shaun. Ich werde das prüfen, wenn ich mit der Neuprogrammierung nicht weiterkomme.
user643192
2
Es tut mir leid für Sie ...
Marko
1
Ich war an deiner Stelle. Es waren die schlimmsten Tage meiner Karriere.
Benutzer

Antworten:

10

Nach meiner Erfahrung ist es ein guter Weg, ein Flussdiagramm des Fortran-Codes zu erstellen. Versuchen Sie, die Ziele der GOTO-Anweisungen in separate Blöcke aufzuteilen, und versuchen Sie anhand des Diagramms, den Code auf hoher Ebene zu verstehen.

Prüfen Sie, ob Sie die GOTOs logisch durch Schleifen oder Funktionsaufrufe ersetzen können. Wenn das resultierende Diagramm die Form einer Baumstruktur hat, ist es relativ einfach, in C # zu konvertieren, ohne auf GOTOs zurückzugreifen. Am Ende müssen Sie den Code jedoch genau verstehen, um das Ergebnis sicher verwalten und verwenden zu können.

Daniel B
quelle
Guter Vorschlag, danke! GOTO-Anweisungen sollten verboten werden.
user643192
6
@ user643192, gotoist eine äußerst nützliche Sache, wenn sie mit Bedacht angewendet wird. Ohne a würden Sie keinen effizienten, großen Zustandsautomaten implementieren goto. Sie werden sie sicherlich auch in Ihrem generierten Code benötigen.
SK-logic
3
Es gibt Tools, die Flussdiagramme aus Fortran-Code zeichnen können. Beispiel: home.comcast.net/~lchen223621
NoChance
OP: Sie können nicht rückwirkend verbieten. @EmmadKareem: Sehr nützlicher Vorschlag.
Kris
Am Ende tat ich, was Daniel B hier vorschlug, und erstellte eine Blockversion des Fortran-Codes. Es hat sehr geholfen, also danke dafür. Für SK-logic haben Sie wahrscheinlich recht mit den GOTOs. Mein Kommentar wurde nach meinem ersten Nachmittag beim Betrachten des Codes abgegeben ... und es gibt VIELE GOTOs darin: o (
user643192
12

Zusätzlich zu dem, was Daniel B oben geschrieben hat, würde ich Folgendes sagen:

Lassen Sie zunächst Ihren Fortran-Code mit Fortran for DotNet arbeiten. Nicht, wenn Sie "mit der Neuprogrammierung nichts anfangen können", sondern bevor Sie eine Neuprogrammierung versuchen. Es wird ein kleiner Schritt sein, aber in die richtige Richtung.

Schreiben Sie dann eine Testsuite in C #, die den Fortran-Code mit den Eingaben füttert, an denen er kaut, und speichert die Ausgabe. Führen Sie die Testsuite einmal aus und speichern Sie die Ausgabe. Erweitern Sie dann die Testsuite, um die produzierte Ausgabe gegen die gespeicherte Ausgabe zu testen. Vorausgesetzt, dass der Fortran-Code immer dieselbe Ausgabe erzeugt, wenn dieselbe Eingabe eingegeben wird, sollte der Test natürlich erfolgreich sein.

Während Sie den Code in C # umschreiben, führen Sie den Code unter der Testsuite aus und erfahren, ob der Code ordnungsgemäß funktioniert oder nicht, dh ob er genau die gleiche Ausgabe wie der Fortran erzeugt Code bei gleicher Eingabe. Ohne sie wirst du verloren sein.

Ich bin mit @ SK-logic nicht einverstanden, Sie sollten KEINE gotos in Ihrem C # -Code verwenden müssen.

(Aber wenn Sie den Fortran-Code erst einmal unter DotNet zum Laufen gebracht haben, werden Sie hoffentlich keinen Grund mehr sehen, Ihre Zeit damit zu verschwenden, ein Stück Spaghetti-Code in C # zu konvertieren.)

Mike Nakis
quelle
1
etwas dagegen zu erklären, warum "du NICHT solltest"? Irgendwelche rationalen Argumente, außer "jeder glaubt, dass es böse ist"? Ich nannte zwei sehr wichtige Fälle , in denen Sie haben goto zu verwenden, sonst werden Sie entweder unleserlich oder unefficient das Schreiben von Code am Ende (oder beides).
SK-logic
@ SK-logic Ich habe nicht geschrieben "du sollst NICHT", ich habe geschrieben "du sollst NICHT müssen". Auf jeden Fall gilt: goto-Anweisungen erschweren es, Code unter fast allen Umständen zu verstehen und auf Richtigkeit zu überprüfen, und ihre angeblichen Effizienzvorteile bewegen sich zwischen einem Mythos und einem Missverständnis. Natürlich könnten diese weiter geklärt werden, aber bitte lassen Sie uns das unterlassen, dies ist nicht der Ort für diese Diskussion. Lasst uns einfach zustimmen, nicht zuzustimmen.
Mike Nakis
2
Ein Fehlen von Statusmeldungen gotokann in manchen Fällen auch dazu führen, dass Sie den Code nur schwer verstehen können (und eine Statusmaschine ist das wichtigste Beispiel für einen solchen Fall). Ich kann diese blöde GOTO-Bashing-Religion einfach nicht ausstehen - die Leute wiederholen immer wieder dieselbe bedeutungslose BS, ohne jemals zu verstehen, warum GOTO als schädlich eingestuft wird.
SK-logic
Sie sind einer von denen, die es einfach nicht aushalten können, wenn sie nicht das letzte Wort haben, was? C -: =
Mike Nakis
1
@ Ridecar2, ich schreibe die ganze Zeit gute Zustandsautomaten. Ich benutze Aufzählungen und switch-Anweisungen und lasse den Compiler die GOTOs in der generierten Maschinensprache schreiben. Ich habe tatsächlich noch nie ein Beispiel einer Zustandsmaschine gesehen, die explizit mit GOTOs geschrieben wurde. Möchtest du einen Zeiger auf ein Beispiel posten?
John R. Strohm
3

Ihre Aufgabe ist schwierig. Sie müssen Fortran wirklich gut kennen. Sie müssen darauf achten, wie ähnlich / unterschiedlich Fortran Berechnungen durchführt und welche Regeln für das Abschneiden und Runden gelten. Sie müssen auch vorsichtig mit den primitiven Typen sein, die in C # und Fortran eine Bedeutung haben.

Ein anderer Ansatz aus dem, was vorgeschlagen wurde (nicht unbedingt ein besserer, es ist nur ein anderer):

A - Erwägen Sie, den Code in C # basierend auf den Geschäftskenntnissen und der Funktion neu zu schreiben. Verwenden Sie den Fortran-Code lediglich als Referenz

B -Betrachten Sie die Verwendung eines kommerziellen Tools, das die Konvertierungsaufgabe erledigt - Beispiel: DataTek

Wenn die Routine eine Standardfunktion oder eine Funktion darstellt, für die Sie eine fertige DLL kaufen können (z. B. numerische Integration), verwenden Sie die Standardfunktion oder das kommerzielle Produkt anstelle der manuellen Übersetzung, und Ihr Problem ist gelöst.

Wenn dies nicht der Fall ist, beantworten Sie diese Frage:

Muss ich den Code optimieren oder einfach zum Laufen bringen? Mit anderen Worten, wie hoch ist der geschäftliche Wert von 500 Stunden, um den Code zu verbessern?

Wenn die Optimierung keinen Wert hat, übersetzen Sie den Code zeilenweise, und Sie sind fertig.

Wenn dies immer noch nicht gut ist, dann:

0-Konvertieren Sie den Fortran-Code zeilenweise in C # (oder verwenden Sie Fortan CLR)

1-Machen Sie einen Schnelltest, um sicherzustellen, dass er ausgeführt wird

2-Verwenden Sie ein Re-Factoring (es stehen kommerzielle Tools zur Verfügung), um den Code auf optimierte Weise zu schreiben.

Viel Glück.

Keine Chance
quelle
2

Eine einfache Möglichkeit, Sachen mit vielen GOTOS neu zu kodieren, besteht darin, ein Flussdiagramm zu zeichnen und die Zeichenfolge gerade zu ziehen. Manchmal sind F77-Programme nur alte F66-Programme oder noch schlechtere FII-Programme. F66 hatte kein if-then-else-Konstrukt, daher waren gotos notwendig. Sie müssen lediglich die Bedingung invertieren, um ein Wenn-Dann zu erhalten.

F66 hatte auch keine Chance, aber F77. Es hängt davon ab, ob der Codierer eine Konvertierung von F66 nach F77 war (wie viele heutige C nach C ++ oder C ++ nach C #), wo sie F77 wie F66 verwenden. Wenn Sie die Muster in der Codierung erkennen können, ist die Konvertierung weitaus einfacher.

Tasse
quelle
1

Bevor Sie beginnen, erstellen Sie eine Testsuite, um den vorhandenen Code zu testen. Seien Sie sehr gründlich, da dies dazu beiträgt, das Verhalten zu beleuchten. Mit dieser Suite können Sie dann die Effektivität Ihrer Conversion messen.

Seien Sie darüber hinaus methodisch , beeilen Sie sich nicht und verwenden Sie viel Papier, um die Funktionalität nachzuvollziehen.

Bryan Oakley
quelle
1

So habe ich den Code tatsächlich in C # übersetzt. Da .NET goto-Anweisungen unterstützt, habe ich zuerst den gesamten Fortran-Code in eine neue Methode eingefügt, genau so viele Methoden, wie es Fortran-Routinen und -Unterroutinen gab.

Dem Compiler sind eine Million Fehler eingefallen, hauptsächlich wegen nicht deklarierter Variablen und falscher Blockanweisungsformatierung, die ich nacheinander behoben habe. Ich musste auch einige der Fortran-spezifischen Codes neu schreiben, wie E / A-Anweisungen und ähnliches. Als das erledigt war, hatte ich eine genaue Kopie des ursprünglichen Codes.

Dank der netten Formatierung von Visual Studio waren die logischen Blöcke viel einfacher zu identifizieren als im Originalcode. Und ich könnte anfangen, die goto-Anweisungen nacheinander zu entwirren.

Aus dieser Erfahrung muss ich sagen, dass es einige Fälle gibt, in denen goto-Anweisungen tatsächlich SEHR nützlich sind, um zu vermeiden, dass derselbe Code immer wieder neu geschrieben werden muss, obwohl dies in vielen Fällen durch die Verwendung von Methoden und den wiederholten Aufruf derselben erreicht werden kann .

Ich habe auch die kostenlose Version von Silverfrost verwendet, um den Originalcode zu kompilieren und regelmäßig meinen neu formatierten Code zu überprüfen, um sicherzustellen, dass die Neuformatierung keine Fehler verursachte.

user643192
quelle
0

Ein allgemeiner Ansatz zum "Dekompilieren" eines solchen Codes wäre der folgende:

  • kompiliere es zuerst in eine niedrigere Form (zB LLVM)
  • Führe eine SSA-Transformation durch durch (es wird dir dabei helfen, deine lokalen Variablen zu bereinigen)
  • Teiltden irreduziblen Kontrollfluss (falls vorhanden)
  • Ermitteln Sie Schleifen und Wenns und ersetzen Sie sie durch die richtigen Konstrukte auf hoher Ebene

Das LLVM-eigene C-Backend kann Ihnen einen ersten Entwurf liefern.

SK-Logik
quelle
0

Der beste Weg, ohne Zweifel, ist, den FORTRAN-Code zuerst in eine besser strukturierte und logischere Weise umzuschreiben / umzugestalten. Dies zwingt Sie, die ursprüngliche Logik zu verstehen, bevor Sie versuchen, sie nach C # zu portieren.

So würde ich es angehen:

  • Verstehen Sie den vorhandenen Code und korrigieren Sie ihn gegebenenfalls und schreiben Sie ihn sogar in FORTRAN neu, damit Sie problemlos testen können, ob er funktioniert.
  • Portieren Sie den überarbeiteten Code in C #

Verschwenden Sie Ihre Zeit nicht mit einem automatischen Code-Konverter, der genauso viele goto-Anweisungen enthält wie das ursprüngliche FORTRAN, da C # Gotos und Labels unterstützt, genau wie C.

dodgy_coder
quelle
0

Andernfalls können Sie goto-Anweisungen in C # verwenden .

Die goto- Anweisung überträgt die Programmsteuerung direkt auf eine beschriftete Anweisung.

Eine gebräuchliche Verwendung von goto besteht darin, die Kontrolle auf ein bestimmtes Schalteretikett oder das Standardetikett in einer switch- Anweisung zu übertragen.

Die goto- Anweisung ist auch nützlich, um tief verschachtelte Schleifen zu verlassen ...

Wyatt Barnett
quelle
-2

Um einen alten FORTRAN-Code in eine neue Sprache zu konvertieren, sollte jemand einige grundlegende Schritte in Ihrem Legacy-Code (1) zur statischen Typprüfung durchlaufen. Konvertieren Sie den Code in "IMPLICIT NONE" Äquivalenz (4) konvertieren gemeinsam zu Modul von FORTRAN 90

Dann können Sie versuchen, in andere Sprachen zu konvertieren.

Debiprasad Ghosh
quelle