clang парсинг комментариев

275
22 апреля 2022, 17:00

Начал изучения библиотеки clang для парсинга кода. Мне необходимо найти все комментарии. Если использовать clang-c, то для этого у меня есть код:

...
unsigned numTokens = 0;
CXToken *tokens = NULL;
clang_tokenize(_tu, range, &tokens, &numTokens);
size_t resLine = 0;
for(unsigned i = 0 ; i < numTokens; i++)
{
    enum CXTokenKind kind = clang_getTokenKind(tokens[i]);
    if(kind == CXToken_Comment)
    {
        const std::string commentText = clang_getCString(clang_getTokenSpelling(_tu, tokens[i]));
        ...
    }
}
...

По некоторым причинам я сейчас использую c++ интерфейс библиотеки clang и я не могу разобраться как мне сделать тоже самое с++ кодом. Подскажите в какое направление копать, какие классы использовать.

UPD1: clang предоставляет 2 интерфейса для работы с кодом, Си интерфейс и C++ интерфейс. Вышеприведенный код использует Си интерфейс, мне нужен тот же функциона но с использование с++ интерфейса. В данном контексте clang не используется для компиляции программы, как gcc или msvc,а для анализа кода, подобно тому как это делает clang-format или clang-check.

Answer 1

Поковырял реализацию метода clang_tokenize и в итоге написал код сам, может кому то пригодится.

struct CommentInfo
{
    std::string content;
    SourceLocation loc;
};
class CommentParser
{
public:
    CommentParser(ASTContext& _ctx, SourceManager& _sm):
        ctx(_ctx),
        sm(_sm)
    {
        
    }
    std::vector<CommentInfo> getAllComments()
    {
        std::vector<CommentInfo> out;
        
        SourceLocation locStart = sm.getLocForStartOfFile(sm.getMainFileID());
        SourceLocation locEnd = sm.getLocForEndOfFile(sm.getMainFileID());
        
        SourceRange Range(locStart, locEnd);
        
        std::pair<FileID, unsigned> BeginLocInfo =
                sm.getDecomposedSpellingLoc(Range.getBegin());
        std::pair<FileID, unsigned> EndLocInfo =
                sm.getDecomposedSpellingLoc(Range.getEnd());
        
        ms_assert(BeginLocInfo.first == EndLocInfo.first, "Cannot tokenize across files.");
        
        // Create a lexer
        bool Invalid = false;
        StringRef Buffer = sm.getBufferData(BeginLocInfo.first, &Invalid);
        ms_assert(!Invalid, "Error while create lexer");
        
        Lexer Lex(sm.getLocForStartOfFile(BeginLocInfo.first),
                  ctx.getLangOpts(), Buffer.begin(),
                  Buffer.data() + BeginLocInfo.second, Buffer.end());
        Lex.SetCommentRetentionState(true);
        
        // Lex tokens until we hit the end of the range.
        const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
        Token Tok;
        bool previousWasAt = false;
        do {
            // Lex the next token
            Lex.LexFromRawLexer(Tok);
            if (Tok.is(tok::eof))
            {
                break;
            }
            
            if(Tok.is(tok::comment))
            {
                std::pair<FileID, unsigned> LocInfo =
                        sm.getDecomposedSpellingLoc(Tok.getLocation());
                
                CommentInfo cInfo;
                cInfo.content = Buffer.substr(LocInfo.second, Tok.getLength());
                cInfo.loc = Tok.getLocation();
                out.push_back(cInfo);
            }
            
            previousWasAt = Tok.is(tok::at);
        } while (Lex.getBufferLocation() < EffectiveBufferEnd);
        
        return out;
    }
private:
    ASTContext& ctx;
    SourceManager& sm;
};

Использовать так:

ASTContext& ctx = d->getASTContext();
SourceManager& sm = ctx.getSourceManager();
CommentParser cParser(ctx, sm);
for(auto &it : cParser.getAllComments())
{
    std::cout << it.loc.printToString(sm) << "\n" << it.content << "\n\n";
}
READ ALSO
Скачать превью с im0-tub-ru.yandex.net

Скачать превью с im0-tub-ru.yandex.net

Каким образом в QT можно получить превью картинки с яндекскартинок

200
Самое быстрое обращение матриц

Самое быстрое обращение матриц

Всем добрый вечер! Столкнулся с потребностью сверхскростного обращения матриц без использования nplinalg

137