我有兴趣了解编译器是如何工作的。我浏览了几本书,所有人都同意编译器阶段大致如此(如果我错了,请纠正我):词法分析,语法分析,语义分析,中间代码,代码优化,代码生成。词法和语法阶段看起来非常清晰和直接作为方法(但这当然并不容易)。但是,我仍然无法找到语义阶段的真正含义。首先,我知道应该有一些子阶段,如范围检查,声明检查和类型检查,但一直困扰我的问题是:还有其他必须要做的事情。你能告诉我在这个阶段必须采取的必要步骤吗?我知道这很大程度上取决于编程语言和编译器实现,但是你能给我一些关于C / C ++,Java的例子。你能否指点我一本书/页/文章,我可以在哪里深入阅读这些内容。感谢。
修改 我看过的书是“编译器:原理,技术和工具”,Aho和“现代编译器设计”,Grune,Reeuwijk。我无法使用它们回答这个问题。如果您发现这个问题过于宽泛,请考虑您选择C,C ++或Java的编译器实现来给出答案。
答案 0 :(得分:4)
许多编译器都以典型的“语义分析”阶段以某种形式进行。在lexing和解析之后,通常会按以下顺序执行以下操作:
名称和类型解析。确定词法范围,在此类范围内声明的标识符,这些标识符的类型信息,以及标识符的每个非声明用法,它所引用的声明
控制流量分析。通过代码明确和/或隐含(例如,构造函数)计算的控制流图的构造。
数据流分析。确定变量接收新值的位置,以及程序其他部分读取这些值的位置。 (这通常在程序中进行局部分析,然后可能在程序中进行一次分析)。
通常也会这样做,作为数据流分析的一部分:
分数分析。确定每个指针,代码中的每个位置,指针可能引用的实体
致电图。在整个过程中构建调用图,通常考虑间接函数指针,其估计值出现在点到分析期间。
实际上,其中一些需要交错以产生更好的结果。
除此之外,还有许多分析用于支持各种优化和代码生成过程。如果你真的想了解更多,请参考任何体面的编译器书。
答案 1 :(得分:1)
正如templatetypedef已经提到的,语义分析是特定于语言的。对于C ++,除其他事项外,还需要涉及哪些模板实例化(C ++语言倾向于越来越多的语义分析),而对于Java,则需要进行一些经过检查的异常分析。
即使对于C,也可以配置GNU C编译器来检查给予字符串插值的参数。我想有一些与半语义分析相关的选项供GCC选择。如果您正在撰写有关该主题的论文,您可以花一个下午来计算它们:)
除了可用性之外,我发现语义分析是区分当今静态类型命令式面向对象语言的原因。
答案 2 :(得分:0)
您根本无法将其划分为子阶段。有许多事情需要完成,但至少在概念上它们都是在从上到下走动解析树并再次备份时完成的。它们到底是什么以及它究竟是如何发生取决于语言,正在处理的语句,特定的编译器编写器......
您可以开始制作列表:
你可以看到,这些必须在实践中有些混杂,而不是构成可分离的子阶段。