文章目录
- 1. 目录结构:
- 2.代码
- 1. test.c
- 2. write_excel.py
- 3. cparser.py
- 4. 模板.xlsx
- 5. output.xlsx
脚本中主要使用 openpyxl cparser 库
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 <stdio.h>
#include <stdlib.h>
#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
5. output.xlsx