Преобразование кода Fortran 77 в C #

14

Я пытаюсь конвертировать программу Fortan77 в C #. У меня есть подпрограмма с примерно 650 строками кода и ужасающими инструкциями GOTO повсюду. У меня много проблем, даже когда я начинаю визуализировать поток подпрограммы, чтобы понять, что она делает.

Есть ли кто-нибудь с опытом в такого рода вещах, кто мог бы дать мне какой-нибудь совет о том, как получить обзор этой подпрограммы? Существуют ли какие-либо инструменты для ускорения или упрощения этого типа конверсии?

user643192
источник
1
Поскольку этот вопрос является более открытым и ищет совета, он был бы более уместным для программистов SE
4
Вы рассматривали просто компиляцию в .NET с использованием silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx, а затем просто ссылались на сборку?
@Shaun, это хорошая идея, Шон. Я посмотрю на это, если я не смогу получить что-либо с перепрограммированием.
user643192
2
Мне жаль тебя ...
Марко
1
Я был на вашем месте. Это были худшие дни в моей карьере.
пользователь

Ответы:

10

По моему опыту, хороший способ сделать это - создать блок-схему кода на Фортране. Попробуйте разделить цели операторов GOTO на отдельные блоки и используйте диаграмму, чтобы попытаться понять код на высоком уровне.

Посмотрите, можете ли вы логически заменить GOTO циклами или вызовами функций; если получающаяся диаграмма имеет форму древовидной структуры, ее относительно легко преобразовать в C #, не прибегая к GOTO. В конце концов, вам нужно будет хорошо понимать код, чтобы иметь возможность поддерживать и использовать результат с уверенностью.

Даниэль Б
источник
Хорошее предложение, спасибо! GOTO заявления должны быть запрещены.
user643192
6
@ user643192, gotoочень полезная вещь, если применять ее с умом. Вы бы не пошли на реализацию эффективного, большого государственного автомата без goto. Они вам наверняка понадобятся и в сгенерированном коде.
SK-logic
3
Есть инструменты, которые могут рисовать потоковые диаграммы из кода Фортрана. Пример: home.comcast.net/~lchen223621
NoChance
ОП: Вы не можете запретить ретро-эффект. @ EmmadKareem: очень полезное предложение.
Крис
В итоге я сделал то, что предложил Дэниел Б, и сделал блочную версию кода на Фортране. Это очень помогло, так что спасибо за это. Для SK-логики вы, вероятно, правы по поводу GOTO. Мой комментарий был сделан после моего первого дня, когда я смотрел на код ... и в нем есть много GOTO: o (
user643192
12

В дополнение к тому, что написал Даниэль Б, я бы сказал следующее:

Во-первых, получите ваш код Fortran для работы с Fortran для DotNet. Не если вы «никуда не денетесь с перепрограммированием», но прежде чем пытаться перепрограммировать. Это будет маленький шаг, но в правильном направлении.

Затем напишите набор тестов на C #, который передает код на Фортране с любым вводимым им кодом и сохраняет результаты. Запустите тестовый набор один раз и сохраните вывод. Затем расширьте набор тестов, чтобы протестировать полученный результат в сравнении с сохраненным. Предполагая, что код Фортрана всегда выдает один и тот же вывод при подаче одного и того же ввода, тест, конечно, должен пройти успешно.

Затем, пока вы переписываете код в C #, вы будете запускать свой код в наборе тестов, и он будет сообщать вам, работает ли ваш код правильно или нет, имея в виду, выдает ли он точно такой же вывод, как и Fortran Код с тем же вводом. Без этого вы будете потеряны.

Я не согласен с @ SK-logic, вам НЕ ДОЛЖНО вообще использоваться gotos в вашем коде C #.

(Но, надеюсь, что после того, как вы запустите код на Фортране в DotNet, вы не увидите причин продолжать тратить время на преобразование фрагмента спагетти-кода в C #.)

Майк Накис
источник
1
объясните, почему «вы не должны»? Есть ли рациональные аргументы, кроме "все считают, что это зло"? Я назвал два чрезвычайно важных случая, когда вам нужно использовать goto, в противном случае вы в конечном итоге будете писать либо нечитаемый, либо неэффективный код (или оба).
SK-logic
@ SK-логика Я не писал «вы не должны», я писал «вы не должны». В любом случае, вот так: операторы goto делают код очень сложным для понимания и проверки его правильности практически при любых обстоятельствах, а их предполагаемые преимущества в эффективности - нечто среднее между мифом и заблуждением. Конечно, это можно уточнить, но, пожалуйста, давайте воздержимся от этого, это не место для этого обсуждения. Давайте просто согласимся не соглашаться.
Майк Накис
2
Отсутствие государственных деятелей gotoможет также сделать ваш код очень трудным для понимания в некоторых случаях (и конечный автомат является наиболее важным примером такого случая). Я просто не выношу эту глупую религию, порождающую гото - люди продолжают повторять одно и то же бессмысленное БС, даже не пытаясь понять причину, по которой гото считается вредным.
SK-logic
Вы один из тех людей, которые просто не могут этого вынести, если у них нет последнего слова, а? C -: =
Майк Накис
1
@ ridecar2, я пишу хорошие машины состояния ВСЕ ВРЕМЯ. Я использую перечисления и операторы switch и позволяю компилятору писать GOTO на сгенерированном машинном языке. На самом деле я никогда не видел пример конечного автомата, явно написанного с помощью GOTO. Хотите опубликовать указатель на пример?
Джон Р. Штром
3

Ваша задача сложная. Вам действительно нужно хорошо знать Фортран. Вы должны быть осторожны с тем, насколько похожи / различны Фортран, выполняет вычисления и какие правила усечения и округления применяются. Кроме того, вы должны быть осторожны с примитивными типами, означающими C # и Fortran.

Другой подход из того, что было предложением (не обязательно лучше, это просто еще один):

A - Подумайте о переписывании кода на C #, основываясь на знаниях и функциях бизнеса, используйте код на Фортране в качестве справочного материала.

B - Рассмотрите использование коммерческого инструмента, который выполняет конвертацию - Пример: DataTek

Если подпрограмма представляет собой стандартную функцию или функцию, для которой вы можете купить готовую dll (например, числовую интеграцию), используйте стандартную функцию или коммерческий продукт вместо ручного перевода, и ваша проблема решена.

Если вышеупомянутое не сокращает это, ответьте на этот вопрос:

Нужно ли оптимизировать код или просто заставить его работать. Другими словами, какова коммерческая ценность того, чтобы тратить 500 часов на улучшение кода?

если в оптимизации нет значения, переведите код построчно, и все готово.

Если это все еще не хорошо, тогда:

0-Конвертировать код Фортран построчно в C # (или использовать Fortan CLR)

1-Сделайте быстрый тест, чтобы убедиться, что он работает

2-Используйте рефакторинг (коммерческие инструменты доступны), чтобы помочь вам написать код более оптимизированным способом.

Удачи.

Без шансов
источник
2

Простой способ перекодировать материал с большим количеством gotos - нарисовать блок-схему и вывести строку прямо. Иногда программы F77 - это просто старые программы F66 или, что еще хуже, программы FII. У F66 не было конструкции if-then-else, поэтому gotos были необходимы. Все, что вам нужно сделать, это инвертировать условие, чтобы получить if-then.

У F66 тоже не было времени, а у F77. Это зависит от того, был ли кодер преобразован из F66 в F77 (как многие сегодня это C на C ++ или C ++ в C #), где они используют F77 как F66. Если вы можете определить паттерны в кодировке, их будет гораздо проще конвертировать.

кружка
источник
1

Прежде чем начать, создайте набор тестов для тестирования существующего кода. Будьте очень внимательны, так как это поможет пролить свет на поведение. Затем вы можете использовать этот пакет, чтобы оценить эффективность вашей конверсии.

Кроме того, будьте методичны , не торопитесь и используйте много бумаги, чтобы отследить функциональность.

Брайан Оукли
источник
1

Вот как я на самом деле пошел переводить код на C #. Поскольку .NET поддерживает операторы goto, я сначала взял весь код на Фортране и вставил его как есть в новый метод, а также столько методов, сколько было подпрограмм и подпрограмм на Фортране.

Компилятор обнаружил миллион ошибок, в основном из-за необъявленных переменных и неправильного форматирования операторов блока, которые я исправлял одну за другой. Мне также пришлось переписать некоторый специфичный для Фортрана код, такой как операторы ввода-вывода и тому подобное. Когда это было сделано, у меня была точная копия исходного кода.

Благодаря удобному форматированию Visual Studio логические блоки было намного проще идентифицировать, чем в исходном коде. И я мог бы начать распутывать заявления goto один за другим.

Исходя из этого опыта, я должен сказать, что в некоторых случаях операторы goto на самом деле ОЧЕНЬ полезны, чтобы избежать необходимости переписывать один и тот же код снова и снова, хотя во многих случаях того же можно достичь, используя методы и вызывая их повторно. ,

Я также использовал бесплатную версию Silverfrost для компиляции исходного кода и регулярных проверок моего переформатированного кода, чтобы гарантировать, что переформатирование не приведет к ошибкам.

user643192
источник
0

Общий подход к «декомпиляции» такого кода будет следующим:

  • сначала скомпилируйте его в форму более низкого уровня (например, LLVM)
  • выполнить на нем SSA-преобразование (это поможет очистить ваши локальные переменные)
  • разделить неприводимый поток управления (если есть)
  • обнаруживать циклы и ifs и заменять их соответствующими конструкциями высокого уровня

Собственный бэкэнд LLVM C может предоставить вам первый черновик.

SK-логика
источник
0

Без сомнения, лучший способ - это сначала переписать / реорганизовать код FORTRAN в более структурированный и логичный способ. Это заставит вас понять оригинальную логику, прежде чем пытаться перенести ее на C #.

Вот как я бы подошел к этому:

  • Понимайте существующий код и, если необходимо, реорганизуйте его и даже переписывайте в FORTRAN, чтобы вы могли легко проверить его работоспособность.
  • Перенесите измененный код на C #

Не тратьте свое время на автоматический конвертер кода, который в конечном итоге будет содержать тот же беспорядок в выражениях goto, что и в оригинальном FORTRAN, поскольку C # поддерживает gotos и метки, как и C.

dodgy_coder
источник
0

В противном случае вы можете использовать операторы goto в C # .

Оператор goto передает управление программой непосредственно в помеченный оператор.

Обычно goto используется для передачи управления определенной метке переключения или метке по умолчанию в инструкции switch .

Оператор goto также полезен для выхода из глубоко вложенных циклов ...

Уайетт Барнетт
источник
-2

Чтобы преобразовать любой старый код FORTRAN в новый язык, кто-то должен пройти через некоторые основные шаги в вашем унаследованном коде (1) для проверки статического типа, преобразовать код в «IMPLICIT NONE» (2) преобразовать все усеченное общее в полное общее (3) Удалить эквивалентность (4) преобразовать общий в модуль FORTRAN 90

Затем вы можете попробовать конвертировать на другие языки.

Дебипрасад Гош
источник