python+libclang;来回迭代:将字段注释绑定到字段
python + libclang; iterating back and forth: binding field comments to the field
我花了一段时间才找到一种合适的方法,使用libclang 3.9.1和python 3.5.2将C++结构中的字段绑定到其注释。
到目前为止,我已经启动并运行了此设置:假设我有文件Foo.h
:
typedef int arbType;
struct Foo {
//First bar comment
//Second bar comment
int Bar; //Third bar comment - after bar
/* First line baz comment - before baz
Second line baz comment - before baz
*/
arbType Baz; //Third line baz comment - after baz
};
我的python代码只提取内联注释:
#bind_comments.py
import clang.cindex
def get_cur_comments(cursor):
comment = ''
print ('nGetting comment for:', cursor.spelling.decode())
parent_cur = cursor.lexical_parent
token_iter = parent_cur.get_tokens()
for token in token_iter:
if token.cursor == cursor:
while token.kind.name != 'PUNCTUATION':
token = next(token_iter)
token = next(token_iter)
if token.kind.name == 'COMMENT':
comment = token.spelling.decode().strip('/')
return comment
def main():
index = clang.cindex.Index.create()
tu = index.parse(b'Foo.h', [b'-x', b'c++'])
tu_iter = tu.cursor.get_children()
next(tu_iter)
root_cursor = next(tu_iter)
for cur in root_cursor.type.get_fields():
print(get_cur_comments(cur))
if __name__ == '__main__':
main()
输出:
C:>bind_comments.py
Getting comment for: Bar
'Third bar comment - after bar'
Getting comment for: Baz
'Third line baz comment - after baz'
现在,对于我的问题,按重要性排序,按降序排列:
如何在字段之前绑定注释?我查看了python中的许多"窥视"解决方案,以便在迭代令牌时发现下一个是否是我感兴趣的游标(字段),但在我的情况下没有发现任何可以正确实现的解决方案。为了向你展示我有多认真,以下是我研究的一些解决方案:
- SO Q:如何锁定蟒蛇生成器中的元素
- 代码配方:在迭代过程中向前看一项
- 只是另一个代码配方:提前查看迭代器
概念缺陷:我还不知道如何区分:
struct Foo { int Bar; // This comment belong to bar // As well as this one // While this comment belong to baz already int Baz; };
- 性能问题:请注意,对于每个字段,我都在迭代it结构的整个令牌列表。如果它是一个大的,并且我有很多代币-我想这会花掉我的钱。我想找到一些捷径。。我考虑过将标记保存在全局列表中,但如果字段是另一个结构/类的声明呢?将其父母的令牌添加到列表中?这开始变得一团糟
只是那些还不知道libclang的人的助手:
>>> print(root_cursor.spelling.decode())
Foo
>>> root_cursor.type.get_fields()
<list_iterator object at 0x0177B770>
>>> list(root_cursor.type.get_fields())
[<clang.cindex.Cursor object at 0x0173B940>, <clang.cindex.Cursor object at 0x017443A0>]
>>> for cur in root_cursor.type.get_fields():
... print (cur.spelling.decode())
...
Bar
Baz
>>> root_cursor.get_tokens()
<generator object TokenGroup.get_tokens at 0x01771180>
libclang直接支持使用Cursor
属性brief_comment
和raw_comment
提取javadoc风格的注释
对您的输入代码进行一点调整:
s = '''
typedef int arbType;
struct Foo {
/// Brief comment about bar
///
/// Extra Text about bar
int Bar;
/** Brief comment about baz
*
* Extra Text about baz
*/
arbType Baz;
/// Brief only comment
int blah;
};
'''
import clang.cindex
from clang.cindex import CursorKind
idx = clang.cindex.Index.create()
tu = idx.parse('tmp.cpp', args=['-std=c++11'], unsaved_files=[('tmp.cpp', s)], options=0)
for c in tu.cursor.walk_preorder():
if c.kind == CursorKind.FIELD_DECL:
print c.brief_comment
print c.raw_comment
print
产品:
Brief comment about bar
/// Brief comment about bar
///
/// Extra Text about bar
Brief comment about baz
/** Brief comment about baz
*
* Extra Text about baz
*/
Brief only comment
/// Brief only comment
相关文章:
- 将结构字段的类型展开为可变模板参数
- 将位字段导出到数组
- 为了方便起见,我应该避免公开私有字段变量吗
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 在java中读取c++字节的位字段
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- 私有字段对象与私有继承?
- 声明没有默认构造函数的字段
- C++内存模型和位字段的最大序列
- 声明为无效的变量或字段'...' Ardunio 编译器上的错误
- 如何在QByteArray中放置和检索位字段而不会感到痛苦?
- C++ win32 如何使密码字段可选并启用复制和粘贴?
- 如何通过UDP接收QByteArray并将其解析为位字段结构?
- 仅匹配集合中的某些字段
- 结构字段名称与 GDB 中的 STL 数组冲突
- 如何使用位字段将数据从二进制文件复制到结构中?
- 结构体和类的不同大小(),彼此具有相同的字段类型
- 如何避免在数据结构中包含存储为字段的类?
- 聚合初始化和删除的复制构造函数,也称为不可复制的 obejcts 作为字段
- python+libclang;来回迭代:将字段注释绑定到字段