import json import re class PythonCodeTreeNode: def __init__(self, data, parent=None, last_node=None, indentation=0, serial_number=0, extent_data=None): if extent_data is None: extent_data = {} self.data = data self.parent = parent self.children = [] self.indentation = indentation self.extent_data = extent_data self.serial_number = serial_number self.last_node = last_node # 树结构类(非平衡非二叉树) class PythonCodeTreeController: # 增 @classmethod def add_data(cls, node): node.parent.children.append(node) # 删 @classmethod def del_data(cls): pass # 改 @classmethod def edit_data(cls): pass # 查 @classmethod def find_data(cls, root_node: PythonCodeTreeNode, i, s): if root_node.indentation == i and root_node.serial_number == s: return root_node for child in root_node.children: result = cls.find_data(child, i, s) if result: return result return None @classmethod def find_data_by_path(cls, root_node, path, depth=0): if root_node is None: return None components = path.split('/') current_node = root_node for component in components: if not component: # 跳过空的组件(例如,路径开头为 '/') continue found = False for child in current_node.children: if child.data["name"] == component: current_node = child found = True break if not found: return None # 如果未找到路径中的某个组件,返回None return current_node # 输出 @classmethod def to_array(cls, node): result = {} if not isinstance(node, str): result = node.data.copy() result["indentation"] = node.indentation result["serial_number"] = node.serial_number result["children"] = [cls.to_array(child) for child in node.children] return result # 输出 @classmethod def to_array2(cls, node): result = {} if not isinstance(node, str): result = node.data.copy() result["indentation"] = node.indentation result["serial_number"] = node.serial_number return result @classmethod def to_string(cls, code_json): code_string = "" # 输出当前节点的值 if code_json['syntax_statement'] != 'Root': code_string += " " * (code_json["syntax_indentation"] - 4) + code_json['syntax_statement'] + "\n" # 递归遍历子节点 for child in code_json['children']: code_string += cls.to_string(child) return code_string def group_tree_data(*args, **kwargs): deepest = [] # 分组,确定序号 group = {} for syntax in kwargs["code_list"]: # 处理字符串 # 提取代码 pattern = r'(\t{4}|\s{4})' matches = re.findall(pattern, syntax) # 确定深度 indentation = len(matches) + 1 # 确定总深度进行分组 deepest.append(indentation) # 去除重复的层级 deepest = set(deepest) # 确认分组数量 for deep in deepest: group.update({f"group{deep}": []}) # 输出详细分组信息 for deep in deepest: serial_number = 0 for i, syntax in enumerate(kwargs["code_list"]): pattern = r'(\t{4}|\s{4})' matches = re.findall(pattern, syntax) # 确定深度 indentation = len(matches) + 1 syntax = re.sub(pattern, "", syntax) lines_data = { "syntax_statement": syntax, # 代码 "syntax_indentation": indentation * 4, # python代码缩进 } if not syntax: continue # Skip empty lines # 生成数据后进行分组 if indentation == deep: node_info = { "lines_data": lines_data, # 内容 "line_number": i, # 行号 "indentation": indentation, # 深度 "serial_number": serial_number # 序号 } # 上层问题 group[f"group{indentation}"].append(node_info) serial_number = serial_number + 1 return group def api_code_transform_to_tree(*args, **kwargs): # 进行代码树的初始化 root = PythonCodeTreeNode({ "syntax_statement": "Root", # 代码 "syntax_indentation": 0, # python代码缩进 }, indentation=0, serial_number=0) parent = {} for group_key, group_value in kwargs["group_data"].items(): for node in group_value: min_difference = float('inf') if f"group{node['indentation'] - 1}" in kwargs["group_data"]: for item in kwargs["group_data"][f"group{node['indentation'] - 1}"]: difference = node["line_number"] - item['line_number'] if 1 <= difference < min_difference: min_difference = difference parent = { "depth": item["indentation"], "serial_number": item["serial_number"], } node.update({"test": parent}) # 至此完整树数据整理完成,进入结构体 for item in kwargs["group_data"].values(): for ss in item: if ss["indentation"] == 1: node = PythonCodeTreeNode(ss["lines_data"], parent=root, indentation=ss["indentation"], serial_number=ss["serial_number"]) else: parent = PythonCodeTreeController.find_data(root, ss["test"]["depth"], ss["test"]["serial_number"]) node = PythonCodeTreeNode(ss["lines_data"], parent=parent, indentation=ss["indentation"], serial_number=ss["serial_number"]) PythonCodeTreeController.add_data(node) return PythonCodeTreeController.to_array(root) def api_transform_to_json(*args, **kwargs): code_string = kwargs["code_string"] code_string = re.sub(r'\s+#.*$', "", code_string, flags=re.M) code_string = re.sub(r'\'\'\'(.*?)\'\'\'|"""(.*?)"""', "", code_string, flags=re.M and re.S) code_string = re.sub(r'\n\s*\n', '\n', code_string) filter_str = r',\n\s+|\{\n\s+|\",\n\s+|\n\s+\"|\n\s+\}|\[\n\s+|\n\s+\]|\}\n\}\)|\(\n\s+[A-z0-9]|[A-z0-9]\n\}|({)' filter_code_list = re.finditer(filter_str, code_string) offset = 0 for ss in filter_code_list: start_index = ss.start() - offset end_index = ss.end() - offset match_pattern = r'\n|\s+' new_code_string = code_string[:start_index] + re.sub(match_pattern, "", code_string[start_index:end_index]) + code_string[ end_index:] offset += len(code_string) - len(new_code_string) code_string = new_code_string code_setting = code_string.split("\n") progress_data = group_tree_data(code_list=code_setting) syntax_config = api_code_transform_to_tree(group_data=progress_data) return syntax_config code = """ res = in_data["ins_dict"]["information_safety"]().check_ufw_status() in_data["out_data"]["msg"] = "success" in_data["out_data"]["data"] = res in_data["out_data"]["code"] = 200 """ res = api_transform_to_json(code_string=code) print(json.dumps(res))