编译器中的语义分析
Posted
技术标签:
【中文标题】编译器中的语义分析【英文标题】:Semantic analysis in compilers [closed] 【发布时间】:2012-02-01 13:43:54 【问题描述】:编译器(通常)如何进行语义分析?
我在上次考试时不得不回答这个问题,这对教授来说还不够。
我在回答中包含了 BNF(带有示例)和句法卡,他问我:“当编译器找到像 int i;
这样的语句时会发生什么?”
【问题讨论】:
他没有在你的课堂上介绍过这些材料吗? 这更像是一个“人的问题”,而不是一个“技术问题”,有时老师希望得到一个更具体的答案... 教师在课堂上勾勒出一个高水平、连贯的主题概述,然后坚持让学生阅读相关材料以了解细节是合理的。如果他们在指定阅读材料中的考试中问您一个问题,您最好了解该材料。也有普通的坏老师。 @uNaturhal,@Atwood:我不知道为什么 Atwood 结束了这个问题。我认为这很清楚,其他人似乎也根据我的回答这么认为。有时,SO 员工做得太过火了,而且经常发生在相对较新的用户身上,我认为这是一种伤害。这里关于教学的讨论有点离题,但这可能是对 cmets 的抱怨,而不是问题。 @IraBaxter, Atwood:“这个问题模棱两可、含糊不清、不完整、过于宽泛或过于夸张,无法以目前的形式得到合理的回答。”阿特伍德,你确定知道你写的东西是什么意思吗?我认为 Ira Baxter 已经理解了我的问题,事实上他的回答正是我所需要的。所以似乎并不难问。很遗憾没有其他人可以为该帖子做出贡献,但我有我的答案,所以这不再是我的问题。玩得开心! 【参考方案1】:是时候仔细阅读 Aho&Ullman/Dragon 的书了。
语义分析是编译器确定各种值的类型、这些类型如何在表达式中交互以及这些交互在语义上是否合理的活动。例如,你不能合理地将字符串乘以类名,尽管没有编辑器会阻止你编写
"abc" * MyClass
为此,编译器必须首先识别声明和作用域,并且通常将此步骤的结果记录在一组符号表中。这告诉它特定标识符在特定上下文中的含义。它还必须确定各种文字常量的类型; "abc" 是与 12.2e-5 不同的类型。
然后它必须访问所有使用标识符和文字的位置,并验证标识符/文字的使用以及计算的结果是否与语言定义兼容(如上例所示)。
至于如何做到这一点:通常会解析源代码,构建程序的一些表示(语法树非常流行),并且该表示是 walk ("visited") 元素按元素收集/验证语义信息。符号表通常只是一组与表示范围的语法树相关联的哈希表,从标识符哈希到包含类型声明的结构。
【讨论】:
我想明白了。你能给我举个例子吗?例如,当编译器在函数中找到一个声明(如long double f;
)时,它会放入一个表,其中f
是一个占8字节的符号,可以包含浮点数,仅在以下范围内定义函数,以及他的取值范围?
@unNatural:是的,你说得对。关键是作用域、标识符和标识符的类型之间的关联。其他数据(例如 float 占用 8 个字节)不一定必须在符号表中,因为对于任何 float 值,编译器中都可能存在这一事实。编译器的后期阶段如果能确定范围信息,捕获范围信息是很有用的,这可以说是语义分析,但是在这个讨论的狭窄范围内,大多数人并不认为范围分析是“编译器语义分析” .
好的,很清楚 :) 如果我滥用您的可用性,请原谅,但我还有另一个问题。按照你说的,好像BNF跟语义分析的过程没有关系。是对还是我错了?
@unNatural:BNF 与语义分析有关。 BNF 告诉您语言结构的形状。这反过来又定义了语言的结构,因此定义了声明、范围、表达式,你可以命名它。您会发现程序表示(例如语法树)和对其所有元素的“访问”直接由 BNF 控制。其实整个编译器都是用BNF写的,直接控制解析和语义分析,就是用BNF加上一些额外的注解来生成编译器……
@unNatural: ...事实上,处理这种注解BNF的工具与目标编译器的问题完全相同,例如,必须解析、对BNF/注解进行语义分析等. 因此被称为“元编译器”。我提出这个的原因是因为句法和语义分析是直接在这种编译器编译器语言中建模的。如果您了解这些是如何工作的,那么编译的细节就会变得更加清晰。请参阅en.wikipedia.org/wiki/Compiler-compiler 但您仍应阅读 Aho&Ull 编译器书籍。以上是关于编译器中的语义分析的主要内容,如果未能解决你的问题,请参考以下文章