#python-3.x #clang #abstract-syntax-tree
#python-3.x #clang #абстрактное синтаксическое дерево
Вопрос:
Я работаю над использованием clang bingings python для преобразования кода c / c в AST, как я могу получить структуру AST на основе дерева? Несколько советов о том, с чего начать, учебные пособия или что-либо еще в этом отношении окажут большую помощь!!!
Я нашел очень полезную работу (если вы хотите это проверить, вот ссылка:https://www.chess.com/blog/lockijazz/using-python-to-traverse-and-modify-clang-s-ast-tree ) и попробовал его код, к сожалению, я не получил полезного результата.
function_calls = []
function_declarations = []
def traverse(node):
for child in node.get_children():
traverse(child)
if node.type == clang.cindex.CursorKind.CALL_EXPR:
function_calls.append(node)
if node.type == clang.cindex.CursorKind.FUNCTION_DECL:
function_declarations.append(node)
print 'Found %s [line=%s, col=%s]' % (node.displayname, node.location.line, node.location.column)
clang.cindex.Config.set_library_path("/Users/tomgong/Desktop/build/lib")
index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
root = tu.cursor
traverse(root)
Ответ №1:
На всякий случай, если у кого-то все еще возникли проблемы, я обнаружил, что если вы должны использовать kind
вместо type
вы можете запустить clang.cindex.CursorKind.get_all_kinds()
для извлечения всех видов и увидеть, что при использовании node.type
ни в одном из них не отображается.
function_calls = []
function_declarations = []
def traverse(node):
for child in node.get_children():
traverse(child)
if node.kind == clang.cindex.CursorKind.CALL_EXPR:
function_calls.append(node)
if node.kind == clang.cindex.CursorKind.FUNCTION_DECL:
function_declarations.append(node)
print 'Found %s [line=%s, col=%s]' % (node.displayname, node.location.line, node.location.column)
clang.cindex.Config.set_library_path("/Users/tomgong/Desktop/build/lib")
index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
root = tu.cursor
traverse(root)
Ответ №2:
как я могу получить структуру AST на основе дерева?
Курсор объекта translation unit ( tu.cursor
) на самом деле является начальным узлом AST. Возможно, вы захотите использовать clang
инструмент для визуального анализа дерева. Возможно, это прольет свет и даст вам представление о том, как работать с деревом.
clang -cc1 -ast-dump test.cpp
Но в основном, это сводится к получению дочерних узлов основного узла ( tu.cursor
) и рекурсивному обходу их и получению узлов, которые представляют для вас интерес.
Возможно, вы также захотите ознакомиться со статьей Эли Бендерски о том, как начать работать с привязкой python: https://eli.thegreenplace.net/2011/07/03/parsing-c-in-python-with-clang#id9
к сожалению, я не получил полезного результата.
Вы можете столкнуться с неполным или неправильным синтаксическим анализом, когда вы не предоставляете пути к включениям в анализируемом файле модулю libclang. Например, если исходный файл, который вы хотите проанализировать, использует некоторые из включений QT, тогда вам нужно указать соответствующие пути включения в parse()
вызове, как в приведенном здесь примере:
index = clang.cindex.Index.create()
tu = index.parse(src_file, args = [
'-I/usr/include/x86_64-linux-gnu/qt5/',
'-I/usr/include/x86_64-linux-gnu/qt5/QtCore'])
Также поищите некоторые комментарии в модуле python libclang.cindex, они могут вам помочь. Например, я нашел решение выше, прочитав эти комментарии.