2024-04-07 16:10:34 +08:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
|
|
|
|
namespace Canon.Core.SemanticParser;
|
2024-04-07 16:10:34 +08:00
|
|
|
|
|
2024-03-16 11:05:38 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
///符号表类
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class SymbolTable
|
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 符号表
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly Dictionary<string, Symbol> _symbols = [];
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 类型表
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly TypeTable _typeTable = new();
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 父符号表
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly SymbolTable? _parent;
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// 获得当前符号表的所有父符号表
|
2024-03-16 11:05:38 +08:00
|
|
|
|
/// </summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
public IEnumerable<SymbolTable> ParentTables => GetParents();
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
public SymbolTable() {}
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
private SymbolTable(SymbolTable parent)
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
_parent = parent;
|
2024-03-16 11:05:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
public SymbolTable CreateChildTable()
|
|
|
|
|
{
|
|
|
|
|
return new SymbolTable(this);
|
|
|
|
|
}
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// 尝试向符号表中添加符号
|
2024-03-16 11:05:38 +08:00
|
|
|
|
/// </summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// <param name="symbol">欲添加的符号</param>
|
|
|
|
|
/// <returns>是否添加成功</returns>
|
|
|
|
|
public bool TryAddSymbol(Symbol symbol) => _symbols.TryAdd(symbol.SymbolName, symbol);
|
2024-03-16 11:05:38 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// 尝试从符号表极其父符号表查找符号
|
2024-03-16 11:05:38 +08:00
|
|
|
|
/// </summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// <param name="name">需要查找的符号名称</param>
|
|
|
|
|
/// <param name="symbol">查找到的符号</param>
|
|
|
|
|
/// <returns>是否查找到符号</returns>
|
|
|
|
|
public bool TryGetSymbol(string name, [NotNullWhen(true)] out Symbol? symbol)
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
if (_symbols.TryGetValue(name, out symbol))
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2024-04-07 16:10:34 +08:00
|
|
|
|
|
|
|
|
|
foreach (SymbolTable table in ParentTables)
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
if (table._symbols.TryGetValue(name, out symbol))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2024-03-16 11:05:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
symbol = null;
|
|
|
|
|
return false;
|
2024-03-16 11:05:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// 从符号表极其父表的类型表中查找类型
|
2024-03-16 11:05:38 +08:00
|
|
|
|
/// </summary>
|
2024-04-07 16:10:34 +08:00
|
|
|
|
/// <param name="typeName">欲查找的类型名称</param>
|
|
|
|
|
/// <param name="type">查找到的类型</param>
|
|
|
|
|
/// <returns>是否查找到类型</returns>
|
|
|
|
|
public bool TryGetType(string typeName, [NotNullWhen(true)] out PascalType? type)
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
if (_typeTable.TryGetType(typeName, out type))
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
return true;
|
2024-03-16 11:05:38 +08:00
|
|
|
|
}
|
2024-04-07 16:10:34 +08:00
|
|
|
|
|
|
|
|
|
foreach (SymbolTable parent in ParentTables)
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
if (parent._typeTable.TryGetType(typeName, out type))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2024-03-16 11:05:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
type = null;
|
|
|
|
|
return false;
|
2024-03-16 11:05:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 10:18:49 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 尝试获得父符号表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="parent">获得的父符号表</param>
|
|
|
|
|
/// <returns>是否存在父符号表</returns>
|
|
|
|
|
public bool TryGetParent([NotNullWhen(true)] out SymbolTable? parent)
|
|
|
|
|
{
|
|
|
|
|
if (_parent is null)
|
|
|
|
|
{
|
|
|
|
|
parent = null;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parent = _parent;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-07 16:10:34 +08:00
|
|
|
|
private IEnumerable<SymbolTable> GetParents()
|
2024-03-16 11:05:38 +08:00
|
|
|
|
{
|
2024-04-07 16:10:34 +08:00
|
|
|
|
SymbolTable? now = _parent;
|
|
|
|
|
|
|
|
|
|
while (now is not null)
|
|
|
|
|
{
|
|
|
|
|
yield return now;
|
|
|
|
|
now = now._parent;
|
|
|
|
|
}
|
2024-03-16 11:05:38 +08:00
|
|
|
|
}
|
|
|
|
|
}
|