python.clangast解析:获取c++;字段声明的模板参数
我正在使用clang通过python接口提供的抽象语法树,试图解析包含std::vector的简单结构:python.clangast解析:获取c++;字段声明的模板参数,python,c++,templates,clang,abstract-syntax-tree,Python,C++,Templates,Clang,Abstract Syntax Tree,我正在使用clang通过python接口提供的抽象语法树,试图解析包含std::vector的简单结构: #include <vector> struct outer_t { std::vector<int> vec_of_ints; }; 这将产生以下结果: node.spelling = vec_of_ints , node.kind = CursorKind.FIELD_DECL node.spelling = std , nod
#include <vector>
struct outer_t
{
std::vector<int> vec_of_ints;
};
这将产生以下结果:
node.spelling = vec_of_ints , node.kind = CursorKind.FIELD_DECL
node.spelling = std , node.kind = CursorKind.NAMESPACE_REF
node.spelling = vector , node.kind = CursorKind.TEMPLATE_REF
node.get_num_template_arguments = -1
是否有其他方法获取模板参数或我做错了什么?光标类似乎没有关于其参数的任何信息,至少在本例中是这样;我不知道为什么。但是
FIELD\u DECL
有一个可以有模板参数的类型。下面是一个经过最小修改的代码版本,它为示例代码中的vec\u of_ints
字段打印模板参数的数量:
import sys
import clang.cindex
clang.cindex.Config.set_library_file("/usr/lib/llvm-6.0/lib/libclang.so.1")
class Walker:
def __init__(self, filename):
self.filename = filename
def walk(self, node):
node_in_file = bool(node.location.file and node.location.file.name == self.filename)
if node_in_file:
print(f"node.spelling = {node.spelling:14}, node.kind = {node.kind}")
# -------- BEGIN modified section --------
type = node.type
if type is not None:
ntargs = type.get_num_template_arguments()
if ntargs > 0:
print(f" type.spelling = {type.spelling}")
print(f" type.get_num_template_arguments = {ntargs}")
# -------- END modified section --------
for child in node.get_children():
self.walk(child)
filename = sys.argv[1]
index = clang.cindex.Index.create()
translation_unit = index.parse(filename)
root = translation_unit.cursor
walker = Walker(filename)
walker.walk(root)
在示例输入文件上运行时,我得到:
node.spelling = outer_t , node.kind = CursorKind.STRUCT_DECL
node.spelling = vec_of_ints , node.kind = CursorKind.FIELD_DECL
type.spelling = std::vector<int>
type.get_num_template_arguments = 1
node.spelling = std , node.kind = CursorKind.NAMESPACE_REF
node.spelling = vector , node.kind = CursorKind.TEMPLATE_REF
node.spelling=outer\u t,node.kind=CursorKind.STRUCT\u DECL
node.spelling=vec\u of\u int,node.kind=CursorKind.FIELD\u DECL
type.spelling=std::vector
type.get\u num\u模板\u参数=1
node.spelling=std,node.kind=CursorKind.NAMESPACE\u REF
node.spelling=vector,node.kind=CursorKind.TEMPLATE\u REF
我并不声称这将处理所有出现在代码中的模板的情况。我通过反复试验和阅读库模块源文件发现了上述内容。但它有望成为一个有用的起点
在任何情况下,关于ClangAST(以及几乎所有C/C++AST)需要了解的一件重要事情是类型不是主语法树中的节点。更确切地说,类型是对树中某些节点的语义解释,因此有点偏向一边。这就是为什么它们不会显示为walk
的参数
node.spelling = outer_t , node.kind = CursorKind.STRUCT_DECL
node.spelling = vec_of_ints , node.kind = CursorKind.FIELD_DECL
type.spelling = std::vector<int>
type.get_num_template_arguments = 1
node.spelling = std , node.kind = CursorKind.NAMESPACE_REF
node.spelling = vector , node.kind = CursorKind.TEMPLATE_REF