使用C#和regex解析源代码并查找带有参数的函数调用
我有一个存储在数据库中的函数调用列表,对于一些函数调用,我关心函数调用的参数是什么。我正在用我的程序(在C#)解析C源代码。我正试图找到获得带有参数的函数调用的最佳方法。在解析源代码之前,我将其读入字符串(这样我就不会在文件上使用流读取器)。我尝试使用一些正则表达式(对我来说有些陌生)来解析源文件,但在使用类似这样的正则表达式字符串时,检索的不仅仅是函数调用:functionCall+“*\”;(我正在逃离开口(在函数调用中) 函数调用以以下格式存储在数据库中使用C#和regex解析源代码并查找带有参数的函数调用,c#,regex,parsing,C#,Regex,Parsing,我有一个存储在数据库中的函数调用列表,对于一些函数调用,我关心函数调用的参数是什么。我正在用我的程序(在C#)解析C源代码。我正试图找到获得带有参数的函数调用的最佳方法。在解析源代码之前,我将其读入字符串(这样我就不会在文件上使用流读取器)。我尝试使用一些正则表达式(对我来说有些陌生)来解析源文件,但在使用类似这样的正则表达式字符串时,检索的不仅仅是函数调用:functionCall+“*\”;(我正在逃离开口(在函数调用中) 函数调用以以下格式存储在数据库中 Function Call ===
Function Call
============
some_Call(
它们以这种方式存储是有原因的,并且不会更改
有没有一种通过正则表达式来实现这一点的好方法,或者我更适合遍历源代码内容
如果需要任何澄清,请告诉我。我已经编写了一个快速正则表达式并对其进行了测试,请检查以下内容:
string tst = "some_function(type<whatever> tesxt_112,type<whatever> tesxt_113){";
Regex r = new Regex(".*\\((.*)\\)");
Match m = r.Match(tst);
if (m.Success)
{
string[] arguments = m.Groups[1].Value.Split(',');
for (int i = 0; i < arguments.Length; i++)
{
Console.WriteLine("Argument " + (i + 1) + " = " + arguments[i]);
}
}
Console.ReadKey();
string tst=“某些函数(类型tesxt_112,类型tesxt_113){”;
正则表达式r=新正则表达式(“.\\(.\\)”);
匹配m=r.匹配(tst);
如果(m.成功)
{
string[]arguments=m.Groups[1]。Value.Split(',');
for(int i=0;i
因此,上述字符串的输出为:
参数1=类型TEXT_112
参数2=类型tesxt_113
希望这有助于:
安德鲁:-)不是为了让你堕落,而是……在C中,我(隐约地)相信你可以做到这一点:
void secondFunction() { /* no-op */ }
void firstFunction()
{
void* xyz = secondFunction;
xyz(); // this should call secondFunction
}
这是一种可能的情况吗?那么指针用法的其他变体呢
说,类型铸造功能风格
int a;
float b = float(a); // call to the "float" function?!? NO! it's a type casting
使用预定义类型的列表?如果转换为自定义结构会怎样?typedefs会怎样?现在您也必须解析它们
说真的,使用解析器!!已经有可以解析C的了
我认为正则表达式对于这项工作来说是一个相当糟糕的工具。解决方案失败的部分原因是您可能应该使用
*?)
,而不是贪婪匹配
完整的答案必须至少遵循以下几点:
忽略字符串和字符中的括号(这可以通过正则表达式实现,不过转义可能有点复杂)
忽略注释中的括号(可以使用正则表达式执行此操作)
不要匹配太多(这可以通过正则表达式实现)
但它也必须忽略平衡括号
functionCall((1+(1))*(2+2))
最后一个是普通正则表达式所不能做的,因为它涉及到计算括号,并且通常是正则表达式不适合的
(从技术上讲,你必须处理宏,我可以想象
#define close_paren )
会毁了你的一天……)
也就是说,你可能会想出一个幼稚的解决方案(类似于你所拥有的,或者其他海报所推荐的)它适用于许多情况,特别是当您使用已知输入时。虽然不适合使用它,.Net正则表达式支持匹配组,这应该得到支持。我通过删除注释、回车和我分类为预处理器指令的内容(任何以#开头的内容)来清理源代码字符串。此外,我几乎可以肯定(至少现在)没有人在我们使用的函数调用中使用嵌套参数。此外,我需要检索参数的调用量只是函数调用的一个很小的子集,所以我不应该遇到任何奇怪的语法,希望如此,谢谢!我真正需要的是您的“tst”从源代码本身获取字符串,但一旦我得到它,这将非常有用:-)您从DB中获取此值有困难吗?我使用Daniel L的解决方案来查找函数行,并使用您的解决方案来获取参数
functionCall(1) + functionCall(2) + (2 * 3) // Don't match past the first )
functionCall((1+(1))*(2+2))
#define close_paren )