识别长fortran代码中的if-endif和do-enddo构造
我试图修改一个很大的Fortran遗留代码(fortran77),但由于代码的作者不喜欢写注释,也没有使用适当的缩进等,所以修改代码时遇到了很大的困难。我需要的是某种方法(一个包或一个命令行工具),使我能够识别给定构造的结尾,如识别长fortran代码中的if-endif和do-enddo构造,fortran,fortran90,fortran77,Fortran,Fortran90,Fortran77,我试图修改一个很大的Fortran遗留代码(fortran77),但由于代码的作者不喜欢写注释,也没有使用适当的缩进等,所以修改代码时遇到了很大的困难。我需要的是某种方法(一个包或一个命令行工具),使我能够识别给定构造的结尾,如if-then或do-enddo,如果我显示它的起始位置。例如: if(x .eq. 0)then if (y .eq. 0)then print*, y endif endif 假设我想看看第一个if语句的结尾在哪里,那么这个工具应该向我显示最后一行
if-then
或do-enddo
,如果我显示它的起始位置。例如:
if(x .eq. 0)then
if (y .eq. 0)then
print*, y
endif
endif
假设我想看看第一个if语句的结尾在哪里,那么这个工具应该向我显示最后一行,依此类推
如果有任何帮助,我将不胜感激。提前谢谢 这里有两种方法可以满足您的需要:
另一种方法是(自己)编写一个缩进FORTRAN文件的小代码。这并不难:)在fort中,标签结构如下(可能是F90中的标准):
Cat\u循环:
&I=1,N吗
!
Dog_环:Dok=1,M,9!因为狗是犬科动物!
!
蜥蜴环:
&DO J=1,M
!
恩多蜥蜴环
恩多狗环
ENDDO Cat_环
在通常使用IF语句的情况下,所选案例有时很有用。这是另一个90标准:
SELECTED CASE (Dog)
CASE(-9)
<Stuff>
!ENDCASE
CASE(1)
<Stuff>
!ENDCASE
CASE(2)
<Stuff>
!ENDCASE
CASE(9)
<Stuff>
ENDCASE
DEFAULT
WRITE(*,*)' Why am I here with Dog=',Dog
ENDCASE
END SELECT
所选案例(狗)
案件(-9)
!尾声
案例(1)
!尾声
案例(2)
!尾声
案件(9)
尾声
违约
写下(*,*)“我为什么和狗在一起?”,狗
尾声
结束选择
我要做的第一件事就是为已知的输入捕获一些输出,并构建一些方法来“单元测试”它。
并定期确保您坚持它所处的路径。是否有任何特定的原因限制您使用Fortran 90;它已经有将近30年的历史了。现代Fortran允许控制结构的标识符,
退出
不再局限于do
循环,goto
最终被弃用,因为它使用了Fortran 2008块
构造
alpha: block
bravo: do i = 1, num_in_set
charlie: if (x == a(i)) then
delta: select case (i)
case (FIRST)
call do_something(x)
case (SECOND)
call do_something_else(x)
case (THIRD)
cycle bravo
case default
exit alpha
end select delta
else if (x == a(i+1)) then
x = foo(a)
else
x = bar(a)
exit alpha
end if charlie
call finally_do_something(x)
end do bravo
end block alpha
芬登很棒!非常感谢。我想你没有读过我问题中的“遗留代码”一词。@SnehalShekatkar我以为你对重构遗留代码以符合现代实践感兴趣。您可以无需修改即可混合和匹配新旧代码。现代Fortran主要是向后兼容的,即Fortran 77标准一致性代码也是Fortran 2015可协调的,但前提是它不包括很少使用的删除功能,如
assign
,do
带浮点索引的循环,pause
,H
编辑描述符等。
alpha: block
bravo: do i = 1, num_in_set
charlie: if (x == a(i)) then
delta: select case (i)
case (FIRST)
call do_something(x)
case (SECOND)
call do_something_else(x)
case (THIRD)
cycle bravo
case default
exit alpha
end select delta
else if (x == a(i+1)) then
x = foo(a)
else
x = bar(a)
exit alpha
end if charlie
call finally_do_something(x)
end do bravo
end block alpha