1、编 译 实 验,一. 概述1. 源语言:求n!的极小语言(文法见后), begin ; end ; integer , abcdefghijklmno pq rstuvwxyz 0123456789 integer function (); ,begin ; end ; read() write(),:= - * ,ifthenelse =,2. 工具语言: Pascal、C或其它3. 语法分析采用递归下降分析法4. 目标代码: P码5. 编译程序的结构,源程序字符串.pas,词法分析器,语法分析器,语义分析、中间代码生成器,代码优化器,目标代码生成器,二元式序列.dyd,二元式序列.dys,
2、中间代码序列.qud,中间代码序列.qdo,符 号 表 管 理 程 序,出 错 处 理 程 序,编译程序的结构,P码,二. 各阶段的输入输出1. 词法分析,词法分析器,源程序 .pas,二元式 (文本文件.dyd),2. 语法分析,语法分析器,.dyd,.dys,同时, 产生文本文件.var、 .pro,3. 语义分析,语义分析器,.dys,.qud(文本文件),同时, 产生二进制文件.ooj、varfil、profil,4. 优化,优化段,.qud .ooj,.qdo(文本文件),同时, 产生二进制文件.coj,5. 目标代码生成,目标代码生成器,.qdo .coj,.obj(P码),同时,
3、 产生二进制文件pf(目标指令),三. 数据结构1. 二元式文件.dyd(1)二元式形式:单词符号种别,长度为16,长度为2,一个空格,单词符号,种别,单词符号,种别,单词符号,种别,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,integer,begin,end,else,function,read,write,标识符,常数,=,=,-,*,:=,(,),;,单词符号与种别对照表,if,then,(2)每行后加一“.EOLN24”(3)文件结尾加“.EOF25”,2. 错误信息文件.err(1)错误信息格式*LINE:
4、行号错误性质(2)注意: 进入每一阶段, 首先打开.err, 如果无错误, 则.err为空。3. .dys 同.dyd,4. 变量名表 变量名vname: char(16) 所属过程vproc:char(16) 分类vkind: 01(0变量、1形参) 变量类型vtype: types 变量层次vlev: int 变量在变量表中的位置vadr: int(相对第一个变量而言) types=(ints),5. 过程名表 过程名pname: char(16) 过程类型ptype: types 过程层次plev: int 第一个变量在变量表中的位置fadr: int 最后一个变量在变量表中的位置lad
5、r: int,6. 四元式表(oprd, op1, op2, result) oprd整数码 op1第一操作数 op2第二操作数 result结果 op1、op2、result可用“值/地址”表示,7. 目标代码P码参见目标代码(P码)指令表,四. 实现提示1. 多数文件均和源文件同名, 仅扩展名不同。2. 词法分析时, 注意行尾和文件尾。3. 词法分析的实现方法利用状态转换图,0,4,1,2,3,5,6,7,开始,空白,字母/数字,字母,非字母数字,数字,非数字,=,-,*,*,*,数字,8,9,(,),10,11,12,=,13,14,15,16,其它,=,17,18,19,:,其它,=,
6、其它,20,21,;,其它,*,*,*,*,4. (有过程说明时)设一个总的变量名表,查、填表时注意嵌套。5. 语法错分类:(1)缺少符号错;(2)符号匹配错;(3)符号无定义或重复定义。6. 递归下降分析时, 必须先消除左递归。,7. 递归下降分析时, 跟踪符号的位置当进入某过程时, 其第一个符号必须已经读出; 退出该过程时, 必须读出该语法成分的右界符。,例: G(E) EE+TTTT*FFF(E) i 消除左递归: ETEE+TETFTT*FT F(E)i,过程match:匹配单词符号,并读入下一符号 变量lookahead:即将处理但尚未处理的符号 procedure match(t:
7、token); beginif lookahead=t then lookahead=nexttokenelse error end;,procedure E; beginT;E end; procedure T; beginF;T end;,procedure E;if lookahead=+ then begin match(+);T;Eend; procedure T;if lookahead=* then begin match(*);F;Tend;,8. 进行自上而下语法制导翻译时, 各过程返回的是指针。,五. 实验要求1. 至少完成词法、语法。2. 提交: 实验报告(1) 源程序、
8、测试程序、运行结果(2) 设计思想、总控算法、主要服务子程序算法、总结(心得、收获、建议等)。,测试程序,begininteger k;integer function F(n);begininteger n;if n=0 then F:=1else F:=n*F(n-1)end;read(m);k:=F(m);write(k) end,算符与整数码对照表1,算府,整数码,算符,整数码,算符,整数码,一元负,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,+,*,/,DIV,MOD,AND,或,非,=,=,=,赋值,无
9、条件转移,JNZ(真转移),过程调用,参数个数,程序结束,JZ(假转移),参数传递,算符与整数码对照表2,算府,整数码,算符,整数码,算符,整数码,参数返回,24,25,26,27,28,29,30,31,32,参数,过程返回,READ,READLN,WRITE,WRITELN,变址存数,变址取数,其中:22,26无操作数;0,9,17,20,21,23,27,28,29只有一个操作数; 16,18,19有两个操作数;1,2,3,4,5,6,7,8,10,11,12,13,14,15,24,25,31, 32有三个操作数。,目标代码(P码)指令表1,编码,助记符,操 作 码,参 数,T,P,Q
10、,功 能 说 明,T类型,P层次号,Q栈内位移 根据P,Q形成栈地址,将其栈内单元的 值装载到栈顶单元,0,LOD,T栈单元类型, P层次号, Q栈内位移 以P,Q形成的栈地址单元的内容作为地址, 间接取栈单元的值装载到栈顶,T类型,P层次号,Q栈内位移 直接存取栈顶单元内容到P,Q指定的栈单元中,间接存取栈顶单元的内容,以P,Q形成的栈 地址单元为间址单元,1,LDO,2,STR,STO,3,目标代码(P码)指令表2,编码,助记符,操 作 码,参 数,T,P,Q,功 能 说 明,将类型为T,值为Q的常数装载到栈顶单元,4,LDC,对栈顶单元中的整型数取负,对栈顶单元中的实型数取负,栈顶两单元
11、整型数加操作,5,NGI,6,NGR,ADI,7,8,ADR,栈顶两单元实型数加操作,9,SBI,栈顶两单元整型数减操作,目标代码(P码)指令表3,编码,助记符,操 作 码,参 数,T,P,Q,功 能 说 明,栈顶两单元实型数减操作,10,SBR,栈顶两单元整型数乘操作,栈顶两单元实型数乘操作,栈顶两单元整型数除操作,11,MPI,12,MPR,DVR,13,14,DVI,栈顶两单元实型数除操作,15,MOD,栈顶两单元整型数取余操作,目标代码(P码)指令表4,编码,助记符,操 作 码,参 数,T,P,Q,功 能 说 明,与操作,16,AND,或操作,非操作,大于比较,17,OR,18,NOT
12、,GRT,19,20,GEQ,大于等于比较,21,LES,小于比较,目标代码(P码)指令表5,编码,助记符,操 作 码,参 数,T,P,Q,功 能 说 明,小于等于比较,22,LEQ,不等于比较,等于比较,条件成立转移。若栈顶单元的布尔值为真, 则转移至Q表示的目标指令序号执行,23,NEQ,24,EQ,TJP,25,26,FJP,假转移。若栈顶单元的布尔值为假,则转移 至Q表示的目标指令序号执行,27,UJP,无条件转移,目标代码(P码)指令表6,编码,助记符,操 作 码,参 数,T,P,Q,功 能 说 明,转移至过程的起始目标指令处,28,PROC,过程调用指令,生成过程的内务管理数据区,过程返回,释放栈成分,分配一个栈单元,29,CALL,30,RET,LD,31,32,LDA,取数组元素内容,装入栈顶单元,33,STA,将数组元素值存入栈单元,目标代码(P码)指令表7,编码,助记符,操 作 码,参 数,T,P,Q,功 能 说 明,非换行读入数据,装入栈顶,34,RAD,换行读入数据,装入栈顶,非换行输出栈顶单元内容,换行输出栈顶单元内容,35,RDN,36,WRI,WRN,37,上机安排,时间 第13周开始,周一晚7:3010:00 地点 清水河校区实验大楼,