У нашій попередній публікації How to parse C++ ‘struct’ definition from source code using clang ми навчилися розбирати визначення struct C++ за допомогою парсера C++ clang. У цій публікації ми покажемо, як розібрати коментарі C++ з вихідного коду за допомогою clang.
parse_comments.cpp
#include <clang-c/Index.h>
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
void extractCommentBlocks(CXTranslationUnit unit) {
CXSourceRange range = clang_getCursorExtent(clang_getTranslationUnitCursor(unit));
CXToken *tokens;
unsigned numTokens;
clang_tokenize(unit, range, &tokens, &numTokens);
for (unsigned i = 0; i < numTokens; ++i) {
CXTokenKind tokenKind = clang_getTokenKind(tokens[i]);
if (tokenKind == CXToken_Comment) {
CXString tokenSpelling = clang_getTokenSpelling(unit, tokens[i]);
CXSourceLocation location = clang_getTokenLocation(unit, tokens[i]);
unsigned line, column;
CXFile file;
clang_getFileLocation(location, &file, &line, &column, nullptr);
std::cout << "Коментар у рядку " << line << ", колонка " << column << ": "
<< clang_getCString(tokenSpelling) << std::endl;
clang_disposeString(tokenSpelling);
}
}
clang_disposeTokens(unit, tokens, numTokens);
}
int main() {
CXIndex index = clang_createIndex(0, 0);
const char *code = R"(
// Це однорядковий коментар
typedef struct {
double a; /* Той дивний параметр */
double b; /* Інший дивний параметр */
} myParameters;
/*
* Це багаторядковий
* блок коментарів
*/
int function() {
// Інший однорядковий коментар
return 42; /* вбудований коментар */
}
)";
CXUnsavedFile unsavedFile = {"test.cpp", code, (unsigned long)strlen(code)};
CXTranslationUnit unit = clang_parseTranslationUnit(index, "test.cpp", nullptr, 0, &unsavedFile, 1, CXTranslationUnit_None);
if (unit == nullptr) {
std::cerr << "Не вдалося розібрати одиницю трансляції." << std::endl;
return 1;
}
CXCursor cursor = clang_getTranslationUnitCursor(unit);
extractCommentBlocks(unit);
clang_disposeTranslationUnit(unit);
clang_disposeIndex(index);
return 0;
}Як скомпілювати
В Ubuntu встановіть необхідні бібліотеки за допомогою
install_libclang19.sh
sudo apt -y install libclang-19-devі скомпілюйте код за допомогою
build_parse_comments.sh
g++ parse_comments.cpp -o parse_comments -std=c++17 -I/usr/lib/llvm-19/include -L/usr/lib/llvm-19/lib -lclangПриклад виводу
Запустіть за допомогою ./parse_comments
parse_comments_output.txt
Коментар у рядку 2, колонка 9: // Це однорядковий коментар
Коментар у рядку 4, колонка 23: /* Той дивний параметр */
Коментар у рядку 5, колонка 23: /* Інший дивний параметр */
Коментар у рядку 8, колонка 9: /*
* Це багаторядковий
* блок коментарів
*/
Коментар у рядку 13, колонка 13: // Інший однорядковий коментар
Коментар у рядку 14, колонка 24: /* вбудований коментар */Альтернативна збірка за допомогою cmake
Можливо, вам доведеться скоригувати версії (19.1.1) та інші параметри тут, щоб це правильно працювало для вашого налаштування.
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(parse_comments)
# Встановити стандарт C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Знайти компоненти LLVM/Clang
find_package(LLVM 19.1.1 REQUIRED CONFIG)
find_package(Clang REQUIRED CONFIG)
# Додати каталоги include
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${CLANG_INCLUDE_DIRS})
# Створити виконуваний файл
add_executable(parse_comments parse_comments.cpp)
# Додати визначення LLVM
target_compile_definitions(parse_comments PUBLIC ${LLVM_DEFINITIONS})
# Зв'язати з libclang
target_link_libraries(parse_comments PUBLIC libclang)
Дивіться схожі статті за категоріями:
C/C++ Clang Source Introspection
Якщо ця стаття допомогла вам, будь ласка, подумайте про те, щоб купити мені каву або зробити пожертву через PayPal на підтримку досліджень та публікації нових статей на TechOverflow