Вопрос по python, c++, api, parsing – Как я могу анализировать макросы в коде C ++, используя CLANG в качестве синтаксического анализатора и Python в качестве языка сценариев?

12

Если у меня есть следующий макрос в коде C ++:

<code>_Foo(arg1, arg2)
</code>

Я хотел бы использовать Python, чтобы найти все экземпляры и экстенты этого макроса, используя Clang и привязки Python, предоставляемые cindex.py. Я не хочу использовать регулярное выражение из Python непосредственно в коде, потому что это дает мне 99% пути, но не 100%. Мне кажется, что для достижения 100% вам нужно использовать настоящий синтаксический анализатор C ++, такой как Clang, для обработки всех случаев, когда люди делают глупые вещи, которые синтаксически корректны и компилируются, но не имеют смысла для регулярных выражений. Мне нужно обработать 100% случаев, и, поскольку мы используем Clang в качестве одного из наших компиляторов, имеет смысл использовать его также в качестве анализатора для этой задачи.

Учитывая следующий код Python, я могу найти предопределенные типы, о которых знают привязки Python Clang, но не макросы:

<code>def find_typerefs(node):
    ref_node = clang.cindex.Cursor_ref(node)
    if ref_node:
        print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (
            ref_node.spelling, ref_node.kind, node.data, node.extent, node.location.line, node.location.column)

# Recurse for children of this node
for c in node.get_children():
    find_typerefs(c)

index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
find_typerefs(tu.cursor)
</code>

Я думаю, что я ищу способ проанализировать необработанный AST для имени моего макроса_FOO(), но я не уверен. Может ли кто-нибудь предоставить какой-нибудь код, который позволит мне передать имя макроса и получить экстент или данные от Clang?

Я думаю, что Clang (как здравомыслящий компилятор) имеет команду простоpreprocess исходный код ... Griwes
s/CLANG/Clang/g Seth Carnegie
@uesp Ну, Clang - это не просто компилятор. Этоgreat компилятор, который старается предоставитьgreat диагностика. Вот почему макросыare отслеживать в Clang (проверьтеclass list для случаев «макро» в некоторой степени. Я был бы очень удивлен, если бы он улавливал даже самые грязные синтаксические макросы, но я думаю, что это очень возможно для функционально-подобных макросов, таких как OP. user395760
Я не использовал Clang, но не думаю, что вы найдете свой макрос в AST. Если вы посмотрите на стадии компиляции C ++ (stackoverflow.com/questions/8833524/…) макросы «исчезают» в части предварительной обработки, которая завершается до компиляции, и генерируется AST. На данный момент ваш макрос не существует, так как он полностью заменен содержимым макроса. Я бы посмотрел на часть Clang для предварительной обработки и посмотрел, что из этого можно получить. uesp

Ваш Ответ

2   ответа
0

который вы получаете из libclang, чтобы узнать, где найти какую информацию.

Вот:https://gist.github.com/2503232

9

options флаг дляIndex.parse:

tu = index.parse(sys.argv[1], options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)

Остальная часть посетителя курсора может выглядеть так:

def visit(node):
    if node.kind in (clang.cindex.CursorKind.MACRO_INSTANTIATION, clang.cindex.CursorKind.MACRO_DEFINITION):
        print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (node.displayname, node.kind, node.data, node.extent, node.location.line, node.location.column)
    for c in node.get_children():
        visit(c)

Похожие вопросы