//! 作用域解析器 use crate::parser::{Clause, Expression}; use std::collections::{HashMap, HashSet}; /// 作用域错误 #[derive(Debug, Clone)] pub struct ScopeError { pub message: String, pub location: Option, } /// 作用域 #[derive(Debug, Clone)] struct Scope { /// 当前作用域中定义的符号 symbols: HashSet, /// 父作用域 parent: Option>, } impl Scope { fn new() -> Self { Self { symbols: HashSet::new(), parent: None, } } fn with_parent(parent: Scope) -> Self { Self { symbols: HashSet::new(), parent: Some(Box::new(parent)), } } fn define(&mut self, name: String) { self.symbols.insert(name); } fn resolve(&self, name: &str) -> bool { if self.symbols.contains(name) { return true; } if let Some(parent) = &self.parent { return parent.resolve(name); } false } } /// 作用域解析器 pub struct ScopeResolver { current_scope: Scope, errors: Vec, } impl ScopeResolver { pub fn new() -> Self { Self { current_scope: Scope::new(), errors: Vec::new(), } } /// 解析条款 pub fn resolve_clause(&mut self, clause: &Clause) -> Result<(), Vec> { // 1. 定义参数 for param in &clause.parameters { self.current_scope.define(param.name.clone()); } // 2. 检查谓词 for predicate in &clause.predicates { // 进入新作用域 let parent_scope = std::mem::replace(&mut self.current_scope, Scope::new()); self.current_scope = Scope::with_parent(parent_scope); // 定义谓词参数 for (param_name, _param_ty) in &predicate.params { self.current_scope.define(param_name.clone()); } // 解析谓词体 self.resolve_expression(&predicate.body, &predicate.name); // 退出作用域 if let Some(parent) = self.current_scope.parent.take() { self.current_scope = *parent; } } // 3. 检查依赖 for dep in &clause.depends_on { // 这里应该检查依赖的条款是否存在 // 简化实现,假设所有依赖都存在 let _ = dep; } if self.errors.is_empty() { Ok(()) } else { Err(self.errors.clone()) } } /// 解析表达式 fn resolve_expression(&mut self, expr: &Expression, context: &str) { match expr { Expression::Variable(name) => { if !self.current_scope.resolve(name) { self.errors.push(ScopeError { message: format!("Undefined variable: {}", name), location: Some(context.to_string()), }); } } Expression::Binary { left, right, .. } => { self.resolve_expression(left, context); self.resolve_expression(right, context); } Expression::Unary { operand, .. } => { self.resolve_expression(operand, context); } Expression::Call { name, args } => { // 检查函数是否存在 if !self.current_scope.resolve(name) { self.errors.push(ScopeError { message: format!("Undefined function: {}", name), location: Some(context.to_string()), }); } // 解析参数 for arg in args { self.resolve_expression(arg, context); } } Expression::If { condition, then_branch, else_branch } => { self.resolve_expression(condition, context); self.resolve_expression(then_branch, context); if let Some(else_br) = else_branch { self.resolve_expression(else_br, context); } } Expression::Block(statements) => { // 处理代码块:创建新作用域并解析块内语句 // 1. 创建新的子作用域 let current_scope = self.current_scope.clone(); self.current_scope = Scope::with_parent(current_scope); // 2. 解析块内的每个语句 // Statement和Expression是不同的类型,需要分别处理 // 这里简化处理:只记录作用域切换 let _ = statements; // 避免未使用警告 // 3. 恢复父作用域 if let Some(parent) = self.current_scope.parent.take() { self.current_scope = *parent; } } Expression::Literal(_) => { // 字面量不需要解析 } } } } impl Default for ScopeResolver { fn default() -> Self { Self::new() } } /// 依赖图 pub struct DependencyGraph { /// 条款依赖关系 dependencies: HashMap>, } impl DependencyGraph { pub fn new() -> Self { Self { dependencies: HashMap::new(), } } /// 添加条款 pub fn add_clause(&mut self, clause_id: String, depends_on: Vec) { self.dependencies.insert(clause_id, depends_on); } /// 检测循环依赖 pub fn detect_cycles(&self) -> Vec> { let mut cycles = Vec::new(); let mut visited = HashSet::new(); let mut path = Vec::new(); for clause_id in self.dependencies.keys() { if !visited.contains(clause_id) { self.dfs_cycle_detection(clause_id, &mut visited, &mut path, &mut cycles); } } cycles } fn dfs_cycle_detection( &self, current: &str, visited: &mut HashSet, path: &mut Vec, cycles: &mut Vec>, ) { if path.contains(¤t.to_string()) { // 找到循环 let cycle_start = path.iter().position(|x| x == current) .expect("Cycle start position not found"); cycles.push(path[cycle_start..].to_vec()); return; } if visited.contains(current) { return; } visited.insert(current.to_string()); path.push(current.to_string()); if let Some(deps) = self.dependencies.get(current) { for dep in deps { self.dfs_cycle_detection(dep, visited, path, cycles); } } path.pop(); } } impl Default for DependencyGraph { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; use crate::parser::{Parameter, Type, ClauseLevel}; #[test] fn test_scope_resolver() { let mut resolver = ScopeResolver::new(); let clause = Clause { id: "TEST".to_string(), level: ClauseLevel::Eternal, title: "Test".to_string(), parameters: vec![Parameter { name: "x".to_string(), ty: Type::U64, value: crate::parser::Literal::Int(42), description: None, }], predicates: vec![], obligations: vec![], depends_on: vec![], }; assert!(resolver.resolve_clause(&clause).is_ok()); } #[test] fn test_dependency_graph() { let mut graph = DependencyGraph::new(); graph.add_clause("A".to_string(), vec!["B".to_string()]); graph.add_clause("B".to_string(), vec!["C".to_string()]); graph.add_clause("C".to_string(), vec![]); let cycles = graph.detect_cycles(); assert_eq!(cycles.len(), 0); } #[test] fn test_cycle_detection() { let mut graph = DependencyGraph::new(); graph.add_clause("A".to_string(), vec!["B".to_string()]); graph.add_clause("B".to_string(), vec!["C".to_string()]); graph.add_clause("C".to_string(), vec!["A".to_string()]); let cycles = graph.detect_cycles(); assert!(!cycles.is_empty()); } }