Python 解析c文件并导出到Excel

文章目录

  • 1. 目录结构:
  • 2.代码
    • 1. test.c
    • 2. write_excel.py
    • 3. cparser.py
    • 4. 模板.xlsx
    • 5. output.xlsx

脚本中主要使用 openpyxl cparser

1. 目录结构:

Python 解析c文件并导出到Excel_第1张图片

  • ast.txt :存放解析 c 文件的语法树,便于查找内容
  • cparser.py :解析 c 文件,并调用 write_excel.py 中封装的类写入 output.xlsx
  • output.xlsx : 存放以模板的样式存放函数
  • test.c : 需要解析的 c 文件
  • write_excel.py : 为 cparser.py 提供接口,写入 output.xlsx
  • 模板.xlsx : 模板样式

2.代码

1. test.c

#include 
#include 

#define lsdl 2

int g_a =3;

void show(void)
{
    printf("hello show");
}

int add(int variate_a, int variate_b)
{
    int variate_c = variate_a * variate_b;
    variate_a += variate_b;
    variate_a += g_a;

    return variate_c-variate_a;
}

int main(void)
{
    int a =lsdl;
    int b =3;
    //printf("c = %d", add(a, b));
    return 0;
}

2. write_excel.py

import openpyxl
from openpyxl.styles import Alignment
import copy
import re

class WriterExcel():
    source_path = r'.\模板.xlsx'
    target_path = r'.\output.xlsx'

    source_temp_data_list = []

    copyfuncnum = 0



    def __init__(self, start_num) -> None:
        self.source_excel = openpyxl.load_workbook(self.source_path)
        self.source_Sheet1 = self.source_excel['Sheet1']
        self.source_Sheet2 = self.source_excel['Sheet2']
        
        self.target_excel = openpyxl.load_workbook(self.target_path)
        self.target_Sheet1 = self.target_excel['Sheet1']
        self.ClearSheet(self.target_Sheet1)

        self.start_num = start_num

    def ClearSheet(self, tagSheet):
        """
        @ 功能: 清空工作表
        @ 参数:目标工作表
        @ 返回值:
        """
        tagSheet.delete_rows(1, tagSheet.max_row)
        
        for row in tagSheet.iter_rows():
            for cell in row:
                cell.style = 'Normal'


    def CopyCell(self, sourow, sourcol, targrow, targcol):
        """
        @ 功能: 复制单元格的值、格式、填充色
        @ 参数:单元格源,工作表源,目标单元格,目标工作表
        @ 返回值:
        """

        self.target_Sheet1.cell(targrow, targcol).value = self.source_Sheet1.cell(sourow, sourcol).value  # 复制单元格的值
        if self.source_Sheet1.cell(sourow, sourcol).has_style:   # 判断该单元格是否有特殊格式
            self.target_Sheet1.cell(targrow, targcol).fill = copy.copy(self.source_Sheet1.cell(sourow, sourcol).fill)
            self.target_Sheet1.cell(targrow, targcol).border = copy.copy(self.source_Sheet1.cell(sourow, sourcol).border)
            self.target_Sheet1.cell(targrow, targcol).font = copy.copy(self.source_Sheet1.cell(sourow, sourcol).font)
            self.target_Sheet1.cell(targrow, targcol).alignment = copy.copy(self.source_Sheet1.cell(sourow, sourcol).alignment)

    def GetSourData(self):

        self.source_temp_data_list = self.source_Sheet1['A1:H16']  # 获取模板数据

    def WriteLine1(self, row, funcName):
        """
        @ Line 1
        """
        
        self.CopyCell(1, 1, row, 1)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=1, end_column=8)
        self.target_Sheet1.cell(row = row, column=1).alignment = Alignment(horizontal='left')

        self.target_Sheet1.cell(row= row, column= 1).value = f'1.{self.copyfuncnum +1} {funcName}'

    def WriteLine2(self, row):
        """
        @ Line 2
        """
        
        for col in range(1, 9):
            self.CopyCell(2, col, row, col)

    def WriteLine3(self, row):
        """
        @ Line 3
        """
        
        for col in range(1, 9):
            self.CopyCell(3, col, row, col)

        self.target_Sheet1.cell(row= row, column= 1).value = f'SWDD-BMU-{self.copyfuncnum +1}'

    def WriteLine4(self, row):
        """
        @ Line 3
        """
        
        self.CopyCell(4, 1, row, 1)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=1, end_column=8)

    def WriteLine5(self, row):
        """
        @ Line 5
        """
        
        for col in range(1, 9):
            self.CopyCell(5, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine6(self, row):
        """
        @ Line 6
        """
        
        for col in range(1, 9):
            self.CopyCell(6, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine7(self, row):
        """
        @ Line 7
        """
        
        for col in range(1, 9):
            self.CopyCell(7, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine8(self, row):
        """
        @ Line 8
        """
        
        for col in range(1, 9):
            self.CopyCell(8, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine9(self, row):
        """
        @ Line 9
        """
        
        for col in range(1, 9):
            self.CopyCell(9, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

    def WriteLine10(self, row, paraList):
        """
        @ Line 10
        """

        if len(paraList) >= 1:
            for index in range(len(paraList)):
                for col in range(1, 9):
                    self.CopyCell(10, col, row, col)
                self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

                if paraList[index][0] != None:
                    self.target_Sheet1.cell(row= row, column= 3).value = paraList[index][0]
                    self.target_Sheet1.cell(row= row, column= 4).value = paraList[index][1]
                else:
                    self.target_Sheet1.cell(row= row, column= 2).value = '-'
                row += 1
        else:
            for col in range(1, 9):
                self.CopyCell(10, col, row, col)
            self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

    def WriteLine11(self, row, retList):
        """
        @ Line 11
        """
        for col in range(1, 9):
            self.CopyCell(11, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

        if len(retList) != 0:
            self.target_Sheet1.cell(row= row, column= 3).value = retList[0]
            self.target_Sheet1.cell(row= row, column= 4).value = retList[1]
        else:
            self.target_Sheet1.cell(row= row, column= 2).value = '-'


    def WriteLine12(self, row):
        """
        @ Line 12
        """
        for col in range(1, 9):
            self.CopyCell(12, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine13(self, row, fileName):
        """
        @ Line 13
        """
        for col in range(1, 9):
            self.CopyCell(13, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

        self.target_Sheet1.cell(row= row, column= 2).value = fileName

    def WriteLine14(self, row):
        """
        @ Line 14
        """
        for col in range(1, 9):
            self.CopyCell(14, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)


    def SaveAll(self):
        self.target_excel.save(self.target_path)
        self.source_excel.save(self.source_path)

3. cparser.py

# parser_file 用于处理c语言文件
from pycparser import parse_file
from pycparser import CParser
# c语言有错误时,会引出此错误
from pycparser.plyparser import ParseError
# c_ast.py 文件下包含了抽象语法树的节点类
from pycparser.c_ast import *

import write_excel
from write_excel import WriterExcel



class CParserInfo:
    current_line = 1
    def __init__(self, filename:str):
        self.filename = filename

        m_cpp_path=r'C:\MinGW\bin\gcc.exe'
        m_cpp_args=['-E', r'-Iutils/fake_libc_include']
        self.ast = parse_file(filename, use_cpp = True, cpp_path=m_cpp_path, cpp_args= m_cpp_args)

        self.writeExcHander = WriterExcel(1)

    def ProcessTreeNode(self):
        for FuncDecNope in self.ast.ext:
            
            if FuncDecNope.__class__.__name__ == 'FuncDef':
                self.ProcessLine1(FuncDecNope)
                self.ProcessLine2()
                self.ProcessLine3()
                self.ProcessLine4()
                self.ProcessLine5()
                self.ProcessLine6()
                self.ProcessLine7()
                self.ProcessLine8()
                self.ProcessLine9()
                self.ProcessLine10(FuncDecNope)
                self.ProcessLine11(FuncDecNope)
                self.ProcessLine12()
                self.ProcessLine13(FuncDecNope)
                self.ProcessLine14()
                self.writeExcHander.copyfuncnum += 1

    def ProcessLine1(self, funcDef):
        """
        @ Line 1
        """
        m_declNode = funcDef.decl

        print(m_declNode.name)
        self.writeExcHander.WriteLine1(row = self.current_line, funcName= m_declNode.name)
        self.current_line += 1
        
    def ProcessLine2(self):
        """
        @ Line 2
        """
        
        self.writeExcHander.WriteLine2(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine3(self):
        """
        @ Line 3
        """
        
        self.writeExcHander.WriteLine3(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine4(self):
        """
        @ Line 4
        """
        
        self.writeExcHander.WriteLine4(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine5(self):
        """
        @ Line 5
        """
        
        self.writeExcHander.WriteLine5(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine6(self):
        """
        @ Line 6
        """
        
        self.writeExcHander.WriteLine5(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine7(self):
        """
        @ Line 7
        """
        
        self.writeExcHander.WriteLine7(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine8(self):
        """
        @ Line 8
        """
        
        self.writeExcHander.WriteLine8(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine9(self):
        """
        @ Line 9
        """
        
        self.writeExcHander.WriteLine9(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine10(self, funcDef):
        """
        @ Line 10
        """
        m_paraList = []

        para_len = len(funcDef.decl.type.args.params)
        print('para_len = ', para_len)
        for index in range(para_len):
            tmp_paraList = funcDef.decl.type.args.params[index]
            tmp_list = []
            if tmp_paraList.name != 'None':
                tmp_list.append(tmp_paraList.name)
                tmp_list.append(tmp_paraList.type.type.names[0])
            m_paraList.append(tmp_list)

        self.writeExcHander.WriteLine10(row = self.current_line, paraList= m_paraList)

        if len(m_paraList) > 1:
            self.current_line += len(m_paraList)
        else:
            self.current_line += 1
        
    def ProcessLine11(self, funcDef):
        """
        @ Line 11
        """
        m_retList = []

        m_blockItem = funcDef.body.block_items

        m_tmpList = []
        for eachNode in m_blockItem:
            m_tmpList.append(eachNode.__class__.__name__)

        if 'Return' not in m_tmpList :
            print('不在')
            self.writeExcHander.WriteLine11(row = self.current_line, retList= m_retList)
            self.current_line += 1
            return

        for eachNode in m_blockItem:
            if eachNode.__class__.__name__ == 'Return':
                if eachNode.expr.__class__.__name__ == 'Constant':
                    m_retList.append(eachNode.expr.value)
                    m_retList.append(funcDef.decl.type.type.type.names[0])
                elif eachNode.expr.__class__.__name__ == 'BinaryOp':
                    if eachNode.expr.op == '-':
                        m_retList.append(eachNode.expr.left.name + eachNode.expr.op + eachNode.expr.right.name)
                        m_retList.append(funcDef.decl.type.type.type.names[0])
        

        self.writeExcHander.WriteLine11(row = self.current_line, retList= m_retList)

        self.current_line += 1
        
    def ProcessLine12(self):
        """
        @ Line 12
        """
        self.writeExcHander.WriteLine12(row = self.current_line)
        self.current_line += 1

    def ProcessLine13(self, funcDef):
        """
        @ Line 13
        """
        self.writeExcHander.WriteLine13(row = self.current_line, fileName= funcDef.coord.file)
        self.current_line += 1

    def ProcessLine14(self):
        """
        @ Line 14
        """
        self.writeExcHander.WriteLine14(row = self.current_line)
        self.current_line += 1

    def SaveExtToTxt(self):
        with open('ast.txt', encoding='utf-8', mode= 'w+') as f:
            f.write(str(self.ast.ext))


def main():

    m_filename = 'test.c'
    m_fileInfo = CParserInfo(m_filename)
    m_fileInfo.ProcessTreeNode()
    m_fileInfo.SaveExtToTxt()

    m_fileInfo.writeExcHander.SaveAll()

if __name__ == '__main__'        :
    main()

4. 模板.xlsx

Python 解析c文件并导出到Excel_第2张图片

5. output.xlsx

Python 解析c文件并导出到Excel_第3张图片

Python 解析c文件并导出到Excel_第4张图片
Python 解析c文件并导出到Excel_第5张图片

你可能感兴趣的:(Python,python,excel,openpyxl,cparser)