简易的python脚本:c代码转c++

最近需要将一些c的代码封装成类的方式,方便调用,手工改太麻烦,于是想到了Python+正则表达式,方便又快捷。

正则表达式的用法网上非常详细,我就不再细说。百度百科的说明就不错:http://baike.baidu.com/view/94238.htm

我只简要说下脚本内容 ,这是转换常见内容的脚本,基本c转换c++都用得上的。有具体要求的,需要转换特定语句的,可以以这个为基础改,代码奉上:

import re

def convertFuncDef(lines , lineNo):
    line = lines[lineNo]
    paras = {} 
    while not re.match('^\s*{\s*$' , line):
        mp = re.match('^\s*(double\s*\**|float\s*\**|char\s*\**|long\s*\**|int\s*\**)\s*([^;]+);\s*$' , line)
        args = mp.group(2).split(',')
        for arg in args:
            if len(arg.strip())==0 : continue
            tmp = arg.strip()
            if '[' in tmp : tmp = arg[:arg.find('[')].strip()   # get rid of [x], for example 'window[13]'
            paras[tmp] = '%s %s'%(mp.group(1).strip(), arg.strip())
        lineNo+=1
        line = lines[lineNo]
    return lineNo, paras


def detectPattern(lines):
    lineNo=0 

    # h =(double **)malloc(sizeof(double *)*n7);
    malloc2 = re.compile(r'^\s*(\w+)\s*=\s*\(\s*(double|float|int)\s*\*\*\)\s*malloc\s*\(\s*sizeof\s*\(\s*(double|float|int)\s*\*\s*\)\s*\*\s*(\w+)\s*\)\s*;\s*$')
    # for(i=0; i<n7; ++i)  h[i]=(double *)malloc(sizeof(double)*n8);
    malloc1 = re.compile(r'^\s*for\(([^\)]*)\)\s*(\w+\[\w+\])\s*=\s*\(\s*(double|float|int)\s+\*\)\s*malloc\s*\(\s*sizeof\s*\(\s*(double|float|int)\s*\)\s*\*\s*(\w+)\s*\)\s*;\s*$')
    # free((char *)a);
    free2 = re.compile(r'^\s*free\s*\(\s*\(\s*(\s*double\s*\*|\s*float\s*\*|\s*int\s*\*|\s*char\s*\*)\s*\)\s*(\w+)\s*\)\s*;\s*$')
    # for(i=0; i<n7; ++i) free((char *)a[i]);
    free1 = re.compile(r'^\s*for\(([^\)]*)\)\s*free\s*\(\s*\((\s*double\s*\*|\s*float\s*\*|\s*int\s*\*|\s*char\s*\*)\)\s*([^\)]+)\)\s*;\s*$')

    # void dral(x9, y9, k9, p0, w)
    funcDef = re.compile(r'^\s*(void\s*\**|bool\s*\**|float\s*\**|double\s*\**|int\s*\**|long\s*\**)\s*(\w+)\s*\(\s*([^\)]*)\)\s*$')
    # double **v0; 
    varDef  = re.compile(r'^\s*(bool\s*\*+|float\s*\*+|double\s*\*+|int\s*\*+|long\s*\*+)\s*(\w+)\s*;\s*$')

    while lineNo < len(lines):
        curline = lines[lineNo].rstrip()
        lineNo += 1        
        if varDef.match( curline):     # double **v0;
            mp = varDef.match( curline)
            text = mp.group(1)[:mp.group(1).index('*')]
            count = mp.group(1).count('*')
            for i in range(count):
                text = 'vector<%s>'%text
            print lineNo , '--- ' , '%s %s;'%(text, mp.group(2))
        elif malloc2.match( curline):   # h =(double **)malloc(sizeof(double *)*n7);
            print lineNo , '--- ' , malloc2.sub(r'\1.resize(\4);' , curline) 
        elif malloc1.match( curline):   # for(i=0; i<n7; ++i)  h[i]=(double *)malloc(sizeof(double)*n8);
            print lineNo , '--- ' , malloc1.sub(r'for(\1)    \3.resize(\5);' , curline)
        elif free2.match( curline):     # free((char *)a);
            print lineNo , '--- ' , free2.sub(r'\2.clear();', curline)
        elif free1.match( curline):     # for(i=0; i<n7; ++i) free((char *)a[i]);
            print lineNo , '--- ' , free1.sub(r'for(\1) \3.clear();', curline)
        elif funcDef.match( curline):   # void dral(x9, y9, k9, p0, w)
            mp = funcDef.match(curline)
            args = mp.group(3).split(',')
            lN , paras = convertFuncDef(lines , lineNo)
            tmpArgs = []
            for arg in args:
                if len(arg.strip())==0: continue
                assert paras[arg.strip()]
                tmpArgs.append(paras[arg.strip()])

            text = '%s %s( %s )'%(mp.group(1) , mp.group(2) , ','.join(tmpArgs))
            print lineNo , '---3333--- ' , text
            if lN-lineNo>0: print '\n'.join(['----']*(lN-lineNo))
            lineNo = lN
        else:
            print curline 

            

f = open('abc.c' , 'rb')
lines = f.readlines()
f.close()
detectPattern(lines)

重点说明下里面的正则表达式吧,及作用吧。
正则表达式中每使用一对圆括号,就代表这后的替换中可以使用'\n'来取出这个匹配(pattern),n代表第几个匹配。另外,‘\s*'用于处理可能存在的空格,嫌麻烦可以把'\s*'删除掉再看。有了这些就很简单了。
malloc和free都是一维加二维的,只介绍二维的情况。
先看malloc的:

    # h =(double **)malloc(sizeof(double *)*n7);
    malloc2 = re.compile(r'^\s*(\w+)\s*=\s*\(\s*(double|float|int)\s*\*\*\)\s*malloc\s*\(\s*sizeof\s*\(\s*(double|float|int)\s*\*\s*\)\s*\*\s*(\w+)\s*\)\s*;\s*$')
    # (\w+)        匹配 h
    # (double|float|int)  匹配 double 、 float  、 int之一
    # (\w+)                   匹配 n7
再看free的

    # for(i=0; i<n7; ++i) free((char *)a[i]);
    free1 = re.compile(r'^\s*for\(([^\)]*)\)\s*free\s*\(\s*\((\s*double\s*\*|\s*float\s*\*|\s*int\s*\*|\s*char\s*\*)\)\s*([^\)]+)\)\s*;\s*$')
    # ([^\)]*)     匹配 for(...)省略号内容,从for之后的'('开始,以for的')'结束
    # (\s*double\s*\*|\s*float\s*\*|\s*int\s*\*|\s*char\s*\*)\)  匹配 数据类型,数据类型可能是double、float、int、char,也可能是它的们指针类型
    #  ([^\)]+)                匹配 a[i],匹配代表"不是)的字符"
变量定义
    # double **v0; 指针类型不安全,且长度不易管理
    varDef  = re.compile(r'^\s*(bool\s*\*+|float\s*\*+|double\s*\*+|int\s*\*+|long\s*\*+)\s*(\w+)\s*;\s*$')
    # (bool\s*\*+|float\s*\*+|double\s*\*+|int\s*\*+|long\s*\*+) 匹配bool、float、double、int、long类型之一或是它们的指针类型
    #  (\w+)                 匹配 v0
函数转换

老式的c语言中,允许类似于的定义

      void dral(x9, y9, k9, p0, w)
      double w[12];
      double x9, y9;
      long p0, k9;
现在要把它转换成
void  exti( long ** ss,long n7,long n8,long m7 )
首先,函数头处理

    # void dral(x9, y9, k9, p0, w)
    funcDef = re.compile(r'^\s*(void\s*\**|bool\s*\**|float\s*\**|double\s*\**|int\s*\**|long\s*\**)\s*(\w+)\s*\(\s*([^\)]*)\)\s*$')
    # 函数返回类型  和前面相似,不再细说
    # ([^\)]*)      匹配 dral(...)省略号内容,也就是参数,这个参数顺序是调用函数时使用的,要保存下来。
函数参数处理

    mp = re.match('^\s*(double\s*\**|float\s*\**|char\s*\**|long\s*\**|int\s*\**)\s*([^;]+);\s*$' , line)
    # 参数类型匹配和之前一样
    # ([^;]+)       匹配 ;之前的所有参数,以','分割,之后制作一个字典,以'参数名:参数定义'为键值对。例如,'x9:long x9',再以之前参数顺序组合,就                            得得参数列表




你可能感兴趣的:(python,正则表达式)