Hallo miteinander,
ich habe hier ein C Programm, welches exzessiv von Goto's Gebrauch macht.
Diese würde ich gern komplett nach Python konvertieren aber scheue mich noch vor dem ganzen vor- & zurückgespringe teilweise in Case Fällen und andere Nettigkeiten.
Habt ihr eine Idee oder kennt Seiten oder Methoden wie effektiv diese Aufgabe(Konvertierung bei Erhalten der Logik) vonstatten gehen kann?
Goto's equivalent ersetzen
@darktrym: Wenn das wirklich Spaghetti-Code ist, dann würde ich nicht versuchen das vom Quelltext her zu portieren sondern es neu schreiben.
Das Problem, der Code stammt aus den 70igern wurde bereits von Fortran nach C transformiert zwecks Portierbarkeit/Lesbarkeit. Daher stammen wohl auch die vielen Labels und die kruden Bezeichner.
Meine erste Idee:
Die Labels als Funktionen umzusetzen und GoTO's als Aufrufe wird spät. bei der endl. Größe des Aufrufsstacks Probleme machen.
Meine erste Idee:
Die Labels als Funktionen umzusetzen und GoTO's als Aufrufe wird spät. bei der endl. Größe des Aufrufsstacks Probleme machen.
@darktrym: Das ist eigentlich ein Grund mehr das von Grund auf neu zu schreiben. Durch eine weitere „Übersetzung” wird der Code sicher nicht besser.
Je nach dem was der Code macht könnte man alternativ vielleicht auch versuchen den bisherigen C-Code in eine dynamische Bibliothek zu stecken und dann per `ctypes` in Python einbinden.
Je nach dem was der Code macht könnte man alternativ vielleicht auch versuchen den bisherigen C-Code in eine dynamische Bibliothek zu stecken und dann per `ctypes` in Python einbinden.
Um eine gründliche Analyse der Funktionalität wirst Du so oder so nicht herum kommen. Unter Umständen kann es sinnvoll sein, Testroutinen in einem ordentlichen C zu schreiben, die sich einfach nach Python umsetzen lassen, so dass man die Äquivalenz der beiden Codes einfach zu prüfen. Danach ist der Schritt, den alten C-Code komplett zu vergessen und alles neu in Python zu schreiben nur noch klein.
Zudem dürfte es sich um sehr statischen Code handeln, der sich in einer dynamischen Sprache gar nicht sinnvoll wörtlich umschreiben läßt.
Nur der Neugier halber: Um wieviel Zeilen Code handelt es sich denn?
Zudem dürfte es sich um sehr statischen Code handeln, der sich in einer dynamischen Sprache gar nicht sinnvoll wörtlich umschreiben läßt.
Nur der Neugier halber: Um wieviel Zeilen Code handelt es sich denn?
Ein Hoch auf strukurierte Programmierung
Wie hoch ist denn der "Zersetzungsgrad" mit GOTOs und LABELs? Du wirst um eine genaue Kontrollflussanalyse nicht herumkommen. Sind die Sprünge sehr vertrackt, lohnt der Aufwand nicht - da ist es einfacher, das Programm von der Spezifikation her neu zu schreiben.
Der Trick mit ctypes ist eine gute Idee, um die Altlast irgendwie an Python ranzukriegen. Mit richtig üblem Nudelsalat kann da aber schon die Ein-/Ausgabe bzw. Interaktion mit Python schwierig werden.
Wie hoch ist denn der "Zersetzungsgrad" mit GOTOs und LABELs? Du wirst um eine genaue Kontrollflussanalyse nicht herumkommen. Sind die Sprünge sehr vertrackt, lohnt der Aufwand nicht - da ist es einfacher, das Programm von der Spezifikation her neu zu schreiben.
Der Trick mit ctypes ist eine gute Idee, um die Altlast irgendwie an Python ranzukriegen. Mit richtig üblem Nudelsalat kann da aber schon die Ein-/Ausgabe bzw. Interaktion mit Python schwierig werden.
Alleine auf den 764 LoC für main.c kommen gut 125 GoTo's. Die Labels besitzen passenderweise den Namen der ehemaligen Fortran Zeilenummer. Gut das ich morgens immer einen Sitzplatz im Zug finde, besser als jedes Sodoku
Ich werde erstmal schauen ob ich einige GoTo's in Schleifen verwandeln kann. Schade das es hierfür keine Heuristiken gibt, solche Knoten wieder zu entwirren.
Ich werde erstmal schauen ob ich einige GoTo's in Schleifen verwandeln kann. Schade das es hierfür keine Heuristiken gibt, solche Knoten wieder zu entwirren.
@darktrym:
Vielleicht hilft Dir das hier weiter (speziell "Application to Cobol"): http://en.wikipedia.org/wiki/Structured_program_theorem
Wenn das von Fortran aus den 70igern ist, basiert es vermutlich auf Fortran-66. Damit dürften alle "modernen" höheren Kontrollstrukturen fehlen, was die Anzahl von gotos erklären würde.
Vielleicht hilft Dir das hier weiter (speziell "Application to Cobol"): http://en.wikipedia.org/wiki/Structured_program_theorem
Wenn das von Fortran aus den 70igern ist, basiert es vermutlich auf Fortran-66. Damit dürften alle "modernen" höheren Kontrollstrukturen fehlen, was die Anzahl von gotos erklären würde.
Vielleicht ist es schlau, sich zunächst eine "Formelsammlung" anzulegen, wo man versucht, für die verschiedensten im Programm vorkommenden `goto`-Konstrukte modernere Übersetzungen aufzuführen. Dann wendet man diese Regeln stumpf auf den vorliegenden Code an. Läuft das Programm und seine Tests (wenn denn vorhanden) dann erwartungsgemäß durch, dann kann man versuchen, den naiv übersetzten Code nochmal insgesamt etwas aufzuhübschen. Klingt in der Theorie sicherlich einfacher als in der Praxis, aber so würde ich vermutlich vorgehen.
Es ist ja nicht so, als ob es Goto in Python nicht gäbe.
@/me: Das man damit nicht mitten in eine Schleife springen kann, könnte aber ein Problem sein, wenn der Quelltext tatsächlich so schlimm aussieht wie die Beschreibung vermuten lässt.
Kurze Frage, ich habe so ein Konstrukt:
Das Label führt das nun in den Block(blub) oder danach(blablub)?
Code: Alles auswählen
if (blabla)
label: {
blub()
}
blablub()
Zuletzt geändert von Anonymous am Donnerstag 11. April 2013, 10:48, insgesamt 1-mal geändert.
Grund: Quelltext in C-Code-Tags gesetzt.
Grund: Quelltext in C-Code-Tags gesetzt.
@darktrym: Ich würde ja sagen das Label markiert den Block mit dem `blub()`-Aufruf. Aber das ist ja nun nichts was man nicht mal eben ausprobieren könnte.
Stimmt, nur ist gerade meine MinGW Installation kaputt.
Nichtsdestotrotz, dank Online Compiler kein Problem.
Das offensichtliche war die Lösung, man hätte das Label besser gleich in den Block schreiben sollen, ist zum. intuitiver.
Nichtsdestotrotz, dank Online Compiler kein Problem.
Das offensichtliche war die Lösung, man hätte das Label besser gleich in den Block schreiben sollen, ist zum. intuitiver.
@darktrym: Ich finde die Idee mit ctypes ganz attraktiv. Wenn der Code wirklich so alt ist, zwischendurch aber gepflegt wurde, dann sollte dieser - trotz Spaghetti-Struktur - im wesentlichen bug-frei sein. Warum also umschreiben und neue Fehler einfügen? Das wären jedenfalls meine 2ct zu den bisherigen Infos.
@darktrym: Es mag offensichtlicher sein, aber IMHO weniger offensichtlich ist ob der Code der durch den Blockanfang generiert werden könnte und für den Blockinhalt dann natürlich wichtig ist, durch ein Label *im* Block dann nicht vielleicht übersprungen wird. Und im Gegenzug wird der Code der durch das Blockende erzeugt werden kann dann ausgeführt, was zu Fehlern führen kann, zum Beispiel einen korrupten Stack. Ich denke das Label ausserhalb des Blocks zu schreiben ist einfach sicherer.
Hier die Fortran-Version von 77: http://jerz.setonhill.edu/if/crowther/
Der Code sieht für mich gruselig aus. Da ich aber kein Fortran kann, ist das nur eine unqualifizierte Einschätzung. Die C-Version dagegen sieht machbar aus.
Der Code sieht für mich gruselig aus. Da ich aber kein Fortran kann, ist das nur eine unqualifizierte Einschätzung. Die C-Version dagegen sieht machbar aus.
Der Code ist mir zu einfach;) Da fehlen die coolen Features wie Verschlüsselung mit geheimen Startvektor(Verschlüsselung abhängig vom PRNG), Virtuelle Festplatte, die Speicherungsfunktion samt Prüfsummenmagie und Hashing für Nerds.