python脚本将json文件生成C语言结构体
1.引言
以前用过python脚本根据excel生成相关C语言代码,其实本质就是文件的读写,主要是逻辑问题,这次尝试将json文件生成C语言的结构体。
2.代码
这是一个json文件,生成这个结构体的本质是深度优先遍历,为了适应最复杂的情况,随便写了一个json文件(大家也可以根据需求自己改,我是自己写的,成功之后就去生产随机json的网站测试,目前没有啥问题,如果大家可以发现问题欢迎指出,在此感谢!)
{
"BE1":{
"apb_base_addr" : "0x80000000",
"stt_base_addr" : "0x40000000",
"size_type" : {
"REG": 64,
"LUT": 64,
"STT": 128
},
"module": [
"BE_SYS", "BE_BIU",
"DEC", "BLC", "LSC", "DGAIN", "AESTAT",
"AWBSTAT", "AWB", "BDRC", "DM", "GAMMA",
"RGBDITHER", "CSC", "SHP", "Y2RCSC", "CDS", "YUVDITHER","YUVDITHER"
],
"nums": [
1,2,6,4,3,6
],
"tests" : [{"test1": 100, "test2": 200, "test3": 300 } ,
{"test1": 400, "test2": 500, "test3": 600 }],
"repeat":{
"a1" : {"test1": 100, "test2": 200, "test3": 300 } ,
"b1" : {"test4": 400, "test5": 500, "test6": 600 }
}
},
"PE1" : 0,
"BE2":{
"apb_base_addr" : "0x80000000",
"stt_base_addr" : "0x40000000",
"size_type" : {
"REG": 64,
"LUT": 64,
"STT": 128
},
"module": [
"BE_SYS", "BE_BIU",
"DEC", "BLC", "aaa", "qwe", "AESTAT",
"AWBSTAT", "AWB", "BDRC", "DM", "GAMMA",
"RGBDITHER", "abc", "SHP", "Y2RCSC", "CDS", "YUVDITHER","YUVDITHER"
],
"nums": [
1,2,3,4,5,6
],
"tests" : [{"test1": 100, "test2": 200, "test3": 300 } ,
{"test1": 400, "test2": 500, "test3": 600 }],
"repeat":{
"a1" : {"test1": 100, "test2": 200, "test3": 300 } ,
"b1" : {"test4": 400, "test5": 500, "test6": 600 }
}
},
"PE2" : 0
}
python脚本:
json解析代码:
#################################################################################
# Company:
# Engineer:
# Create Date: 2022/7/25
# Project Name:
# Design Name:
# Module Name: json_parse
# Description:
# parse json file
# Dependencies:
#
# Record:
# Revision Date Description
# v0.1 2022/7/25 parse json
# Additional Comments:
##################################################################################
import json
def is_addr(addr):
return (addr.find("0x") == 0) and (addr[2:-1].isdigit())
def is_array(node):
if ((node.find("{") != -1) and (node.find("}") != -1)):
if ((node.find("[") != -1) and (node.find("]") != -1)
and (node.find("}") + 1 == node.find("["))):
return True
if ((node.find("(") != -1) and (node.find(")") != -1)
and (node.find("}") + 1 == node.find("["))):
return True
return False
def is_number(value):
return value.isdigit()
def is_struct_array(node, member_list):
if((is_array(node)) and (member_list[-1] != node)):
return True
return False
def is_number_array(node, member_list):
if((is_array(node)) and (member_list[-1] == node)):
return True
return False
def load_json(fp):
try:
data = json.load(fp)
except Exception as e:
print("This is not a json file! %s" % e)
return ""
return data
def analyze_data(data, result, members):
if isinstance(data, dict):
for k, v in data.items():
analyze_data(v, result + "->get{\"%s\"}" % str(k), members)
elif isinstance(data, (list, tuple)):
for i in range(len(data)):
analyze_data(data[i], result + "[%s]" % i, members)
else:
members.append(result + "=" + str(data))
def get_members(fp, members):
data = load_json(fp)
if data != "":
analyze_data(data, "{\"json_config\"}", members)
def get_max_depth(members):
max_depth = 0
for i in members:
max_depth = max(max_depth, len(i.split("->")) - 1)
return max_depth
def get_member_lists(members_array):
member_lists = []
for member in members_array:
member_list = member.split("->")
member_lists.append(member_list)
return member_lists
def get_node_name(node, format):
node_name_first = node.find("{\"") + 2
node_name_end = node.find("\"}")
node_name = node[node_name_first:node_name_end]
if format == "array":
if ((node.find("[") != -1
and
node.find("]") != -1)):
index_1 = node.find("[") + 1
index_2 = node.find("]")
node_name += "[" + node[index_1:index_2] + "]"
return node_name
def get_array_index(node):
index_left = node.find("[") + 1
index_right = node.find("]")
array_index = node[index_left:index_right]
return array_index
def check_value(value):
if value.count(".") != 1:
if value.isdigit():
return "int"
elif value.count("-") == 1 and value.startswith("-"):
num = value.split("-")[-1]
if num.isdigit():
return "int"
else:
return check_bool(value)
else:
return check_bool(value)
else:
left = value.split(".")[0]
right = value.split(".")[1]
if right.isdigit():
if left.isdigit():
return "double"
elif left.count("-") == 1 and left.startswith("-"):
left_num = left.split("-")[-1]
if left_num.isdigit():
return "double"
else:
return check_bool(value)
else:
return check_bool(value)
else:
return check_bool(value)
def check_bool(value):
if value.title() in ("True", "On"):
return "bool"
elif value.title() in ("False", "Off"):
return "bool"
elif is_addr(value):
return "unsigned int"
else:
return "char *"
def get_type(node, member_list):
if is_number_array(node, member_list):
value = node.split("=")[-1]
return "array " + check_value(value)
if(node.find("=") != -1):
value = node.split("=")[-1]
return check_value(value)
if is_struct_array(node, member_list):
for i, temp in enumerate(member_list):
if(temp == node):
node_child = member_list[i+1]
return "array " + "struct " + get_node_name(node, "") + "_s"
return "struct " + get_node_name(node, "") + "_s"
def find_fathers(node_pre_names, node_name, node_father_names):
node_pres = node_father_names.get(node_name, False)
if (node_pres):
for i in node_pres:
if i== node_pre_names:
return True
return False
def get_node_info_list(member_lists):
node_info_list = []
node_father_names = {}
row = len(member_lists)
flag = 0 # json
for i, member_list in enumerate(member_lists):
for j, node in enumerate(member_list):
node_info = {}
node_name = get_node_name(node, "")
node_pre_names = []
node_pres = []
if j == 0 and flag == 1:
continue
# root
if j == 0:
node_info["name"] = node_name
child_names = []
node_info["value"] = ""
child_type = {}
number = 0
if node.find("[") != -1 and node.find("]") != -1:
index_l = node.find("[")
index_r = node.find("]")
last_node = member_lists[-1][0]
number = max(number, int(last_node[index_l + 1: index_r]))
for index in range(i, row):
if (len(member_lists[index]) <= j):
break
if (member_lists[index][j] != node):
break
node_child = member_lists[index][j + 1]
child_name = get_node_name(node_child, "")
child_names.append(child_name)
child_type[child_name] = get_type(node_child, member_lists[index])
child_names = list(set(child_names))
node_info["child_name"] = child_names
node_info["child_num"] = len(child_names)
node_info["child_type"] = child_type
node_info["self_type"] = "struct " + node_name + "_s"
node_info["depth"] = j
node_info["json_number"] = number
node_info_list.append(node_info)
flag = 1
continue
index = j - 1
while (index >= 0):
node_pre_name = get_node_name(member_list[index], "array")
node_pre_names.append(node_pre_name)
index -= 1
if (j > 0
and
(not find_fathers(node_pre_names, node_name, node_father_names))
) :
node_info["name"] = node_name
node_info["father_name"] = node_pre_names
node_pres.append(node_pre_names)
node_father_names[node_name] = node_pres
# leaf node (array)
if (is_number_array(node, member_list)):
node_value_list = []
for index in range(i, row):
if (len(member_lists[index]) <= j):
break
if (get_node_name(member_lists[index][j], "") != node_name):
break
node_value_list.append(member_lists[index][j][member_lists[index][j].find("=") + 1:])
node_info["value"] = node_value_list
for i in node_value_list:
node_info["self_type"] = "array " + check_value(i)
break
node_info["child_num"] = len(node_value_list)
node_info["depth"] = j
node_info_list.append(node_info)
continue
# leaf node (value)
if (node.find("=") != -1):
node_value = node[node.find("=") + 1:]
node_info["value"] = node_value
node_info["self_type"] = get_type(node, member_list)
node_info["depth"] = j
node_info_list.append(node_info)
continue
# struct array
if (is_struct_array(node, member_list)):
child_names = []
node_info["value"] = ""
child_type = {}
arr_index = "0"
for index in range(i, row):
if (len(member_lists[index]) <= j):
break
if (get_node_name(member_lists[index][j], "") != node_name):
break
arr_index = get_array_index(member_lists[index][j])
node_child = member_lists[index][j + 1]
child_name = get_node_name(node_child, "")
child_names.append(child_name)
child_type[child_name] = get_type(node_child, member_list)
node_info["self_type"] = "array " + "struct " + node_name + "_s"
child_names = list(set(child_names))
node_info["child_name"] = child_names
node_info["child_num"] = int(arr_index) + 1
node_info["child_type"] = child_type
node_info["depth"] = j
node_info_list.append(node_info)
continue
# dict json
child_names = []
node_info["value"] = ""
child_type = {}
for index in range(i, row):
if (len(member_lists[index]) <= j):
break
if (member_lists[index][j] != node):
break
node_child = member_lists[index][j + 1]
child_name = get_node_name(node_child, "")
child_names.append(child_name)
child_type[child_name] = get_type(node_child, member_lists[index])
child_names = list(set(child_names))
node_info["child_name"] = child_names
node_info["child_num"] = len(child_names)
node_info["child_type"] = child_type
node_info["self_type"] = "struct " + node_name + "_s"
node_info["depth"] = j
node_info_list.append(node_info)
return node_info_list
def get_nodes_info_from_jsonFile(file_path):
members_array = []
with open(file_path, "r+") as fp:
get_members(fp, members_array)
max_depth = get_max_depth(members_array)
member_lists = get_member_lists(members_array)
node_info_list = get_node_info_list(member_lists)
return (node_info_list, max_depth)
代码生成部分:
#################################################################################
# Company:
# Engineer:
# Create Date: 2022/7/25
# Project Name:
# Design Name:
# Module Name: gen_code
# Description:
# gen header file and config file from json file
# Dependencies:
#
# Record:
# Revision Date Description
# v0.1 2022/7/25 File Created
# Additional Comments:
##################################################################################
from utils.json_parse import *
def get_nodeinfo_dict(node_info_list):
node_info_dict = {}
for i in node_info_list:
data_list = []
name = i["name"]
if(node_info_dict.get(name)):
data_list = node_info_dict.get(name)
data_list.append(i)
node_info_dict[name] = data_list
return node_info_dict
def gen_struct(node_info, node_info_dict, fp):
node_name = node_info["name"]
fp.write(
'/* Define the struct %s_s */\n' %node_name +
'struct %s_s\n' %node_name +
'{\n'
)
child_names = node_info["child_name"]
child_types = node_info["child_type"]
for child_name in child_names:
child_type = child_types[child_name]
# if array
if (child_type.find("array") != -1):
# find same node
index = 0
for i, j in enumerate(node_info_dict[child_name]):
if j["name"] == node_name \
and j["self_type"] == node_info["self_type"] \
and j["child_types"] == node_info["child_types"]:
index = i
child_child_num = node_info_dict[child_name][index]["child_num"]
child_name += "[" + str(child_child_num) + "]" + ";"
child_type = child_type.lstrip("array ")
fp.write(
'\t%s\t' % child_type.ljust(20) +
child_name.ljust(30)
+ ' /* '.ljust(5) + child_name.rsplit(";")[0].ljust(15) + ' */\n'
)
continue
child_name += ";"
fp.write(
'\t%s\t' % child_type.ljust(20) +
child_name.ljust(30)
+ ' /* '.ljust(5) + child_name.rsplit(";")[0].ljust(15) + ' */\n'
)
fp.write(
'}; \n\n'
)
def get_depth_list(node_info_list, max_depth):
depth_list = [[] for x in range(max_depth)]
for node_info in node_info_list:
depth = node_info["depth"]
depth_list[depth-1].append(node_info)
return depth_list
def is_same_father(node1, node2):
if(node1["father_name"] == node2["father_name"]):
return True
return False
# not same node but same name and type
def is_same_name_and_type(gened_nodes, node):
node_name = node["name"]
processed = gened_nodes.get(node_name, False)
if(not processed):
if(not is_same_father(processed, node)
and
processed["self_type"] == node["self_type"]):
return True
return False
def is_same_struct(gened_nodes, node):
node_name = node["name"]
processed = gened_nodes.get(node_name)
if (processed != None):
processed = gened_nodes.get(node_name)
if processed["child_type"] == node["child_type"]:
return True
return False
def get_father_str(node_info):
if(node_info["value"] != ""):
fathers = list(reversed(node_info["father_name"]))
name = node_info["name"]
ret = ""
for val in fathers:
ret += val + "."
# array
if (node_info["self_type"].find("array") != -1):
temp_name = ""
for val in fathers:
if(val.find("[") != -1 and val.find("]") != -1):
index_left = val.find("[")
index_right = val.find("]")
val = val[:index_left] + val[index_left+1:index_right]
temp_name += val + "_"
temp_name += name
if(node_info["self_type"].find("*") != -1):
temp = node_info["self_type"].lstrip("array ") + temp_name
else:
temp = node_info["self_type"].lstrip("array ") + " " + temp_name
child_num = node_info["child_num"]
temp += "[" + str(child_num) + "]" + " = " + "{"
value_list = node_info["value"]
for i, j in enumerate(value_list):
if (i == len(value_list) - 1):
if (check_value(value_list[0]) != "char *"):
temp += j
else:
temp += "\"" + j + "\""
continue
if (check_value(value_list[0]) != "char *"):
temp += j + ", "
else:
temp += "\"" + j + "\""+ ", "
temp += "};\n\t"
ret += name
ret = temp + "memcpy(" + temp_name + ", " + ret + ", sizeof(" + temp_name + "));"
return ret
# not array
val = node_info["value"]
if (check_value(val) != "char *"):
if(val == "True"):
val = "true"
if(val == "False"):
val = "false"
else:
val = "\"" + val + "\""
ret += name + " = " + val +";"
return ret
return
def define_struct(node_info_dict, fp):
node_info_config = node_info_dict["json_config"][0]
if (node_info_config["json_number"] != 0):
json_number = node_info_config["json_number"]
fp.write("\t%s %s[%s];\n" % (node_info_config["self_type"],
node_info_config["name"],
str(json_number + 1)))
else:
fp.write("\t%s %s;\n" % (node_info_config["self_type"], node_info_config["name"]))
def generate_struct_h(gened_nodes, node_info_list, node_info_dict, fp):
fp.write("#ifndef __JSON_CONFIG_H\n")
fp.write("#define __JSON_CONFIG_H\n")
fp.write("#include <stdio.h>\n")
fp.write("#include <stdlib.h>\n")
fp.write("#include <string.h>\n\n")
for node_info in node_info_list:
node_name = node_info["name"]
if node_info["value"] == "":
# not generated
if not is_same_struct(gened_nodes, node_info):
gen_struct(node_info, node_info_dict, fp)
gened_nodes[node_name] = node_info
node_info_config = node_info_dict["json_config"][0]
if (node_info_config["json_number"] != 0):
fp.write("%s *config_init(void);\n" %node_info_config["self_type"])
else:
fp.write("%s config_init(void);\n" %node_info_config["self_type"])
fp.write("#endif")
def generate_struct_init(node_info_dict, node_info_list, fp):
node_info_config = node_info_dict["json_config"][0]
fp.write("#include \"json_config.h\" \n\n") # TODO
if (node_info_config["json_number"] != 0):
fp.write("%s *config_init(void)\n" %node_info_config["self_type"])
else:
fp.write("%s config_init(void)\n" %node_info_config["self_type"])
fp.write("{\n")
# define struct
define_struct(node_info_dict, fp)
for node_info in node_info_list:
ret = get_father_str(node_info)
if ret == None:
continue
fp.write("\t" + ret + "\n")
fp.write("\treturn %s;\n" %node_info_config["name"])
fp.write("}\n")
def generate_test(node_info_dict, test_path):
with open(test_path, "w") as fp:
fp.write("//******************************************************************************\n\
// Copyright : Copyright (C) 2022, NIOd.\n\
// File name : json_test.c \n\
// Author : yoshi.shao \n\
// Version : 1.0 \n\
// Date : 2022-07-25 \n\
// Description : test \n\
// History : \n\
//******************************************************************************\n\n")
fp.write("#include \"json_config.h\"\n\n")
fp.write("int main(void)\n{\n")
node_info_config = node_info_dict["json_config"][0]
if (node_info_config["json_number"] != 0):
fp.write("\t%s *%s = " % (node_info_config["self_type"], node_info_config["name"]))
else:
fp.write("\t%s %s = " % (node_info_config["self_type"], node_info_config["name"]))
fp.write("config_init();\n")
fp.write("\treturn 0;\n")
fp.write("}\n")
def generate_all(json_path, file_path, init_path, test_path):
(node_info_list, max_depth) = get_nodes_info_from_jsonFile(json_path)
node_info_dict = get_nodeinfo_dict(node_info_list)
node_info_list = list(reversed(node_info_list))
gened_nodes = {}
# generate struct.h
with open(file_path, "w") as fp:
fp.write("//****************************************************************************** \n\
// Copyright : Copyright (C) 2022, NIOd.\n\
// File name : json_config.h \n\
// Author : yoshi.shao \n\
// Version : 1.0 \n\
// Date : 2022-07-25 \n\
// Description : Define all struct \n\
// History : \n\
//******************************************************************************\n\n")
generate_struct_h(gened_nodes, node_info_list, node_info_dict, fp)
with open(init_path, "w") as fp:
fp.write("//******************************************************************************\n\
// Copyright : Copyright (C) 2022, NIOd.\n\
// File name : json_config.c \n\
// Author : yoshi.shao \n\
// Version : 1.0 \n\
// Date : 2022-07-25 \n\
// Description : init json struct \n\
// History : \n\
//******************************************************************************\n\n")
generate_struct_init(node_info_dict, node_info_list, fp)
generate_test(node_info_dict, test_path)
python脚本将json文件生成C语言结构体的更多相关文章
- python脚本解析json文件
python脚本解析json文件 没写完.但是有效果.初次尝试,写的比较不简洁... 比较烦的地方在于: 1,中文编码: pSpecs.decode('raw_unicode_escape') 2,花 ...
- python如何编译py文件生成pyc、pyo、pyd以及如何和C语言结合使用
python执行py文件的流程 当我们执行一个py文件的时候,直接python xx.py即可,那么这个流程是怎么样的呢.先说明一下,python执行代码实际上是先打开文件然后执行里面的代码,所以文件 ...
- 使用jsonschema2pojo-maven-plugin 插件根据json文件生成代码
jsonschema2pojo 是一个不错的工具,可以帮助我们快速的根据json 文件生成pojo代码,提高开发效率,以下为简单的 使用maven 插件进行代码生成 使用maven 插件配置 < ...
- Linux Shell输出颜色字符学习笔记(附Python脚本实现自动化定制生成)
齿轮发出咔嚓一声,向前进了一格.而一旦向前迈进,齿轮就不能倒退了.这就是世界的规则. 0x01背景 造了个轮子:御剑师傅的ipintervalmerge的Python版本.觉得打印的提示信息如果是普通 ...
- Go语言结构体转json的坑
Go语言结构体转json的坑 标签(空格分隔): go json.Marshal() JSON输出的时候必须注意,只有导出的字段(首字母是大写)才会被输出,如果修改字段名,那么就会发现什么都不会输出, ...
- 06. Go 语言结构体
Go语言结构体(struct) Go 语言通过用自定义的方式形成新的类型,结构体是类型中带有成员的复合类型.Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性. Go 语言中的类 ...
- GO学习-(38) Go语言结构体转map[string]interface{}的若干方法
结构体转map[string]interface{}的若干方法 本文介绍了Go语言中将结构体转成map[string]interface{}时你需要了解的"坑",也有你需要知道的若 ...
- C语言结构体变量私有化
操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 问题描述 C语言结构体定义中的变量默认是公有(Public)属性,如果实现成员变量的私有(Private)化? 解决方案 ...
- Linux C语言结构体-学习笔记
Linux C语言结构体简介 前面学习了c语言的基本语法特性,本节进行更深入的学习. 预处理程序. 编译指令: 预处理, 宏定义, 建立自己的数据类型:结构体,联合体,动态数据结构 c语言表达式工具 ...
随机推荐
- Elasticsearch学习系列四(聚合搜索)
聚合分析 聚合分析是数据库中重要的功能特性,完成对一个查询的集中数据的聚合计算.如:最大值.最小值.求和.平均值等等.对一个数据集求和,算最大最小值等等,在ES中称为指标聚合,而对数据做类似关系型数据 ...
- 攻防世界pwn题:Recho
0x00:查看文件信息 一个64位二进制文件,canary和PIE保护机制没开. 0x01:用IDA进行静态分析 分析:主程序部分是一个while循环,判断条件是read返回值大于0则循环.函数ato ...
- Collection子接口:List接口
1. 存储的数据特点:存储序的.可重复的数据. 2. 常用方法:(记住)增:add(Object obj)删:remove(int index) / remove(Object obj)改:set(i ...
- 一文深入浅出学习Spring框架系列,强烈推荐
本系列主要介绍Spring框架整体架构,Spring的核心IOC,AOP的案例和具体实现机制:以及SpringMVC框架的案例和实现机制.@pdai 相关文章 首先, 从Spring框架的整体架构和组 ...
- java 九九乘法表(for循环)
package study5ran2yl.study; public class ForDemo01 { public static void main(String[] args) { int h; ...
- STC8H开发(十四): I2C驱动RX8025T高精度实时时钟芯片
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- javaweb 03: jsp
JSP 我的第一个JSP程序: 在WEB-INF目录之外创建一个index.jsp文件,然后这个文件中没有任何内容. 将上面的项目部署之后,启动服务器,打开浏览器,访问以下地址: http://loc ...
- vue使用vuex报错 "export 'watch' was not found in 'vue'
问题 安装Vuex后报错"export 'watch' was not found in 'vue' 解决方法 如果你的vue版本是 2.X ,将vuex升到 3.X.X 就能够解决 npm ...
- 使用Pure Pipes来替换HTML里面的纯函数
<ul *ngFor="let item of list"> <li>{{show(item.label)}}</li> </ul> ...
- python 异常捕捉与异常处理
简介 在实际开发中,为了防止异常界面直接被用户看到,往往我们会采用捕捉异常的方式来进一步处理异常. 异常捕捉 如下代码由于下标越界会导致异常 data = range(10) print(data[1 ...