题 Go中没有符号表?


谷歌的新语言“Go”说 在其网站上

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

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


14
2017-11-12 22:52


起源




答案:


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

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

本页讨论了一些原因 为什么C ++需要一个符号表来进行解析

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

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


21
2017-11-12 23:05



这是一个很好的参考。 - Mark Bessey
老实说,这只是谷歌的第一个(或第二个)结果 - hasen
还要注意对该帖子的回复 - 它们也包含非常好的理由,说明为什么这是不可能的。 - MSalters


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

在C和C ++中,甚至 解析 该语言需要一个符号表。


10
2017-11-12 22:55



我也这么想。那他们的主张怎么可能是真的呢?我认为一定是,但我不明白怎么做。 - Dinah
@Dinah:慢慢再读一遍,再读一遍这个答案。他们并不矛盾。 - Michael Myers♦
@Dinah:编译比解析更多。解析构建了程序结构的树形表示。然后,语义分析和代码生成在该树上运行以产生编译输出。 - quark


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

T t;

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

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

B::C (c);

除了不清楚是否这样的事实 B 是一个 class, 一个 typedef或者a namespace,还不清楚是否 C 是一种类型和 c 这种类型的对象,或者如果 C 是一个函数(或构造函数) c 作为一个参数(或者即使C是一个对象 operator() 过载)。您需要符号表来进行解析,尽管仍然可以足够快地继续,因为符号的类型在符号表中。

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

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

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

9
2017-11-12 23:23





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

例如:

int x = Foo(bar);

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


2
2018-03-29 13:19





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

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

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

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

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


0
2017-12-18 01:30