如何避免符号 table 查找中的歧义?
How to avoid ambiguity within symbol table lookups?
我有一个相当基本的符号 table 用于将标识符映射到符号,存储 VariableSymbols、MethodSymbols、BuiltInTypeSymbols 等。这对我的简单解释器来说效果很好。但是现在我想实现更高级的符号类型,例如存储 BuiltInTypes 数组的元组(比如 - TupleSymbol)。
我可以轻松实现一个 TupleSymbol 并将其存储在 table 中,但我意识到继续使用我当前的映射到符号存储类型的方法最终会导致很多歧义符号 table 查找时的符号类型。例如,如果我想将元组分配给名为“test”的元组变量,则在分配操作中,我将必须检查存储在 table 中用于标识符“test”的 Symbol 是 TupleSymbol 还是BuiltInTypeSymbol,我将不得不为我想分配给它的值做同样的事情。
是否有更好的方法来实现符号 table?例如,最好在符号 table 范围内有多个区域分别存储每种类型的符号,即 std::map 用于方法和 std::map 对于变量?
编辑
这里有一些代码可以帮助可视化我当前的设计。请注意符号 table 映射 symbolTable
如何使用基本符号 class.
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
。
您可能还需要迭代某些符号类型,例如内置符号 - 最好也为它们创建一个地图。
我有一个相当基本的符号 table 用于将标识符映射到符号,存储 VariableSymbols、MethodSymbols、BuiltInTypeSymbols 等。这对我的简单解释器来说效果很好。但是现在我想实现更高级的符号类型,例如存储 BuiltInTypes 数组的元组(比如 - TupleSymbol)。
我可以轻松实现一个 TupleSymbol 并将其存储在 table 中,但我意识到继续使用我当前的映射到符号存储类型的方法最终会导致很多歧义符号 table 查找时的符号类型。例如,如果我想将元组分配给名为“test”的元组变量,则在分配操作中,我将必须检查存储在 table 中用于标识符“test”的 Symbol 是 TupleSymbol 还是BuiltInTypeSymbol,我将不得不为我想分配给它的值做同样的事情。
是否有更好的方法来实现符号 table?例如,最好在符号 table 范围内有多个区域分别存储每种类型的符号,即 std::map
编辑
这里有一些代码可以帮助可视化我当前的设计。请注意符号 table 映射 symbolTable
如何使用基本符号 class.
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
。
您可能还需要迭代某些符号类型,例如内置符号 - 最好也为它们创建一个地图。