正则表达式找到C ++元素?

时间:2010-11-11 18:18:39

标签: c++ regex grammar

我正在为ANSI C ++的元素寻找一些预定义的正则表达式。

我想创建一个程序,它接受一个头文件(带有包含,命名空间,类等)作为输入,并返回包含找到的类名,方法,属性等的列表。

很难谷歌这样的东西,我总是最后得到如何在C ++中使用正则表达式的教程。也许我只是在谷歌搜索错误的条款? 也许有人已经找到/使用/创建了这样的Regexes。

4 个答案:

答案 0 :(得分:7)

这种类型的操作不能与正则表达式一起使用。 C ++不是常规语言,因此无法使用正则表达式进行可靠的解析。这里最安全的方法是在这里使用实际的解析器来定位C ++元素。

如果100%正确性不是目标,那么正则表达式将起作用,因为它可以精心设计以捕获代码库中的大多数情况。最简单的例子是以下

class\s+[a-z]\w+

然而,它将错误地将以下内容与类

匹配
  • 转发声明
  • 任何字符串文字,文字如“class foo”
  • 模板参数
  • 等...

答案 1 :(得分:5)

您可能会找到ctags的代码。它将解析代码并打破用于emacs和其他程序的符号。事实上,它可能只是做你想要做的所有工作。

答案 2 :(得分:0)

如上所述,你也可以在ctags或cscope中找到有趣的东西。我也遇到了flist here

答案 3 :(得分:0)

我正在编写一个Python程序,用于从大型凌乱的C ++源代码树中提取一些必要的类信息。使用正则表达式我有好运。幸运的是,几乎所有代码都遵循一种风格,让我可以通过定义几个正则表达式来检测类声明,方法等。大多数成员变量的名称都是“itsSomething_”或“m_something”。我用硬编码的hackwork来抓住任何不符合风格的东西。

class_decl_re   = re.compile(  r"^class +(\w+)\s*(:|\{)"  )
close_decl_re   = re.compile(  r"^\};"  )
method_decl_re  = re.compile(  r"(\w[ a-zA-Z_0-9\*\<\>]+) +(\w+)\("    ) 
var_decl1_re    = re.compile(  r"(\w[ a-zA-Z_0-9\*\<\>]+) +(its\w+);"  )
var_decl2_re    = re.compile(  r"(\w[ a-zA-Z_0-9\*\<\>]+) +(m_\w+);"  )
comment_pair_re = re.compile(  r"/\*.*\*/" )

这是一项正在进行中的工作,但我会展示这个(可能是错误的)(不,几乎肯定是错误的)代码片段以显示如何使用正则表达式:

# at this point, we're looking at one line from a .hpp file
# from inside a class declaration.  All initial whitespace has been 
# stripped.  All // and /*...*/ comments have been removed.
    is_static = (line[0:6]=="static")
    if is_static:
        line=line[6:]

    is_virtual = (line[0:7]=="virtual")
    if is_virtual:
        line=line[7:]

    # I believe "virtual static" is impossible, but if our goal
    # is to detect such coding gaffes, this code can't do it.

    mm = method_decl_re.match(line)
    vm1 = var_decl1_re.match(line)
    vm2 = var_decl2_re.match(line)
    if mm:
        meth_name = mm.group(2)
        minfo = MethodInfo(meth_name, classinfo.name)  # class to hold info about a method
        minfo.rettype = mm.group(1)              # return type
        minfo.is_static = is_static
        if is_static:
            if is_virtual:
                classinfo.screwed_up=True
            classinfo.class_methods[meth_name] = minfo
        else:
            minfo.is_polymorphic = is_virtual    
            classinfo.obj_methods[meth_name] = minfo

    elif vm1 or vm2:
        if vm1: # deal with vars named "itsXxxxx..."
            vm=vm1   
            var_name = vm.group(2)[3:]
            if var_name.endswith("_"):
                var_name=var_name[:-1]
        else:  # deal with vars named "m_Xxxxx..."
            vm=vm2   
            var_name = vm.group(2)[2:]  # remove the m_
        datatype = vm.group(1)
        vi = VarInfo(var_name, datatype)
        vi.is_static = is_static 
        classinfo.vars[var_name] = vi

我希望这很容易理解并翻译成其他语言,至少对于任何疯狂到试试的人来说都是一个起点。使用风险自负。