Go中没有符号表?

时间:2009-11-12 22:52:15

标签: go symbol-tables

Google的新语言“Go”代表on its website

  

该语言设计为易于分析,无需符号表即可解析

我当然不是这方面的专家,但我认为符号表是使用变量的语言的所有编译器共同的基本结构,Go显然使用变量。我不理解的是什么?

5 个答案:

答案 0 :(得分:22)

解析意味着只计算程序结构:将模块分成语句/声明,将表达式分解为子表达式等等。最终得到一个树结构,称为“解析树”或“抽象语法”树“(AST)。

显然,C ++需要一个符号表来进行解析。

此页面讨论了why C++ requires a symbol table for parsing的一些原因。

当然,解析只是编译的一部分,你需要一个符号表来进行完整的编译。

但是,解析本身在编写分析工具(例如,哪个模块导入哪些模块)时非常有用。因此,简化解析过程意味着编写代码分析工具更容易。

答案 1 :(得分:10)

解释和编译绝对需要符号表或类似表。几乎所有语言都是如此。

在C和C ++中,即使解析,语言也需要符号表。

答案 2 :(得分:9)

@Justice是对的。为了进一步扩展,在C中,唯一真正棘手的部分是告诉类型除变量之外。特别是当你看到这个:

T t;

您需要知道T是一种合法解析的类型。这是你必须在符号表中查找的东西。只要在解析继续时将类型添加到符号表中,这就相对简单了。您不需要在编译器中做太多额外的工作:表中存在T或不存在。

在C ++中,事情很多,很多更复杂。存在大量模糊或可能含糊不清的结构。最明显的是这一个:

B::C (c);

除了Bclasstypedef还是namespace还不清楚之外,还不清楚C是否c是类型和C该类型的对象,或者c是以operator()作为参数的函数(或构造函数)(或者即使C是具有{{1的对象)重载)。你需要符号表来进行解析,尽管它仍然可以足够快地继续,因为符号的类型在符号表中。

当模板进入组合时,事情变得更加糟糕得多。如果C (c)在模板中,您可能不知道模板的实际定义,如果C是类型或函数/对象。这是因为模板可以将C声明为类型或变量。这意味着您需要符号表,但是没有一个 - 并且在实际声明模板之前不能。更糟糕的是,仅仅使用符号的类型并不一定足够:您可以提出需要符号所代表类型的完整信息的情况,包括大小,对齐和其他机器特定信息。

所有这些都有几个实际效果。我要说的两个最重要的是:

  • 编译速度更快。我认为Go的编译速度比C快,而C ++在涉及大量模板的情况下编译速度很慢。
  • 您可以编写不依赖于完整编译器的解析器。这对于进行代码分析和重构非常有用。

答案 3 :(得分:2)

要解析大多数语言,您需要知道名称是变量,类型或函数,以消除某些结构的歧义。 Go没有这种模棱两可的结构。

例如:

int x = Foo(bar);

Foo可以是一个类型或函数,它们由不同的AST类型表示。基本上,解析器永远不必对符号进行查找以了解如何构造AST。语法和AST比大多数语言简单。非常酷。

答案 4 :(得分:0)

符号表很慢,通常不需要。所以选择离开吧。其他功能语言也不需要。 快速查找需要哈希,但是为了支持嵌套范围,您需要将名称推送/弹出到堆栈。简单的symtabs实现为线性搜索堆栈,更好的symtabs实现为hash,每个符号堆栈。但是,搜索必须在运行时完成。

词汇范围语言的解释和编译绝对不需要符号表或类似表。 只有动态范围的符号才需要符号表, 一些具有严格类型语言的编译器需要某种内部符号表来保存类型注释。

在C和C ++中,即使解析语言也需要符号表,因为你需要存储全局和函数的类型和声明。

词法范围符号不存储在symtab中,而是存储在块框架中的索引名称列表中,如在函数式语言中一样。这些索引是在编译时计算的。因此,运行时访问是即时的。保留范围会使这些变量无法自动访问,因此您无需从命名空间/符号组中推送/弹出名称。

不是没有第一类函数的函数式语言通常需要将它们的函数名存储在符号表中。作为语言设计者,您尝试将函数绑定到词法,以便能够在symtabs中摆脱动态名称查找。