using System.Diagnostics.CodeAnalysis; namespace Canon.Core.SemanticParser; /// ///符号表类 /// public class SymbolTable { /// /// 符号表 /// private readonly Dictionary _symbols = []; /// /// 类型表 /// private readonly TypeTable _typeTable = new(); /// /// 父符号表 /// private readonly SymbolTable? _parent; /// /// 获得当前符号表的所有父符号表 /// public IEnumerable ParentTables => GetParents(); public SymbolTable() {} private SymbolTable(SymbolTable parent) { _parent = parent; } public SymbolTable CreateChildTable() { return new SymbolTable(this); } /// /// 尝试向符号表中添加符号 /// /// 欲添加的符号 /// 是否添加成功 public bool TryAddSymbol(Symbol symbol) { if (_symbols.ContainsKey(symbol.SymbolName)) { return false; } _symbols.Add(symbol.SymbolName, symbol); return true; } /// /// 尝试从符号表极其父符号表查找符号 /// /// 需要查找的符号名称 /// 查找到的符号 /// 是否查找到符号 public bool TryGetSymbol(string name, [NotNullWhen(true)] out Symbol? symbol) { if (_symbols.TryGetValue(name, out symbol)) { return true; } foreach (SymbolTable table in ParentTables) { if (table._symbols.TryGetValue(name, out symbol)) { return true; } } symbol = null; return false; } /// /// 从符号表极其父表的类型表中查找类型 /// /// 欲查找的类型名称 /// 查找到的类型 /// 是否查找到类型 public bool TryGetType(string typeName, [NotNullWhen(true)] out PascalType? type) { if (_typeTable.TryGetType(typeName, out type)) { return true; } foreach (SymbolTable parent in ParentTables) { if (parent._typeTable.TryGetType(typeName, out type)) { return true; } } type = null; return false; } /// /// 尝试获得父符号表 /// /// 获得的父符号表 /// 是否存在父符号表 public bool TryGetParent([NotNullWhen(true)] out SymbolTable? parent) { if (_parent is null) { parent = null; return false; } parent = _parent; return true; } private IEnumerable GetParents() { SymbolTable? now = _parent; while (now is not null) { yield return now; now = now._parent; } } }