代码之家  ›  专栏  ›  技术社区  ›  Dan McClain

使用C#和正则表达式解析源代码并查找带参数的函数调用

  •  2
  • Dan McClain  · 技术社区  · 17 年前

    我在数据库中存储了一个函数调用列表,对于某些函数调用,我关心函数调用的参数是什么。我正在用我的程序(C#)解析C源代码。我试图找到获得带参数的函数调用的最佳方法。在解析源代码之前,我将其读入字符串中(这样我就不会在文件上使用流读取器)。我尝试使用一些正则表达式(对我来说有点新)来解析源文件,但在使用这样的正则表达式字符串时,检索的不仅仅是函数调用:functionCall+“.*\\)”;(我正在逃离(函数调用中的)开头

    函数调用以以下格式存储在数据库中

    Function Call
    ============
    some_Call(
    

    如果需要澄清,请告诉我。

    3 回复  |  直到 11 年前
        1
  •  6
  •   Daniel LeCheminant    17 年前

    您的解决方案失败的部分原因是您可能应该使用 .*?)

    完整的答案至少应该遵循以下几点:

    忽略字符串和字符中的括号(这可以用正则表达式来实现,尽管转义可能有点复杂)

    functionCall("\")", ')')
    

    functionCall(/*)*/ 1, // )
    2)
    

    不要匹配太多(可以使用正则表达式)

    functionCall(1) + functionCall(2) + (2 * 3) // Don't match past the first )
    

    但它也必须忽略平衡括号

    functionCall((1+(1))*(2+2))
    

    最后一个是普通正则表达式无法做到的,因为它涉及括号计数,而正则表达式通常不适合这样做。然而,似乎 .NET has ways to do this .

    (从技术上讲,你必须处理宏,我可以想象

    #define close_paren )
    

    会毁了你的一天。..)

    也就是说,你可能会想出一个幼稚的解决方案(类似于你的解决方案,或者其他一些海报推荐的解决方案),它适用于许多情况,特别是如果你使用已知的输入。

        2
  •  1
  •   REA_ANDREW    17 年前

    我编写了一个快速正则表达式并对其进行了测试,请检查以下内容:

                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();
    

    因此,上述字符串的输出将是:

    参数1=类型<无论什么>tesxt_112

    参数2=类型<无论什么>tesxt_113

    安德鲁:-)

        3
  •  0
  •   chakrit Dutchie432    17 年前

    不是为了让你变坏,但是。..在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
    

    使用预定义类型列表?如果转换为自定义结构,那么typedef呢?现在你也必须解析这些!

    说真的,使用解析器!!有 several available options 已经可以解析C了。

    我认为Regex对于这项工作来说是一个相当糟糕的工具。