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

Python如何获取C++文件指定函数起止索引实现整段注释

C++指定函数整段注释的Python实现方案

原有实现的核心问题

逐行find()匹配函数名+提前启动括号栈平衡的逻辑,没有覆盖C++的两类常见语法场景,必然出现注释错位:

  • 未兼容函数签名跨多行的情况:包括参数列表通过\续行、函数体起始{和函数名不在同一行、函数返回值/修饰符与函数名换行书写的场景,容易漏掉函数签名段
  • 括号匹配启动时机错误:从函数名位置就开始做括号平衡判定,在未定位到函数体起始{时栈为空,碰到参数列表的右括号、其他无关符号就会误判函数结束,提前插入*/导致注释包裹范围错误。

正确实现逻辑

要精准获取void test_func的完整起止索引,按三个核心步骤执行即可:

  • 全量文本匹配函数起点:用正则在完整文件内容中匹配void test_func的定义位置,匹配时忽略换行、空白、\续行符,同时排除注释、字符串内部的同名假匹配,拿到函数签名的起始索引
  • 定位函数体起始左大括号:从函数签名起点向后扫描,过程中跳过注释、字符串、参数列表、函数修饰符、续行符、空白内容,直到碰到第一个语法层面有效的{,此时才初始化括号栈,压入该起始左括号
  • 平衡匹配找函数终点:从起始{的下一位开始逐字符扫描,全程跳过注释、字符串/字符字面量内部的符号(这些位置的{}不属于语法括号,不参与计数),每遇到有效{压栈,遇到有效}弹栈,当栈重新为空时,当前}的位置就是函数的结束索引。
  • 最后在函数签名起始位置插入/*,在函数结束}的后一位插入*/,即可完整包裹整个函数,不会出现错位。

可运行代码实现

import re

def wrap_test_func_with_comment(cpp_content: str) -> str:
    # 匹配void test_func定义起点,排除注释、字符串内的假匹配
    func_pattern = re.compile(
        r'(?<!["\'/])void\s+test_func\s*\(',
        re.DOTALL
    )
    func_match = func_pattern.search(cpp_content)
    if not func_match:
        return cpp_content
    func_start = func_match.start()
    pos = func_match.end()
    content_len = len(cpp_content)
    brace_stack = []
    func_end = -1

    # 扫描状态标记
    in_str = None
    in_line_comment = False
    in_block_comment = False

    # 第一步:跳过整个函数签名,找到函数体第一个有效左大括号
    while pos < content_len:
        cur_char = cpp_content[pos]
        next_char = cpp_content[pos+1] if pos + 1 < content_len else ''

        # 处理已进入注释/字符串的状态
        if in_line_comment:
            if cur_char == '\n':
                in_line_comment = False
            pos += 1
            continue
        if in_block_comment:
            if cur_char == '*' and next_char == '/':
                in_block_comment = False
                pos += 2
                continue
            pos += 1
            continue
        if in_str:
            if cur_char == '\\':
                pos += 2
                continue
            if cur_char == in_str:
                in_str = None
            pos += 1
            continue

        # 处理注释/字符串起始标记
        if cur_char == '/' and next_char == '/':
            in_line_comment = True
            pos += 2
            continue
        if cur_char == '/' and next_char == '*':
            in_block_comment = True
            pos += 2
            continue
        if cur_char in ('"', "'"):
            in_str = cur_char
            pos += 1
            continue

        # 找到第一个有效左大括号,启动栈匹配
        if cur_char == '{':
            brace_stack.append('{')
            pos += 1
            break
        pos += 1
    else:
        return cpp_content

    # 第二步:括号平衡匹配,找到函数结束的右大括号
    while pos < content_len and brace_stack:
        cur_char = cpp_content[pos]
        next_char = cpp_content[pos+1] if pos + 1 < content_len else ''

        # 跳过注释、字符串内的所有符号
        if in_line_comment:
            if cur_char == '\n':
                in_line_comment = False
            pos += 1
            continue
        if in_block_comment:
            if cur_char == '*' and next_char == '/':
                in_block_comment = False
                pos += 2
                continue
            pos += 1
            continue
        if in_str:
            if cur_char == '\\':
                pos += 2
                continue
            if cur_char == in_str:
                in_str = None
            pos += 1
            continue

        # 识别注释/字符串起始
        if cur_char == '/' and next_char == '/':
            in_line_comment = True
            pos += 2
            continue
        if cur_char == '/' and next_char == '*':
            in_block_comment = True
            pos += 2
            continue
        if cur_char in ('"', "'"):
            in_str = cur_char
            pos += 1
            continue

        # 统计有效括号
        if cur_char == '{':
            brace_stack.append('{')
        elif cur_char == '}':
            brace_stack.pop()
            if not brace_stack:
                func_end = pos
                break
        pos += 1

    if func_end == -1:
        return cpp_content
    
    # 插入块注释符
    return (
        cpp_content[:func_start]
        + '/*'
        + cpp_content[func_start:func_end+1]
        + '*/'
        + cpp_content[func_end+1:]
    )

# 测试用例
if __name__ == '__main__':
    test_cpp_code = """
#include <stdio.h>
// 测试续行、大括号跨行场景
void \
test_func(int a,
    int b,
    int c)
{
    if (a > 0) {
        // 行注释里的}不参与匹配
        printf("字符串里的{ }也不参与匹配");
        /* 块注释里的{ 同样不参与 */
        for (int i = 0; i < b; i++) {
            c += i;
        }
    }
}

int main() {
    test_func(1, 2, 3);
    return 0;
}
"""
    result = wrap_test_func_with_comment(test_cpp_code)
    print(result)

兼容性说明

  • 自动识别\续行的函数签名、跨多行的函数体起始{,不会漏包函数定义部分
  • 自动跳过注释、字符串、字符字面量内的括号符号,不会出现括号计数错误
  • 只有定位到函数体的第一个有效{才启动平衡匹配,不会提前触发空栈判定导致注释提前闭合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:01:08