题
Google的新语言“ Go”说 在其网站上:
该语言被设计为易于分析,可以在没有符号表的情况下解析
我当然不是在这些问题上的专家,但是我认为符号表是所有使用变量的语言的编译器共有的基本构造,并且清楚地使用了变量。我不了解什么?
解决方案
解析意味着只弄清程序结构:将模块分为语句/声明,将表达式分解为子表达等。您最终以树结构(称为“ parse树”或“抽象语法树”( AST)。
显然,C ++需要一个符号表进行解析。
本页讨论了一些原因 为什么C ++需要一个用于解析的符号表.
当然,解析只是汇编的一部分,您将需要一个符号表来完成完整的汇编。
但是,解析本身在编写分析工具(例如哪些模块导入的模块)中很有用。因此,简化解析过程意味着编写代码分析工具更容易。
其他提示
解释和汇编绝对需要符号表或类似的符号表。几乎所有语言都是如此。
在C和C ++中,甚至 解析 该语言需要一个符号表。
@Justice是对的。为了扩展一点,在C中,唯一的实际棘手部分是告诉类型以外的变量。特别是当您看到这个时:
T t;
你需要知道 T
是一种法律解析的类型。这是您必须在符号表中查找的东西。只要添加到符号表中,这是相对简单的。您不需要在编译器中做很多额外的工作:要么 T
存在于表中,或者不存在。
在C ++中,事情很多, 很多 更复杂。有大量模棱两可或潜在的模棱两可的构造。最明显的是这个:
B::C (c);
除了事实还不清楚是否是否 B
是一个 class
, , 一个 typedef
, ,或 namespace
, ,还不清楚是否是否 C
是一种类型和 c
该类型的对象,或者 C
是函数(或构造函数) c
作为参数(甚至C是一个对象 operator()
超载)。您需要符号表进行解析,尽管仍然可以足够快地继续进行解析,因为符号的类型在符号表中。
当模板加入时,事情变得比那些要差得多。如果 C (c)
在模板中,您可能在模板的实际定义中不知道C是类型或函数/对象。那是因为模板可以声明 C
成为 类型或变量. 。这意味着您需要符号表,但您不需要 有 一个 - 你 不能 有一个直到实际声明模板为止。更糟糕的是,仅具有符号的类型不一定足以:您可以提出需要符号代表的类型的完整信息,包括大小,对齐方式和其他机器特定信息。
所有这些都有几种实际效果。我要说的两个最重要的是:
- 汇编要快得多。我认为GO的编译速度比C更快,并且C ++在涉及许多模板的情况下的汇编时间却是较慢的汇编时间。
- 您可以编写不依赖完整编译器的解析器。这对于进行代码分析和重构非常有用。
要解析大多数语言,您需要知道何时名称是变量,类型或功能以消除某些构造。 Go没有这种模棱两可的结构。
例如:
int x = foo(bar);
FOO可能是一种类型或函数,它们由不同的AST类型表示。基本上,解析器不必在符号上查找即可知道如何构建AST。语法和AST比大多数语言都要简单。真的很酷。
符号表很慢,通常不需要。因此,选择去做它。其他功能性语言也无需。快速查找需要哈希,但是要支持嵌套范围,您需要将/弹出名称推入堆栈。简单的Symtabs被实现为线性搜索堆栈,更好的Symtab和每个符号的堆栈。但是,必须在运行时进行搜索。
词汇范围的语言的解释和汇编绝对不需要符号表或类似的符号表。只有动态范围的符号需要符号表,而某些具有严格键入语言的编译器需要某种内部符号表来保存类型注释。
在C和C ++中,即使解析语言也需要一个符号表,因为您需要存储全球和功能的类型和声明。
词汇范围的符号不是在Symtab的符号中存储,而是作为块框架中的名称列表,如功能性语言。这些索引是在编译时计算的。因此,运行时访问是立即的。离开示波器使这些var无法自动访问,因此您无需从命名空间/symtabs推出/pop名称。
没有一流函数的功能性语言通常不需要将其功能名称存储在符号表中。作为语言设计师,您尝试将功能绑定到词汇,以便摆脱Symtabs中的动态名称查找。