一、语义分析和中间代码生成:
-
任务:对语法分析(中间代码)识别出对各类语法范畴,分析其含义,进行初步翻译,产生介于源代码和目标代码之间对一种代码。
-
分为两阶段对工作:
-
对每种语法范畴进行静态语义检查(含义上合不合理,有没有可能去执行等等)
-
若语义正确,就进行中间代码翻译
-
中间代码对形式:四元式、三元式、逆波兰式
🍊:中间代码的生成,例如下面:注意运算的时候要是同一种类型,a,b都是float型,所以要把50也转换成float型。转换的结果给一个内存单元叫T1。然后再算乘法以此类推。这张表就是中间代码表,例子是一个四元式。
二、优化:
-
任务:对前面产生的中间代码进行加工交换,以期在最后阶段能产生更为高效的目标代码。
-
原则: 等价变换
-
主要方面:公共子表达式的提取、合并已知量、删除无用语句、循环优化等等。
-
🍊例如:计算 x=(a+b) *c+(a+b) *d 我们计算的时候只用计算一次(a+b)但是计算机算两次,所以效率很低,所以要提取公共子表达式。
-
🍊把下面的程序转换成中间代码:
FOR (k=1;k<=100;k++)
{
m=i+10k;
n=j+10k
} -
运算的时候会这样进行:
先给k赋值为1,然后判断,接着运行,再回到判断,这样循环。
转换成中间代码以后是这样的:
优化以后的程序:
三、目标代码的生成:
-
任务:把经过优化的中间代码转换成特定机器上的低级语言代码。
-
目标代码的形式:
-
绝对指令代码:可立即执行的目标代码。(完全的0,1代码,直接生成exe文件,可以直接拿去用)
-
汇编指令代码:汇编语言程序,需要通过汇编程序汇编后才能运行。
-
可重定位指令代码:先将各目标块 连接起来 确定变量、常数在主存中的位置,装入主存后才能成为可以运行的绝对指令代码。(例如obj文件,不能拿去用,必须链接起来,有一步link操作)
-
四、表格与表格管理:(会产生表格的主要是前三个阶段)
-
表格作用:用啦记录源程序的各种信息以及编译过程中的各种状况。
-
与编译前三阶段有关的表格有:
-
符号表、常数表、标号表、分程序入口表、中间代码表等。
-
符号表:登记源程序中的常量名、变量名、数组名、过程名等,记录他们的性质、定义引用情况。🍊例如:
void main() { int m ,n ,k; }
NAME INFORMATION m 整型、变量地址 n 整型、变量地址 k 整型、变量地址 -
常数表和标号表:分别登记各类的常数值和登记标号的定义与应用
常数表 值 1 4 标号表:
NAME INFORMATION … … 10 四元式序号4 (表示10后面执行哪一个四元式)
-
入口名表:登记过程的层号,分程序符号表入口等。
NAME INFORMATION … … INCWAP 二目子程序、四元式序号1 -
中间代码表:上面的例子中。
-
-
-
-
五、出错处理:
-
任务:如果源程序有错误,编译程序应设法发现错误,并报告给用户。
-
完成:由专门的出错处理程序来完成。
-
错误类型:(逻辑错误检测不出来)
-
语法错误:在词法分析和语法分析阶段检测出来。
-
语义错误:一般在语义分析阶段检测。(有功能无法实现)
-
六、遍:
-
遍:对源程序或源程序的中间结果从头到尾扫描一次,并做有关的加工处理,生成新的中间结果或目标代码
-
一遍扫描