代码之家  ›  专栏  ›  技术社区  ›  ssube

ReGEX解析C/C++函数声明

  •  3
  • ssube  · 技术社区  · 14 年前

    我从标题或列表中选择签名:

    public:void\uu thiscall myClass::method(int,class myOtherClass*)

    我有以下正则表达式,适用于大多数函数:

    (?<expo>public\:|protected\:|private\:) (?<ret>(const )*(void|int|unsigned int|long|unsigned long|float|double|(class .*)|(enum .*))) (?<decl>__thiscall|__cdecl|__stdcall|__fastcall|__clrcall) (?<ns>.*)\:\:(?<class>(.*)((<.*>)*))\:\:(?<method>(.*)((<.*>)*))\((?<params>((.*(<.*>)?)(,)?)*)\)
    

    有一些函数它不喜欢解析,但似乎与模式匹配。我并不担心匹配目前不是类成员的函数(以后可以处理)。表达式用于C#程序,因此 <label> 用于轻松检索组。

    我想知道是否有一个标准的正则表达式来解析所有函数,或者如何改进我的正则表达式来处理奇怪的异常?

    3 回复  |  直到 14 年前
        1
  •  4
  •   Thomas    14 年前

    众所周知,C++是很难解析的;编写一个能够捕获所有案例的正则表达式是不可能的。例如,可以有无限数量的嵌套圆括号,这表明即使是C++语言的这一子集也不是规则的。

        2
  •  2
  •   jbernadas    14 年前

    看一看 Boost.Spirit 它是一个增强库,允许使用C++代码和没有预处理器实现递归下降分析器。您必须指定一个 BNF Grammar ,然后传递一个字符串供其解析。您甚至可以生成一个抽象语法树(abstractsyntax Tree,AST),这对于处理解析的数据非常有用。

    BNF规范看起来像是一个整数或单词的列表,分开后可能看起来像:

    using spirit::alpha_p;
    using spirit::digit_p;
    using spirit::anychar_p;
    using spirit::end_p;
    using spirit::space_p;
    
    // Inside the definition...
    integer    = +digit_p;                      // One or more digits.
    word       = +alpha_p;                      // One or more letters.
    token      = integer | word;                // An integer or a word.
    token_list = token >> *(+space_p >> token)  // A token, followed by 0 or more tokens.
    

    有关更多信息,请参阅文档,该库在开始时有点复杂,但随后它变得更易于使用(而且功能更强大)。

        3
  •  0
  •   Oliver Charlesworth    14 年前

    不可以。即使是函数原型也可以有任意级别的嵌套,因此不能用单个正则表达式来表示。

    如果你真的把自己限制在非常接近你的例子的事情上(正好是2个参数,等等),那么你能提供一个不匹配的例子吗?