#!/usr/bin/env python3 """ 解析 C 文件中的 TKeyForest 初始化表,生成全局共享模式的 HTML 交互树状图。 用法: python gen_shared_html_tree.py [table_name] """ import re import sys import os from collections import defaultdict def parse_table(c_file, table_name): """从 .c 文件中提取并解析 TKeyForest 初始化表""" with open(c_file, "r", encoding="utf-8") as f: content = f.read() # 1. 定位初始化块 pat = re.compile( r'(?:const\s+)?TKeyForest\s+' + re.escape(table_name) + r'\s*=\s*\{(.*)\}\s*;', re.DOTALL ) m = pat.search(content) if not m: print(f"错误:未找到 {table_name} 的初始化块", file=sys.stderr) sys.exit(1) body = m.group(1) key_blocks = [] pos = 0 # 2. 拆分各个 Key while pos < len(body): km = re.search(r'\.(\w+)\s*=\s*\{', body[pos:]) if not km: break field_name = km.group(1) start = pos + km.end() depth = 1 i = start while i < len(body) and depth > 0: if body[i] == '{': depth += 1 elif body[i] == '}': depth -= 1 i += 1 block_content = body[start:i - 1] key_blocks.append((field_name, block_content)) pos = i # 3. 解析三元组 {Mode, SubMode, Func} # 使用集合去重,确保相同的 Mode->Func 关系只被记录一次 edges = set() all_keys = set() for field_name, block in key_blocks: all_keys.add(field_name) block_clean = re.sub(r'//.*', '', block) # 去除注释 for em in re.finditer(r'\{([^}]+)\}', block_clean): parts = [p.strip().strip(',') for p in em.group(1).split(',')] if len(parts) >= 3: mode, sub_mode, func = parts[0], parts[1], parts[2] if func != "NULL": # 记录边关系:Key -> Mode -> Func edges.add((field_name, mode, func)) return list(all_keys), edges def build_html(keys, edges): """构建包含 CSS 和 JS 的完整 HTML 字符串""" # 预处理数据,计算每个节点的入度和出度 node_stats = defaultdict(lambda: {'in': 0, 'out': 0}) # 用于生成唯一 ID,避免特殊字符 def get_id(name): return name.replace('-', '_').replace('(', '').replace(')', '') for key, mode, func in edges: k_id = get_id(key) m_id = get_id(mode) f_id = get_id(func) node_stats[k_id]['out'] += 1 node_stats[m_id]['in'] += 1 node_stats[m_id]['out'] += 1 node_stats[f_id]['in'] += 1 # 构建 HTML 结构 html_parts = [] html_parts.append(""" KeyForest 全局共享树状图

TKeyForest 全局共享交互图 (单击节点高亮路径)

""") # 渲染 Keys for key in sorted(keys): k_id = get_id(key) stats = node_stats[k_id] html_parts.append(f'
{key}
') html_parts.append("""
""") # 收集所有唯一的 Modes all_modes = sorted(set(mode for _, mode, _ in edges)) for mode in all_modes: m_id = get_id(mode) stats = node_stats[m_id] html_parts.append(f'
{mode}
') html_parts.append("""
""") # 收集所有唯一的 Funcs all_funcs = sorted(set(func for _, _, func in edges)) for func in all_funcs: f_id = get_id(func) stats = node_stats[f_id] html_parts.append(f'
{func}()
') html_parts.append("""
""") return "".join(html_parts) def main(): if len(sys.argv) < 2: print("用法: python gen_shared_html_tree.py [table_name]", file=sys.stderr) sys.exit(1) c_file = sys.argv[1] table_name = sys.argv[2] if len(sys.argv) > 2 else "g_ActionTable" if not os.path.isfile(c_file): print(f"错误:文件不存在: {c_file}", file=sys.stderr) sys.exit(1) keys, edges = parse_table(c_file, table_name) html_content = build_html(keys, edges) out_file = os.path.splitext(c_file)[0] + "_shared_tree.html" with open(out_file, "w", encoding="utf-8") as f: f.write(html_content) print(f"成功生成全局共享 HTML 树状图: {out_file}") if __name__ == "__main__": main()