PHP 之局部变量与全局变量的交错(一)嵌套for循环中的变量

本文探讨了在PHP中循环嵌套时容易出现的错误,并提供了避免此类问题的方法,即尽量将每次for循环的自增变量名字区分开,以及推荐使用foreach结构来替代传统的for循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      相信很多从c++/java/c#等过来的同学,可能会犯这样的错误:

<?php
  for($i=0;$i<9;$i++)
{
    #some code
    #many many code!...
    for($i=0;$i<8;$i++)
     {
          #some my ugly code
      }
}
?>

外面一个大的for循环,写了很多代码以后,又要一个循环,大家想都不想又扔个i,我们在其他语言都是这么干的,但是在php这样干以后,你会发现,代码变成死循环了!究其原因是什么呢?

   原来for语句并不是函数,只是一种语句形式,在php里面,两个i都被当作了全局变量,每次运行到完里面的循环,i都被重新赋值为7,当然永远都跳不出循环了。

    我的解决办法是尽量将每次for循环的自增变量名字区分开,这样可以极大的避免这种问题。并且尽量使用foreach.

我在做个C语言函数的解析工具,希望能够正确识别输入代码中的局部变量全局变量,调用函数,数组,结构体等,但是我的代码无法正确识别,请帮我找到问题并修正。代码为: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.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.local_vars = [] # 局部变量列表 self.struct_tags = set() # 存储识别的结构体标签 self.recorded_locals = set() # 跟踪已记录的局部变量 self.recorded_globals = set() self.recorded_params = 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') # 添加结构体支持 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 += 1 # 跳过结构体标签 # 检测函数定义 if token['text'] in self.storage_classes or token['text'] in self.allowed_types: if self._is_function_definition(): self._handle_function_definition() continue self.pos += 1 # 第二步:识别变量声明和函数调用 self.pos = 0 while self.pos < len(self.tokens): token = self.tokens[self.pos] self.current_line = token['line'] # 跟踪大括号深度 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.allowed_types or token['text'] in self.storage_classes: 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 self.pos += 1 # 第三步:识别全局变量(函数体内使用但未声明的变量) self._identify_global_vars() 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 _identify_global_vars(self): """识别全局变量(函数体内使用但未声明的变量)""" self.pos = 0 while self.pos < len(self.tokens): token = self.tokens[self.pos] # 只关注标识符 if token['type'] == 'IDENTIFIER': var_name = token['text'] # 跳过已处理的标识符 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, any(fc['name'] == var_name for fc in self.function_calls) # 跳过函数调用 ) if not any(skip_conditions): # 检查是否在函数调用参数中 in_function_call = False for fc in self.function_calls: if var_name in fc['params']: in_function_call = True break if not in_function_call and var_name not in self.recorded_globals: self.global_vars.append({ 'name': var_name, 'line': token['line'], 'scope': 'global', 'is_struct': var_name in self.struct_tags, 'is_array': False }) self.recorded_globals.add(var_name) self.variable_declarations[var_name] = True self.pos += 1 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_params.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'] is_array = False is_struct = False # 处理结构体声明 if var_type == 'struct': is_struct = True # 收集结构体类型名 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 = [] array_dims = [] # 处理变量名和声明 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'] == '[': is_array = True # 记录数组维度 dims = [] while self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == '[': self.pos += 1 dim = "" while self.pos < len(self.tokens) and self.tokens[self.pos]['text'] != ']': dim += self.tokens[self.pos]['text'] self.pos += 1 if self.pos < len(self.tokens) and self.tokens[self.pos]['text'] == ']': self.pos += 1 dims.append(dim) array_dims = dims 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: var_info = { 'type': var_type, 'name': var_name, 'line': current_line, 'is_struct': is_struct, 'is_array': is_array, 'array_dims': array_dims if is_array else None } # 更精确地判断变量作用域 if self.in_function and self.brace_depth > 0: # 在函数体内 var_info['scope'] = 'local' self.local_vars.append(var_info) self.recorded_locals.add(var_name) else: # 在函数体外 var_info['scope'] = 'global' self.global_vars.append(var_info) 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 # 确定返回类型 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("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) # 进度条 self.progress = ttk.Progressbar(btn_frame, orient="horizontal", length=300, mode="determinate") self.progress.pack(side="left", padx=10, fill="x", expand=True) # 示例按钮 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; U2 u2_array[10][20]; 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 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.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, "-" * 60 + "\n") # 显示参数 for param in func_params: self.output_text.insert(tk.END, f"参数 | {param['name']} | 参数 | {param['line']} | 基本类型\n") # 显示局部变量 for var in local_vars: category = "结构体" if var.get('is_struct', False) else "基本类型" self.output_text.insert(tk.END, f"变量 | {var['name']} | 局部 | {var['line']} | {category}\n") # 显示全局变量 for var in global_vars: # 检查是否是结构体变量 category = "结构体" if var.get('is_struct', False) else "基本类型" self.output_text.insert(tk.END, f"变量 | {var['name']} | 全局 | {var['line']} | {category}\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") # 基本类型局部变量 basic_locals = [v for v in local_vars if not v.get('is_struct', False) and not v.get('is_array', False)] if basic_locals: self.output_text.insert(tk.END, "基本类型变量:\n") for var in basic_locals: self.output_text.insert(tk.END, f"{var['type']} {var['name']} (行号: {var['line']})\n") # 数组类型局部变量 array_locals = [v for v in local_vars if v.get('is_array', False)] if array_locals: self.output_text.insert(tk.END, "\n数组变量:\n") for var in array_locals: dims = "".join([f"[{dim}]" for dim in var['array_dims']]) if var['array_dims'] else "[]" self.output_text.insert(tk.END, f"{var['type']} {var['name']}{dims} (行号: {var['line']})\n") # 结构体局部变量 struct_locals = [v for v in local_vars if v.get('is_struct', False)] if struct_locals: self.output_text.insert(tk.END, "\n结构体变量:\n") for var in struct_locals: 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") # 基本类型全局变量 basic_globals = [v for v in global_vars if not v.get('is_struct', False) and not v.get('is_array', False)] if basic_globals: self.output_text.insert(tk.END, "基本类型变量:\n") for var in basic_globals: self.output_text.insert(tk.END, f"{var['name']} (行号: {var['line']})\n") # 数组类型全局变量 array_globals = [v for v in global_vars if v.get('is_array', False)] if array_globals: self.output_text.insert(tk.END, "\n数组变量:\n") for var in array_globals: dims = "".join([f"[{dim}]" for dim in var['array_dims']]) if var['array_dims'] else "[]" self.output_text.insert(tk.END, f"{var['name']}{dims} (行号: {var['line']})\n") # 结构体全局变量 struct_globals = [v for v in global_vars if v.get('is_struct', False)] if struct_globals: self.output_text.insert(tk.END, "\n结构体变量:\n") for var in struct_globals: 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") # 结构体统计 struct_locals = [v for v in local_vars if v.get('is_struct', False)] struct_globals = [v for v in global_vars if v.get('is_struct', False)] self.output_text.insert(tk.END, f"结构体变量数量: {len(struct_locals) + len(struct_globals)}\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 | 基本类型 变量 | Diag21_PID_C9 | 全局 | 1 | 基本类型 变量 | u1_t_cmplt | 全局 | 1 | 基本类型 变量 | u1_t_cnt | 全局 | 4 | 基本类型 变量 | u2_array | 全局 | 6 | 基本类型 变量 | u1_t_swrstcnt | 全局 | 8 | 基本类型 变量 | u1_t_cnt | 全局 | 8 | 基本类型 变量 | sensor | 全局 | 5 | 基本类型 函数调用 | u1_g_InspSoftwareVersion | 调用 | 12 | 函数 函数调用 | vd_s_Diag21_U2ToU1 | 调用 | 14 | 函数 未找到局部变量 === 使用的全局变量 === 基本类型变量: Diag21_PID_C9 (行号: 1) u1_t_cmplt (行号: 1) u1_t_cnt (行号: 4) u1_t_swrstcnt (行号: 8) u1_t_cnt (行号: 8) sensor (行号: 5) 数组变量: u2_array[10][20] (行号: 6) === 函数调用 === 函数名: u1_g_InspSoftwareVersion (行号: 12) 返回类型: U1 参数: u4_g_cmd, &u4_g_data, (U1)TRUE 函数名: vd_s_Diag21_U2ToU1 (行号: 14) 返回类型: void 参数: u2_g_buf, u1_g_data, (U1)DIAG21_PIDC9_FLAG === 解析统计 === 参数数量: 1 局部变量数量: 0 全局变量数量: 7 函数调用数量: 2 结构体变量数量: 0 总变量数量: 10
最新发布
07-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值