2010-11-11 16 views
1

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

我想创建一个程序,这需要headerfile(与包括命名空间,类等)作为输入,并与类名找到返回列表,方法,属性等

它很难谷歌的类似那我最终会得到关于如何在C++中使用Regexes的教程。也许我只是用错误的术语搜索? 也许有人已经找到/使用/创建了这样的Regexes。

+4

即使C++的解析器也很困难,并且您想要使用正则表达式吗? :p(无论如何,请尝试'gccxml'。) – kennytm 2010-11-11 18:21:54

+0

你真的想要创建程序,还是只是在寻找结果? ctags足够了吗? – Cascabel 2010-11-11 18:24:58

+0

0x(及更早版本)草案以类似于正则表达式的语言定义语法。如果这就是你[真正需要的](http://tinyurl.com/meta-xy),并且熟悉正则表达式,它不会很难转换;然而,我不认为这是你最终想要做的。 – 2010-11-11 18:42:07

回答

5

您可能会发现代码ctags方便。它将解析代码并分解用于emacs和其他程序的符号。事实上,它可能只是做你想做的所有工作。

+0

CTags似乎正是我正在寻找...我不用编写我自己的程序来寻找元素,我只能使用CTags ... – MOnsDaR 2010-11-11 19:28:06

7

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

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

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

但是它会不正确地匹配以下为一类

  • 正向声明
  • 任何字符串文本中包含“类Foo”
  • 模板参数文本
  • 等...
0

如前所述,您可能还会在ctags或cscope中发现一些有趣的内容。我也遇到过flisthere

0

我正在写一个Python程序,从一个大杂乱的C++源代码树中提取一些基本的类信息。我使用正则表达式的运气非常好。幸运的是,几乎所有的代码都遵循一种风格,我可以通过定义几个正则表达式来检测类声明,方法等。大多数成员变量的名称都是“itsSomething_”或“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 

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