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

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

  •  1
  • MOnsDaR  · 技术社区  · 15 年前

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

    我想创建一个程序,它以headerfile(包含、名称空间、类等)作为输入,并返回包含找到的类名、方法、属性等的列表。

    对于这样的事情,谷歌很难,我总是在教程中介绍如何在C++中使用正则表达式。也许我只是在搜索错误的术语? 也许已经有人找到/使用/创建了这样的regex。

    4 回复  |  直到 15 年前
        1
  •  5
  •   boatcoder    15 年前

    你可能会找到 ctags 方便。它将解析代码并分解出符号,以便在emacs和其他程序中使用。事实上,它可能只会做你想做的所有工作。

        2
  •  7
  •   JaredPar    15 年前

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

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

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

    但是它将不正确地将以下内容作为类进行匹配

    • 向前声明
    • 任何字符串文本,如“类foo”
    • 模板参数
    • 等。。。
        3
  •  0
  •   udslk    15 年前

    你也可以在ctag或cscope中发现一些有趣的东西。我也遇到过 flist here

        4
  •  0
  •   DarenW    15 年前

    我正在编写一个Python程序,从一个大杂乱的C++源树中提取一些重要的类信息。我在使用regex方面运气很好。幸运的是,几乎所有的代码都遵循这样一种风格:我只需定义几个正则表达式就可以检测类声明、方法等。大多数成员变量都有“itssange”或“m_something”这样的名称。我在硬编码的黑客工作中游手好闲,捕捉任何不符合风格的东西。

    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
    

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