在编译器中使用单例

时间:2014-10-25 04:26:29

标签: c++ design-patterns

我正在为类似C ++的语言编写编译器。我必须处理符号表,它在我的代码中用只包含静态数据和方法的类表示。

就像:

class GlobalTable
{
    /* static members */
    static map<int, Symbol*> symbol_by_id;
    static map<Symbol*, int> id_by_symbol;

    /* some static methods */
};

还有一个代表config的类:

class GlobalConfig
{
    static const int int_size;
    /* and so on ... */
};

我需要从很多地方访问这些内容。传递它将导致代码膨胀。 这样使用我的课程是否方便,还是有更好的方法来组织一切?

1 个答案:

答案 0 :(得分:1)

在编译器中,通常将符号类型存储在符号表中,以用于符号的某些定义。通常,每个范围都有一个符号表,因此每个模块或可编译单元的全局范围都有自己的符号表。

您还有AST节点,其中包含符号和符号子类作为其成员。

大多数内部编译器apis处理符号和ast子类型,并且这些存储在索引的快速访问数据结构中。所有这些都必须可用于大多数编译器函数,因此您要么使用全局编译器或上下文变量,要么将其作为参数传递。

严格来说,没有必要使用单身人士。我只能在示例中讨论,所以我这样做的方式是使用Compiler类,其中包含currentScope和globalScope等实例成员以及根AST或currentCompilableUnit,因此解析器main实例化一个Compiler,并且所有内容都是可重入的。但是,如果你的编译器实例是一个全局变量,那么它会更方便一些,所以你的函数可以省略编译器参数,但除此之外,不需要任何其他参数。

简而言之,大多数API通常包含&#34;范围&#34;或&#34;编译器&#34;许多签名中的struct或class。虽然如果你使用OOP来编译编译器,那么该类的任何方法都隐含了&#34;这个&#34;访问。