import tkinter as tk
from tkinter import scrolledtext, ttk, messagebox
import os
import logging
from datetime import datetime
import sys
import locale
import traceback
# 在文件开头添加编码设置
if sys.platform == "win32":
# 设置Windows系统的标准输出编码
sys.stdout.reconfigure(encoding='utf-8') # Python 3.7+
# 设置系统区域设置
locale.setlocale(locale.LC_ALL, '')
# 对于Python 3.7以下版本
if sys.version_info < (3, 7):
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
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 = set()
self.local_vars = []
self.global_vars = []
self.function_calls = []
self.current_function = None
self.in_function = False
self.in_function_body = False
self.brace_depth = 0
self.variable_declarations = {}
self.control_structures = {"if", "for", "while", "switch", "return", "else"}
self.macro_definitions = set()
self.recorded_globals = set()
self.storage_classes = {"static", "extern", "auto", "register"}
# 定义允许的类型(修复错误)
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.inside_expression = False # 添加新状态跟踪
self.debug_level = 3 # 1=基本, 2=详细, 3=非常详细
self.all_variables = [] # 记录所有找到的变量
# 添加函数前缀识别
self.function_prefixes = {
"vd_": "void",
"u1_": "U1",
"u2_": "U2",
"u4_": "U4",
"s1_": "S1",
"s2_": "S2",
"s4_": "S4"
}
def log(self, message, level="info", debug_level=1):
"""增强版日志方法"""
if level == "debug" and debug_level > self.debug_level:
return
prefix = {
1: "[DEBUG1]",
2: "[DEBUG2]",
3: "[DEBUG3]"
}.get(debug_level, "[DEBUG]")
full_message = f"{prefix} {message}"
if self.log_to_gui:
self.log_to_gui(full_message, level)
else:
print(f"{level.upper()}: {full_message}")
def analyze(self, tokens):
self.tokens = tokens
self.pos = 0
self.current_line = 0
self.inside_expression = False # 重置表达式状态
# 第一步:识别宏定义(全大写标识符)
self._identify_macros()
self.log("开始分析函数体", "debug", 1)
self.log(f"共收到 {len(tokens)} 个token", "debug", 2)
# 第二步:分析函数体
while self.pos < len(self.tokens):
token = self.tokens[self.pos]
self.log(f"处理token: {token['text']} (类型:{token['type']}, 行:{token['line']})", "debug", 3)
self.current_line = token['line']
# 检测表达式开始和结束
if token['text'] in {'(', '{', '['}:
self.inside_expression = True
elif token['text'] in {')', '}', ']'}:
self.inside_expression = 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:
if token['text'] in self.allowed_types:
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)
# 跟踪大括号深度
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
self.pos += 1
self.log("分析完成", "debug", 1)
self.log(f"找到的总变量数: {len(self.all_variables)}", "debug", 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
# 参数列表必须包含至少一个参数或void
if pos < len(self.tokens) and self.tokens[pos]['text'] == ')':
# 空参数列表
pos += 1
else:
# 非空参数列表
depth = 1
while pos < len(self.tokens) and depth > 0:
if self.tokens[pos]['text'] == '(':
depth += 1
elif self.tokens[pos]['text'] == ')':
depth -= 1
pos += 1
# 检测函数体开头的'{' (允许最多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):
self.log(">>> 进入函数定义处理", "debug", 2)
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.current_function = 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
param_names = [p['name'] for p in params] if params else []
# 查找函数体开头的'{'
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.in_function_body = False
self.brace_depth = 0
self.pos += 1
# 添加函数名到变量列表
func_info = {
'name': func_name,
'type': 'function',
'line': self.current_line,
'scope': 'function'
}
self.all_variables.append(func_info)
self.log(f"添加函数: {func_name}", "info")
self.log("<<< 退出函数定义处理", "debug", 2)
return param_names
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):
self.log(">>> 进入变量声明处理", "debug", 2)
self.log(f"当前token: {self.tokens[self.pos]['text']}", "debug", 3)
# 获取变量类型
var_type = self.tokens[self.pos]['text']
self.log(f"检测到变量声明类型: {var_type}", "debug")
self.pos += 1
# 处理指针声明
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '*':
var_type += '*'
self.pos += 1
var_names = []
current_line = self.current_line
# 处理变量名
while self.pos < len(self.tokens):
token = self.tokens[self.pos]
# 标识符 - 变量名
if token['type'] == 'IDENTIFIER' and not token['text'].isupper():
var_name = token['text']
# 跳过宏定义
if var_name not in self.macro_definitions:
self.log(f"找到变量名: {var_name}", "debug")
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'] == '*':
self.pos += 1
continue
# 结束声明
elif token['text'] == ';':
self.pos += 1
break
# 数组声明 - 跳过数组大小
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.log("跳过初始化表达式", "debug")
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
# 类型转换 - 跳过
elif token['text'] == '(' and self.pos + 1 < len(self.tokens):
# 尝试识别类型转换
next_token = self.tokens[self.pos + 1]
if next_token['text'] in self.allowed_types:
self.log(f"跳过类型转换: ({next_token['text']})", "debug")
# 跳过类型转换
self.pos += 2
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == ')':
self.pos += 1
continue
# 其他情况
self.log(f"跳过token: {token['text']} (类型: {token['type']})", "debug")
self.pos += 1
# 添加到局部变量 (跳过宏定义和参数)
for var_name in var_names:
# 检查是否在参数列表中
is_param = False
for param in self.parameters:
if param['name'] == var_name:
is_param = True
self.log(f"跳过参数变量: {var_name}", "debug")
break
if not is_param and var_name not in self.macro_definitions:
var_info = {
'type': var_type,
'name': var_name,
'line': current_line,
'scope': 'local'
}
self.local_vars.append(var_info)
self.all_variables.append(var_info)
self.log(f"添加局部变量: {var_type} {var_name} (行:{current_line})", "info")
self.log("<<< 退出变量声明处理", "debug", 2)
def _handle_identifier_use(self, token):
var_name = token['text']
line = token['line']
self.log(f"处理标识符: {var_name} (行:{line})", "debug", 3)
# 跳过宏定义(全大写)
if var_name in self.macro_definitions or var_name.isupper():
self.log(f"跳过宏定义: {var_name}", "debug")
return
# 跳过已声明的变量(局部变量、参数、函数名)
if var_name in self.variable_declarations:
self.log(f"跳过已声明变量: {var_name}", "debug")
return
# 跳过函数调用(函数名已经在函数调用处理中记录)
for call in self.function_calls:
if call['name'] == var_name:
self.log(f"跳过函数调用变量: {var_name}", "debug")
return
# 跳过控制结构
if var_name in self.control_structures:
self.log(f"跳过控制结构: {var_name}", "debug")
return
# 跳过类型别名
if var_name in self.type_aliases:
self.log(f"跳过类型别名: {var_name}", "debug")
return
# 跳过已经记录过的全局变量
if var_name in self.recorded_globals:
self.log(f"跳过已记录全局变量: {var_name}", "debug")
return
# 添加到全局变量
var_info = {
'name': var_name,
'line': line,
'scope': 'global'
}
self.global_vars.append(var_info)
self.all_variables.append(var_info)
self.recorded_globals.add(var_name)
self.log(f"添加全局变量: {var_name} (行:{line})", "info")
def _handle_function_call(self):
self.log(">>> 进入函数调用处理", "debug", 2)
# 提取函数名
func_name = self.tokens[self.pos]['text']
line = self.current_line
self.pos += 2 # 跳过函数名和 '('
# 提取参数
params = []
depth = 1
current_param = []
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())
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())
# 跳过 ')' 如果还在范围内
if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == ')':
self.pos += 1
# 确定返回类型
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()
# 添加到函数调用列表
func_info = {
'name': func_name,
'return_type': return_type,
'type': "function_call",
'params': ", ".join(params), # 将参数列表转换为字符串,用逗号分隔
'line': line,
'scope': 'call'
}
self.function_calls.append(func_info)
self.all_variables.append(func_info)
self.log(f"添加函数调用: {func_name} (行:{line})", "info")
self.log("<<< 退出函数调用处理", "debug", 2)
class FunctionParserApp:
def __init__(self, root):
self.root = root
self.root.title("C语言函数解析器 (内置解析器版)")
self.root.geometry("900x700")
self.setup_logging()
# 创建输入区域
input_frame = tk.LabelFrame(root, text="输入C语言函数体", padx=5, pady=5)
input_frame.pack(fill="both", expand=True, padx=10, pady=5)
self.input_text = scrolledtext.ScrolledText(input_frame, width=100, height=20)
self.input_text.pack(fill="both", expand=True, padx=5, pady=5)
# 按钮区域
btn_frame = tk.Frame(root)
btn_frame.pack(fill="x", padx=10, pady=5)
# 解析按钮
parse_btn = tk.Button(btn_frame, text="解析函数", command=self.parse_function, bg="#4CAF50", fg="white")
parse_btn.pack(side="left", padx=5)
# 保存日志按钮
save_log_btn = tk.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)
# 创建输出区域
output_frame = tk.LabelFrame(root, text="解析结果", padx=5, pady=5)
output_frame.pack(fill="both", expand=True, padx=10, pady=5)
self.output_text = scrolledtext.ScrolledText(output_frame, width=100, height=15)
self.output_text.pack(fill="both", expand=True, padx=5, pady=5)
self.output_text.config(state=tk.DISABLED)
# 日志区域
log_frame = tk.LabelFrame(root, text="日志信息", padx=5, pady=5)
log_frame.pack(fill="both", expand=True, padx=10, pady=5)
self.log_text = scrolledtext.ScrolledText(log_frame, width=100, height=8)
self.log_text.pack(fill="both", expand=True, padx=5, pady=5)
self.log_text.config(state=tk.DISABLED)
# 添加调试级别控制
debug_frame = tk.Frame(btn_frame)
debug_frame.pack(side="left", padx=10)
tk.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, 3], width=3).pack(side="left")
# 添加示例按钮
example_btn = tk.Button(btn_frame, text="加载示例", command=self.load_example)
example_btn.pack(side="right", padx=5)
# 示例函数体
self.example_code = """static void Diag21_PID_C9(U1 u1_a_num)
{
U1 u1_t_cmplt;
U1 u1_t_cnt;
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 */
}
}"""
def setup_logging(self):
"""配置日志系统"""
self.log_filename = f"parser_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
# 创建文件处理器并指定UTF-8编码
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)
# 添加控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
root_logger.addHandler(console_handler)
logging.info("应用程序启动")
def log_to_gui(self, message, level="info"):
"""将日志信息显示在GUI中"""
try:
self.log_text.config(state=tk.NORMAL)
timestamp = datetime.now().strftime("%H:%M:%S")
# 确保消息是字符串
if not isinstance(message, str):
message = str(message)
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:
# 如果GUI日志失败,回退到控制台日志
print(f"GUI日志错误: {str(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"
# 使用UTF-8编码保存文件
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.log_to_gui = self.log_to_gui
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):
"""增强版结果显示,包含所有变量信息"""
# 显示函数签名
if func_name:
self.output_text.insert(tk.END, "=== 函数签名 ===\n")
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']}")
# 添加参数到变量列表
param_info = {
'name': param['name'],
'type': param['type'],
'line': param['line'],
'scope': 'parameter'
}
self.log_to_gui(f"添加参数: {param['type']} {param['name']} (行:{param['line']})")
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")
self.output_text.insert(tk.END, "警告: 无法识别函数签名\n\n")
self.log_to_gui("无法识别函数签名", "warning")
# 显示所有找到的变量
self.output_text.insert(tk.END, "=== 所有变量分析 ===\n")
self.output_text.insert(tk.END, "类型 | 名称 | 作用域 | 行号\n")
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 func_name:
self.output_text.insert(tk.END, "=== 函数签名 ===\n")
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")
self.output_text.insert(tk.END, "警告: 无法识别函数签名\n\n")
self.log_to_gui("无法识别函数签名", "warning")
# 显示局部变量
if local_vars:
self.output_text.insert(tk.END, "=== 局部变量 ===\n")
for var in local_vars:
self.output_text.insert(tk.END, f"{var['type']} {var['name']} (行号: {var['line']})\n")
self.log_to_gui(f"找到局部变量: {var['type']} {var['name']}")
self.output_text.insert(tk.END, "\n")
else:
self.output_text.insert(tk.END, "未找到局部变量\n\n")
self.log_to_gui("未找到局部变量", "warning")
# 显示使用的全局变量
if global_vars:
self.output_text.insert(tk.END, "=== 使用的全局变量 ===\n")
for var in global_vars:
self.output_text.insert(tk.END, f"{var['name']} (行号: {var['line']})\n")
self.log_to_gui(f"找到全局变量: {var['name']}")
self.output_text.insert(tk.END, "\n")
else:
self.output_text.insert(tk.END, "未使用全局变量\n\n")
self.log_to_gui("未使用全局变量", "warning")
# 显示函数调用
if function_calls:
self.output_text.insert(tk.END, "=== 函数调用 ===\n")
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")
self.log_to_gui(f"找到函数调用: {func['name']}")
else:
self.output_text.insert(tk.END, "未调用任何函数\n\n")
self.log_to_gui("未调用任何函数", "warning")
# 显示统计信息
self.output_text.insert(tk.END, "=== 解析统计 ===\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, "\n")
# 添加变量统计
self.output_text.insert(tk.END, "=== 变量统计 ===\n")
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.insert(tk.END, "\n")
if __name__ == "__main__":
root = tk.Tk()
app = FunctionParserApp(root)
root.mainloop()
=== 函数签名 ===
函数名: Diag21_PID_C9
参数: U1 u1_a_num
=== 所有变量分析 ===
类型 | 名称 | 作用域 | 行号
--------------------------------------------------
参数 | u1_a_num | 参数 | 1
变量 | u1_t_cmplt | 全局 | 3
变量 | u1_t_cnt | 全局 | 4
变量 | u1_t_swrstcnt | 全局 | 6
函数调用 | u1_g_InspSoftwareVersion | 调用 | 10
函数调用 | vd_s_Diag21_U2ToU1 | 调用 | 12
=== 函数签名 ===
函数名: Diag21_PID_C9
参数: U1 u1_a_num
未找到局部变量
=== 使用的全局变量 ===
u1_t_cmplt (行号: 3)
u1_t_cnt (行号: 4)
u1_t_swrstcnt (行号: 6)
=== 函数调用 ===
函数名: u1_g_InspSoftwareVersion (行号: 10)
返回类型: U1
参数: u4_g_cmd, &u4_g_data, (U1)TRUE
--------------------------------------------------
函数名: vd_s_Diag21_U2ToU1 (行号: 12)
返回类型: void
参数: u2_g_buf, u1_g_data, (U1)DIAG21_PIDC9_FLAG
--------------------------------------------------
=== 解析统计 ===
局部变量数量: 0
使用的全局变量数量: 3
函数调用数量: 2
=== 变量统计 ===
参数数量: 1
局部变量数量: 0
全局变量数量: 3
函数调用数量: 2
总变量数量: 6
[13:43:54] 已加载示例函数体
[13:43:57] 开始解析函数体...
[13:43:57] 执行词法分析...
[13:43:57] 执行语法分析...
[13:43:57] [DEBUG1] 开始分析函数体
[13:43:57] [DEBUG2] 共收到 77 个token
[13:43:57] [DEBUG3] 处理token: static (类型:KEYWORD, 行:1)
[13:43:57] [DEBUG2] >>> 进入函数定义处理
[13:43:57] [DEBUG1] 添加函数: Diag21_PID_C9
[13:43:57] [DEBUG2] <<< 退出函数定义处理
[13:43:57] [DEBUG3] 处理token: U1 (类型:TYPE, 行:3)
[13:43:57] [DEBUG3] 处理token: u1_t_cmplt (类型:IDENTIFIER, 行:3)
[13:43:57] [DEBUG3] 处理标识符: u1_t_cmplt (行:3)
[13:43:57] [DEBUG1] 添加全局变量: u1_t_cmplt (行:3)
[13:43:57] [DEBUG3] 处理token: ; (类型:OPERATOR, 行:3)
[13:43:57] [DEBUG3] 处理token: U1 (类型:TYPE, 行:4)
[13:43:57] [DEBUG3] 处理token: u1_t_cnt (类型:IDENTIFIER, 行:4)
[13:43:57] [DEBUG3] 处理标识符: u1_t_cnt (行:4)
[13:43:57] [DEBUG1] 添加全局变量: u1_t_cnt (行:4)
[13:43:57] [DEBUG3] 处理token: ; (类型:OPERATOR, 行:4)
[13:43:57] [DEBUG3] 处理token: if (类型:KEYWORD, 行:6)
[13:43:57] [DEBUG3] 处理token: ( (类型:OPERATOR, 行:6)
[13:43:57] [DEBUG3] 处理token: ( (类型:OPERATOR, 行:6)
[13:43:57] [DEBUG3] 处理token: U1 (类型:TYPE, 行:6)
[13:43:57] [DEBUG3] 处理token: ) (类型:OPERATOR, 行:6)
[13:43:57] [DEBUG3] 处理token: DIAG_CNT_ZERO (类型:IDENTIFIER, 行:6)
[13:43:57] [DEBUG3] 处理标识符: DIAG_CNT_ZERO (行:6)
[13:43:57] [DEBUG1] 跳过宏定义: DIAG_CNT_ZERO
[13:43:57] [DEBUG3] 处理token: == (类型:OPERATOR, 行:6)
[13:43:57] [DEBUG3] 处理token: u1_t_swrstcnt (类型:IDENTIFIER, 行:6)
[13:43:57] [DEBUG3] 处理标识符: u1_t_swrstcnt (行:6)
[13:43:57] [DEBUG1] 添加全局变量: u1_t_swrstcnt (行:6)
[13:43:57] [DEBUG3] 处理token: ) (类型:OPERATOR, 行:6)
[13:43:57] [DEBUG3] 处理token: { (类型:OPERATOR, 行:7)
[13:43:57] [DEBUG3] 处理token: for (类型:KEYWORD, 行:8)
[13:43:57] [DEBUG3] 处理token: ( (类型:OPERATOR, 行:8)
[13:43:57] [DEBUG3] 处理token: u1_t_cnt (类型:IDENTIFIER, 行:8)
[13:43:57] [DEBUG3] 处理标识符: u1_t_cnt (行:8)
[13:43:57] [DEBUG1] 跳过已记录全局变量: u1_t_cnt
[13:43:57] [DEBUG3] 处理token: = (类型:OPERATOR, 行:8)
[13:43:57] [DEBUG3] 处理token: ( (类型:OPERATOR, 行:8)
[13:43:57] [DEBUG3] 处理token: U1 (类型:TYPE, 行:8)
[13:43:57] [DEBUG2] >>> 进入变量声明处理
[13:43:57] [DEBUG3] 当前token: U1
[13:43:57] [DEBUG1] 检测到变量声明类型: U1
[13:43:57] [DEBUG1] 跳过token: ) (类型: OPERATOR)
[13:43:57] [DEBUG1] 跳过token: DIAG21_ZERO (类型: IDENTIFIER)
[13:43:57] [DEBUG2] <<< 退出变量声明处理
[13:43:57] [DEBUG3] 处理token: u1_t_cnt (类型:IDENTIFIER, 行:8)
[13:43:57] [DEBUG3] 处理标识符: u1_t_cnt (行:8)
[13:43:57] [DEBUG1] 跳过已记录全局变量: u1_t_cnt
[13:43:57] [DEBUG3] 处理token: < (类型:OPERATOR, 行:8)
[13:43:57] [DEBUG3] 处理token: ( (类型:OPERATOR, 行:8)
[13:43:57] [DEBUG3] 处理token: U1 (类型:TYPE, 行:8)
[13:43:57] [DEBUG2] >>> 进入变量声明处理
[13:43:57] [DEBUG3] 当前token: U1
[13:43:57] [DEBUG1] 检测到变量声明类型: U1
[13:43:57] [DEBUG1] 跳过token: ) (类型: OPERATOR)
[13:43:57] [DEBUG1] 跳过token: DIAG21_PIDC9_FLAG (类型: IDENTIFIER)
[13:43:57] [DEBUG2] <<< 退出变量声明处理
[13:43:57] [DEBUG3] 处理token: u1_t_cnt (类型:IDENTIFIER, 行:8)
[13:43:57] [DEBUG3] 处理标识符: u1_t_cnt (行:8)
[13:43:57] [DEBUG1] 跳过已记录全局变量: u1_t_cnt
[13:43:57] [DEBUG3] 处理token: ++ (类型:OPERATOR, 行:8)
[13:43:57] [DEBUG3] 处理token: ) (类型:OPERATOR, 行:8)
[13:43:57] [DEBUG3] 处理token: { (类型:OPERATOR, 行:9)
[13:43:57] [DEBUG3] 处理token: u1_t_cmplt (类型:IDENTIFIER, 行:10)
[13:43:57] [DEBUG3] 处理标识符: u1_t_cmplt (行:10)
[13:43:57] [DEBUG1] 跳过已记录全局变量: u1_t_cmplt
[13:43:57] [DEBUG3] 处理token: = (类型:OPERATOR, 行:10)
[13:43:57] [DEBUG3] 处理token: u1_g_InspSoftwareVersion (类型:IDENTIFIER, 行:10)
[13:43:57] [DEBUG2] >>> 进入函数调用处理
[13:43:57] [DEBUG1] 添加函数调用: u1_g_InspSoftwareVersion (行:10)
[13:43:57] [DEBUG2] <<< 退出函数调用处理
[13:43:57] [DEBUG3] 处理token: ; (类型:OPERATOR, 行:10)
[13:43:57] [DEBUG3] 处理token: } (类型:OPERATOR, 行:11)
[13:43:57] [DEBUG3] 处理token: vd_s_Diag21_U2ToU1 (类型:IDENTIFIER, 行:12)
[13:43:57] [DEBUG2] >>> 进入函数调用处理
[13:43:57] [DEBUG1] 添加函数调用: vd_s_Diag21_U2ToU1 (行:12)
[13:43:57] [DEBUG2] <<< 退出函数调用处理
[13:43:57] [DEBUG3] 处理token: ; (类型:OPERATOR, 行:12)
[13:43:57] [DEBUG3] 处理token: } (类型:OPERATOR, 行:13)
[13:43:57] [DEBUG3] 处理token: else (类型:KEYWORD, 行:14)
[13:43:57] [DEBUG3] 处理token: { (类型:OPERATOR, 行:15)
[13:43:57] [DEBUG3] 处理token: } (类型:OPERATOR, 行:17)
[13:43:57] [DEBUG3] 处理token: } (类型:OPERATOR, 行:18)
[13:43:57] [DEBUG1] 分析完成
[13:43:57] [DEBUG1] 找到的总变量数: 6
[13:43:57] 生成解析报告...
[13:43:57] 添加参数: U1 u1_a_num (行:1)
[13:43:57] 未找到局部变量
[13:43:57] 找到全局变量: u1_t_cmplt
[13:43:57] 找到全局变量: u1_t_cnt
[13:43:57] 找到全局变量: u1_t_swrstcnt
[13:43:57] 找到函数调用: u1_g_InspSoftwareVersion
[13:43:57] 找到函数调用: vd_s_Diag21_U2ToU1
[13:43:57] 解析完成!
发现变量都没有找全,而且局部变量被识别为了全局变量