2010-11-11 74 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 

我希望這很容易理解並翻譯成其他語言,至少對於任何瘋狂嘗試的人來說都是一個起點。使用風險自負。