在 C 源代码中插入缺失的逗号
Insert missing commas in C source
我有一个 perl 脚本(使用 -p
标志)可以对损坏的 C 源文件执行一些更正。这是脚本的一部分:
sub remove_sp {
$_ = shift;
s/ /, /g;
return $_;
}
s/(\([^}]*\))/remove_sp()/eg;
这会将括号内的 spaces 替换为 ,
,例如foo(bar baz)
变为 foo(bar, baz)
。但是,它不是很聪明。它还将 foo("bar baz")
更改为 foo("bar, baz")
,这显然不是我想要的。
我想不出一种方法来重写脚本,以便它仅在 space 不在引号之间时才用逗号 space 替换 space。我该怎么做?
这是一个简单的 table 我需要什么和什么不起作用。
Search | Replace | Currently handled correctly?
--------------------------------------------------------------------------------------------
foo(bar baz) | foo(bar, baz) | Yes
foo("bar baz") | foo("bar baz") | No
foo("bar baz" bak) | foo("bar baz", bak) | No
foo("bar baz" bak "123 abc") | foo("bar baz", bak, "123 abc") | No
您可以使用 Text::ParseWords 获取括号之间的数据并对解析结果进行替换。
#!/usr/bin/perl
use strict;
use warnings;
use Text::ParseWords;
for ('foo("bar baz")', 'print("foo bar" baz)', 'foo(bar baz)') {
my $s = $_;
$s =~ s/(\([^)]*\))/remove_sp()/eg;
print $s, $/;
}
sub remove_sp {
join ", ", quotewords('\s+', 1, shift);
}
输出:
foo("bar baz")
print("foo bar", baz)
foo(bar, baz)
我不认为这是可能的。我可以想到一些无法确定是否需要逗号的语法边缘情况:
字符串粘贴
foo("abc" "def"); // = foo("abcdef")
foo("foo", "bar");
将两个字符串常量并排放置会使它们 "pasted" 在一起。如果不知道一个函数需要多少参数,就无法判断这是否是预期的行为。
逗号表达式,例如在 for
循环中
The comma is an operator in C;它计算两个表达式和 returns RHS 上那个表达式的值。结合 +
、-
、&
和 *
运算符的 unary/binary 双重性质,这意味着像这样简单的表达式:
a + b or a * b
可以插入一个逗号:
a, +b or a, *b
虽然这是一个人为的例子,但可能会出现更复杂的情况,例如在复杂的 for
循环中。
函数参数
同理:
foo(a * b - 1);
foo(a * b, -1);
foo(a, *b - 1);
foo(a, *b, -1);
(etc)
在不知道函数预期的参数数量的情况下,无法判断是否应插入逗号。有时甚至还不够!
我有一个 perl 脚本(使用 -p
标志)可以对损坏的 C 源文件执行一些更正。这是脚本的一部分:
sub remove_sp {
$_ = shift;
s/ /, /g;
return $_;
}
s/(\([^}]*\))/remove_sp()/eg;
这会将括号内的 spaces 替换为 ,
,例如foo(bar baz)
变为 foo(bar, baz)
。但是,它不是很聪明。它还将 foo("bar baz")
更改为 foo("bar, baz")
,这显然不是我想要的。
我想不出一种方法来重写脚本,以便它仅在 space 不在引号之间时才用逗号 space 替换 space。我该怎么做?
这是一个简单的 table 我需要什么和什么不起作用。
Search | Replace | Currently handled correctly?
--------------------------------------------------------------------------------------------
foo(bar baz) | foo(bar, baz) | Yes
foo("bar baz") | foo("bar baz") | No
foo("bar baz" bak) | foo("bar baz", bak) | No
foo("bar baz" bak "123 abc") | foo("bar baz", bak, "123 abc") | No
您可以使用 Text::ParseWords 获取括号之间的数据并对解析结果进行替换。
#!/usr/bin/perl
use strict;
use warnings;
use Text::ParseWords;
for ('foo("bar baz")', 'print("foo bar" baz)', 'foo(bar baz)') {
my $s = $_;
$s =~ s/(\([^)]*\))/remove_sp()/eg;
print $s, $/;
}
sub remove_sp {
join ", ", quotewords('\s+', 1, shift);
}
输出:
foo("bar baz")
print("foo bar", baz)
foo(bar, baz)
我不认为这是可能的。我可以想到一些无法确定是否需要逗号的语法边缘情况:
字符串粘贴
foo("abc" "def"); // = foo("abcdef")
foo("foo", "bar");
将两个字符串常量并排放置会使它们 "pasted" 在一起。如果不知道一个函数需要多少参数,就无法判断这是否是预期的行为。
逗号表达式,例如在 for
循环中
The comma is an operator in C;它计算两个表达式和 returns RHS 上那个表达式的值。结合 +
、-
、&
和 *
运算符的 unary/binary 双重性质,这意味着像这样简单的表达式:
a + b or a * b
可以插入一个逗号:
a, +b or a, *b
虽然这是一个人为的例子,但可能会出现更复杂的情况,例如在复杂的 for
循环中。
函数参数
同理:
foo(a * b - 1);
foo(a * b, -1);
foo(a, *b - 1);
foo(a, *b, -1);
(etc)
在不知道函数预期的参数数量的情况下,无法判断是否应插入逗号。有时甚至还不够!