如何避免符号表查找中的歧义?

问题描述

我有一个相当基本的符号表来将标识符映射到一个符号,存储 VariableSymbols、MethodSymbols、BuiltInTypeSymbols 等。这对我的简单解释器来说效果很好。但是现在我想实现更高级的符号类型,例如元组(比如 - TupleSymbol),它存储了一个 BuiltInTypes 数组。

我可以轻松实现一个 TupleSymbol 并将其存储在表中,但我已经意识到继续使用我当前的映射到符号方法来存储类型最终会导致在符号表查找时出现很多不明确的符号类型.例如,如果我想将一个元组分配给一个名为“test”的元组变量,在赋值操作中,我必须检查表中存储的标识符“test”的符号是 TupleSymbol 还是 BuiltInTypeSymbol,然后我必须对我要分配给它的值执行相同的操作。

有没有更好的方法来实现符号表?例如,最好在符号表范围内有多个区域分别存储每种类型的符号,即 std::map<:string methodsymbol> 用于方法, std::map<:string varsymbol> 用于变量?

编辑

这里有一些代码可以帮助可视化我当前的设计。请注意符号表映射 symbolTable 如何使用基本 Symbol 类。

class BuiltInTypeSymbol;
class Symbol {
    public:
       BuiltInTypeSymbol* type;
       std::string name;
       Symbol(std::string inname,BuiltInTypeSymbol* intype) : name(inname),type(intype){}
};

class BuiltInTypeSymbol : public Symbol {
    public:
       BuiltInTypeSymbol(std::string inname) : Symbol(inname,this) {}
}

class VarSymbol : public Symbol {
    public:
       VarSymbol(std::string inname,BuiltInTypeSymbol* typesymbol) : Symbol(inname,typesymbol) {}
}

BuiltInTypeSymbol* intType = new BuiltInTypeSymbol("int");
BuiltInTypeSymbol* floatType = new BuiltInTypeSymbol("float");

std::map<std::string,Symbol*> symbolTable = {
     {intType->name,intType},// registering int type
     {floatType->name,floatType},// registering float type
     {"a",new VarSymbol("a",intType)} // registering test variable "a" of type int
};

解决方法

如果您允许不同类型的符号名称重复,正如大多数语言所允许的那样,例如变量和函数的名称相同,您需要为每种类型使用不同的 map

此外,您可能还需要迭代某些符号类型,例如内置符号 - 最好也为它们创建地图。