一、简介
扫描C语言文件中第一个结构体,生成结构体初始化和打印结构体出来。
二、使用方法
运行即可
'''
作者:黄宏哲
struct\s+[_a-zA-Z0-9\*]+\s+\{[\s\S]+?\};
# 匹配到第一个括号
struct\s+[_a-zA-Z0-9\*]+\s+\{
# 匹配中间内容
(\s+(char|unsigned char|float|double|long double|signed char|int|unsigned int|short|unsigned short|long|unsigned long)\s+[_a-zA-Z0-9\[\]]+;)+
# 匹配最后一个括号
\s+}\s.*?;
'''
import re
import os
import pyperclip
reference = {"char": "%s",
"float": "%f",
"unsigned int": "%u",
"double": "%lf ",
"int": "%d",
}
# path = input("请输入:")
path = "first.c"
if os.path.isfile(path):
with open(path, encoding="utf-8")as file:
data = u'%s' % file.read()
pattern = re.compile('''struct\s+([_a-zA-Z0-9\*]+)\s+\{[\s\S]+?\}''')
result = pattern.search(data).group(0)
result = result.strip().replace("\n", "")
struct_name = pattern.search(data).group(1)
left = result.index("{")
right = result.index("}")
args_list = result[left+1:right].split()
def get_struct_print_code() -> str:
global struct_name
struct_name_ = struct_name.lower()
left_, right_ = '', ''
for index, arg in enumerate(args_list):
if reference.__contains__(arg):
left_ += ' %s' % (reference[arg])
right_ += "," + struct_name_+"." + \
args_list[index+1].replace("*",
"").replace(";", "").replace("[]", "")
right_ = re.sub("\[.*?\]", "", right_)
return 'printf("{0}"{1});'.format(left_, right_)
def define_struct():
global struct_name
one = "struct %s %s;\n" % (struct_name, struct_name.lower())
for index, arg in enumerate(args_list):
if reference.__contains__(arg):
right_ = struct_name+"." + \
args_list[index+1].replace("*",
"").replace(";", "").replace("[]", "")
right_ = re.sub("\[.*?\]", "", right_)
if "char" in args_list[index]:
one += 'strcpy( {}, NULL);\n'.format(right_.lower()+"\n")
elif "float" in args_list[index]:
one += right_.lower()+" = 1.0f;\n"
else:
one += right_.lower()+" = NULL;\n"
return one
if __name__=="__main__":
msg = define_struct()+'\n'+get_struct_print_code()
pyperclip.copy(msg)
print("成功复制至剪切板!")
os.system("pause")
更新,优化版
# Copyright (c) 2022 黄宏哲 All rights reserved.
# Email: hongzhe2022@163.com
import re
from os import getcwd
from os import path as Path
from os import walk
from typing import List
from typing import Tuple
import pyperclip
class CodeString:
def __str__(self) -> str:
"""
:return: struct_name
"""
return self.struct_name
def __init__(self, declaration_struct_variable: str, declaration_struct_member_variable_string: str,
print_member_variable_message: str, total_message: str, struct_name: str, struct_variables: List[str],
struct_instance: str) -> None:
"""
:param declaration_struct_variable: 声明结构体变量语句
:param declaration_struct_member_variable_string: 声明结构体成员变量语句
:param print_member_variable_message: 打印结构体成员变量语句
:param total_message: 全部代码模板
:param struct_name: 结构体名称
:param struct_variables: 结构体变量成员列表
:param struct_instance: 结构体初始化变量
"""
self.declaration_struct_variable, self.declaration_struct_member_variable_string, self. \
print_member_variable_message, self.total_message, self.struct_name, self.struct_variables, \
self.struct_instance = declaration_struct_variable, declaration_struct_member_variable_string, \
print_member_variable_message, total_message, struct_name, struct_variables, struct_instance
declaration_struct_variable = str()
print_member_variable_message = str()
declaration_struct_member_variable = list()
total_message = str()
struct_name = str()
struct_variables = str()
struct_instance = str()
class TemplateBase:
ONE_LINE = '''([a-zA-Z\[\]0-9\(\)\s,\.\=_\"\'\%]+;)'''
def __init__(self) -> None:
pass
def clean(self, string: str) -> str:
"""
:param string: 输入字符串
:return: string 字符串
"""
string = string.strip().replace("\n", "").replace(";", "")
string = re.sub("\[\d+\]", "", string)
return string
def scan(self) -> List[str]:
"""
:return: 字符串列表
"""
res = []
def get_string(path):
with open(path, encoding='utf-8') as file:
data = file.read()
return data
for root, dirs, files in walk(getcwd(), topdown=False):
for name in files:
file_path = Path.join(root, name)
if "mingw" in file_path:
continue
if name.endswith(".c"):
print(file_path)
res.append(get_string(file_path))
return res
def parser(self, *args) -> any:
"""
解析器
"""
raise NotImplementedError
def string_concat(self, *args) -> CodeString:
"""
处理字符串
"""
raise NotImplementedError
def engine(self) -> CodeString:
"""
:return: CodeString
"""
results: List[CodeString] = []
for s in self.scan():
string_concat_response = self.string_concat(*self.parser(s))
results.append(string_concat_response)
for index, i in enumerate(results):
print("结构体:[%s] \t%d" % (i, index))
num = int(input("请输入序号:"))
pyperclip.copy(results[num].total_message)
print(results[num].total_message)
print("\nSuccessful replication!")
return results[num]
class Generate_c_struct_template(TemplateBase):
def __init__(self) -> None:
super().__init__()
self.reference = {"char": "%s",
"float": "%f",
"unsigned int": "%u",
"double": "%lf ",
"int": "%d",
}
def parser(self, struct_string) -> Tuple[str, List[List[str]], str]:
"""
:param struct_string: 结构体字符串
:return: 1.struct_name
2.struct_variables[struct_variable_type,struct_variable_name]
3.struct_instance
"""
struct_instance = str()
struct_variables = []
pattern = re.compile(r'struct\s*?([_a-zA-Z0-9\*]+)\s*?\{[\s\S]+?\}')
match_result = pattern.search(struct_string)
if match_result:
match_result = match_result.group(0)
else:
print(struct_string)
raise ValueError("结构体不存在!:", match_result)
match_result = match_result.strip().replace("\n", "")
struct_name = pattern.search(struct_string).group(1)
left = match_result.index("{")
right = match_result.index("}")
args = match_result[left + 1:right].split()
for index, arg in enumerate(args):
if self.reference.__contains__(arg):
struct_variable_type, struct_variable_name = arg, self.clean(args[index + 1])
struct_variables.append(
[struct_variable_type, struct_variable_name])
struct_instance = struct_name.lower() # 未完成
return struct_name, struct_variables, struct_instance
def string_concat(self, struct_name: str, struct_variables: List[str], struct_instance: str) -> CodeString:
"""
:param struct_name:
:param struct_variables:
:param struct_instance:
:return: declaration_struct_variable
:return: declaration_struct_member_variable
:return: print_member_variable_message
"""
def clean(string: str):
string = string.strip().replace("\n", "").replace(";", "")
string = re.sub("\[\d+\]", "", string)
return string
print_variable_list = []
format_string_list = []
declaration_struct_member_variable_list = []
declaration_struct_variable = "struct {0} {1};".format(
struct_name, struct_instance)
for struct_variable in struct_variables:
struct_variable_type, struct_variable_name = struct_variable[0], struct_variable[1]
struct_variable_type = clean(struct_variable_type)
struct_variable_name = clean(struct_variable_name)
if self.reference.__contains__(struct_variable_type):
format_string = self.reference[struct_variable_type]
format_string_list.append(format_string)
if "char" in struct_variable_type:
declaration_struct_member_variable = "strcpy({0}.{1}, NULL);".format(
struct_instance, struct_variable_name)
elif "float" in struct_variable_type:
declaration_struct_member_variable = "{0}.{1} = 1.0f;".format(
struct_instance, struct_variable_name)
else:
declaration_struct_member_variable = "{0}.{1} = NULL;".format(
struct_instance, struct_variable_name)
declaration_struct_member_variable_list.append(
declaration_struct_member_variable)
print_variable_name = "{0}.{1}".format(
struct_instance, struct_variable_name)
print_variable_list.append(print_variable_name)
print_str_mid = ' "{0}",{1}'.format(
" ".join(format_string_list), ",".join(print_variable_list))
print_member_variable_message = "printf(%s);" % print_str_mid
declaration_struct_member_variable_string = "\n".join(
declaration_struct_member_variable_list)
total_message = declaration_struct_variable + "\n" + \
declaration_struct_member_variable_string + "\n" + print_member_variable_message
code_string = CodeString(declaration_struct_variable, declaration_struct_member_variable_string,
print_member_variable_message, total_message, struct_name, struct_variables,
struct_instance)
return code_string
if __name__ == "__main__":
Generate_c_struct_template().engine()