import tkinter as tk
from tkinter import scrolledtext, ttk, messagebox
import logging
from datetime import datetime
import traceback
class SimpleCLexer:
def __init__(self):
self.tokens = []
def tokenize(self, input_str):
tokens = []
pos = 0
line = 1
column = 0
length = len(input_str)
# 定义C语言的关键词和类型
keywords = {
'void', 'int', 'char', 'float', 'double', 'short', 'long', 'signed', 'unsigned',
'struct', 'union', 'enum', 'typedef', 'static', 'extern', 'auto', 'register',
'const', 'volatile', 'return', 'if', 'else', 'switch', 'case', 'default', 'for',
'while', 'do', 'break', 'continue', 'goto', 'sizeof'
}
# 扩展类型别名识别
types = {'U1', 'U2', 'U4', 'S1', 'S2', 'S4', 'BOOL', 'BYTE', 'WORD', 'DWORD'}
while pos < length:
char = input_str[pos]
# 跳过空白字符
if char in ' \t':
pos += 1
column += 1
continue
# 处理换行
if char == '\n':
line += 1
column = 0
pos += 1
continue
# 处理单行注释
if pos + 1 < length and input_str[pos:pos+2] == '//':
end = input_str.find('\n', pos)
if end == -1:
end = length
pos = end
continue
# 处理多行注释
if pos + 1 < length and input_str[pos:pos+2] == '/*':
end = input_str.find('*/', pos + 2)
if end == -1:
end = length
else:
end += 2
pos = end
continue
# 处理标识符
if char.isalpha() or char == '_':
start = pos
pos += 1
while pos < length and (input_str[pos].isalnum() or input_str[pos] == '_'):
pos += 1
token_text = input_str[start:pos]
token_type = 'IDENTIFIER'
# 检查是否为关键字或类型
if token_text in keywords:
token_type = 'KEYWORD'
elif token_text in types:
token_type = 'TYPE'
tokens.append({
'type': token_type,
'text': token_text,
'line': line,
'column': column
})
column += (pos - start)
continue
# 处理数字
if char.isdigit():
start = pos
pos += 1
while pos < length and (input_str[pos].isdigit() or input_str[pos] in '.xXabcdefABCDEF'):
pos += 1
tokens.append({
'type': 'NUMBER',
'text': input_str[start:pos],
'line': line,
'column': column
})
column += (pos - start)
continue
# 处理字符串
if char == '"':
start = pos
pos += 1
while pos < length and input_str[pos] != '"':
if input_str[pos] == '\\' and pos + 1 < length:
pos += 2
else:
pos += 1
if pos < length and input_str[pos] == '"':
pos += 1
tokens.append({
'type': 'STRING',
'text': input_str[start:pos],
'line': line,
'column': column
})
column += (pos - start)
continue
# 处理字符
if char == "'":
start = pos
pos += 1
while pos < length and input_str[pos] != "'":
if input_str[pos] == '\\' and pos + 1 < length:
pos += 2
else:
pos += 1
if pos < length and input_str[pos] == "'":
pos += 1
tokens.append({
'type': 'CHAR',
'text': input_str[start:pos],
'line': line,
'column': column
})
column += (pos - start)
continue
# 处理运算符和标点符号
operators = {
'(', ')', '{', '}', '[', ']', ';', ',', '.', '->',
'++', '--', '&', '*', '+', '-', '~', '!',
'/', '%', '<<', '>>', '<', '>', '<=', '>=', '==', '!=',
'^', '|', '&&', '||', '?', ':', '=', '+=', '-=', '*=',
'/=', '%=', '<<=', '>>=', '&=', '^=', '|=', ','
}
# 尝试匹配最长的运算符
matched = False
for op_len in range(3, 0, -1):
if pos + op_len <= length and input_str[pos:pos+op_len] in operators:
tokens.append({
'type': 'OPERATOR',
'text': input_str[pos:pos+op_len],
'line': line,
'column': column
})
pos += op_len
column += op_len
matched = True
break
if matched:
continue
# 无法识别的字符
tokens.append({
'type': 'UNKNOWN',
'text': char,
'line': line,
'column': column
})
pos += 1
column += 1
return tokens
class FunctionAnalyzer:
def __init__(self):
self.function_name = ""
self.parameters = []
self.local_vars = []
self.global_vars = []
self.function_calls = []
self.in_function = False
self.in_function_body = False
self.brace_depth = 0
self.variable_declarations = {}
self.macro_definitions = set()
self.storage_classes = {"static", "extern", "auto", "register"}
self.recorded_globals = set() # 修复:添加缺失的属性
self.local_vars = [] # 局部变量列表
self.struct_tags = set() # 存储识别的结构体标签
self.recorded_globals = set()
self.recorded_locals = set() # 新增:跟踪已记录的局部变量
# 定义允许的类型
self.basic_types = {'void', 'int', 'char', 'float', 'double', 'short', 'long', 'signed', 'unsigned'}
self.type_aliases = {"U1", "U2", "U4", "S1", "S2", "S4"}
self.allowed_types = self.basic_types | self.type_aliases
self.allowed_types.add('struct') # 添加结构体支持
self.debug_level = 2 # 1=基本, 2=详细
def analyze(self, tokens):
self.tokens = tokens
self.pos = 0
self.current_line = 0
self.brace_depth = 0
# 识别宏定义
self._identify_macros()
while self.pos < len(self.tokens):
token = self.tokens[self.pos]
self.current_line = token['line']
# 检测结构体类型声明
if token['text'] == 'struct' and self.pos + 1 < len(self.tokens):
next_token = self.tokens[self.pos + 1]
if next_token['type'] == 'IDENTIFIER':
self.struct_tags.add(next_token['text'])
self.allowed_types.add(next_token['text']) # 添加为有效类型
self.pos += 2 # 跳过 'struct' 和标识符
continue
# 跟踪大括号深度
if token['text'] == '{':
self.brace_depth += 1
if self.in_function and self.brace_depth == 1:
self.in_function_body = True
elif token['text'] == '}':
self.brace_depth -= 1
if self.brace_depth == 0 and self.in_function:
self.in_function = False
self.in_function_body = False
# 检测函数定义
if token['text'] in self.storage_classes or token['text'] in self.allowed_types:
if self._is_function_definition():
self._handle_function_definition()
continue
# 检测变量声明 - 只在函数体内处理
if self.in_function_body and token['text'] in self.allowed_types:
# 检查下一个token是否是标识符(变量名)
if self.pos + 1 < len(self.tokens) and \
self.tokens[self.pos + 1]['type'] == 'IDENTIFIER':
# 确保不是函数返回类型
if self.pos + 2 < len(self.tokens) and self.tokens[self.pos + 2]['text'] != '(':
self._handle_variable_declaration()
continue
# 检测函数调用
if token['type'] == 'IDENTIFIER' and self.pos + 1 < len(self.tokens):
next_token = self.tokens[self.pos + 1]
if next_token['text'] == '(':
self._handle_function_call()
continue
# 检测变量使用
if token['type'] == 'IDENTIFIER':
self._handle_identifier_use(token)
self.pos += 1
return self
def _identify_macros(self):
"""识别宏定义(全大写标识符)"""
for token in self.tokens:
if token['type'] == 'IDENTIFIER' and token['text'].isupper():
self.macro_definitions.add(token['text'])
def _is_function_definition(self):
pos = self.pos
storage_class = None
# 检测存储类说明符
if self.tokens[pos]['text'] in self.storage_classes:
storage_class = self.tokens[pos]['text']
pos += 1
# 检测返回类型
if pos >= len(self.tokens) or self.tokens[pos]['text'] not in self.allowed_types:
return False
return_type = self.tokens[pos]['text']
pos += 1
# 处理指针声明
if pos < len(self.tokens) and self.tokens[pos]['text'] == '*':
return_type += '*'
pos += 1
# 检测函数名
if pos < len(self.tokens) and self.tokens[pos]['type'] == 'IDENTIFIER':
func_name = self.tokens[pos]['text']
pos += 1
else:
return False
# 检测参数列表开头的'('
if pos < len(self.tokens) and self.tokens[pos]['text'] == '(':
pos += 1
else:
return False
# 检测函数体开头的'{' (允许最多5个token的间隔)
found_brace = False
for i in range(min(5, len(self.tokens) - pos)):
if self.tokens[pos + i]['text'] == '{':
found_brace = True
break
return found_brace
def _handle_function_definition(self):
start_pos = self.pos
storage_class = None
# 处理存储类说明符
if self.tokens[self.pos]['text'] in self.storage_classes:
storage_class = self.tokens[self.pos]['text']
self.pos += 1
# 获取返回类型
return_type = self.tokens[self.pos]['text']
self.pos += 1
# 处理指针声明
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '*':
return_type += '*'
self.pos += 1
# 获取函数名
if self.pos < len(self.tokens) and self.tokens[self.pos]['type'] == 'IDENTIFIER':
func_name = self.tokens[self.pos]['text']
self.pos += 1
else:
self.pos = start_pos
return
# 记录函数名
self.function_name = func_name
self.variable_declarations[func_name] = True
# 跳过 '('
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '(':
self.pos += 1
# 提取参数
params = []
current_param = []
depth = 1
param_line = self.current_line
while self.pos < len(self.tokens) and depth > 0:
token = self.tokens[self.pos]
if token['text'] == '(':
depth += 1
elif token['text'] == ')':
depth -= 1
if depth == 0:
break
elif token['text'] == ',' and depth == 1:
# 提取参数类型和名称
param_type, param_name = self._extract_param_info(current_param)
if param_type and param_name:
params.append({
'type': param_type,
'name': param_name,
'line': param_line
})
self.variable_declarations[param_name] = True
current_param = []
param_line = token['line']
self.pos += 1
continue
current_param.append(token)
self.pos += 1
# 处理最后一个参数
if current_param:
param_type, param_name = self._extract_param_info(current_param)
if param_type and param_name:
params.append({
'type': param_type,
'name': param_name,
'line': param_line
})
self.variable_declarations[param_name] = True
# 记录参数
self.parameters = params
# 记录参数为局部变量
for param in params:
self.recorded_locals.add(param['name'])
self.variable_declarations[param['name']] = True
# 查找函数体开头的'{'
while self.pos < len(self.tokens) and self.tokens[self.pos]['text'] != '{':
self.pos += 1
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '{':
self.in_function = True
self.brace_depth = 0
self.pos += 1
return [p['name'] for p in params] if params else []
def _extract_param_info(self, tokens):
"""从参数token列表中提取类型和名称"""
param_type = []
param_name = None
for token in tokens:
if token['type'] in ('KEYWORD', 'TYPE') or token['text'] in self.allowed_types:
param_type.append(token['text'])
elif token['type'] == 'IDENTIFIER' and not token['text'].isupper():
param_name = token['text']
return ' '.join(param_type), param_name
def _handle_variable_declaration(self):
start_pos = self.pos
current_line = self.current_line
# 获取变量类型
var_type = self.tokens[self.pos]['text']
# 处理结构体声明
if var_type == 'struct':
# 收集结构体类型名
struct_type = []
self.pos += 1
while self.pos < len(self.tokens) and self.tokens[self.pos]['text'] != ';':
token = self.tokens[self.pos]
if token['text'] == '{': # 跳过结构体定义
depth = 1
self.pos += 1
while self.pos < len(self.tokens) and depth > 0:
if self.tokens[self.pos]['text'] == '{':
depth += 1
elif self.tokens[self.pos]['text'] == '}':
depth -= 1
self.pos += 1
continue
elif token['type'] == 'IDENTIFIER':
struct_type.append(token['text'])
self.pos += 1
if struct_type:
var_type = 'struct ' + ' '.join(struct_type)
else:
var_type = 'struct'
else:
self.pos += 1
# 处理指针声明
while self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '*':
var_type += '*'
self.pos += 1
var_names = []
# 处理变量名和声明
while self.pos < len(self.tokens):
token = self.tokens[self.pos]
# 结束声明
if token['text'] == ';':
self.pos += 1
break
# 标识符 - 变量名
if token['type'] == 'IDENTIFIER' and not token['text'].isupper():
var_name = token['text']
# 跳过宏定义
if var_name not in self.macro_definitions:
var_names.append(var_name)
self.variable_declarations[var_name] = True
self.pos += 1
continue
# 逗号 - 多个变量声明
elif token['text'] == ',':
self.pos += 1
# 处理指针声明
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '*':
var_type += '*'
self.pos += 1
continue
# 数组声明 - 跳过数组大小
elif token['text'] == '[':
self.pos += 1
depth = 1
while self.pos < len(self.tokens) and depth > 0:
t = self.tokens[self.pos]
if t['text'] == '[':
depth += 1
elif t['text'] == ']':
depth -= 1
self.pos += 1
continue
# 初始化 - 跳过初始化表达式
elif token['text'] == '=':
self.pos += 1
depth = 0
while self.pos < len(self.tokens):
t = self.tokens[self.pos]
if t['text'] in {'(', '['}:
depth += 1
elif t['text'] in {')', ']'}:
depth -= 1
elif t['text'] in {',', ';'} and depth == 0:
break
self.pos += 1
continue
self.pos += 1
# 添加到局部变量 (跳过宏定义和参数)
for var_name in var_names:
# 检查是否在参数列表中
is_param = any(param['name'] == var_name for param in self.parameters)
if not is_param and var_name not in self.macro_definitions:
self.local_vars.append({
'type': var_type,
'name': var_name,
'line': current_line,
'scope': 'local'
})
# 记录为局部变量
self.recorded_locals.add(var_name)
self.variable_declarations[var_name] = True
# 如果未找到变量名,回退位置
if not var_names:
self.pos = start_pos
def _handle_identifier_use(self, token):
var_name = token['text']
line = token['line']
# 跳过已处理的标识符
skip_conditions = (
var_name in self.variable_declarations,
var_name in self.macro_definitions,
var_name == self.function_name,
var_name in self.struct_tags # 跳过结构体标签
)
if any(skip_conditions):
return
# 检查是否是局部变量(在函数体内使用但未声明)
if self.in_function_body and var_name not in self.recorded_locals:
# 添加到局部变量
self.local_vars.append({
'type': 'implicit', # 隐式类型
'name': var_name,
'line': line,
'scope': 'local'
})
self.recorded_locals.add(var_name)
self.variable_declarations[var_name] = True
return
# 添加到全局变量
if var_name not in self.recorded_globals:
self.global_vars.append({
'name': var_name,
'line': line,
'scope': 'global'
})
self.variable_declarations[var_name] = True
self.recorded_globals.add(var_name)
# 添加到全局变量
self.global_vars.append({
'name': var_name,
'line': line,
'scope': 'global'
})
self.variable_declarations[var_name] = True
self.recorded_globals.add(var_name) # 记录已处理的全局变量
def _handle_function_call(self):
# 提取函数名
func_name = self.tokens[self.pos]['text']
line = self.current_line
self.pos += 2 # 跳过函数名和 '('
# 提取参数
params = []
depth = 1
current_param = []
# 保存所有参数token用于后续分析
param_tokens = []
while self.pos < len(self.tokens) and depth > 0:
token = self.tokens[self.pos]
if token['text'] == '(':
depth += 1
elif token['text'] == ')':
depth -= 1
if depth == 0:
break
elif token['text'] == ',' and depth == 1:
params.append(''.join([t['text'] for t in current_param]).strip())
param_tokens.extend(current_param)
current_param = []
self.pos += 1
continue
current_param.append(token)
self.pos += 1
if current_param:
params.append(''.join([t['text'] for t in current_param]).strip())
param_tokens.extend(current_param)
# 跳过 ')' 如果还在范围内
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == ')':
self.pos += 1
# 处理参数中的标识符
for token in param_tokens:
if token['type'] == 'IDENTIFIER' and not token['text'].isupper():
self._handle_identifier_use(token)
# 确定返回类型
return_type = "unknown"
if func_name.startswith("vd_"):
return_type = "void"
elif func_name.startswith(("u1_", "u2_", "u4_", "s1_", "s2_", "s4_")):
prefix = func_name.split("_")[0]
return_type = prefix.upper()
# 添加到函数调用列表
self.function_calls.append({
'name': func_name,
'return_type': return_type,
'params': ", ".join(params),
'line': line
})
class FunctionParserApp:
def __init__(self, root):
self.root = root
self.root.title("C语言函数解析器")
self.root.geometry("1000x800")
self.root.configure(bg="#f0f0f0")
self.setup_logging()
# 创建样式
style = ttk.Style()
style.configure("TFrame", background="#f0f0f0")
style.configure("TLabelFrame", background="#f0f0f0", font=("Arial", 10, "bold"))
style.configure("TButton", font=("Arial", 10), padding=5)
style.configure("TCombobox", padding=5)
style.configure("TProgressbar", thickness=10)
# 主框架
main_frame = ttk.Frame(root)
main_frame.pack(fill="both", expand=True, padx=15, pady=15)
# 创建输入区域
input_frame = ttk.LabelFrame(main_frame, text="输入C语言函数体")
input_frame.pack(fill="both", expand=True, padx=5, pady=5)
self.input_text = scrolledtext.ScrolledText(input_frame, width=100, height=15,
font=("Consolas", 11), bg="#ffffff")
self.input_text.pack(fill="both", expand=True, padx=10, pady=10)
# 按钮区域
btn_frame = ttk.Frame(main_frame)
btn_frame.pack(fill="x", padx=5, pady=5)
# 解析按钮
parse_btn = ttk.Button(btn_frame, text="解析函数", command=self.parse_function)
parse_btn.pack(side="left", padx=5)
# 保存日志按钮
save_log_btn = ttk.Button(btn_frame, text="保存日志", command=self.save_logs)
save_log_btn.pack(side="right", padx=5)
# 进度条
self.progress = ttk.Progressbar(btn_frame, orient="horizontal", length=300, mode="determinate")
self.progress.pack(side="left", padx=10, fill="x", expand=True)
# 调试级别控制
debug_frame = ttk.Frame(btn_frame)
debug_frame.pack(side="left", padx=10)
ttk.Label(debug_frame, text="调试级别:").pack(side="left")
self.debug_level = tk.IntVar(value=1)
ttk.Combobox(debug_frame, textvariable=self.debug_level,
values=[1, 2], width=3).pack(side="left")
# 示例按钮
example_btn = ttk.Button(btn_frame, text="加载示例", command=self.load_example)
example_btn.pack(side="right", padx=5)
# 创建输出区域
output_frame = ttk.LabelFrame(main_frame, text="解析结果")
output_frame.pack(fill="both", expand=True, padx=5, pady=5)
self.output_text = scrolledtext.ScrolledText(output_frame, width=100, height=15,
font=("Consolas", 11), bg="#ffffff")
self.output_text.pack(fill="both", expand=True, padx=10, pady=10)
self.output_text.config(state=tk.DISABLED)
# 日志区域
log_frame = ttk.LabelFrame(main_frame, text="日志信息")
log_frame.pack(fill="both", expand=True, padx=5, pady=5)
self.log_text = scrolledtext.ScrolledText(log_frame, width=100, height=6,
font=("Consolas", 10), bg="#f8f8f8")
self.log_text.pack(fill="both", expand=True, padx=10, pady=10)
self.log_text.config(state=tk.DISABLED)
# 示例函数体
self.example_code = """static void Diag21_PID_C9(U1 u1_a_num)
{
U1 u1_t_cmplt;
U1 u1_t_cnt;
struct SensorData sensor;
if((U1)DIAG_CNT_ZERO == u1_t_swrstcnt) /* Determine if a software reset is in progress */
{
for(u1_t_cnt = (U1)DIAG21_ZERO; u1_t_cnt < (U1)DIAG21_PIDC9_FLAG; u1_t_cnt ++)
{
u1_t_cmplt = u1_g_InspSoftwareVersion(u4_g_cmd, &u4_g_data, (U1)TRUE);
}
vd_s_Diag21_U2ToU1(u2_g_buf, u1_g_data, (U1)DIAG21_PIDC9_FLAG);
}
else
{
/* Do Nothing */
}
}"""
# 加载示例
self.load_example()
def setup_logging(self):
"""配置日志系统"""
self.log_filename = f"parser_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
# 创建文件处理器
file_handler = logging.FileHandler(self.log_filename, encoding='utf-8')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
# 配置根日志器
root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO)
root_logger.addHandler(file_handler)
def log_to_gui(self, message, level="info"):
"""将日志信息显示在GUI中"""
try:
self.log_text.config(state=tk.NORMAL)
timestamp = datetime.now().strftime("%H:%M:%S")
self.log_text.insert(tk.END, f"[{timestamp}] {message}\n")
self.log_text.see(tk.END)
self.log_text.config(state=tk.DISABLED)
if level == "info":
logging.info(message)
elif level == "warning":
logging.warning(message)
elif level == "error":
logging.error(message)
except Exception as e:
logging.error(f"GUI日志错误: {str(e)}")
def save_logs(self):
"""保存日志到文件"""
try:
log_content = self.log_text.get("1.0", tk.END)
filename = f"saved_log_{datetime.now().strftime('%H%M%S')}.txt"
with open(filename, "w", encoding='utf-8') as f:
f.write(log_content)
self.log_to_gui(f"日志已保存到: {filename}", "info")
messagebox.showinfo("保存成功", f"日志已保存到:\n{filename}")
except Exception as e:
self.log_to_gui(f"保存日志失败: {str(e)}", "error")
messagebox.showerror("保存失败", f"无法保存日志:\n{str(e)}")
def update_progress(self, value):
"""更新进度条"""
self.progress['value'] = value
self.root.update_idletasks()
def load_example(self):
"""加载示例函数体"""
self.input_text.delete(1.0, tk.END)
self.input_text.insert(tk.END, self.example_code)
self.log_to_gui("已加载示例函数体")
def parse_function(self):
"""使用内置解析器解析C语言函数体"""
try:
code = self.input_text.get(1.0, tk.END)
if not code.strip():
self.log_to_gui("错误: 没有输入函数体", "error")
messagebox.showerror("错误", "请输入要解析的C语言函数体")
return
self.log_to_gui("开始解析函数体...")
self.output_text.config(state=tk.NORMAL)
self.output_text.delete(1.0, tk.END)
self.update_progress(0)
# 使用内置词法分析器
self.log_to_gui("执行词法分析...")
lexer = SimpleCLexer()
tokens = lexer.tokenize(code)
self.update_progress(30)
# 使用内置语法分析器
self.log_to_gui("执行语法分析...")
analyzer = FunctionAnalyzer()
analyzer.debug_level = self.debug_level.get()
analyzer.analyze(tokens)
# 显示结果
self.log_to_gui("生成解析报告...")
self.display_results(
analyzer.local_vars,
analyzer.global_vars,
analyzer.function_calls,
analyzer.function_name,
analyzer.parameters
)
self.update_progress(100)
self.output_text.config(state=tk.DISABLED)
self.log_to_gui("解析完成!")
messagebox.showinfo("完成", "函数体解析成功完成!")
except Exception as e:
self.log_to_gui(f"解析错误: {str(e)}", "error")
self.log_to_gui(f"错误详情: {traceback.format_exc()}", "error")
messagebox.showerror("解析错误", f"发生错误:\n{str(e)}")
self.update_progress(0)
def display_results(self, local_vars, global_vars, function_calls, func_name, func_params):
"""增强版结果显示,包含所有变量信息"""
# 显示函数签名
self.output_text.insert(tk.END, "=== 函数签名 ===\n", "header")
if func_name:
self.output_text.insert(tk.END, f"函数名: {func_name}\n")
if func_params:
param_list = []
for param in func_params:
param_list.append(f"{param['type']} {param['name']}")
self.output_text.insert(tk.END, f"参数: {', '.join(param_list)}\n\n")
else:
self.output_text.insert(tk.END, "参数: 无\n\n")
else:
self.output_text.insert(tk.END, "警告: 无法识别函数签名\n\n")
# 显示所有找到的变量
self.output_text.insert(tk.END, "=== 所有变量分析 ===\n", "header")
self.output_text.insert(tk.END, "类型 | 名称 | 作用域 | 行号\n", "subheader")
self.output_text.insert(tk.END, "-" * 50 + "\n")
# 显示参数
for param in func_params:
self.output_text.insert(tk.END, f"参数 | {param['name']} | 参数 | {param['line']}\n")
# 显示局部变量
for var in local_vars:
self.output_text.insert(tk.END, f"变量 | {var['name']} | 局部 | {var['line']}\n")
# 显示全局变量
for var in global_vars:
self.output_text.insert(tk.END, f"变量 | {var['name']} | 全局 | {var['line']}\n")
# 显示函数调用
for func in function_calls:
self.output_text.insert(tk.END, f"函数调用 | {func['name']} | 调用 | {func['line']}\n")
self.output_text.insert(tk.END, "\n")
# 显示局部变量
if local_vars:
self.output_text.insert(tk.END, "=== 局部变量 ===\n", "header")
for var in local_vars:
self.output_text.insert(tk.END, f"{var['type']} {var['name']} (行号: {var['line']})\n")
else:
self.output_text.insert(tk.END, "未找到局部变量\n\n")
# 显示使用的全局变量
if global_vars:
self.output_text.insert(tk.END, "=== 使用的全局变量 ===\n", "header")
for var in global_vars:
self.output_text.insert(tk.END, f"{var['name']} (行号: {var['line']})\n")
self.output_text.insert(tk.END, "\n")
else:
self.output_text.insert(tk.END, "未使用全局变量\n\n")
# 显示函数调用
if function_calls:
self.output_text.insert(tk.END, "=== 函数调用 ===\n", "header")
for func in function_calls:
self.output_text.insert(tk.END, f"函数名: {func['name']} (行号: {func['line']})\n")
self.output_text.insert(tk.END, f"返回类型: {func['return_type']}\n")
self.output_text.insert(tk.END, f"参数: {func['params']}\n")
self.output_text.insert(tk.END, "-" * 50 + "\n")
else:
self.output_text.insert(tk.END, "未调用任何函数\n\n")
# 添加变量统计
self.output_text.insert(tk.END, "=== 解析统计 ===\n", "header")
self.output_text.insert(tk.END, f"参数数量: {len(func_params)}\n")
self.output_text.insert(tk.END, f"局部变量数量: {len(local_vars)}\n")
self.output_text.insert(tk.END, f"全局变量数量: {len(global_vars)}\n")
self.output_text.insert(tk.END, f"函数调用数量: {len(function_calls)}\n")
self.output_text.insert(tk.END, f"总变量数量: {len(func_params) + len(local_vars) + len(global_vars) + len(function_calls)}\n")
# 配置标签样式
self.output_text.tag_config("header", font=("Arial", 12, "bold"), foreground="#2c3e50")
self.output_text.tag_config("subheader", font=("Arial", 10, "bold"), foreground="#34495e")
if __name__ == "__main__":
root = tk.Tk()
app = FunctionParserApp(root)
root.mainloop()
=== 函数签名 ===
函数名: Diag21_PID_C9
参数: U1 u1_a_num
=== 所有变量分析 ===
类型 | 名称 | 作用域 | 行号
--------------------------------------------------
参数 | u1_a_num | 参数 | 1
变量 | u4_g_cmd | 局部 | 11
变量 | u4_g_data | 局部 | 11
变量 | u2_g_buf | 局部 | 13
变量 | u1_g_data | 局部 | 13
变量 | u1_t_cmplt | 全局 | 3
变量 | u1_t_cmplt | 全局 | 3
变量 | u1_t_cnt | 全局 | 4
变量 | u1_t_cnt | 全局 | 4
变量 | sensor | 全局 | 5
变量 | sensor | 全局 | 5
变量 | u1_t_swrstcnt | 全局 | 7
变量 | u1_t_swrstcnt | 全局 | 7
函数调用 | u1_g_InspSoftwareVersion | 调用 | 11
函数调用 | vd_s_Diag21_U2ToU1 | 调用 | 13
=== 局部变量 ===
implicit u4_g_cmd (行号: 11)
implicit u4_g_data (行号: 11)
implicit u2_g_buf (行号: 13)
implicit u1_g_data (行号: 13)
=== 使用的全局变量 ===
u1_t_cmplt (行号: 3)
u1_t_cmplt (行号: 3)
u1_t_cnt (行号: 4)
u1_t_cnt (行号: 4)
sensor (行号: 5)
sensor (行号: 5)
u1_t_swrstcnt (行号: 7)
u1_t_swrstcnt (行号: 7)
=== 函数调用 ===
函数名: u1_g_InspSoftwareVersion (行号: 11)
返回类型: U1
参数: u4_g_cmd, &u4_g_data, (U1)TRUE
--------------------------------------------------
函数名: vd_s_Diag21_U2ToU1 (行号: 13)
返回类型: void
参数: u2_g_buf, u1_g_data, (U1)DIAG21_PIDC9_FLAG
--------------------------------------------------
=== 解析统计 ===
参数数量: 1
局部变量数量: 4
全局变量数量: 8
函数调用数量: 2
总变量数量: 15
最新发布