Goto's equivalent ersetzen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

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?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Wenn das wirklich Spaghetti-Code ist, dann würde ich nicht versuchen das vom Quelltext her zu portieren sondern es neu schreiben.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

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.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@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.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

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?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

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.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

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.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Es ist ja nicht so, als ob es Goto in Python nicht gäbe. :evil:
BlackJack

@/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. :-)
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Kurze Frage, ich habe so ein Konstrukt:

Code: Alles auswählen

if (blabla)
label: {
blub()
}
blablub()
Das Label führt das nun in den Block(blub) oder danach(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.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@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. :-)
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

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.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@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.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Ich betrachte das zum Teil auch als Fingerübung/Weiterbildung.
Hier ein Einblick in feinster Spagetti-Programmierung.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@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.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

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.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

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.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Antworten