libclang只定义了5种类型的令牌:
是否有可能获得有关令牌的更详细信息?例如,对于以下源代码:
struct Type;
void foo(Type param);
我希望输出如下:
我还需要将这些实体映射到文件位置。
答案 0 :(得分:7)
首先,您可能需要一些关于解析如何工作的背景知识。关于编译器的教科书将是一种有用的资源。首先,将文件转换为一系列令牌;它为您提供标识符,标点符号等。执行此操作的代码称为词法分析器。然后,解析器运行;这会将令牌列表转换为AST(结构化声明/表达式等)。
clang会跟踪声明和表达式的各个部分,但不会按照您描述的方式进行跟踪。对于给定的函数声明,它会跟踪诸如函数名称的位置和参数列表的开头之类的内容,但它会根据文件中的位置保留这些内容,而不是标记。
CXToken
只是一个标记;除了您列出的五种类型之外,没有任何其他关联的语义信息。 (您可以使用clang_getTokenSpelling
获取令牌的实际文本,并使用clang_getTokenExtent
。clang_annotateTokens
的位置为您提供CXCursor
,以便您查看相关声明。
请注意,libclang API未公开某些细节;如果您需要更多细节,可能需要使用clang的C ++ API。
答案 1 :(得分:2)
您正在寻找libclang公开的令牌spelling
和location
属性。在C ++中,可以使用函数clang_getTokenLocation和clang_getTokenSpelling来检索这些函数。最少使用这些函数(使用它们的python等价物将是:
s = '''
struct Type;
void foo(Type param);
'''
idx = clang.cindex.Index.create()
tu = idx.parse('tmp.cpp', args=['-std=c++11'], unsaved_files=[('tmp.cpp', s)], options=0)
for t in tu.get_tokens(extent=tu.cursor.extent):
print t.kind, t.spelling, t.location
给出:
TokenKind.KEYWORD struct <SourceLocation file 'tmp.cpp', line 2, column 1>
TokenKind.IDENTIFIER Type <SourceLocation file 'tmp.cpp', line 2, column 8>
TokenKind.PUNCTUATION ; <SourceLocation file 'tmp.cpp', line 2, column 12>
TokenKind.KEYWORD void <SourceLocation file 'tmp.cpp', line 3, column 1>
TokenKind.IDENTIFIER foo <SourceLocation file 'tmp.cpp', line 3, column 6>
TokenKind.PUNCTUATION ( <SourceLocation file 'tmp.cpp', line 3, column 9>
TokenKind.IDENTIFIER Type <SourceLocation file 'tmp.cpp', line 3, column 10>
TokenKind.IDENTIFIER param <SourceLocation file 'tmp.cpp', line 3, column 15>
TokenKind.PUNCTUATION ) <SourceLocation file 'tmp.cpp', line 3, column 20>
TokenKind.PUNCTUATION ; <SourceLocation file 'tmp.cpp', line 3, column 21>