我有一些Fortran 77源文件,我正在尝试将其从非标准STRUCTURE
和RECORD
语法转换为标准化的Fortran 90 TYPE
语法。其中一个棘手的方面是结构成员的不同处理方式。
非标:
s.member = 1
标准
s%member = 1
因此,我需要在这些场景中捕获句点的所有用法,并用%
个字符替换它们。还不错,除非您考虑可以使用句点的所有方式(数字中的小数点,include
语句中的文件名,注释中的标点符号,Fortran 77关系运算符,可能还有其他)。我已经做了一些预处理来修复关系运算符以使用Fortran 90符号,我并不真正关心修改注释的语法,但我还没有想出一个很好的方法来翻译{{1}对于上述案例,请.
。看起来我应该能够用sed做到这一点,但我不确定如何匹配我需要修复的实例。以下是我想到的规则:
逐行:
如果该行以%
开头,那么我们就不应对该行做任何事情;将它传递给输出,所以我们不会搞乱include语句中的文件名。
以下字符串是没有符号等效项的运算符,因此必须保持不变:<whitespace>include
否则,如果我们找到一个被2个非数字字符包围的句点(因此它不是小数点),那么它应该是我想要替换的运算符。将该期间更改为.not. .and. .or. .eqv. .neqv.
。
我自己不是本土的Fortran演讲者,所以这里有一些例子:
%
解决这个问题的好方法是什么?
编辑:我实际上发现了一些额外的运算符,其中包含一个没有符号等价物的点。我已经更新了上面的规则列表。
答案 0 :(得分:2)
你不能用正则表达式做到这一点,并不是那么容易。
如果我必须做你必须做的事情,我可能会手工完成,除非代码库很大。如果前者适用,首先将所有[a-zA-Z0-9]。[a-zA-Z]替换为非常奇怪的东西,保证永远不会编译,如“@ WHATEVER @”,然后继续搜索所有这些参赛作品并在手动控制后手动更换。
如果代码量很大,那么你需要编写一个解析器。我建议你使用python来标记基本的fortran结构,但请记住fortran不是一种易于解析的语言。按“每个例程”工作,并尝试查找所有使用的变量名称,将它们用作过滤器。如果您遇到类似a.whatever
的内容,并且您知道a
位于本地或全局变量列表中,请应用更改。
答案 1 :(得分:2)
除非代码库真的是 HUUGE (并且确实非常认真地考虑到这种情况),我只需要像 Vim < / strong>(垂直选择和块选择是你的朋友)a * nd留出一个下午手动执行此操作* 。在一个下午,我的猜测是你将完成 大部分,如果不是全部 。 下午是很多时间。想象一下,这两个小时内你可以覆盖多少案例。
只需通过 尝试为此类内容编写解析器,将花费更长的时间。
当然,这个问题要求自己......如果所有编译器仍支持F77的代码,并且代码有效......为什么你如此热衷于改变呢?
答案 2 :(得分:2)
我不是那些精通正则表达式的人,所以我想我会尝试从另一方面解决这个问题。如果grep
关键字为STRUCTURE
,则会获得代码中使用的所有STRUCTURES
的列表。完成后,对于每个STRUCTURE S
,您只需将S.
的所有实例替换为S%
。
这样您就不必担心.true.
,.and.
,.neq.
及其亲属等问题。那么主要的担心是能够解析STRUCTURE
声明。
答案 3 :(得分:0)
虽然正则表达式如下:
(?<!')\b([^.\s]+)(?<!\.(?:not|and|or|eqv|neqv))(?<=\D)\.(?=\D)(?!(?:not|and|or|eqv|neqv)\.)([^.\s]+)\b(?!')
替换$1%$2
完美适用于您的示例,我不建议将其与您当前的任务一起使用。它肯定不会涵盖你的所有情况。现在如果你关心80%的覆盖率或者你可以使用它的东西,但是你应该备份你的资源。由于我有一组有限的输入案例,我确信会出现正则表达式会替换它不应该的东西的情况。
祝你好运:)答案 4 :(得分:0)
这个sed oneliner可能是一个开始
sed -r '/^\s*include/b;/^\s*! /b;G;:a;s/^(\.(not|and|or|eqv|neqv)\.)(.*\n.*)/\3\1/;ta;s/^\.([^0-9]{2,})(.*\n.*)/\2%\1/;ta;s/^(.)(.*\n.*)/\2\1/;ta;s/\n//'
答案 5 :(得分:0)
根据您的示例,我猜测保护带引号的字符串就足够了,然后用双面字母替换句点。
perl -pe '1 while s%(\x27[^\x27]+)\.([^\x27]+\x27)%$1@@::@@$2%;
s/([a-z])\.([a-z])/$1%$2/g;
s/@@::@@/./g' file.f
我提供这种Perl解决方案并不是因为sed不是一个足够好的工具,而是因为它避免了sed方言之间的微小但令人讨厌的差异问题。能够为单引号使用十六进制代码是一个很好的奖励。