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?
Antworten:
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.
quelle
goto
ist eine äußerst nützliche Sache, wenn sie mit Bedacht angewendet wird. Ohne a würden Sie keinen effizienten, großen Zustandsautomaten implementierengoto
. Sie werden sie sicherlich auch in Ihrem generierten Code benötigen.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.)
quelle
goto
kann 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.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.
quelle
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.
quelle
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.
quelle
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.
quelle
Ein allgemeiner Ansatz zum "Dekompilieren" eines solchen Codes wäre der folgende:
Das LLVM-eigene C-Backend kann Ihnen einen ersten Entwurf liefern.
quelle
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:
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.
quelle
Andernfalls können Sie goto-Anweisungen in C # verwenden .
quelle
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.
quelle