将Fortran 77代码转换为C#


14

我正在尝试将Fortan77程序转换为C#。我有一个子程序,到处都有大约650行代码和可怕的GOTO语句。我什至开始可视化子例程的流程以弄清楚它的作用,这给我带来了很多麻烦。

有没有在这种事情上有经验的人可以给我任何有关如何大致了解此子程序的建议?是否有一些工具可以加快或促进这种转换?


1
由于这个问题更加开放且需要咨询,因此对于Programmers SE

4
您是否考虑过仅使用silverfrost.com/11/ftn95/ftn95_fortran_95_for_windows.aspx将其编译为.NET ,然后仅引用程序集?

@ Shaun,Shaun是个好主意。如果重新编程无法解决问题,我会看一下。
user643192 2011年

2
我为您感到抱歉...
marko

1
我去过你家了 那是我职业生涯中最糟糕的日子。
用户

Answers:


10

以我的经验,解决此问题的一个好方法是创建Fortran代码流程图。尝试将GOTO语句的目标分离到单独的块中,并使用该图从较高的层次上理解代码。

看看是否可以用循环或函数调用在逻辑上替换GOTO;如果结果图为树形结构,则无需借助GOTO即可相对容易地转换为C#。最后,您将需要深入理解代码,以便能够自信地维护和使用结果。


好建议,谢谢!GOTO语句应被禁止。
2011年

6
@ user643192,goto如果明智地应用,将非常有用。如果没有,您将无法实现高效的大型状态自动机goto。当然,您在生成的代码中也会需要它们。
SK-logic

3
有一些工具可以从Fortran代码中绘制流程图。示例:home.comcast.net/~lchen223621
NoChance 2011年

OP:您不能有效地禁止追溯。@EmmadKareem:非常有用的建议。
克里斯(Kris)

我最终完成了Daniel B在这里提出的建议,并制作了Fortran代码的代码块版本。它提供了很大帮助,所以谢谢。对于SK-logic来说,您可能对GOTO是正确的。我的评论是在我第一个下午看代码后做出的……里面有很多GOTO:o(
user643192 2011年

12

除了丹尼尔·B(Daniel B)上面写的以外,我还要说以下内容:

首先,获取您的Fortran代码以与Fortran for DotNet一起使用。不是,如果您“无法进行任何重新编程”,而是在尝试进行任何重新编程之前。这将是一小步,但方向正确。

然后,用C#编写一个测试套件,该套件向Fortran代码提供要进行修改的任何输入,并存储输出。运行测试套件一次,然后保存输出。然后,扩展测试套件以针对保存的输出来测试产生的输出。假设在输入相同的输入时,Fortran代码始终产生相同的输出,则测试当然应该成功。

然后,当您使用C#重写代码时,将在测试套件下运行代码,它将告诉您代码是否正常运行,这意味着它是否产生与Fortran完全相同的输出。代码给出相同的输入。没有它,您会迷路。

我不同意@ SK-logic,您完全不必在C#代码中使用任何gotos。

(但希望一旦在DotNet下使Fortran代码正常工作,您将看不到继续浪费时间将一段意大利面条式代码转换为C#的理由。)


1
介意解释,为什么“你不应该”?除了“每个人都认为这是邪恶的”以外,还有任何理性的论点吗?我 列举了两个非常重要的案例,其中您必须使用goto,否则您将最终编写不可读或效率低下的代码(或两者)。
SK-logic

@ SK-logic我没有写“你不应该”,我写了“你不应该”。无论如何,goto语句使代码很难在几乎所有情况下理解和验证其正确性,并且它们假定的效率收益介于神话和误解之间。当然可以进一步澄清这些,但是请不要这样做,这不是进行讨论的地方。让我们只是同意不同意。
Mike Nakis 2011年

2
goto在某些情况下,缺少政治家也会使您的代码很难理解(而状态机是这种情况下最重要的例子)。我实在受不了这种愚蠢的goto-bash宗教-人们不断重复同样无意义的BS,而从未试图理解goto被视为有害的原因。
SK-logic

您是如果没有最后决定就无法忍受的人之一,是吗?C-:=
Mike Nakis

1
@ ridecar2,我一直都在写好的状态机。我使用枚举和switch语句,并让编译器以生成的机器语言编写GOTO。实际上,我从未见过用GOT​​O明确编写的状态机示例。愿意发布指向示例的指针吗?
约翰·斯特罗姆

3

您的任务很棘手。您确实需要非常了解Fortran。您必须注意相似/不同的Fortran进行的计算方式以及适用的截断和舍入规则。另外,您需要注意C#和Fortran中的原始类型。

建议中的另一种方法(不一定是更好的方法,它只是另一种方法):

A-考虑根据业务知识和功能用C#重写代码,使用Fortran代码作为参考

B-考虑使用进行转换工作的商业工具-示例:DataTek

如果例程表示标准函数或可以购买现成的dll的函数(例如,数值积分),请使用标准函数或商业产品,而不是手动翻译,即可解决问题。

如果以上方法不能解决问题,请回答以下问题:

我需要优化代码还是只是使其运行。换句话说,花500个小时使代码变得更好的商业价值是什么?

如果优化没有价值,则逐行翻译代码即可。

如果仍然不好,则:

0逐行将Fortran代码转换为C#(或使用Fortan CLR)

1-进行快速测试以确保其运行

2-使用重构(提供商业工具)来帮助您以更优化的方式编写代码。

祝好运。


2

用很多getos来编码东西的一种简单方法是绘制流程图并将直线拉直。有时,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语句,因此我首先获取了整个Fortran代码并将其按原样粘贴到新方法中,以及与Fortran例程和子例程一样多的方法。

编译器出现了100万个错误,主要是有关未声明的变量和不正确的语句块格式的错误,我一一清除了这些错误。我还不得不重写一些特定于Fortran的代码,例如I / O语句和类似的东西。完成后,我得到了原始代码的精确副本。

得益于Visual Studio的出色格式,逻辑块比原始代码更容易识别。我可以一一解开goto语句。

根据这种经验,我不得不说,在某些情况下,goto语句实际上非常有用,可以避免一遍又一遍地重写相同的代码,尽管在很多情况下,使用方法并重复调用可以实现相同的目的。 。

我还使用了免费版本的Silverfrost来编译原始代码,并对重新格式化的代码进行定期检查,以确保重新格式化不会产生错误。


0

一种“反编译”这样的代码的通用方法如下:

  • 首先将其编译为较低级别的形式(例如LLVM)
  • 在其上执行SSA转换(这将有助于清理您的局部变量)
  • 拆分不可约的控制流(如果有)
  • 检测循环和ifs并将其替换为适当的高级构造

LLVM自己的C后端可以为您提供初稿。


0

毫无疑问,最好的方法是首先将FORTRAN代码重写/重构为更好的结构化和逻辑性方式。这将迫使您在尝试将其移植到C#之前了解原始逻辑。

这是我的处理方法:

  • 了解现有代码,并在必要时进行重构,甚至在FORTRAN中将其重写,以便您可以轻松测试其是否有效。
  • 将重构的代码移植到C#

不要使用自动代码转换器浪费时间,因为它最终会产生与原始FORTRAN相同的goto语句混乱,因为C#像C一样支持gotos和标签。


0

如果没有其他任何事情,则可以在C#中使用goto语句

跳转语句程序控制直接传输到标签的语句。

goto的常见用法是将控制权转移到特定的切换用例标签或switch语句中的默认标签。

跳转语句也得到深度嵌套的循环出有用...


-2

要将任何旧的FORTRAN代码转换为新语言,有人应该在您的旧代码中执行一些基本步骤(1)进行静态类型检查,将代码转换为“ IMPLICIT NONE”(2)将所有截断的通用转换为完全通用(3)删除等价(4)转换为FORTRAN 90的通用模块

然后,您可以尝试转换为其他语言。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.