引入

今天主要是和大家交流一下,一个程序中逻辑表达式的计算在编译中是怎样一个过程。

大家都知道编译器的主要功能是将高级语言转换为低级语言,C语言程序转换成汇编程序,然后通过汇编器最终生成机器可识别的代码。那我们先通过一个简单的例子,整体地看一下编译器的结构。

编译器结构

compiler structs

词法分析

比如说像这样一段程序,这个程序只有一条赋值语句,首先词法分析器读入这段源程序,然后将它转换成词法单元,除了这个工作之外,词法分析器还会将空白的部分以及注释过滤掉。

语法分析

然后就是语法分析,语法分析得到词法单元的输入,创建出词法单元的语法结构,例如说,S可以是一个赋值语句,表达式E可以是两个表达式相加,或相乘,或者可以直接是一个标志符。那么有了这样的文法,那么就能够检测源程序是否是符合这样文法的语句,是的话就可以生成一棵语法树。【解释一下语法树,画出深度搜索得到的算术表达式】。

语义分析

接着就是语义分析,它先得到语法树,然后对它进行语义分析,看看有没有出现类型错误等。

中间代码生成、优化

然后验证好的语法树就可以通过中间代码生成得到程序的中间代码,中间代码有好多种,不过最流行的还是3地址代码【解释3地址代码】。【解释生成的图以及中间代码的好处:扩平台只需修改后两层】

生成代码

然后就是生成代码,这里面包括了对中间代码的优化,最后生成代码【解释汇编代码:不同的处理器架构会生成不同的汇编指令,例如mips或x86等】。

布尔逻辑表达式的翻译

boolean expression 1

类似算术表达式

接下来再来看看逻辑表达式是怎样的过程,与刚才的算术表达书类似,先假设这一文法,自然就能够生成一个语法树,然后对树进行深度优先搜索,根据语法语义可以得到这样的三地址指令,依旧可以进行优化最后生成合适的汇编代码。

控制流与布尔逻辑表达式

control flow boolean 那么,从上节课的算法中也能看到,往往在程序中逻辑运算会出现在控制语句中,那么在这里直觉就告诉我们可以有另一种计算的方法,因为,往往可以不用全部计算出每一个式子的真值。【根据ppt举个例子引出控制语句与逻辑表达式】

案例

那么对于这样的一个文法,如何通过控制流来计算其真值呢?那我们就可以重新定义它的语义规则,使得它的每次判断可以跳转到对应的真假出口,那么计算它的值,我们就只需要在它的真假出口处给予赋值就行。【结合一张图,解说例子】 那么,如何计算我们一开始的呢?要么在文法中引入括号,或者将表达式转换为析取范式。

参考资料

  1. 编译原理龙书
  2. 编译原理实用教程