Canon/Canon.Core/SemanticParser/SymbolTable.cs
Lan_G ccd1899739 feat: symbol-table & type checker (#14)
Reviewed-on: PostGuard/Canon#14
Co-authored-by: Lan_G <2911328695@qq.com>
Co-committed-by: Lan_G <2911328695@qq.com>
2024-03-16 11:05:38 +08:00

108 lines
2.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}