4

我对了解编译器的真正工作原理很感兴趣。我翻阅了几本书,他们都同意编译器阶段大致是这样的事实(如果我错了,请纠正我):词法分析,语法分析,语义分析,中间代码,代码优化,代码生成。词汇和语法阶段看起来非常清晰和直接的方法(但这当然并不意味着容易)。但是,我仍然无法找到语义阶段的真正组成部分。一方面,我知道应该有一些子阶段,比如范围检查、声明检查和类型检查,但一直困扰我的问题是:还有其他事情需要做吗?你能告诉我在这个阶段必须采取哪些强制性步骤吗?我知道这在很大程度上取决于编程语言和编译器实现,但你能给我一些关于 C/C++、Java 的例子吗?您能否指点我一本书/页面/文章,我可以在哪里深入阅读这些内容。谢谢。

编辑: 我看过的书是“编译器:原理、技术和工具”,Aho 和“现代编译器设计”,Grune,Reeuwijk。我无法使用它们回答这个问题。如果您发现这个问题过于宽泛,请考虑您为 C、C++ 或 Java 选择的编译器实现给出答案。

4

3 回答 3

4

许多编译器以一种或另一种形式经历了典型的“语义分析”阶段。在进行词法分析和解析之后,通常会按此顺序执行以下操作:

  • 名称和类型解析。确定词法范围、在此类范围中声明的标识符、这些标识符的类型信息,以及对于标识符的每个非声明使用,它所引用的声明

  • 控制流分析。在代码显式和/或隐含的计算(例如,构造函数)上构建控制流图。

  • 数据流分析。确定变量接收新值的位置,以及程序其他部分读取这些值的位置。(这通常在过程中进行局部分析,然后可能在整个过程中进行)。

作为数据流分析的一部分,也经常这样做:

  • 点对点分析。在代码中的每个位置确定每个指针可能引用的实体

  • 调用图。跨过程构建调用图,通常考虑间接函数指针,其估计值出现在指向分析期间。

实际上,其中一些需要交错以产生更好的结果。

除此之外,还有许多分析用于支持各种优化和代码生成过程。如果您真的想了解更多信息,请查阅任何不错的编译器书籍。

于 2013-09-19T01:43:11.960 回答
1

正如 templatetypedef 已经提到的,语义分析是特定于语言的。对于 C++,它会涉及需要哪些模板实例化(C++ 语言倾向于越来越多的语义分析),而对于 Java,则需要进行一些检查异常分析。

即使对于 C,GNU C 编译器也可以配置为检查给定字符串插值的参数。我想 GCC 有数百种与半语义分析相关的选项可供选择。如果你正在写一篇关于这个主题的论文,你可以花一个下午数数:)

除了可用性之外,我发现语义分析是当今静态类型命令式面向对象语言的区别所在。

于 2013-09-18T21:49:09.613 回答
0

您根本不必将其划分为子阶段。有许多事情需要做,但至少从概念上讲,它们都是在从上到下遍历解析树并再次备份时完成的。它们到底是什么以及这一切如何发生取决于语言、正在处理的语句、特定的编译器编写者,......

你可以开始列一个清单:

  1. 建立符号表。
  2. 查找引用的变量的声明。
  3. 检查变量数据类型的兼容性。
  4. 建立子表达式类型。
  5. ...

您可以看到,这些在实践中必须有所混合,而不是构成可分离的子阶段。

于 2013-09-18T22:16:40.870 回答