gpt4 book ai didi

c++ - 玩具编译器符号表

转载 作者:行者123 更新时间:2023-11-30 03:38:14 25 4
gpt4 key购买 nike

我正在创建一个编译器(用于 Cool 语言)作为个人项目,但我在设计符号表时遇到了问题。对于上下文,我使用类的层次结构作为我的 AST。这是 AST 的一小段:

class NodeAST {
public:
virtual void accept(Visitor&) = 0;
};

class ProgramAST : public NodeAST {
private:
const std::vector<ClassPtr> vClasses;

public:
ProgramAST(std::vector<ClassPtr> vClasses);

auto class_cbegin() const {
return std::cbegin(vClasses);
}
auto class_cend() const {
return std::cend(vClasses);
}

virtual void accept(Visitor& v) override;
};

class ClassAST : public NodeAST {
private:
const std::string name;
const std::vector<FeaturePtr> vFeatures;

public:
ClassAST(std::string name, std::vector<FeaturePtr> vFeatures);

auto getName() const {
return name;
}

auto feature_cbegin() const {
return std::cbegin(vFeatures);
}
auto feature_cend() const {
return std::cend(vFeatures);
}

virtual void accept(Visitor& v) override;
};

目前,我的符号表的核心是一个定义如下的映射:

std::unordered_map<std::string, NodeAST*> table

它将声明的名称映射到 AST 中相应的节点。这样,例如,我可以使用我在 AST 节点中设置的类型来填充松散标识符的类型。

但是,问题是当我查询节点的符号表时,我得到了 NodeAST*。因此,我必须将它向下转换为 ClassAST*MethodAST*VarDecAST* 等才能实际使用它。

如何设计符号表以避免向下转型?

最佳答案

我不知道您正在实现的编程语言,但我认为您不太可能完全避免动态转换。例如在 f(1) 中,如果您的语言有 lambda,则 f 可以是函数或变量。您需要通过在符号表中查找来找出答案。

如果您可以绝对排除这种可能性,理论上您可以为每种类型创建单独的符号表。但请记住,如果您需要检测名称冲突,这显然会使查找名称冲突变得更加困难,并且可能意味着您的编程语言以后更难扩展。我不推荐此解决方案。

就我个人而言,我只会添加方法,例如 to_class()to_var()is_class()is_var() 等到你的 NodeAST 类,这样动态转换就被封装了,而不是散布在整个代码库中。您还可以为您的符号表创建一个类,以便您可以使用 get_class()get_var() 等访问元素。

如果您担心 C++ 中 RTTI 的运行时成本,您可以查看其他编译器正在使用的解决方案。对于 LLVM,此处进行了描述:http://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html

关于c++ - 玩具编译器符号表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39696044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com