我正在努力拼凑一个正则表达式以匹配函数调用,如下所示:
funcname (...(..
...)..(..(...
)...)..)
因此该函数可以在多行上分布多个括号参数。
点可以是来自'('或')'的任何其他东西。
我会使用sed或grep的正则表达式。
谢谢, 瑞斯托
答案 0 :(得分:0)
由于C是irregular language,您可能需要parser。当所有打开的括号再次关闭时,您将遇到的问题是解决问题。你可以用C做一些相当奇怪的事情。例如,你可以有一个参数,它本身就是一个函数定义。例如,在下面的程序中考虑如何区分a(),b(),c(),d(),e(),f()和g()?
#include <stdio.h>
#define f(c) c;
char a()
{
return f('z');
}
/*
A function in a comment.
char b()
{
return 'y';
}
*/
char c(char d())
{
return d();
}
#if 0
This code is not included
char g()
{
return 'v';
}
#endif
void main()
{
printf ("A function in a string: char e() { return 'x'; }\n");
printf ("The result from passing a to c: %c\n", c(a));
printf ("Press enter to exit");
getchar();
}
我已经看到许多尝试使用正则表达式执行此类操作,但大多数尝试最终会出现Catastrophic Backtracking个问题。
答案 1 :(得分:0)
所以,我继续用bash编写这个简单的解析器。它并不完美,但可以作为一个起点。例如,它无法区分函数调用是否被注释掉等等。
while read file; do
linenum=0
while IFS= read -r line; do
(( linenum++ ))
if [ $fmatch -eq 0 ]; then
if [[ ! $line =~ $funcname ]]; then
continue
fi
linenummatch=$linenum
fmatch=1
fstripped=0
openbracket=0
closebracket=0
spacenum=0
fi
linelen=${#line}
position=0
while [ $position -lt $linelen ]; do
if [ $fstripped -eq 0 ]; then
subline=${line:$position}
mlen=`expr "$subline" : "$funcname"`
if [ $mlen -gt 0 ]; then
(( position+=mlen ))
resultstr=$funcname
fstripped=1
continue
fi
(( position++ ))
continue
fi
ch=${line:$position:1}
case $ch in
'(' )
(( openbracket++ ))
spacenum=0
newresultstr="$resultstr$ch"
;;
')' )
if [ $openbracket -eq 0 ]; then
fmatch=0
break
fi
(( closebracket++ ))
spacenum=0
newresultstr="$resultstr$ch"
if [ $closebracket -eq $openbracket ]; then
echo "$file $linenummatch $newresultstr"
fmatch=0
break
fi
;;
' ' | '\t' )
if [ $spacenum -eq 0 ]; then
newresultstr=$resultstr' '
fi
(( spacenum++ ))
;;
'\n' )
# line feeds are skipped
;;
* )
if [ $openbracket -eq 0 ]; then
fmatch=0
break
fi
spacenum=0
newresultstr="$resultstr$ch"
;;
esac
resultstr=$newresultstr
(( position++ ))
done
done < $file
done < $filelist