编译原理实践

上传人:z****2 文档编号:177652153 上传时间:2022-12-26 格式:DOCX 页数:32 大小:235.45KB
收藏 版权申诉 举报 下载
编译原理实践_第1页
第1页 / 共32页
编译原理实践_第2页
第2页 / 共32页
编译原理实践_第3页
第3页 / 共32页
资源描述:

《编译原理实践》由会员分享,可在线阅读,更多相关《编译原理实践(32页珍藏版)》请在装配图网上搜索。

1、实验二 算数表达式的扩充一、实验目的掌握LR分析表的设计方法和语义加工程序的扩充。二、实验内容算术表达式文法扩充如下:Ef E+E|E-E|E *E|E/E|(E)|i试根据该文法添加单词“-”、“/”的内部定义以及重新设计LR分析表,并修改语 义加工程程序,最后验证修改的结果。I丄上宜” 乩/即 FTJS訪 / N皿心十十人心处心环鳥歸日3曲 事3人Q二芒f和他用,讣x乍皆诽衍日佔匕 厶他;|珅戶止ET 地宀7“ J Sg y匪)E氏儿J 加代的2的j解叠曰冃ET% 半4:瓷世世怕苗巧三、LR分析表的构造j帀仏卩“塚e He歹臼e &匕x7 g :亦国1上 再 h::-I,亦:血4应二心圧E

2、T“e吃兀七0E #匕田E冋脚迈斗E m日4氏疋T E Et哗*T呵犷妙 E专订I3爲Q; f -?rJ 二2舟彳蠢少2沁心弋曽5妇5仙勺&皿D十刃”巴?十J _16如尸凸j斥血冷,止创沙心0日二曲就勺 心总二心沁归沙曰皿曰誓妙 弭如讯2J日日EJ已丿&衣匕扌挪阳&7时。5一鸟二11_ -I_丿 他虫丿上_3v_1 钳 丿 V7I4u d14 _& 輸 吆Jk 耳T I UT 沪 d,t_二|_d tk ii T % 久% 4 ”! 小 6 a T_ AA- A-卜匕“ i l _. i,出丿、)()刁&那编译程序的修改与扩充#define sub#define div35/ 减37/ 除定义

3、符号减和除的编号重新构造 LR 分析表 action1static int action1149=3,-1,-1,2,-1,-1,1,-1,-1,-1,4,6,-1,-1,ACC,-1,5,7,3,-1,-1,2,-1,-1,8,-1,-1,-1,104,104,-1,104,104,-1,104,104, 3,-1,-1,2,-1,-1,9,-1,-1, 3,-1,-1,2,-1,-1,10,-1,-1, 3,-1,-1,2,-1,-1,11,-1,-1, 3,-1,-1,2,-1,-1,12,-1,-1, -1,4,6,-1,13,-1,-1,5,7, -1,101,6,-1,101,10

4、1,-1,101,7, -1,105,6,-1,105,105,-1,105,7, -1,102,102,-1,102,102,-1,102,102, -1,106,106,-1,106,106,-1,106,106, -1,103,103,-1,103,103,-1,103,103; 在扫描程序中添加-,/情况, ,case -: bufcount.sy1=sub; count+; break;,/,case /: bufcount.sy1=div; count+; break;changel(int chan)/actionl 的符号查找排序(i,+, *,(,),#,E,-, /) 加入

5、:case sub:return 7;/- case div:return 8;/ / lrparse1 语义分析中 状态数增加if(lrl=0)/在 013 个状态之中 规约增加数if(lr1=100)&(lr1E-Egen(-,sstackssp-2,sstackssp,E.pos+100); ssp=ssp-2;sstackssp.sy1=tempsy; sstackssp.pos=E.pos; sp1=sp1-3;break;case 106:E.pos=newtemp();/E-E/E gen(/,sstackssp-2,sstackssp,E.pos+100); ssp=ssp-2

6、;sstackssp.sy1=tempsy; sstackssp.pos=E.pos;sp1=sp1-3; break;测试字符是否为表达式中的值(不包括:),test(int value)增加: case sub: case div:五、编译程序的验证测试用例:while (ab) dobeginif m=n then a:=a-1 elsewhile k=h do x:=x/2;m:=n+x*(m+y)end#测试结果:press425655638563757856385634563648563456496continue10程序总共7行,产生了 43个二元式!口工过程及归n=3n=9n=

7、5n=4n=0n=9n=ln=7n=2lr=9 lr=13lr=18 lr=101lr=15 lr=10210日约11tack3. tack 4.-)评hi 1 e tack0.tack1=1=13=9=0Lr=5Lr=L04lr=9Lr=lQ5lr=16 lr=106lr=15lr=102Lr=lLr=-25n n n nn n n nn10o- -12= n12= nii10=11M 8 77=108 = 149 = 1710111213 归约12 = 1113=15 ile e do s 归约9 = 1710 = 18then s else=4=9=13=5tack 7-自归约tack

8、6tack 7.-S归约=13=16日约=8=12L end.归约=11=15e do s归约tack6; tack 7 -S;L I tack 4;tack5. tack&.sn=约归41.-.U.-.U3 7142615 1lr=14 lr=17 lr=3 lr=7 lr=ll lr=5 lr=104lr=8lr=12lr=103*四丿|_|工I.J分析结果*100j,a,b,102)101j7,117)102j=,m,n,104)103j77,107)104,a,1,T1)105,T17,a)106j7,112)107j =、k、h,109)108j,112)109/,2,T2)110:

9、=,T27)111j7,107)112+7 y,T3)113*,x,T3,T4)114+,n,T4,T5)115,T57)116j77,100)程序运行结束!六、实验体会经过一个星期的编译原理课程设计,本人在李艳老师的指导下,顺利完成该课 程设计。通过该课程设计,收获颇多。1. 对实验原理有更深的理解通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶 段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程、构造工 具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面 的。通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的 书本知

10、识变的更为简单,对实验原理有更深的理解。2. 对该理论在实践中的应用有深刻的理解通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论 在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。3. 激发了学习的积极性通过该课程设计,全面系统的理解了编译原理程序构造的一般原理和基本实现 方法。把死板的课本知识变得生动有趣,激发了学习的积极性。把学过的计算机编 译原理的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了 对理论知识的理解。以前对与计算机操 作系统的认识是模糊的,概念上的,现 在通过自己动手做实验,从实践上认识了操作系统是如何处理命令的,如何协调计 算

11、机内部各个部件运行,对计算机编译原理的认识更加深刻。课程设计中程序比较 复杂,在调试时应该仔细,在程序调试时,注意指针,将不必要的命令去除。 在 这次课程设计中,我就是按照实验指导的思想来完成。加深了理解文件系统的内部 功能及内部实现,培养实践动手能力和程序开发能力的目的。 四、理解了该知 识点以及学科之间的融合渗透 本次课程设计程序部分是用 c 语言编写的,把计 算机操作系统,编译原理算法分析与设计C语言四门学科联系起来,把 各个学科之间的知识融合起来,把各门课程的知识联系起来,对计算机整体的认识 更加深刻。使我加深了对计算机操作系统编译原理算法分析与设计C 语言四门课程的认识。七、源码#i

12、nClude stdio.h#inClude string.h#define ACC -2/*/#define sy_if0#define sy_then1#define sy_else2#define sy_while3#define sy_begin4#define sy_do5#define sy_end6#define a7#define semiColon8#define e9#define jinghao10#define S11#define L12#define tempsy15#define EA18#define E019#define plus34#define sub3

13、5/减#define times36#define div37/除#define beComes38#define op_and39#define op_or40#define op_not41#define rop42#define lparent48#define rparent49#define ident 56#define intconst 57/*/char ch二0;/可用于存放读出的一个字符int coun t=0;/词法分析结果缓冲区计数器static char spelling10 = ;/存放是别的字static char line81 = ;/一行字符缓冲区char *

14、pline;/line 的指针static char nt abl10010;/变量类型名表struct ntabint tc;/真int fc;/假nt ab2200;/用于存放布尔表达式的值int label=0;/指向 ntab2 的指针struct rwordschar sp10;int sy;/匹配表结构体struct rwords reswords10=if,sy_if,do,sy_do,else,sy_else, while,sy_while, then,sy_then, begin,sy_begin, end,sy_end, and,op_and, or,op_or,not,o

15、p_not;/初始化匹配表,用于关键字的匹 配 struct aaint sy1;/存放变量的类型名int pos;/存放该变量在自己表中的位置buf1000,/词法分析结果缓冲区n,/存放二元式当前字符n1,/表达式当前的字符E,/非终结符sst ack100,/算术表达式和布尔表达式的符号栈ibuf100,/ 算术表达式和布尔表达式的缓冲区stack1000;/ 语法分析的符号栈st ruct aa ot h;/四元式中没有填写的空白位置st ruct fourexp/四元式结构体char op10;struct aa arg1;struct aa arg2;int result;fexp

16、200;int ssp=0;/指向 sstack 的指针st ruct aa *pbuf=buf;/词法分析结果缓冲区的指针int nleng th=0;/词法分析中记录单词的长度int lnum=0;/行数计数源程序int tt 1=0;/变量类型名表的指针FILE *cfil e;/源程序文件/*/int new t二0;/临时变量计数器int nxq=100;/总是指向下一个要形成的四元式每次执行gen()int lr;/用于存放actionl中的当前状态int lr1;/用于存放action2, 3中的当前状态int sp=0;/LR 分析表栈顶指针int st ack1100;/状态

17、栈 1int sp1=0;/状态栈的指针int num=0;/算术表达式或布尔表达式的指针 struct llint nxql;/指向下一条四元式的指针int tcl;/真值链int fcl;/假值链labelmark10;/记录嵌套中每层布尔表达式e的首地址int labeltemp10;/记录每层else之前四元式的地址int pointmark=-1,pointtemp=-1;/labelmark 的指针, labelmark 的指针 int sign=0;/ sign=1 赋值语句, sign=2 while 语句, sign=3 if 语句 /*程序语句的 LR 分析表*/ stat

18、ic int action1913=2,-1,-1,3,4,-1,-1,5,-1,-1,10,1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,ACC,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,6,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,7,-1,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,8,-1,-1,104,-1,-1,-1,104,-1,104,-1,104,-1,-1,-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-

19、1,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,105,-1,13,-1,-1,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,14,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,15,-1, -1,-1,103,-1,-1,-1,103,-1,103,-1,103,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,16, -1,-1,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1

20、,-1,102,-1,-1,-1,102,-1,102,-1,102,-1,-1, -1,-1,-1,-1,-1,-1,106,-1,-1,-1,-1,-1,-1, 2,-1,-1,3,4,-1,-1,5,-1,-1,-1,18,-1, -1,-1,101,-1,-1,-1,101,-1,101,-1,101,-1,-1;/*算术表达式的 LR 分析表*/ static int action1149=3,-1,-1,2,-1,-1,1,-1,-1,-1,4,6,-1,-1,ACC,-1,5,7,3,-1,-1,2,-1,-1,8,-1,-1, -1,104,104,-1,104,104,-1,

21、104,104, 3,-1,-1,2,-1,-1,9,-1,-1, 3,-1,-1,2,-1,-1,10,-1,-1, 3,-1,-1,2,-1,-1,11,-1,-1, 3,-1,-1,2,-1,-1,12,-1,-1, -1,4,6,-1,13,-1,-1,5,7, -1,101,6,-1,101,101,-1,101,7, -1,105,6,-1,105,105,-1,105,7, -1,102,102,-1,102,102,-1,102,102, -1,106,106,-1,106,106,-1,106,106, -1,103,103,-1,103,103,-1,103,103;/*布

22、尔表达式的 LR 分析表*/ static int action21611=1,-1,4,-1,5,-1,-1,-1,13,7,8, -1,2,-1,101,-1,101,101,101,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,102,-1,102,102,102,-1,-1,-1, 1,-1,4,-1,5,-1,-1,-1,11,7,8, 1,-1,4,-1,5,-1,-1,-1,6,7,8, -1,-1,-1,104,-1,9,10,104,-1,-1,-1, 1,-1,4,-1,5,-1,-1,-1,14,7,8, 1,-1

23、,4,-1,5,-1,-1,-1,15,7,8,105,-1,105,-1,105,-1,-1,-1,-1,-1,-1,107,-1,107,-1,107,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,9,10,-1,-1,-1,-1, -1,-1,-1,103,-1,103,103,103,-1,-1,-1,-1,-1,-1,-1,-1,9,10,ACC,-1,-1,-1,-1,-1,-1,106,-1,9,10,106,-1,-1,-1,-1,-1,-1,108,-1,9,10,108,-1,-1,-1;readline()/读一行char ch1;pline=line

24、;chi二fge tc(c fil e);/从文件中取一个wh il e(ch1!=n) & (ch1!=EOF)/把字符缓冲区填满 *pline=chi;pline+;chi=fgetc(cfile);*pline=0;/结尾终结符pline=line;/字符缓冲区指针重新回到字符缓冲区的第一个字符位置 readch()/读一个if(ch=0)/读到尾姐再来一行,行数加一readline();lnum+;ch=*pline;/从行缓冲区读取一个字符 pline+;/字符缓冲区指针后移find(char spel)/在变量表中查询int ss1=O;/是否查到的变量的标志(1为查到,0为没查到

25、)int ii=0;/记录查到变量表第几条whil e(ss1=0) & (ii=a) & (ch二z)|(ch二0) & (ch二9);/数字或小写字母 pline;/取字时多加的一个,-1可使*pline指向字符缓冲区行尾 spellingk=0;while(ss=0)&(iii10)if(!s trcmp(spelling,reswordsiii.sp)/在关键字表中查询 ss=1;/查到标志置1 iii+;/*关键字匹配*/ if(ss=1)/在关键字表中查到bufcoun t.sy1二reswordsiii-1.sy;/关键字名字放入结果缓冲区else/没查到bufcoun t.sy

26、1二iden t; /将变量名置入结果缓冲区 j=find(spelling);/变量表查询,查到就把变量在变量表的地址赋给j if(j=-1)/没查到就新建一个变量bufcoun t.pos二tt 1;/将其在变量表中的地址放入结果缓冲区中的地址栏 st rcpy(n tab1 tt 1,spelling);/将识别的变量名放入变量名表 tt1+;nlength+;/ 变量名表长加一else bufcount.pos=j;/ 查到后,将变量名表中变量的地址放入结果缓冲区该 变量的地址栏中count+;/ 指向结果缓冲区下一位置for(k=0;k=0)&(ch=9);bufcount.sy1=

27、intconst;/ 常量名存入结果缓冲区 bufcount.pos=ivalue;/ 该常量地址存入结果缓冲区 count+;/ 向结果缓冲区下一位置pline-;/ 指向行缓冲区尾字符scan()int i;whil e(ch!=)/为程序结束符switch(ch)case :break;case a:case b:case c:case d:case e:case f:case g:case h:case i:, ,case j:case k:,1,case l:, ,case m:,case n:,case o:,case p:,case q:,case r:,case s:,亠,ca

28、se t:, ,case u:,case v:,case w:,case x:,case y:casez:identifier();break;/ 关键词或变量查询case 0:,1,case 1:,acase 2:case 3:,A,case 4:,厂,case 5:case 6:,*7,case 7:case 8:case9:number();break;/ 数字查询case :readch();/6 种关系运算符 bufcount.pos= ( = 为 0 , = 为 2,为3,为 4,=为 5)if(ch=) bufcount.pos=0;elseif(ch=) bufcount.po

29、s=4;else bufcount.pos=1; pline-;bufcount.sy1=rop;/ 关系运算符名存入结果 count+;/ 结果指针后移 break;case :readch(); if(ch=)bufcount.pos=2;else bufcount.pos=3; pline-;bufcount.sy1=rop; count+;break;case (:bufcount.sy1=lparent; count+;break;case ):bufcount.sy1=rparent; count+;break;case #:bufcount.sy1=jinghao; count+

30、;break;,I,case +:bufcount.sy1=plus; count+;break;, ,case -:bufcount.sy1=sub; count+;break;case *:bufcount.sy1=times; count+;break;,/,case /:bufcount.sy1=div;count+;break;case :readch(); if(ch=) bufcount.sy1=becomes;count+; break;, ,case =:bufcount.sy1=rop; bufcount.pos=5; count+;break;, ,case ;:bufc

31、ount.sy1=semicolon;count+; break;readch();/ 取下一个字符 bufcount.sy1=-1;/ 结束了 /*/readnu()/读取当前结果缓冲区的二元式存入struct aa n中,pbuf指向结果缓 冲区中下一位置的指针if(pbuf-sy1=0)n.syl二pbuf-syl;/存放当前二元式字符名称n.pos二pbuf-pos;/存放当前二元式字符位置pbuf+;new temp()/返回目前临时变量数new t+;/临时变量计数器+1return newt;/*生成四元式*/gen(char op1,struet aa arg11,struet

32、 aa arg22,int result1 )/op1 算符,arg11 操作数 1,arg22 操作数 2, result1 结果strcpy(fexpnxq.op,op1);/ 为四元式传入算符fexpnxq.arg1.sy1=arg11.sy1;/ 为四元式操作数 1 传入名字 fexpnxq.arg1.pos=arg11.pos;/ 为四元式操作数 1 传入地址 fexpnxq.arg2.sy1=arg22.sy1;/ 为四元式操作数 2 传入名字 fexpnxq.arg2.pos=arg22.pos;/ 为四元式操作数 2 传入地址 fexpnxq.result=result1;/

33、为四元式结果传入结果 nxq+;/ 每次指向下一个要生成的四元式地址 return nxq-1;/ 当前四元式地址merg(int p1,int p2)/ 将链首“指针”分别为 p1 和 p2 的两条链合并为一条,并 返回新链的链首“指针”(此处的“指针”实际上是四元式的序号,应为整型值)int p;if(p2=0) return p1; elsep=p2;while(fexpp.result!=0)p=fexpp.result;fexpp.result=p1;return p2;backpatch(int p,int t)/用四元式序号t回填以p为首的链,将链中每个四元式 的 Result

34、域改写为 t 的值。int tempq; int q;q=p;while(q!=0)tempq=fexpq.result;fexpq.result=t;q=tempq;/*/change1(int chan)/actionl 的符号查找排序(i,+, *,(,),#,E,-, /)switch(chan)case ident:/ 变量case intconst:return 0;/icase plus:return 1;/+case times:return 2;/*case lparent:return 3;/(case rparent:return 4;/)case jinghao:ret

35、urn 5;/#case tempsy:return 6;/Ecase sub:return 7;/-case div:return 8;/ /change2(int chan)/action2 的符号查找排序 switch(chan)case ident:caseinconst:return 0;case rop:return 1;case lparent:return 2;case rparent:return 3;case op_not:return 4;case op_and:return 5;case op_or:return 6;case jinghao:return 7;case

36、 tempsy:return 8;case EA:return 9; case E0:return 10;lrparsel(int num)/算数表达式语义分析lr1=ac tionls tacklsplchangel(nl.syl);/ 由栈顶装状态和当前符号查一 个 action1 中的值if(lrl=-l)/查出为-1表示出错printf(n算术表达式或赋值语句出错!n);getch();exit(0);if(lr1=0)/ 在 013 个状态之中sp1+;/ 状态栈指针 +1stack1sp1=lr1;/ 该状态值存入状态栈该位置 if(n1.sy1!=tempsy)/ 当前符号不是非

37、终结符 ssp+;/ 符号栈指针 +1num+;/ibuf( 布尔或算术缓冲区 ) 指针 +1 sstackssp.sy1=n1.sy1;/ 将当前符号类型名存入符号栈名字域 sstackssp.pos=n1.pos;/ 将当前符号地址存入符号栈地址域n1.sy1=ibufnum.sy1;/ 从布尔或算术缓冲区中取下一个符号名 n1.pos=ibufnum.pos;/ 从布尔或算术缓冲区中取下一个符号名的地址 lrparse1(num);/ 继续分析if(lrl=100) & (lrlEcase 101:E.pos=newtemp();/E-E+E gen(+,sstackssp-2,ssta

38、ckssp,E.pos+100);ssp=ssp-2;/按照规约,符号栈退出个符号E+E出栈 sstackssp.syl二tempsy;/装入归约式左边文法符号E sstackssp.pos=E.pos; /置临时变量序号 sp1=sp1-3; /状态栈退出三个状态 break;case 102:E.pos=newtemp();/E-E*E gen(*,sstackssp-2,sstackssp,E.pos+100); ssp=ssp-2;sstackssp.sy1=tempsy; sstackssp.pos=E.pos; sp1=sp1-3;break;case 103:E.pos=ssta

39、ckssp-1.pos;/E-(E)ssp=ssp-2;sstackssp.sy1=tempsy;sstackssp.pos=E.pos;sp1=sp1-3; break;case 104:E.pos=sstackssp.pos;/E-isp1-; break;case 105:E.pos=newtemp();/E-E-E gen(-,sstackssp-2,sstackssp,E.pos+100); ssp=ssp-2;sstackssp.sy1=tempsy; sstackssp.pos=E.pos; sp1=sp1-3;break;case 106:E.pos=newtemp();/E-

40、E/E gen(/,sstackssp-2,sstackssp,E.pos+100); ssp=ssp-2;sstackssp.sy1=tempsy; sstackssp.pos=E.pos; sp1=sp1-3;break;n1.sy1=tempsy;/ 当前类型名为 En1.pos=E.pos;/ 当前地址为 E 的地址 lrparse1(num);/ 继续分析if(lrl=ACC) &(stacklspl=l)/当 lr1 的值为 ACC 时分析完毕 gen(:=,sstackssp,oth,ibuf0.pos);ssp二ssp-3;/符号栈退spl二spl-3;/状态栈退lrparse

41、2(int num)int templabel;lr1=ac tion2s tack1sp1change2(n1.sy1);/ 由栈顶装状态和当前符号查一 个 action2 中的值if(lr1=-1)/ 出错if(sign=2) printf (nwhile 语句出错n);if(sign=3) printf (nif 语句出错n);getch();exit(0); if(lr1=0)/ir1 是 016 状态中的一个时sp1+; stack1sp1=lr1;/lr1 存入状态栈ssp+;sstacksp1.sy1=n1.sy1;/ 当前符号名存入符号栈名字域 sstackssp.pos=n1

42、.pos;/ 当前符号地址存入符号栈地址域 if(n1.sy1!=tempsy)&(n1.sy1!=EA)&(n1.sy1!=E0) num+;/ 不是 B,A,O , 就从布尔缓冲区取下一个n1.sy1=ibufnum.sy1;n1.pos=ibufnum.pos; lrparse2(num);/ 继续分析 if(lr1=100)&(lr1Bcase 101:/B-intab2label.tc=nxq; ntab2label.fc=nxq+1; gen(jnz,sstackssp,oth,0); gen(j,oth,oth,0);sp1-;ssp-;label+;n1.sy1=tempsy;

43、break;case 102:/B-i rop intab2label.tc=nxq; ntab2label.fc=nxq+1;switch(sstackssp-1.pos) case 0:gen(j=,sstackssp-2,sstackssp,0); break;case 1: gen(j=,sstackssp-2,sstackssp,0); break;case 3: gen(j,sstackssp-2,sstackssp,0); break;case 4: gen(j,sstackssp-2,sstackssp,0); break;case 5: gen(j=,sstackssp-2,

44、sstackssp,0); break; gen(j,oth,oth,0); sp1=sp1-3; ssp=ssp-3;label+;n1.sy1=tempsy; break;103:/B-(B) label=label-1;ssp=ssp-3;sp1=sp1-3;label+;n1.sy1=tempsy; break;104:/B-NOT Blabel=label-1;templabel=ntab2label.tc; ntab2label.tc=ntab2label.fc;ntab2label.fc=templabel;ssp=ssp-2;sp1=sp1-2;label+;n1.sy1=te

45、mpsy; break;105:/A-B AND backpatch(ntab2label-1.tc,nxq); label=label-1;ssp=ssp-2;sp1=sp1-2;label+;n1.sy1=EA;break;case 106:/B-ABlabel=label-2;ntab2label.tc=ntab2label+1.tc; ntab2label.fc=merg(ntab2label.fc,ntab2label+1.fc); ssp=ssp-2;sp1=sp1-2;label+;n1.sy1=tempsy;break;case 107:/O-B ORbackpatch(nta

46、b2label-1.fc,nxq); label=label-1;ssp=ssp-2;sp1=sp1-2;label+;n1.sy1=E0;break;case 108:/B-OBlabel=label-2;ntab2label.fc=ntab2label+1.fc; ntab2label.tc=merg(ntab2label.tc,ntab2label+1.tc); ssp=ssp-2;sp1=sp1-2;label+;n1.sy1=tempsy;break;lrparse2(num);/ 继续分析if(lr1=ACC) return 1;/ 分析结束 /*测试字符是否为表达式中的值(不包括

47、:)*/ test(int value)switch(value)case intconst:case ident:case plus:case sub:case times:case div:case becomes:case lparent:case rparent:case rop:case op_and:case op_or:case op_not:return 1;default:return 0;/*/ lrparse()int i1=0;int num=0;/ 初始化布尔缓冲区指针if(test(n.sy1)/ 确定为什么语句if(stacksp.sy1=sy_while) si

48、gn=2;/while 语句elseif(stacksp.sy1=sy_if) sign=3;/if 语句else sign=1;/ 赋值语句do/ 将字符信息存入布尔或算数缓冲区ibufi1.sy1=n.sy1;ibufi1.pos=n.pos;readnu();/ 取当前字符i1+;/ 布尔缓冲区指针后移while(test(n.sy1);/ 只要是表达式当中的值 ,就放入缓冲区 ibufi1.sy1=jinghao;pbuf-;/ 词法分析缓冲区指针 -1sstack0.sy1=jinghao;ssp=0;/ 符号栈初始化if(sign=1)/ 为赋值表达式sp1=0;/ 从状态栈初始化

49、 stack1sp1=0;num=2;n1.sy1=ibufnum.sy1;/ 取当前布尔或算数缓冲区字符名n1.pos=ibufnum.pos;/ 取当前布尔或算数缓冲区字符地址 lrparse1(num);/ 赋值语句分析n.sy1=a;/ 语句分析当前为赋值表达式 aif(sign=2)|(sign=3)/if 语句或 while 语句pointmark+;/ 下层嵌套labelmarkpointmark.nxq1=nxq;/ 取下一条sp1=0;/ 状态栈初始化stack1sp1=0;num=0;/ 缓冲区初始化n1.sy1=ibufnum.sy1;n1.pos=ibufnum.pos

50、;lrparse2(num);/ 布尔表达式分析 labelmarkpointmark.tc1=ntab2label-1.tc;/ 记录布尔表达式真值地 址labelmarkpointmark.fc1=ntab2label-1.fc;/ 记录布尔表达式假值地 址backpatch(labelmarkpointmark.tc1,nxq);/ 回填 t 值n.sy1=e;/ 语句分析的当前符号名存放布尔表达式名字lr=actionstacksp.posn.sy1;/ 查 actio 表的值 printf(stack%d=%dttn=%dttlr=%dn,sp,stacksp.pos,n.sy1,lr);/ 输出状态栈信息if(lr=0)/019 的移进状态sp+;stacksp.pos=lr; stacksp.sy1=n.sy1; readnu();lr

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!