Я изо всех сил пытаюсь найти подходящий способ привязать поле в структуре C++ к его комментариям, используя libclang 3.9.1 и python 3.5.2.python + libclang; итерация назад и вперед: привязка полей комментариев к полю
До сих пор я получил эту установку и работает: Предполагая, что у меня есть файл 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
};
Мой питон код экстракт только в онлайн Комментарии:
#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'
Теперь, для моих проблем, заказанных impo rtance, уровень нисходящего:
Как я могу связать для комментариев перед поля? Я смотрел на многие «peeking» решения в python, чтобы узнать, когда я повторяю токены, если следующий - это курсор (поле), который мне интересен, но не нашел ничего, что я мог бы правильно реализовать в моем случае , Просто, чтобы показать вам, насколько серьезно я, вот некоторые из решений я посмотрел на:
- SO Q: how-to-look-ahead-one-element-in-a-python-generator
- Код Рецепт: look-ahead-one-item-during-iteration
- Просто еще один код Рецепт: peek-ahead-an-iterator
Концептуальный недостаток: Я еще не знаю, как сказать разницу между:
struct Foo { int Bar; // This comment belong to bar // As well as this one // While this comment belong to baz already int Baz; };
- Проблемы с производительностью: обратите внимание, что для каждого поля я повторяю список всех его токенов. Если он большой, и у меня много жетонов - я думаю, это будет стоить мне. Я бы хотел найти несколько ярлыков .. Я думал о сохранении токенов в глобальном списке, но что тогда, если поле является объявлением другого struct/class? Добавить токены родителя в список? Это начинает запутаться ...
всего помощники для тех, кто не знает 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>
Блин, забыл упомянуть об этом:) ... Я уже знал о '' Cursor.brief_comment' и Cursor.raw_comment', но это требует изменения .h файла. Предположим, что я не могу изменить его, и он находится в формате, который появляется в моем вопросе. Как я могу справиться с этим сейчас? (И, BTW, clang предполагают, что перед ним появляются все соответствующие комментарии к курсору. Что относительно встроенных в liner-файлов, например, в моем файле .h'?) В любом случае, спасибо за ваше время ... –