ccd1899739
Reviewed-on: PostGuard/Canon#14 Co-authored-by: Lan_G <2911328695@qq.com> Co-committed-by: Lan_G <2911328695@qq.com>
108 lines
2.9 KiB
C#
108 lines
2.9 KiB
C#
using Canon.Core.Exceptions;
|
||
|
||
namespace Canon.Core.SemanticParser;
|
||
/// <summary>
|
||
///符号表类
|
||
/// </summary>
|
||
public class SymbolTable
|
||
{
|
||
public Dictionary<string, SymbolTableEntry> Entries;
|
||
|
||
public TypeTable TypesTable; //当前符号表对应的类型表
|
||
|
||
public SymbolTable? PreTable; //直接外围符号表
|
||
|
||
public SymbolTable()
|
||
{
|
||
Entries = new Dictionary<string, SymbolTableEntry>();
|
||
TypesTable = new TypeTable();
|
||
PreTable = null;
|
||
}
|
||
|
||
public SymbolTable(SymbolTable preTable)
|
||
{
|
||
Entries = new Dictionary<string, SymbolTableEntry>();
|
||
TypesTable = new TypeTable();
|
||
PreTable = preTable;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 向符号表里插入一个表项
|
||
/// </summary>
|
||
public void AddEntry(string idName, IdentifierType type, bool isConst, bool isVarParam)
|
||
{
|
||
if (Check(idName))
|
||
{
|
||
throw new SemanticException("failed to insert to SymbolTable! " + idName + " is defined repeatedly");
|
||
}
|
||
|
||
Entries.Add(idName, new SymbolTableEntry(idName, type, isConst, isVarParam));
|
||
}
|
||
|
||
public void AddEntry(string idName, IdentifierType type, SymbolTable subTable)
|
||
{
|
||
if (Check(idName))
|
||
{
|
||
throw new SemanticException("failed to insert to SymbolTable! " + idName + " is defined repeatedly");
|
||
}
|
||
|
||
Entries.Add(idName, new SymbolTableEntry(idName, type, subTable));
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
///检查符号表,看是否有变量重复声明
|
||
/// </summary>
|
||
/// <param name="idName">查询的id名称</param>
|
||
/// <returns>如果变量重复声明,返回true</returns>
|
||
public bool Check(string idName)
|
||
{
|
||
return Entries.ContainsKey(idName);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在符号表里查找,看当前引用变量是否声明
|
||
/// </summary>
|
||
/// <param name="idName">查询的id名称</param>
|
||
/// <returns>如果有定义,返回true</returns>
|
||
public bool Find(string idName)
|
||
{
|
||
if (Entries.ContainsKey(idName))
|
||
{
|
||
return true;
|
||
}
|
||
if (PreTable is not null && PreTable.Entries.ContainsKey(idName))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
throw new SemanticException("identifier "+ idName + " is not defined!");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过id名获取id的类型
|
||
/// </summary>
|
||
/// <param name="idName">id名字</param>
|
||
/// <returns>id在符号表里的类型</returns>
|
||
public IdentifierType GetIdTypeByName(string idName)
|
||
{
|
||
if (Entries.ContainsKey(idName))
|
||
{
|
||
return Entries[idName].Type;
|
||
}
|
||
if (PreTable is not null && PreTable.Entries.ContainsKey(idName))
|
||
{
|
||
return PreTable.Entries[idName].Type;
|
||
}
|
||
|
||
throw new SemanticException("identifier "+ idName + " is not defined!");
|
||
}
|
||
|
||
|
||
|
||
public bool IsConst(string idName)
|
||
{
|
||
return Find(idName) && Entries[idName].IsConst;
|
||
}
|
||
}
|