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) => _symbols.TryAdd(symbol.SymbolName, symbol);
///
/// 尝试从符号表极其父符号表查找符号
///
/// 需要查找的符号名称
/// 查找到的符号
/// 是否查找到符号
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;
}
private IEnumerable GetParents()
{
SymbolTable? now = _parent;
while (now is not null)
{
yield return now;
now = now._parent;
}
}
}