基于python的c++ 类空实现代码生成器

本文介绍了一个Python脚本,用于自动化地在C++ .cpp文件中生成类函数的空实现,通过解析 .h头文件和 .cpp源文件来匹配函数声明并填充到对应的实现中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近换了linux,没有了vs很不习惯,虽然还有eclipse和codeblocks也不错,但是c++类函数代码生成不怎么强,基本没有。

每次写c++代码,写完.h头文件里类的声明后总要在.cpp文件里再写实现,这个时候通常把头文件的函数声明复制过来,再加上类作用域限定符,写多了感觉很麻烦。而且容易复制错地方。不过现在既然在linux下就自己动手丰衣足食吧,所以就像自己做个工具完成这件事。

字符串处理是脚本语言的强项,学了python后还没怎么用过,这次就用python做吧。

先在命令行里输入.h文件和.cpp文件的路径,可以不要.cpp文件,那样就从头生成.cpp文件。

先扫描.cpp文件(如果有的话)用正则表达式把纯函数声明(就是函数名和参数类型,不要参数名,要去空格)抓出来,存在列表里。

再扫描.h文件,同样用正则先抓出类名。

再抓纯函数声明,然后每抓出一项,就和刚才存的比对,如果没有就在.cpp文件里加上这个函数的空实现,当然如果开头没有给.cpp文件就把所有的函数都加进去。

 工具只能针对一个文件里只有一个类的情况,类型名不能有泛型,而且函数声明要写在一行里,代码风格不能太乱。接下来希望能改进到支持一个文件有多个类。

虽然说起来很简单,但是便起来很麻烦,尤其是正则表达式调的我眼都花了。

不多说了,上代码:


'''
#headfileparse.py
'''
import re

line_pattern = re.compile(r'\A\s*//.*')
mullinestart_pattern = re.compile(r'\A\s*/\*.*')
mullineend_pattern = re.compile(r'.*\*/\s*\Z')
fun_pattern = re.compile(r'((~?\w+|operator [-\].[<>+*&|^/%=\(\)]{1,2})\s*\(.*\)\s*(const)?);')
class_pattern = re.compile(r'\A\s*class\s+(\w+)')
inline_pattern = re.compile(r'\A.*\s*inline\s*.*')
returnvaluetype_pattern = re.compile(r'\A\s*((virtual|static|explicit)\s+)?((const\s+)?(?!virtual)\w+(?!\w+\s*\()(\s*(\*|&))?\s*(const\s+)?)'+fun_pattern.pattern)

def is_linecomment(line):
    match = line_pattern.match(line)
    return match;

def is_mullinecomment_start(line):
    match = mullinestart_pattern.match(line)
    return match;

def is_mullinecomment_end(line):
    match = mullineend_pattern.match(line)
    return match;

def is_function(line):
    match = fun_pattern.search(line)
    if match:
        return match.group(1)
    else:
        return None

def is_classname(line):
    match = class_pattern.match(line)
    return match;

def get_classname(line):
    match = class_pattern.match(line)
    if match:
        return match.group(1)
    else:
        return None

def is_inlinemember(line):
    match = inline_pattern.match(line)
    return match;

def get_returnedvaluetype(line):
    match = returnvaluetype_pattern.match(line)
    if match:
        return match.group(3)
    else:
        return None


'''
#sourcefileparse.py
Created on 2013-5-23

@author: bjr
'''
import re
fun_pattern = re.compile(r'(((~?\w+|operator [-\].[<>+*&|^/%=\(\)]{1,2})\s*\(.*\))\s*(const)?){?')
fun_declare_pattern = re.compile(r'((?:~?\w+|operator [-\].[<>+*&|^/%=\(\)]{1,2})\s*)\((\s*((const\s+)?\w+(\s*(\*|&))*\s*(const\s+)?)\w*\s*(=[^,)]*)?(,|\)))*')
type_pattern = re.compile(r'(\s*((const\s+)?\w+(\s*(\*|&))*\s*(const\s+)?)\w*\s*(=[^,)]*)?(,|\)))')
def get_fun_declare(fun):
    match = fun_declare_pattern.match(fun)
    fun_name = match.group(1).replace(' ','')
    param = []
    param_str = fun[match.end(1)+1:]
    while match:
        match = type_pattern.search(param_str)
        if match:
            param.append(match.group(2).replace(' ',''))
            param_str = param_str[match.end(8):]
    param.insert(0, fun_name)  
    return param;

def is_function(line):
    match = fun_pattern.search(line)
    if match:
        return match.group(1)
    else:
        return None

'''
#function_check.py
Created on 2013-5-23

@author: bjr
'''

import sourcefileparse
import sys
import headfileparse

if len(sys.argv)>1:
    headfilename = sys.argv[1]
    if not headfilename.lower().endswith(".h"):
        print "error headfile type"
        sys.exit();
else:
    print "must need headfile"
    sys.exit();     

try:
    headfile = open(headfilename)
except IOError:
    print "can't open "+headfilename
    sys.exit();

if len(sys.argv)>2:
    sourcefilename = sys.argv[2]
    if not sourcefilename.lower().endswith(".cpp"):
        print "error sourcefile type"
        sys.exit();
else:
    sourcefilename = headfilename[:-2]+".cpp"
try:
    sourcefile = open(sourcefilename,"r")
except IOError:
    try:
        sourcefile = open(sourcefilename,"w")
    except IOError:
        print "can't write"+sourcefilename
        sys.exit()
    print >> sourcefile,'#include"'+headfilename+'"'
    sourcefile.close()

sourcefile = open(sourcefilename,"r+w")

    

classname=None
functionprefix=None
functionname=None
mulcommentflag=False

fun_implement_list = []

#parse sourcefile
for line in sourcefile.readlines():
    if mulcommentflag:
        if headfileparse.is_mullinecomment_end(line):
            mulcommentflag=False;continue
    if headfileparse.is_mullinecomment_start(line):mulcommentflag=True; continue
    if headfileparse.is_linecomment(line):continue
    
    function = sourcefileparse.is_function(line)
    if function:
        fun_implement_list.append(sourcefileparse.get_fun_declare(function)) 
 
#parse headfile       
for line in headfile.readlines():
    if mulcommentflag:
        if headfileparse.is_mullinecomment_end(line):
            mulcommentflag=False;continue
    if headfileparse.is_mullinecomment_start(line):mulcommentflag=True; continue
    if headfileparse.is_linecomment(line):continue
    if not classname:
        if headfileparse.is_classname(line):
            classname = headfileparse.get_classname(line)
            continue
    function = sourcefileparse.is_function(line)
    if function:
        if sourcefileparse.get_fun_declare(function) not in fun_implement_list:   
        
            function = str(function)
            functionreturn = headfileparse.get_returnedvaluetype(line)
            if functionreturn:
                functionreturn = str(functionreturn)
            else:
                functionreturn = ""
            functioniplement = functionreturn+classname+"::"+function+"\n{\n}\n"
            print >>sourcefile,functioniplement
 
#print fun_implement_list
headfile.close()
sourcefile.close()

用python运行最后一个function_check.py,把头文件名和.cpp文件名作为参数传进去。

这个是在python2.6下运行的,python3的自己把print的那些语句改成符合python3的形式就行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值