




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
编写一个语法分析程序并生成四元式中间代码班级 学号 姓名: 指导老师: 一、 实验目的:1、 学习编译的基本原理;2、 巩固课堂学习的知识;3、 会对最基本的语句进行分析,转换成四元式;二、 实验内容: 编制一个大型程序,可以对小型的EL语言程序进行翻译,可以处理最基本的语句如:if语句,while语句等;三、 实验硬件和软件平台:INTEL C433MHz Cpu128Mb SDRAMTPWMicrosoft Windows XP SP1四、 步骤和算法描述:1、 先对输入的语句进行词法分析,建立各种表格;2、 对程序进行语法分析,建立四元式;对部分程序语句进行翻译,生成相应的四元式,及出错处理五 源程序:10program elcompiler(input,output,f); const reser=20; type alfa=packed array1.9 of char; opr=(jmp,prt,jeq,jne,jgt,jlt,jge,jle,add,sub,mul,did,ass,umi,jsr,ret,inp,out,xxx); 中间代码的操作码符号 instruction=record 四元式 op:opr; arg1,arg2,result:integer; end; symset=set of 0.45; obj=1.45; var reserve:array0.reser of alfa; 保留字表 token,id:alfa; line:array1.80 of char; 输入缓冲区 ch,ch1:char; quad:array0.300 of instruction; 四元式表 table:array0.100 of 符号表 recordname:alfa; level:integer; case cat:obj of 2 : (val:integer); 18,7: (addr:integer) end; mnemonic:arrayopr of array1.3 of char; cp,tp,new,nxq:integer; cc,ii,i,j,k,num:integer; kind,l,err:integer; filename:string; 外部文件名 f:text;procedure getchar; 从扫描缓冲区取一字符 begin if cc=ii then 如果已取到缓冲区的最后,则从外部 文件再读一行 begin if eof(f) then begin writeln(program incomplete!); close(f); exit end; cc:=0; ii:=0; cc is input to buffer pointer; ii is output pointer from buffer; while not eoln(f) do begin cc:=cc+1; read(f,linecc); write(linecc) end; readln(f); writeln; cc:=cc+1; linecc:= ; end; ii:=ii+1; ch:=lineii end; procedure getnbc; 读取非空字符 label l; begin l:getchar; while ch= do getchar; if ch= then begin repeat getchar until ch=;goto l end 跳过注解 end;procedure retract; 退回一 字符 begin ii:=ii-1 end;procedure scanner; 词法分析过程 begin getnbc; if ch in a.z then symbol is id or reserve begin k:=0; repeat if k10 then begin k:=k+1; tokenk:=ch end; getchar until not(ch ina.z,0.9); retract; if k10 then repeat k:=k+1; tokenk:= until k=10; id:=token; i:=0; j:=reser; repeat k:=(i+j) div 2; 对半查找保留字表 if id=reservek then i:=k+1 until ij; if i-1j then kind:=k else kind:=21 变量的类别 end else if ch in 0.9 then begin 整数 k:=0; num:=0; kind:=22; repeat num:=10*num+(ord(ch)-ord(0); k:=k+1; getnbc; until not(ch in 0.9); retract end else begin case ch of +,-:begin ch1:=ch; retract; retract; getchar; if (ch=) or (ch=() then 区分单目双目算符 if ch1=+ then kind:=32 else kind:=33 else if ch1=+ then kind:=34 else kind:=35; getchar end; *:kind:=36; /:kind:=37; ,:kind:=23; .:kind:=26; ;:begin writeln; kind:=24 end; (:kind:=27; ):kind:=28; :kind:=29; :kind:=30; =:kind:=38; : begin getnbc; if ch= then kind:=44 else begin retract; kind:=25 end end; #:kind:=47; :kind:=45; :kind:=46; :begin getnbc; if ch= then kind:=43 else begin retract; kind:=40 end end; then kind:=41 else begin kind:=39; retract end end; else; end; end end;procedure error(n:integer); 出错处理 begin write(*, ,ii-2,n:2); err:=err+1; case n of 0:writeln(lack program); 1:writeln(ought to= );2:writeln(lack=); 3:writeln(expected indent); 4:writeln(expected factor); 5:writeln(expeced ,;); 6:writeln(expected begin or functin); 7:writeln(expected statement) ; 8:writeln(expectedbegin); 9:writeln(expect ,); 10:writeln(num is too big); 11:writeln(indent isnt specify); 12:writeln(cant assign to const); 13:writeln(expeced :=); 14:writeln(expected (); 16:writeln(ought to then); 17:writeln(expected endor;); 18:writeln(ought to do); 19:writeln(expected ;on.); 20:writeln(expeced rop); 22:writeln(expected ); 23:writeln(may be to lack*); 25:writeln(to lack type specify); 26:writeln(indent double define) else ; end end;procedure test(s1,s2:symset;m:integer); 测试单词的合法 begin if not(kind in s1) then begin error(m); s1:=s1+s2; while not (kind in s1) do scanner end end;procedure gen(op:opr;ag1,ag2,result:integer); 生成中间代码 begin quadcp.op:=op;quadcp.arg1:=ag1; quadcp.arg2:=ag2;quadcp.result:=result; cp:=cp+1;nxq:=cp; end;procedure blk(lev,tp:integer;sys:symset); var tp0,cp0,dp:integer; chain:integer; function entry(iden:alfa):integer; var i:integer; begin i:=tp;:=iden; while iden do i:=i+1; entry:=i end;procedure fill(k:obj); 填写符号表 var i:integer; begin for i:=tp0 to tp do tp0 本分程序符号表首址 if =id then begin error(26); exit end; tp:=tp+1; with tabletp do begin name:=id; cat:=k; level:=lev; case k of 2: begin if num22767 then const 说明 begin error(10); num:=22767 end; val:=num; end; 18:begin addr:=dp; dp:=dp+1 end; var 说明7:addr:=0; function 说明 end end end;procedure constdec; 说明处理 begin if kind=21 then 变量 begin scanner if kind in 38,44 then =,:= begin if kind=44 then error(1); scanner; if kind=22 then begin fill(2); scanner end else error(4) end else error(2) end else error(3) end;procedure vardec; var说明处理 begin if kind=21 then begin fill(18); scanner end else error(4); end;procedure listquad; 显示中间代码结果 var i:integer; begin for i:=cp0 to cp-1 do with quadi do writeln(i:3,mnemonicop:6,arg1:6,arg2:6,result:6); end;procedure listtable; 显示符号表 var i:integer; begin for i:=1 to tp do with tablei do writeln(name:5,cat:5,level:5,val:5,addr:5); end;function newtemp:integer; 取一临时变量序号 begin new:=new+1; newtemp:=new end;procedure bp(p,t:integer); 回填四元式链 var q:integer; begin q:=p; while q0 do begin p:=quadq.result; quadq.result:=t; q:=p end end;function merg(p1,p2:integer):integer; 并链 var p:integer; begin if p2=0 then merg:=p1 else begin p:=p2; while quadp.result 0 do p:=quadp.result; quadp.result:=p1; end end;procedure statement(var schain:integer; sys :symset); 语句分析处理 var i,j,k,q,place:integer; ttc,ffc,slchain,s2chain:integer; function exp(sys:symset):integer; 表达式处理 var addop,e1place,e2place,t:integer; function term(sys:symset):integer; 项处理 var mulop,t1place,t2place,t:integer; function fact(sys:symset):integer; 因子处理 var i,j,k,f,f1,t1:integer; queue:array1.5 of integer; 存实参队列 begin test(27,21,22,sys,6); if kind=21 then 变量 begin i:=entry(id); if i=0 then begin error(11);scanner end else with tablei do case cat of 2:begin j:=val;fact:=j+10000;scanner end; 常数 18:begin j:=lev-level; k:=addr; lev当前层次 fact:=100*j+k;scanner; 变量地址 end; 7: begin scanner;f:=1; 函数调用 if kind=27 then begin scanner; k:=4; k+1是形参开始单元 queuef:=exp(28,23+sys); ), while kind=23 do begin scanner; f:=f+1; queuef:=exp(28,23+sys); end; if kind=28 then ) begin scanner; for f1:=1 to f do 传递实在参数 gen(ass,queuef1,0,dp+k+f1) end else error(22) end; f:=lev-level; f为相对当前的外层层次 gen(jsr,0,f,addr); 调函数 t1:=newtemp; gen(ass,dp,0,t1); 返回结果在dp单元 fact:=t1; 函数结果作为因子 end end case end else if kind=22 then 数 begin fact:=10000+num;scanner end elseif kind=27 then (,表达式) begin scanner;j:=exp(28+sys); if kind=28 then scanner else error(22); fact:=j; end; test(sys,27,23); end; begin 项 t1place:=fact(sys+3,36,37); div,*,/ while kind in 3,36,37 do begin mulop:=kind;scanner; t2place:=fact(sys+3,36,37); t:=newtemp; if mulop=36 then gen(mul,t1place,t2place,t) else gen(did,t1place,t2place,t); t1place:=t; end; term:=t1place; end; begin 表达式 if kind in 32,33 then 单目+or- begin addop:=kind;scanner; e1place:=term(sys+34,35); 双目+or- if addop=33 then begin t:=newtemp; gen(umi,e1place,0,t);e1place:=t; end end else e1place:=term(sys+34,35); while kind in 34,35 do begin addop:=kind;scanner; e2place:=term(sys+34,35); t:=newtemp; if addop=34 then gen(add,e1place,e2place,t) else gen(sub,e1place,e2place,t); e1place:=t; end; exp:=e1place; end; procedure condition(var tc,fc:integer;sys:symset); 条件表达式处理 var cond1,cond2,relop:integer; begin cond1:=exp(38,43+sys); if not(kind in 38,43) then begin error(20);scanner end else begin relop:=kind;scanner; cond2:=exp(38,43+sys); tc:=cp; case relop of 38:gen(jeq,cond1,cond2,0); 39:gen(jlt,cond1,cond2,0); 40:gen(jgt,cond1,cond2,0); 41:gen(jne,cond1,cond2,0); 42:gen(jle,cond1,cond2,0); 43:gen(jge,cond1,cond2,0); end;fc:=cp; gen(jmp,0,0,0); end end; begin if kind=21 then 赋值语句 begin i:=entry(id); if i=0 then begin error(11);scanner end else if tablei.cat 18 then if tablei.cat=7 then k:=0 else begin error(12);i:=0 end 把赋值给常量错 else begin j:=lev-tablei.level; k:=100*j+tablei.addr end; scanner; if kind=44 then := begin scanner; place:=exp(sys);gen(ass,place,0,k); schain:=0; end else error(13); end else if kind =8 then begin scanner;condition(ttc,ffc,sys+16); if kind=16 then begin scanner; bp(ttc,nxq); statement(slchain,sys); end else error (16); if kind=5 then begin scanner; q:=nxq;gen(jmp,0,0,0);bp(ffc,nxq); slchain:=merg(slchain,q); statement(s2chain,sys); end else schain:=merg(ffc,slchain); end else if kind=19 then begin scanner; q:=nxq;condition(ttc,ffc,sys+4); if kind=4 then do begin scanner; bp(ttc,nxq); statement(slchain,sys); bp(slchain,q);gen(jmp,0,0,q); schain:=ffc; end else error(18); end else if kind =1 then begin scanner;statement(schain,sys); while kind=24 do ; begin scanner;bp(schain,nxq); statement(schain,sys); end; if kind=6 then end begin scanner;bp(schain,nxq);schain:=0 end else error(17); expected end end else if kind=14 then read 语句 begin scanner; if kind 27 then error(14) else begin scanner; if kind=21 then begin i:=entry(id);j:=tablei.level; k:=tablei.addr;q:=j*100+k; gen(inp,0,0,q);scanner; while kind=23 do , begin scanner; if kind =21 then begin i:=entry(id);j:=tablei.level; k:=tablei.addr;q:=j*100+k; gen(inp,0,0,q) end else error(4); scanner; end; if kind=28 then scanner else error(22) ) end else error(4); end; schain:=0; end else if kind=20 then write 语句 begin scanner; if kind27 then error(14) else repeat scanner; place:=exp(28,23+sys); gen(out,0,0,place); until kind23; if kind28 then error(22); scanner;schain:=0 end; test(sys,19); 空语句自动匹配 end; begin blk 分程序处理 dp:=5;tp0:=tp;tabletp.addr:=cp;cp0:=cp; gen(jmp,0,0,0); 跳过函数说明的语句体代码 if kind=27 then ( 处理形参说 明 begin scanner; vardec; while kind=23 do , begin scanner;vardec; end; if kind=25 then begin scanner; if(kind=9) or (kind=15) then scanner else error(25); end; if kind=28 then scanner else error(22); ) end; if kind=25 then : begin scanner; if(kind=9) or (kind=15) then scanner else error(25); end; type is integer or real? if kind=24 then scanner else error(5); ; if kind=2 then const 处理常量说明 begin scanner; repeat scanner; while kind=23 do , begin scanner;constdec end; if kind=24 then scanner else error(5) ; until kind21; end; if kind=18 then var 处理变量说明 begin scanner; repeat vardec; while kind=23 do , begin scanner;vardec end; if kind=25 then : begin scanner; if(kind=9) or (kind=15) then scanner else error(25) end; integer or real if kind=24 then scann
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工作中如何做好沟通和协作
- 制作小技巧及演讲注意事项20
- 2025年度汽车展览会场地租赁及独家商标使用权合同
- 2025年度家庭山场中药材种植项目合作租赁合同
- 2025年度城市星级酒店分店品牌经营管理授权协议
- 2025新型农业合作种植合同:绿色农产品供应链全程管理
- 2025年中小企业财务优化与专项融资扶持合同
- 2025生物制药知识产权全面保护及许可合同
- 2025年度连锁经营营业执照及品牌形象使用权租赁协议
- 2025年环保印刷用纸张定制供应合同
- 成人机械通气患者俯卧位护理(中华护理学会团体标准T-CNAS-23-2023)
- 室分测试报告模板
- 住所经营场所使用证明
- 联想AIO超融合解决方案
- 锡焊机理与焊点可靠性分析
- 北京市工业污染行业生产工艺调整退出及设备淘汰目录(2022年版)
- 3.盖立春-课堂教学行为研究的“元问题”研究
- 机电工程施工监理管理、检验和交工评定用表
- GB/T 33982-2017分布式电源并网继电保护技术规范
- 光电及光化学转化原理与应用电化学全册配套课件
- 压力性损伤预防及处理课件
评论
0/150
提交评论