You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Clang LibTooling:从FunctionDecl获取令牌序列做函数相似性检查

基于Clang LibTooling提取函数令牌序列实现代码相似性检测

问题背景

开发一款基于Clang LibTooling的工具用于检测相似函数,已能获取clang::FunctionDecl,但基于源码文本的相似性检测精度低、速度慢,希望将函数源码转换为令牌序列,实现类似如下功能:

SomeContainer<Token> tokens = getTokenSequence(funcDecl);
for (const auto &t : tokens)
  // ...

解决方案

Clang提供了原生的Lexer和Token API,可以直接从FunctionDecl提取令牌序列,无需自行实现分词逻辑,具体实现如下:

所需头文件

#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"
#include "clang/Basic/TokenKinds.h"

实现getTokenSequence函数

std::vector<clang::Token> getTokenSequence(const clang::FunctionDecl *funcDecl, clang::ASTContext &ctx) {
    std::vector<clang::Token> tokens;

    // 获取函数的完整源范围:覆盖函数声明到函数体结束
    clang::SourceRange funcRange(
        funcDecl->getSourceRange().getBegin(),
        funcDecl->getBody()->getSourceRange().getEnd()
    );

    if (!funcRange.isValid()) {
        return tokens;
    }

    // 初始化Lexer,绑定到函数所在的源码缓冲区
    auto &srcMgr = ctx.getSourceManager();
    const char *bufStart = srcMgr.getBufferData(funcRange.getBegin()).data();
    const char *bufEnd = bufStart + srcMgr.getBufferSize(funcRange.getBegin());

    clang::Lexer lexer(
        funcRange.getBegin(),
        ctx.getLangOpts(),
        bufStart,
        bufStart,
        bufEnd
    );

    clang::Token token;
    // 遍历并收集范围内的所有令牌
    while (lexer.LexFromRawLexer(token)) {
        if (srcMgr.isBeforeInSLocAddrSpace(token.getEndLoc(), funcRange.getEnd())) {
            // 可选:过滤注释、空白等无关令牌
            if (!token.is(clang::tok::comment) && !token.is(clang::tok::unknown)) {
                tokens.push_back(token);
            }
        } else {
            break;
        }
    }

    return tokens;
}

关键说明

  • 范围准确性:通过合并函数声明和函数体的SourceRange,确保覆盖整个函数的源码内容
  • 令牌过滤:可根据需求跳过注释、空白等无关令牌,减少后续相似性分析的噪音
  • 令牌类型利用:通过token.getKind()可获取令牌的类型(如关键字、标识符、运算符等),后续相似性检测时可忽略标识符名称这类易变内容,只保留语法结构相关的令牌,大幅提升检测精度
  • 性能优势:直接基于Clang预处理后的令牌操作,比文本分词速度更快,且避免了文本处理中的语法歧义问题

内容的提问来源于stack exchange,提问作者GKxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 07:02:15