C++ 如何设计符号表以支持函数重载?

C++ 如何设计符号表以支持函数重载?,c++,data-structures,compiler-construction,C++,Data Structures,Compiler Construction,我正在创建一个编译器,并在语义分析阶段苦苦挣扎。我不知道如何处理符号表中的函数重载。我似乎找不到任何资源来描述这个特殊的问题。我认为名称混乱必须在某个地方使用,我非常确定AST中的类型应该转换为字符串 允许在同一范围内声明具有相同名称的多个函数,只要每个声明具有不同的参数集。下面的代码片段是我的语言中的一个示例(它与Swift非常相似) func添加(a:Int,b:Int){ 返回a+b; } func add(a:浮点,b:浮点){ 返回a+b; } 我不知道如何在符号表中存储函数。这是我

我正在创建一个编译器,并在语义分析阶段苦苦挣扎。我不知道如何处理符号表中的函数重载。我似乎找不到任何资源来描述这个特殊的问题。我认为名称混乱必须在某个地方使用,我非常确定AST中的类型应该转换为字符串

允许在同一范围内声明具有相同名称的多个函数,只要每个声明具有不同的参数集。下面的代码片段是我的语言中的一个示例(它与Swift非常相似)

func添加(a:Int,b:Int){
返回a+b;
}
func add(a:浮点,b:浮点){
返回a+b;
}
我不知道如何在符号表中存储函数。这是我的符号表数据结构的一部分

struct-Symbol{};
结构变量final:Symbol{
std::字符串类型;
};
使用FuncParams=std::vector;
结构函数final:Symbol{
std::字符串ret;
FuncParams-params;
};
使用Table=std::无序的_图;
结构范围{
表格;
Scope*parent=nullptr;
};
使用Scopes=std::vector;
我可以使用
std::unordered_multimap
并将函数名
add
存储为键,并将参数名存储在symbol对象中。我可以使用一个
std::unordered_map
并存储带有参数
add_Int_Int
装饰的函数名作为键,并将参数名存储在symbol对象中

另外,
Symbol
应该是一个基类,还是应该将各种符号放在一个
Symbol
对象中?我见过许多使用
enum
区分函数、变量和类型声明的示例,但函数存储返回类型和参数类型。我应该使用带标签的接头吗

我觉得有一种聪明而简单的方法可以解决这个问题,但我就是找不到

更新:


我采纳了@NeilButterworth的建议,使用未混合的函数名作为符号键,这似乎是可行的方法(但我知道什么!)。如果您能回答我的其他问题或就此主题提供一些建议,我们将不胜感激。

解决方案是按照@NeilButtworth在评论中所说的去做。但您需要围绕创建“兼容”类型树构建一些逻辑。因为您希望函数具有兼容的参数。如果一个类型是另一个类型的子类型,如
isTypeCompatible(actualType,formalType)
,我建议使用一些返回函数。然后,您可以尝试并找到具有与调用匹配的最特定签名的函数。因此
f(5)
应该调用
f(int)
,因为5是显式int,但只是隐式浮点。实现这一点的一种方法是查看哪个签名使类型树与给定类型和形式类型之间的距离最小化


编辑:通过“兼容”类型树,它本质上与继承相同。比如,如果我们有g(float)
g(5)
的话,它是如何工作的,因为int文本可以转换为float文本。类型树比自定义C++类更容易构建,因为AST应该已经在解析和类型检查时构建了。可能还有其他方法,但是C++相对简单。还有其他的方法,关于这个问题可能有很多研究论文(免费提供和付费)。@某个程序员,你能详细说明一下吗?考虑这个函数<代码> FUNC F(n:FLULT){} /CUD>和这个调用:<代码> f(5)< /代码>。如果我在呼叫站点的符号表中查找
f_Int
,我将找不到任何内容。我想找到
f_Float
,然后查找从
Int
Float
的转换。你不想在这里弄乱名称-查找命名函数,不考虑参数,然后遍历列表,查找与参数匹配的或存在conversion@NeilButterworth我自己也开始得出这个结论。谢谢你的意见!