利用tree-sitter提取代码文件中的函数和注释

利用tree-sitter提取代码文件中的函数和注释

    • 1. 需求
    • 2. 工具
    • 3. 实现

1. 需求

提取.c或.cpp文件中的带有注释的函数,作为训练数据喂给大语言模型。要求是能够批量处理,提取函数前带有注释的函数和注释,并将函数中的注释同样提取出来作为辅助训练数据,结果保存在JSON文件中。

2. 工具

tree-sitter
如何配置使用环境见https://blog.csdn.net/sluck_0430/article/details/134194493
pycharm
如何将conda的虚拟python环境添加到pycharm中见https://blog.csdn.net/weixin_62783109/article/details/129962054?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171402346916800178588080%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171402346916800178588080&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-4-129962054-null-null.142%5Ev100%5Econtrol&utm_term=conda%E5%90%8E%E7%9A%84%E7%8E%AF%E5%A2%83%E5%A6%82%E4%BD%95%E6%B7%BB%E5%8A%A0%E5%88%B0pycharm%E4%B8%AD&spm=1018.2226.3001.4187

3. 实现

from tree_sitter import Language, Parser
import json
import os
import re


# 加载C语言模块
Language.build_library(
    'build/my-languages.so',
    [
        'vendor/tree-sitter-c'
    ]
)


C_LANGUAGE = Language('build/my-languages.so', 'c')
parser = Parser()
parser.set_language(C_LANGUAGE)


# 提取代码信息
def extract_code_information(node, code):
    functions = []  # 存放最终的代码提取结果
    comment = ''  # 存放函数前的注释
    in_comment = ''  # 存放函数中的注释
    function = ''  # 存放函数
    for child in node.children:
        # 只保存函数前存在注释的函数及其注释
        if child.type == 'function_definition' and child.prev_sibling and child.prev_sibling.type == 'comment':
            # 首先处理函数
            function = extract_node_information(child, code)
            # 然后处理函数中的注释
            in_comment = traverse_children(child, code)
            # 最后处理函数前的注释
            temp_node = child.prev_sibling
            while temp_node.type == 'comment':
                comment += extract_node_information(temp_node, code)
                if temp_node.prev_sibling:
                    temp_node = temp_node.prev_sibling
                else:
                    break
            # 将函数和其注释保存到最终的结果中
            functions.append({
                'comment_before_function': comment,
                'comment_in_function': in_comment,
                'function': function
            })
            comment = ''
            in_comment = ''
            function = ''
    return functions


# 深度优先遍历节点的全部孩子节点
def traverse_children(node, code):
    if node is None:
        return ''
    comment = ''
    if node.type == 'comment':
        comment += extract_node_information(node, code)
    for child in node.children:
        comment += traverse_children(child, code)
    return comment


# 提取节点信息
def extract_node_information(node, code):
    try:
        start_row, start_col = node.start_point
        end_row, end_col = node.end_point
        # 将源代码按行进行拆分
        code_lines = code.split('\n')
        # 如果起始行和结束行在同一行
        if start_row == end_row:
            extracted_code = code_lines[start_row][start_col:end_col]
        else:
            # 提取起始行到结束行中的内容
            extracted_code = code_lines[start_row][start_col:]
            for i in range(start_row + 1, end_row):
                extracted_code += code_lines[i] + '\n'
            extracted_code += code_lines[end_row][:end_col]
        return extracted_code
    except AttributeError as e:
        return ''


# 查找文件夹中的.c和.cpp文件
def get_c_files(folder):
    c_files = []
    for root, dirs, files in os.walk(folder):
        for file in files:
            if re.search(r'\.c$|\.cpp$', file):
                c_files.append(os.path.join(root, file))
    return c_files


# 处理文件夹中的.c和.cpp文件
def pipeline(folder_path):
    c_files = get_c_files(folder_path)
    functions = []
    for c_file in c_files:
        print(c_file)
        temp = []
        try:
            try:
                with open(c_file, 'r', encoding='gbk') as file:
                    code = file.read()
                    tree = parser.parse(bytes(code, 'gbk'))
                    root_node = tree.root_node
                    temp = extract_code_information(root_node, code)
                    functions.append(temp)
            except UnicodeDecodeError as e:
                with open(c_file, 'r', encoding='utf8') as file:
                    code = file.read()
                    tree = parser.parse(bytes(code, 'utf8'))
                    root_node = tree.root_node
                    temp = extract_code_information(root_node, code)
                    functions.append(temp)
        except UnicodeDecodeError as e:
            print("UnicodeDecodeError!")
        # 将结果保存在functions.json中
        with open('functions.json', 'w', encoding='utf8') as json_file:
            json.dump(functions, json_file, indent=4, ensure_ascii=False)


if __name__ == '__main__':
    folder_path = '文件夹的绝对路径'
    pipeline(folder_path)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/574349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL主键:自增id、UUID、雪花算法

视频可看: 动画讲解:为什么不能使用自增ID或者UUID做MySQL的主键,雪花算法生成的主键存在哪些问题_哔哩哔哩_bilibili 一、MySQL分布式架构中,为什么不能使用自增id作为主键 自增主键的好处:写入效率高 弊端&#x…

你只可以转让未使用“通过 Apple 登录”功能的 App。

你只可以转让未使用“通过 Apple 登录”功能的 App。 因为这个问题遇到的比较少,同时也比较难以解决,所以这个问题的答案,必须要开会员我才让你们看。 华丽的开会员分割线 当前问题的主要原因是被接入的账号有30天的封号提示了,…

12(第十一章,数据仓库和商务智能)

目录 概述 目标和原则 基本概念 商务智能 数据仓库 数据仓库建设方法 数据仓库架构组件 加载处理方式 1、历史数据 2、批量变更数据捕获(CDC) 3、准实时和实时数据加载 活动 运营分析应用 方法 数据仓库构建 架构演进 数据处理过程 数…

Python+Selenium基于PO模式的Web自动化测试框架

🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 一、什么是Selenium? Selenium是一个基于浏览器的自动化测试工具,它提供…

pytest教程-30-测试数据管理插件-pytest-datadir

领取资料,咨询答疑,请➕wei: June__Go 上一小节我们学习了pytest重复执行用例插件pytest-repeat,本小节我们讲解一下测试数据管理插件-pytest-datadir。 在软件测试中,有效管理测试数据对于编写全面的测试用例至关重要。Pytest…

Allure精通指南(04)静态和动态生成报告标记

文章目录 Allure 静态定制报告标记Allure 动态生成报告标记Allure 实现方式选择Allure 分类执行运行epic相关运行feature相关运行story相关运行story相关运行feature和多个story相关(取并集) Allure 静态定制报告标记 定义和用法: Decorators…

Learn ComputeShader 01 First Computer Shader

使用Unity版本:2019.4.12f1 整体流程: 1添加一个quad object并添加一个无光照材质 2.相机投影模式设置为正交 3.调整quad使其完全显示在相机内 4.创建脚本并且使用计算着色器覆盖quad的纹理 5.创建一个compute shader 前三步完成以后结果应该是这…

深入了解计算机系统——利用循环展开对程序的优化

系列文章: 操作系统详解(1)——操作系统的作用 操作系统详解(2)——异常处理(Exception) 操作系统详解(3)——进程、并发和并行 操作系统详解(4)——进程控制(fork, waitpid, sleep, execve) 操作系统详解(5)——信号(Signal) 文章目录 一些概念CPE 初步优化消除不必…

Mysql基础篇

1 数据库的三大范式 第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项。 第二范式:在第一范式的基础上,消除非主属性对主属性的部分函数依赖。要求实体的非主键完全依赖于主键。所谓完全依赖是指不能存…

Linux进程间通讯

文章目录 Linux进程间通讯1、进程间通信介绍1.1、进程间通信目的1.2、进程间通信发展1.3、进程间通信分类 2、管道2.1、什么是管道2.2、匿名管道2.2.1、标准输入stdin和标准输出stdout通信2.2.2、父子进程通信2.2.3、父子进程通信现象2.2.4、父子进程通信特性2.2.5、进程池 2.3…

【window环境、Linux环境、QT三种方法实现TCP通信】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Windows环境下实现TCP通信1.服务器2.客户端3.运行 二、Linux环境下实现TCP通信1.服务端2.客户端 三、Qt实现TCP通信1.服务端1.客户端 总结 前言 大多数项目…

RAG文本解析工具open-parse

简介 对于RAG来说,将文本有效的分块(chucking)是很重要的一件事,open-parse是一个用来分块pdf的开源工具,它主要基于视觉驱动(Visually-Driven)的方式来将文档分块,也就是说它不仅仅是按照段落或者字数来对文档分块,而…

easyx 按键信息

前言 看看代码吧 ExMessage msg { 0 }; bool button(int x, int y, int w, int h, const char* text) {//绘制按钮setfillcolor(RGB(230, 231, 232));fillroundrect(x, y, x w, y h, 5, 5);if ((msg.x > x && msg.x<x w && msg.y>y && …

为什么要分库分表?(设计高并发系统的时候,数据库层面该如何设计?)

目录 1.分表 2.分库 说白了&#xff0c;分库分表是两回事儿&#xff0c;大家可别搞混了&#xff0c;可能是光分库不分表&#xff0c;也可能是光分表不分库&#xff0c;都有可能。 我先给大家抛出来一个场景。 假如我们现在是一个小创业公司(或者是一个 BAT …

java反序列化之URLDNS链学习

一、前言 近来学习java反序列化&#xff0c;听p神所说这个URLDNS利用链比较好理解&#xff0c;故决定由此进入学习的第一篇。 URLDNS是Java反序列化中比较简单的一个链&#xff0c;由于URLDNS不需要依赖第三方的包&#xff0c;同时不限制jdk的版本&#xff0c;所以通常用于检…

hertzbeat 源码阅读记录

关于自定义标签的说明 EmailValid.java HostValid PhoneNumValid 枚举值说明&#xff1a;

【OpenGL实践08】现代渲染管线在GLUT和Pygame和Qt.QOpenGLWidget上各自的实现代码

Qt.QOpenGLWidget进行现代渲染管线实验效果 一、说明 据说QOpenGLWidget是用来取代QGLWidget的继承者&#xff0c;我们试图将GLUT上的旧代码改成QOpenGLWidget&#xff0c;本以为差别不大&#xff0c;轻易搞定&#xff0c;经实践发现要付出极大努力才能完成。经多次实验发现G…

Java面试八股之Java中为什么没有全局变量

Java中为什么没有全局变量 Java中没有传统意义上的全局变量&#xff0c;这是因为Java语言设计遵循面向对象的原则&#xff0c;强调封装性和模块化&#xff0c;以及避免全局状态带来的副作用。 封装性&#xff1a; 全局变量违反了面向对象编程中的封装原则&#xff0c;即隐藏对…

【ZYNQ】zynq启动模式及程序固化

一、前言 由于zynq含有arm cpu ,其启动模式由ps主导&#xff0c;与纯逻辑的fpga不相同&#xff0c;此处做一个记录。 二、zynq启动模式 关于zynq的启动模式详细内容可以参考官方文档&#xff1a;ug585-Zynq 7000 SoC Technical Reference Manual&#xff0c;第六章。 2.1 启…

帮助中心系统搭建不再是难题,这几个工具来帮你

在面临客户服务挑战时&#xff0c;有效的帮助中心系统是提升用户满意度和解决问题效率的关键。幸运的是&#xff0c;搭建一个功能全面的帮助中心不再是什么难事。下面&#xff0c;我要为你介绍三款能够帮忙打造帮助中心的超实用工具&#xff0c;让你的客户支持体验迅速升级。 1…