识别长 Fortran 代码中的 if-endif 和 do-enddo 结构
Identify if-endif and do-enddo constructs in long fortran code
我正在尝试修改一个非常大的 Fortran 遗留代码 (fortran77),但由于代码的作者不关心写注释,也没有使用适当的缩进等,我在修改时遇到了巨大的困难代码。我需要的是某种方式(一个包或命令行工具),如果我在它开始的地方显示它,它将使我能够识别给定结构的结尾,如 if-then
或 do-enddo
。例如:
if(x .eq. 0)then
if (y .eq. 0)then
print*, y
endif
endif
假设我想看看第一个 if 语句在哪里结束,那么这个工具应该会显示最后一行等等。
如有任何帮助,我将不胜感激。提前致谢。
这里有两个选项可以满足您的需求:
http://www.polyhedron.com/pf-plusfort0html
https://sourceforge.net/projects/findent/files/
另一个是(自己)做一个小代码来缩进 FORTRAN 文件。没那么难:)
堡垒中有如下标注结构(可能是F90的标准):
Cat_Loop:
&DO I = 1, N
!<stuff>
Dog_Loop: DO K = 1, M, 9 !Because Dogs are canines!
!<stuff>
Lizard_Loop:
& DO J = 1, M
!<stuff>
ENNDO Lizard_Loop
ENNDO Dog_Loop
ENDDO Cat_Loop
SELECTED CASE 有时在 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
我要做的第一件事是为已知输入捕获一些输出,并构建一些方法来 'unit test' 它。
并定期确保您坚持以前的路径。
您将自己限制在 Fortran 90 上有什么特别的原因吗?它已经有将近 3 年的历史了。现代 Fortran 允许标识符用于控制结构,exit
不再局限于 do
循环,并且 goto
最终通过使用 Fortran 2008 block
结构被弃用。
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
我正在尝试修改一个非常大的 Fortran 遗留代码 (fortran77),但由于代码的作者不关心写注释,也没有使用适当的缩进等,我在修改时遇到了巨大的困难代码。我需要的是某种方式(一个包或命令行工具),如果我在它开始的地方显示它,它将使我能够识别给定结构的结尾,如 if-then
或 do-enddo
。例如:
if(x .eq. 0)then
if (y .eq. 0)then
print*, y
endif
endif
假设我想看看第一个 if 语句在哪里结束,那么这个工具应该会显示最后一行等等。
如有任何帮助,我将不胜感激。提前致谢。
这里有两个选项可以满足您的需求:
http://www.polyhedron.com/pf-plusfort0html
https://sourceforge.net/projects/findent/files/
另一个是(自己)做一个小代码来缩进 FORTRAN 文件。没那么难:)
堡垒中有如下标注结构(可能是F90的标准):
Cat_Loop:
&DO I = 1, N
!<stuff>
Dog_Loop: DO K = 1, M, 9 !Because Dogs are canines!
!<stuff>
Lizard_Loop:
& DO J = 1, M
!<stuff>
ENNDO Lizard_Loop
ENNDO Dog_Loop
ENDDO Cat_Loop
SELECTED CASE 有时在 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
我要做的第一件事是为已知输入捕获一些输出,并构建一些方法来 'unit test' 它。 并定期确保您坚持以前的路径。
您将自己限制在 Fortran 90 上有什么特别的原因吗?它已经有将近 3 年的历史了。现代 Fortran 允许标识符用于控制结构,exit
不再局限于 do
循环,并且 goto
最终通过使用 Fortran 2008 block
结构被弃用。
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