gpt4 book ai didi

regex - 用于匹配对 c 函数的多行调用的 perl 正则表达式

转载 作者:行者123 更新时间:2023-12-02 18:05:27 25 4
gpt4 key购买 nike

我正在寻找一个正则表达式来匹配对可变参数 c 函数的所有潜在多行调用。最终目标是打印文件、行号和每次调用的第四个参数,但不幸的是我还没有。到目前为止,我有这个:

 perl -ne 'print if s/^.*?(func1\s*\(([^\)\(,]+||,|\((?2)\))*\)).*?$/$1/s' test.c

与测试.c:

int main() {
func1( a, b, c, d);
func1( a, b,
c, d);
func1( func2(), b, c, d, e );
func1( func2(a), b, c, d, e );
return 1;
}

-- 与第二个调用不匹配。它不匹配的原因是表达式末尾的 s 允许 . 匹配换行符,但似乎不允许 [.. ] 构造以匹配换行符。我不确定如何克服这个问题。

我也不确定如何引用这里的第四个参数......我想我会因为正则表达式的递归性质而遇到一些问题。

最佳答案

这应该捕获你的功能,但要注意

perl -0777 -wnE'@f = /(func1\s*\( [^;]* \))\s*;/xg; s/\s+/ /g, say for @f' tt.c

我使用了语句必须由 ; 终止的事实。然后这排除了注释中的意外 ; 并且排除了对嵌套在另一个调用中的调用。如果这是可能的,那么需要做更多的工作来解析它。

但是,进一步解析捕获的调用(大概是用逗号)很复杂,因为嵌套调用很可能而且实际上包含逗号。怎么样

func1( a, b, f2(a2, b2), c, f3(a3, b3), d );

这变成了一个更有趣的小解析问题。或者,宏怎么样?

您能否阐明哪些事情是不需要考虑的?


由于提到的注意事项可能会被忽略,这里有一种解析参数列表的方法,使用 Text::Balanced .

由于我们需要提取作为参数出现的整个函数调用,例如 f(a, b),因此库中最合适的函数是 extract_tagged。有了它,我们可以使开始标记成为单词左括号 (\w+\(),结束标记成为右括号 \)

此函数仅提取第一次出现,因此它被包装在 extract_multiple

use warnings;
use strict;
use feature 'say';

use Text::Balanced qw(extract_multiple extract_tagged);
use Path::Tiny; # path(). for slurp

my $file = shift // die "Usage: $0 file-to-parse\n";

my @functions = path($file)->slurp =~ /( func1\( [^;]* \) );/xg;
s/\s+/ /g for @functions;

for my $func (@functions) {
my ($args) = $func =~ /func1\s*\(\s* (.*) \s*\)/x;
say $args;

my @parts = extract_multiple( $args, [ sub {
extract_tagged($args, '\\w+\\(', '\\\)', '.*?(?=\w+\()')
} ] );

my @arguments = grep { /\S/ } map { /\(/ ? $_ : split /\s*,\s*/ } @parts;
s/^\s*|\s*\z//g for @arguments;
say "\t$_" for @arguments;
}

extract_multiple 仅返回带有(嵌套)函数调用的部分(可通过括号来识别),它们是原样的参数,也是我们用所有这些寻找的内容,部分是带逗号的字符串- 其他参数的分隔组,被分成单独的参数。

注意 extract_tagged 中的转义量(通过反复试验发现)!这是必需的,因为这些字符串在 string-eval 中被两次用双引号引起来。这根本没有记录,所以请参阅 the source (例如 here )。

或者直接生成急需转义的字符(\x5C for \),这样就不需要转义了

extract_tagged($_[0], "\x5C".'w+'."\x5C(", '\x5C)', '.*?(?=\w+\()')

我不知道我会称之为“更清晰”

我测试了问题中提供的文件,并在其中添加了一个函数

func1( a, b, f2(a2, f3(a3, b3), b2), c, f4(a4, b4), d, e );

对于每个函数,程序打印带有要解析的参数列表的字符串和已解析的参数,输出中最有趣的部分是上述(添加的)函数

[ ... ]a, b, f2(a2, f3(a3, b3), b2), c, f4(a4, b4), d, e         a        b        f2(a2, f3(a3, b3), b2)        c        f4(a4, b4)        d        e

关于regex - 用于匹配对 c 函数的多行调用的 perl 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73376526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com