Я пишу программу 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 надеюсь, что это легко понять и перевести на другие языки, по крайней мере, для отправной точки для любого сумасшедшего достаточно, чтобы попробовать. Используйте на свой риск.
Даже синтаксический анализатор для C++ затруднен, и вы хотите использовать регулярное выражение? : p (Во всяком случае, попробуйте 'gccxml'.) – kennytm
Вы действительно хотите создать программу или просто ищете результаты? Достаточно ли ctags? – Cascabel
Шаблоны 0x (и более ранние) определяют грамматику в языке, подобном регулярному выражению. Если это то, что вам [действительно нужно] (http://tinyurl.com/meta-xy) и знакомо с регулярным выражением, было бы непросто преобразовать; однако я не думаю, что это то, что вы в конечном итоге пытаетесь сделать. – 2010-11-11 18:42:07