Konwersja kodu Fortran 77 na C #

14

Próbuję przekonwertować program Fortan77 do C #. Mam podprogram z około 650 liniami kodu i przerażającymi instrukcjami GOTO w każdym miejscu. Mam dużo problemów, nawet zaczynam wizualizować przebieg podprogramu, aby dowiedzieć się, co on robi.

Czy jest ktoś z doświadczeniem w tego rodzaju sprawach, który mógłby udzielić mi porady, jak uzyskać przegląd tego podprogramu? Czy są dostępne narzędzia przyspieszające lub ułatwiające tego typu konwersję?

użytkownik643192
źródło
1
Ponieważ pytanie to jest bardziej otwarte i szuka porady, byłoby bardziej odpowiednie dla Programistów SE
4
czy zastanawiałeś się nad skompilowaniem go w .NET przy użyciu silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx, a następnie po prostu odwołując się do zestawu?
@Shaun, to niezły pomysł Shaun. Spojrzę na to, jeśli nie uda mi się dostać z powodu przeprogramowania.
user643192
2
Żal mi ciebie ...
marko
1
Byłem na twoim miejscu. To były najgorsze dni w mojej karierze.
użytkownik

Odpowiedzi:

10

Z mojego doświadczenia wynika, że ​​dobrym sposobem na to jest stworzenie schematu blokowego kodu Fortran. Spróbuj rozdzielić cele instrukcji GOTO na osobne bloki i użyj diagramu, aby spróbować zrozumieć kod na wysokim poziomie.

Sprawdź, czy możesz logicznie zastąpić GOTO pętlami lub wywołaniami funkcji; jeśli wynikowy diagram ma postać struktury drzewa, stosunkowo łatwo przekonwertować go do C # bez uciekania się do GOTO. W końcu jednak musisz dokładnie zrozumieć kod, aby móc zachować wynik i korzystać z niego z pewnością.

Daniel B.
źródło
Dobra sugestia, dzięki! Instrukcje GOTO powinny zostać zbanowane.
user643192
6
@ user643192, gotojest niezwykle przydatna, jeśli jest mądrze zastosowana. Nie wdrożyłbyś wydajnego, dużego automatu stanowego bez goto. Z pewnością będziesz ich potrzebować również w wygenerowanym kodzie.
SK-logic
3
Istnieją narzędzia, które mogą rysować schematy blokowe z kodu Fortran. Przykład: home.comcast.net/~lchen223621
NoChance
OP: Nie możesz banować z mocą wsteczną. @EmmadKareem: Bardzo przydatna sugestia.
Kris,
Skończyło się na tym, co sugerował Daniel B i stworzyłem blokową wersję kodu Fortran. Bardzo mi pomógł, więc dzięki za to. Jeśli chodzi o SK-logic, prawdopodobnie masz rację co do GOTO. Mój komentarz został
napisany
12

Oprócz tego, co napisał Daniel B powyżej, powiedziałbym, co następuje:

Najpierw przygotuj kod Fortran do współpracy z Fortran dla DotNet. Nie, jeśli „nie da się nigdzie przeprogramować”, ale przed próbą przeprogramowania. To będzie mały krok, ale we właściwym kierunku.

Następnie napisz pakiet testowy w języku C #, który podaje kod Fortranowi dane wejściowe, które zostały wprowadzone do gryzienia, i zapisuje dane wyjściowe. Uruchom pakiet testowy raz i zapisz wynik. Następnie rozszerz zestaw testów, aby przetestować wygenerowane dane wyjściowe względem zapisanego wyniku. Zakładając, że kod Fortran zawsze generuje to samo wyjście, gdy jest zasilany tym samym wejściem, test powinien oczywiście zakończyć się powodzeniem.

Następnie, gdy przepisujesz kod w C #, będziesz uruchamiał swój kod w pakiecie testowym i będzie ci mówił, czy twój kod działa poprawnie, czy nie, co oznacza, że ​​produkuje dokładnie taki sam wynik jak Fortran kod ma takie same dane wejściowe. Bez tego zgubisz się.

Nie zgadzam się z @ SK-logic, NIE powinieneś używać żadnych gotów w swoim kodzie C #.

(Ale mam nadzieję, że kiedy już sprawisz, że kod Fortran będzie działał pod DotNet, nie zobaczysz powodu, aby kontynuować marnowanie czasu na konwersję kawałka kodu spaghetti do C #.)

Mike Nakis
źródło
1
wyjaśnij umysł, dlaczego „NIE powinieneś”? Jakieś racjonalne argumenty oprócz „wszyscy uważają, że to zło”? Nazwałam dwa przypadki niezwykle ważne gdzie mają używać goto, inaczej skończysz pisać albo nieczytelne lub unefficient kod (lub oba).
SK-logic
@ SK-logic Nie napisałem „nie powinieneś”, napisałem „nie powinieneś”. W każdym razie, oto jest: instrukcje goto bardzo utrudniają zrozumienie kodu i weryfikację jego poprawności w prawie wszystkich okolicznościach, a ich rzekome korzyści w zakresie wydajności są czymś pomiędzy mitem a nieporozumieniem. Oczywiście można to wyjaśnić dalej, ale powstrzymajmy się od robienia tego, nie jest to miejsce na tę dyskusję. Po prostu zgódźmy się nie zgodzić.
Mike Nakis,
2
brak gotostatemenów może również sprawić, że kod będzie bardzo trudny do zrozumienia w niektórych przypadkach (a automat stanowy jest najważniejszym przykładem takiej sprawy). Po prostu nie mogę znieść tej głupiej religii walczącej z goto - ludzie powtarzają tę samą bezsensowną BS bez prób zrozumienia, dlaczego goto jest uważany za szkodliwy.
SK-logic
Jesteś jedną z tych osób, które nie mogą tego znieść, jeśli nie mają ostatniego słowa, co? C -: =
Mike Nakis
1
@ ridecar2, Piszę dobry stan maszyny CAŁY CZAS. Używam wyliczeń i instrukcji switch i pozwalam kompilatorowi pisać GOTO w wygenerowanym języku maszynowym. Tak naprawdę nigdy nie widziałem przykładu maszyny stanów napisanej wyraźnie za pomocą GOTO. Chcesz zamieścić wskaźnik na przykładzie?
John R. Strohm,
3

Twoje zadanie jest trudne. Naprawdę musisz dobrze znać Fortran. Musisz uważać na to, jak podobne / różne Fortran wykonuje obliczenia i jakie zasady obcinania i zaokrąglania mają zastosowanie. Ponadto musisz uważać na prymitywne typy znaczeń w C # i Fortran.

Kolejne podejście z sugestii (niekoniecznie lepsze, to tylko kolejne):

Odp. - Rozważ ponowne napisanie kodu w języku C # w oparciu o wiedzę biznesową i funkcję, użyj kodu Fortran jako odniesienia

B-Rozważ użycie komercyjnego narzędzia, które wykonuje zadanie konwersji - Przykład: DataTek

Jeśli procedura reprezentuje funkcję standardową lub funkcję, dla której można kupić gotową bibliotekę DLL (na przykład integrację numeryczną), użyj funkcji standardowej lub produktu komercyjnego zamiast tłumaczenia ręcznego, a problem zostanie rozwiązany.

Jeśli powyższe nie ogranicza, odpowiedz na to pytanie:

Czy muszę zoptymalizować kod, czy po prostu go uruchomić. Innymi słowy, jaka jest wartość biznesowa spędzenia 500 godzin na ulepszeniu kodu?

jeśli w optymalizacji nie ma żadnej wartości, przetłumacz wiersz po wierszu i gotowe.

Jeśli nadal nie jest to dobre, to:

0-Konwertuj kod Fortran linia po linii na C # (lub użyj Fortan CLR)

1-Wykonaj szybki test, aby upewnić się, że działa

2-Użyj faktoringu (dostępne są narzędzia komercyjne), aby pomóc Ci napisać kod w bardziej zoptymalizowany sposób.

Powodzenia.

Bez szans
źródło
2

Prostym sposobem przekodowywania rzeczy z dużą ilością gotów jest narysowanie schematu blokowego i pociągnięcie łańcucha prosto. Czasami programy F77 to po prostu stare programy F66 lub nawet gorsze programy FII. F66 nie miał konstrukcji „jeśli-to-inaczej”, więc konieczne były gotos. Wszystko, co musisz zrobić, to odwrócić warunek, aby uzyskać „jeśli-to”.

F66 też nie miał czasu na wykonanie, ale F77 ma. Zależy to od tego, czy program kodujący był konwertowany z F66 na F77 (podobnie jak wielu obecnie używa C na C ++ lub C ++ na C #), gdzie używają F77 jak F66. Jeśli zauważysz wzorce w kodowaniu, konwersja jest znacznie łatwiejsza.

Puchar
źródło
1

Zanim zaczniesz, stwórz zestaw testowy, aby przetestować istniejący kod. Bądź bardzo dokładny, ponieważ pomoże to rzucić światło na zachowanie. Następnie możesz użyć tego pakietu do oceny skuteczności konwersji.

Poza tym bądź metodyczny , nie spiesz się i używaj dużej ilości papieru, aby sprawdzić funkcjonalność.

Bryan Oakley
źródło
1

Oto sposób, w jaki faktycznie zająłem się tłumaczeniem kodu na C #. Ponieważ .NET obsługuje instrukcje goto, najpierw wziąłem cały kod Fortran i wkleiłem go, tak jak jest, do nowej metody, cóż, tyle metod, ile było procedur i podprogramów Fortran.

Kompilator wyszedł z milionem błędów, głównie dotyczących niezadeklarowanych zmiennych i niepoprawnego formatowania instrukcji blokowych, które wyczyściłem jeden po drugim. Musiałem także przepisać niektóre kody specyficzne dla Fortrana, takie jak instrukcje We / Wy i podobne rzeczy. Kiedy to zrobiłem, miałem dokładną replikę oryginalnego kodu.

Dzięki ładnemu formatowaniu Visual Studio bloki logiczne były o wiele łatwiejsze do zidentyfikowania niż w oryginalnym kodzie. I mógłbym zacząć rozwiązywać instrukcje goto jeden po drugim.

Z tego doświadczenia muszę powiedzieć, że istnieją przypadki, w których instrukcje goto są BARDZO przydatne, aby uniknąć konieczności przepisywania tego samego kodu w kółko, chociaż w wielu przypadkach można to zrobić, stosując metody i wywołując je wielokrotnie .

Użyłem również darmowej wersji Silverfrost do skompilowania oryginalnego kodu i regularnego sprawdzania mojego przeformatowanego kodu, aby upewnić się, że formatowanie nie spowodowało błędów.

użytkownik643192
źródło
0

Ogólne podejście do „dekompilacji” takiego kodu byłoby następujące:

  • najpierw skompiluj go do postaci niższego poziomu (np. LLVM)
  • wykonaj na nim transformację SSA (pomoże to wyczyścić zmienne lokalne)
  • podzielić nieredukowalny przepływ kontrolny (jeśli występuje)
  • wykrywaj pętle i ifs i zastępuj je odpowiednimi konstrukcjami wysokiego poziomu

Własny backend C w LLVM może zapewnić ci pierwszą wersję roboczą.

Logika SK
źródło
0

Najlepszym sposobem bez wątpienia jest najpierw przepisanie / refaktoryzacja kodu FORTRAN w bardziej uporządkowany i logiczny sposób. To zmusi cię do zrozumienia oryginalnej logiki przed próbą przeniesienia jej do C #.

Oto jak do tego podejdę:

  • Zapoznaj się z istniejącym kodem i, jeśli to konieczne, przebuduj go, a nawet przepisz go w FORTRAN, abyś mógł łatwo przetestować jego działanie.
  • Przenieś refaktoryzowany kod do C #

Nie trać czasu na automatyczny konwerter kodu, który skończy z tym samym bałaganem instrukcji goto, co oryginalny FORTRAN, ponieważ C # obsługuje gotos i etykiety, podobnie jak C.

dodgy_coder
źródło
0

Jeśli coś innego się nie powiedzie, możesz użyć instrukcji goto w języku C # .

Instrukcja goto przenosi kontrolę programu bezpośrednio do instrukcji oznaczonej etykietą.

Częstym zastosowaniem goto jest przeniesienie kontroli na określoną etykietę skrzynki rozdzielczej lub etykietę domyślną w instrukcji switch .

Instrukcja goto jest również przydatna, aby wydostać się z głęboko zagnieżdżonych pętli ...

Wyatt Barnett
źródło
-2

Aby przekonwertować dowolny stary kod FORTRAN na nowy język, ktoś powinien przejść przez kilka podstawowych kroków w starszym kodzie (1) w celu sprawdzenia typu statycznego przekonwertować kod na „IMPLICIT NONE” (2) przekonwertować wszystkie obcięte wspólne na pełne wspólne (3) Usuń równoważność (4) konwersja wspólna na moduł FORTRAN 90

Następnie możesz spróbować przekonwertować na inne języki.

Debiprasad Ghosh
źródło