目录
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文件生成C语言结构体的资料请关注其它相关文章!
© 版权声明
THE END
暂无评论内容