python + libclang;来回迭代:将字段注释绑定到字段

时间:2017-01-31 12:38:29

标签: python c++ iteration libclang peek

我现在努力寻找一种合适的方法,使用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'

现在,对于我的问题,按重要性排序,按降级:

  1. 如何在字段之前绑定评论?我在python中查看了很多'偷看'的解决方案,以便在我迭代令牌的时候发现,如果下一个是我感兴趣的光标(字段),但在我的情况下我找不到任何可以正确执行的东西。只是为了告诉你我有多严肃,这里有一些我看过的解决方案:

  2. 概念缺陷:我还不知道如何区分:

    struct Foo {
       int Bar; // This comment belong to bar
                // As well as this one
    
       // While this comment belong to baz already
       int Baz;
     };
    
  3. 性能问题:请注意,对于每个字段,我都在迭代它的结构的整个标记列表。如果它是一个大的,我有很多代币 - 我想这将花费我。我想找一些快捷方式..我想在全局列表中保存令牌,但是如果该字段是另一个struct / class的声明怎么办?将他们父母的代币添加到列表中?这开始变得凌乱......
  4. 对于那些不了解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>
    

1 个答案:

答案 0 :(得分:1)

libclang为使用Cursor属性brief_comment属性raw_comments = ''' 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

提取javadoc样式注释提供直接支持

稍微调整输入代码:

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

产地:

SELECT  *
FROM    cc_open_incident_view
WHERE   yourdatetimecolumn BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE()