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ę?
Odpowiedzi:
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ą.
źródło
goto
jest niezwykle przydatna, jeśli jest mądrze zastosowana. Nie wdrożyłbyś wydajnego, dużego automatu stanowego bezgoto
. Z pewnością będziesz ich potrzebować również w wygenerowanym kodzie.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 #.)
źródło
goto
statemenó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.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.
źródło
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.
źródło
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ść.
źródło
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.
źródło
Ogólne podejście do „dekompilacji” takiego kodu byłoby następujące:
Własny backend C w LLVM może zapewnić ci pierwszą wersję roboczą.
źródło
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ę:
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.
źródło
Jeśli coś innego się nie powiedzie, możesz użyć instrukcji goto w języku C # .
źródło
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.
źródło