2010-11-11 5 views
1

Я ищу некоторые предопределенные регулярные выражения для элементов ANSI C++.Регулярные выражения для поиска элементов C++?

Я хотел бы создать программу, которая принимает headerfile (с включает в себя, пространства имен, классы и т.д.) в качестве входных данных и возвращает список с найденными названий класса, методы, атрибуты и т.д.

Его трудно Google что-то вроде что я всегда получаю учебники о том, как использовать регулярные выражения в C++. Возможно, я просто искал неправильные условия? Возможно, кто-то уже нашел/использовал/создал такие Regexes.

+4

Даже синтаксический анализатор для C++ затруднен, и вы хотите использовать регулярное выражение? : p (Во всяком случае, попробуйте 'gccxml'.) – kennytm

+0

Вы действительно хотите создать программу или просто ищете результаты? Достаточно ли ctags? – Cascabel

+0

Шаблоны 0x (и более ранние) определяют грамматику в языке, подобном регулярному выражению. Если это то, что вам [действительно нужно] (http://tinyurl.com/meta-xy) и знакомо с регулярным выражением, было бы непросто преобразовать; однако я не думаю, что это то, что вы в конечном итоге пытаетесь сделать. – 2010-11-11 18:42:07

ответ

5

Возможно, вы найдете код для ctags. Он будет анализировать код и вырывать символы для использования в emacs и других программах. Фактически, это может просто сделать всю работу, которую вы пытаетесь сделать сами.

+0

Сетаг, кажется, именно то, что я искал ...Вместо написания моей собственной программы, которая ищет элементы, я просто могу использовать CTags ... – MOnsDaR

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 

I надеюсь, что это легко понять и перевести на другие языки, по крайней мере, для отправной точки для любого сумасшедшего достаточно, чтобы попробовать. Используйте на свой риск.

Смежные вопросы