天津理工大学编译原理试验3:语义分析与中间代码生成.docx
大讲记大塔实验报告学院(系)名称:计算机与通信工程学院姓名学号专业班级实验项目实验三:语义分析与中间代码生成课程名称编译原理课程代码实验时间实验地点计算机软件实验室7-220计算机软件实验室7-215批改意见成绩教师签字:实验内容:可选择LLl分析法、算符优先分析法、LR分析法之一,实现如下表达式文法的语法制导翻译过程。文法GE如下所示:E-E+TIE-TITT-T*FIT/FIFF-PaFIPP(E)Ii要求构造出符合语义分析要求的属性文法描述,并在完成实验二(语法分析)的基础上,进行语义分析程序设计,最终输出与测试用例等价的四元式中间代码序列。实验目的:1 .掌握语法制导翻译的基本功能。2 .巩固对语义分析的基本功能和原理的认识。3 .能够基于语法制导翻译的知识进行语义分析。4 .掌握类高级语言中基本语句所对应的语义动作。5 .理解并处理语义分析中的异常和错误。实验要求:1 .在实验二的基础上,实现语法制导翻译功能,输出翻译后所得四元式序列;2 .要求详细描述所选分析方法进行制导翻译的设计过程;3 .完成对所设计分析器的功能测试,并给出测试数据和实验结果;4 .为增加程序可读性,请在程序中进行适当注释说明;5 .整理上机步骤,总结经验和体会;6 .认真完成并按时提交实验报告。【实验过程记录(源程序、测试用例、测试结果及心得体会等)】#include<iostream>#include<cstring>#definesize1024usingnamespacestd;intstep=();typedefstructvariable_T(charOPerateJ操作符stringVar1;变量1stringvar2;变量2intnum;第几个变量variable_T;VariabIe_Ttsize;记录四元式变量的变量iniIsize=-I;/依示是第tsize+1个变量typedefstructchar_stack(charcontentJ/当前字符stringendchar:这个符号代表的中间变量可以是i,也可以是tl,t2,等等intnum;和该字符相关的中间变量的序号chajstack;stringtable1913=/+-*a)#(iETFP*0*/"e"err","e"Je"Je","err","e飞5”,飞6","1","2","3","4",/*1*,'s7",飞8"JenvelT”,“err”,"eir”acc”,“enVerr7err“JenVenVerr",/*2*/,r3","r3,"s9,"sl","err,"r3",yy',e,',err,'err"err'',err,'err,/*3*/,r6",',r6",r6,"r6',"err,"r6",''>>rr,'err,err,err,err,/*4*/"r8","r8",',r8",ur8,"sl,r8",'Y8rr',e,'err'',err',e'',e,/*5*/,'err*,e>''err','err',',err,',err'"s5",s6",',c",2,"3","4u,/*6*/"rl0","10"Jrl0",'T10",'T10",'Tl(,'T10'',"err"Jerr","err","err"Jerr","err",*7*/"e"Je","err"Jerr"e"Je"Je","s5","s6","err","d",“3“,“4",*8*/,'err',errW',',e,','err,err,e'',"s5',s6","err,"e,"3","4°,*9*/,errW',',err,','err,7,err,err,err,',"s5","s6","err'"err","f',"4,/10*/,err',e,err,'e,e',e'',''e,"s5,t"s6',',err","err'"g'"4",*11*/,err,err'',''e,','err,err,7,err',',err,s5","s6',e",''err","h",',4u,*12*/"s7",err,err,slo,err,err,errerr,err,err,err13*/"rl",'r,"s9","slO"eVTl",R"JeVeVerr",5,"eVe”14*/"r2","r2,s9,sl","e,m2m,2W',err,7,e,7,e,err,err,15*/"r4","r4,w,4»1l-zfHII-_Htw,zfIlMw,z<HH-HH_l»”“-_11_H*->r4,r4terr,r4r4,err,err,err,err,err,err16*/"r5","r5,r,r3,r5,err,r3,r5,err,err,err,err,errerr*17*/,r7","r7","r7'"r7",',err'"r7",'Y7>'',',e,'err,',err,err',err,*18*/',r9",r9","r9'"r9u,"r9u,',r9",',r9,'err,''err',',e'',err'','err,err',;inigetLength(charstrsize)(inti=0;while(stri!=,)i+;returni;)intgetLengthc(char_stackstrsize)(inti=O;vhile(stri.conlent!=,0')i+;returni;intgetstringLength(stringstr)inti=O;while(stri!=,O')i+;returni;)chargettop(charstacksize,inttop)(if(stacktop!='0')returnstacktop;elsereturnvoidpopstack(char*stack,int*pointer,inttimes)intp;fbr(inti=l;i<=times;i+)(p=*pointer;stackp='0'(*pointer)-;1voidPoPStaCkC(ChaJStaCk*stack,int*poinler,inttimes)intp;fbr(inti=l;i<=times;i+)p=*pointer;stackp.content=,0,;(*pointer)"1voidPUShStaCk(Char_stack*stack,int*pointer,char*stack_state,int*poinler_state,charstr,charsxjntx)inti=0;if(x=0)COUt<<"ttt状态"<<sx<<”进状态栈elseif(x=l)CoUtVV"状态"VVsxVV”进状态栈”;if(str!=,)(cout<<str<<"进字符栈":(*poinler)+;stack(*pointer).Content=Str;(*pointer_state)+;stack_state(*pointer_state)=sx;intgetcol(chartop)(Switch(Iop)(casereturnO;case-':return1;case'*':return2;caseV,:retum3;case'a':retum4;case'),:return5;casereturn6;casereturn7;case'i,:return8;case,E':return9;case,T':return10;case'F:return11;case,P':return12;default:cout<<"Error!Thischaracterstringisnotthisgrammer,ssentence,"<<endl;return-1;intgetraw(charraw)(switch(raw)(case'0":return0;case,:return1;case,2':return2;case,3':return3;case,4,:return4;case,5,:return5;case,6':return6;case,7,:return7;case,8':return8;case,9':return9;case,a,:return10;case,b':return11;case'c':return12;case,d':return13;case,e,:return14;case'f:return15;case'g':return16;case,h,:return17;case,i,:return18;default:cout<<"Error!Thischaracterstringisnotthisgrammer'ssentence."<<endl;return-1;chargetraw_content(stringstr)(if(str="'l")return'elseif(str="2")return'2'elseif(str="3")return3;elseif(str=,4")return'4'elseif(str="c")return'c'elseif(str=,'d")return'd'elseif(str="e")return'e'elseif(str="f')return'f;elseif(slr="g")return'g,;elseif(str="h")return'h,;elseif(str="i")return'i,;stringget_lx(intnum)switch(num)case 1:return,t,;case 2:return',t2"case 3:return"t3"case 4:return',t4"case 5:return,t5"case 6:return,'t6"case 7:return"t7"case 8:return',t8"case 9:return'rt9"case 10:return',tl'r;case 11:return,tl,;case 12:return"tl2"case 13:return''tl3"case 14:return,tl4u;case 15:return,tl5,r;case 16:return',tl6"/.本程序暂时用到这么多,等有时间编写合适的可以将数字转换为字符串的函数时,即可更改本函数)voidshow(charstrsize,intindex)(inilength=getLenglh(str);if(index!=-l)cout<<"f'fbr(inti=index+1;i<length;i+)cout<<stri;voidshowc(char_stackstrsize,intindex)(intlength=getLengthc(str);if(index!=-l)cout<<"t"for(inti=index+1;i<length;i+)cout<<stri.content;voidSWitCh.method(Char_stack*stack,int*pointer,char*state_stack,int*pointer_state,stringproduction,char*strjnt*index)(step+;CoUt<<"n"<<step<<"t"显示步骤ShOW(State_stack,-1);显示状态栈cout<<'<t"ShoWe(StaCk,-1);显示符号站cout<<"t"<<str(X?ndex)<<"t"显示当前字符ShOW(Str,(*index);显示输入串charc=str(*index);if(production="err,)(cout<<"Error!Thischaracterstringisnotthisgrammer,ssentence."<<endl;return;)elseif(production="s5")(charsx='5'(*index)+;pushstack(stack,pointer.state_stack,pointer_state,c,sx,0);)elseif(production="s6")(charsx='6'(*index)÷+;pushstack(stack,pointer.state_stack,pointer_state,c,sx,0);elseif(production="s7")(charsx='7,;(*index)+;pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);elseif(production="s8")(charsx=,8,;(*index)+;pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);elseif(production="s9")charsx='9'(*index)+;pushstack(stack,pointer.state_stack,pointer_state,c,sx,0);elseif(roduction="s10")(charsx=,a,;(*index)+;pushstack(stack,pointer,state_stack,pointer_state,c,sx,O);elseif(production="sl1")(charsx='b'(*index)+;pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);elseif(production="s18")charsx-i,;(*index)+;pushstack(stack,pointer.state_stack,pointer_state,c,sx,0);elseif(production="rl")(intpo=(*pointer)P规约该表达式,有效变量在E的endchar中,需要找到E的位置,即面的操作stringst=stackpo.endchar;/X对应Fpo-=2;stringSe=StaCkpo.endchar;在规约之前记录下要规约的字符所代表的变量。对应Ttsize+;新增临时变量ttsize.num=tsize+l;/下面四个表达式是按照上面的规约式进行的赋值ttsize.operate=*+'ttsize.varl=se;ttsize.var2=st;cout<<"t("<<ttsize.operate<<,"<<ttsize.varl<<,',<<ttsize.var2<<",t,<<ttsize.num<<")"intp=(*pointer_stale);p-=3;charsecond=state-stackp;inti=getraw(second);intj=getcol('E');charc_out=getraw_content(tablei|jJ);8a<<,ff1:用E->E+T规约且”;popslack(state_stack,pointer_state,3);PoPStaCkC(StaCk,pointer,3);charc-E'str(*index);pushstack(stack,pointer,stale_stack,poinier_state,c,c_oul,1);strings=get_tx(ttsize.num);StaCk(*pointer).endchar=s;把保存E+T规约的结果的变量保存至当前字符的终结符elseif(production="r2")(inipo=(*poinler);/AP规约该表达式,有效变量在E的endchar中,需要找到E的位置,即面的操作stringst=stackpo.endchar;/X对应Tpo-=2;StringSe=StaCkpoendchar;在规约之前记录下要规约的字符所代表的变量。对应Etsize+;新增临时变量ttsize.num=tsize+1;/下面四个表达式是按照上面的规约式进行的赋值ttsize.operate='-'ttsize.varl=se;ttsize.var2=st;cout<<"t("<<ttsize.operate<<","<<ltsize.varl<<,7,<<ttsize.var2<<<t"<<ttsize.num<<")"intp=(*pointer_state);p-=3;charsecond=state_stackp;inti=getraw(second);intj=getcol('E');charc_out=getraw_content(tableij);CoUtVV"tr2:用E->E-T规约且”;popstack(state_stack,pointer_state,3);popstackc(stack,pointer,3);charc='E,str(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);strings=get-tx(ttsize.num);StaCk(*poinier).endchar=s;把保存E-T规约的结果的变量保存至当前字符的终结符)elseif(roduction="r3")(StringS=S3ck(*pointer).endchar,在规约之前记录下要规约的字符所代表的变量intp=(*pointer_state);P-;charsecond=state_stackp;inti=getraw(second);intj=getcol('E');charc_out=getraw_content(tableijj);8仇田山3:用E->T规约且”;popstack(state_stack,pointer_state,1);popstackc(stack,pointer,1);charc='E,str(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);StaCk(*poinier).endchar=s;将记录下的变量赋值给规约后的字符elseif(production="r4")(intpo=(*pointer);/AP规约该表达式,有效变量在E的endchar中,需要找到E的位置,即面的操作StringSf=StaCkpo.endchar;X对应Fpo-=2;stringSt=StaCkpo.endchar;在规约之前记录下要规约的字符所代表的变量。对应Ttsize+;新增临时变量ttsize.num=tsize+l;/下面四个表达式是按照上面的规约式进行的赋值ttsize.operate='*'ttsize.varl=st;ttsize.var2=sf;cout<<',t("<<ttsize.operate<<'"<<ttsizel.varl<<,',<<ttsize.var2<<'t',<<ttsize.num<<")"intp=(*pointer_state);p-=3;charsecond=state_stackp;inti=getraw(second);intj=getcol(T);charc_out=getraw_content(tableij);CoUt<<"tr4:用T->T*F规约且“:popstack(state_stack,pointer_state,3);POPStaCkC(StaCk,pointer,3);charc=T,str(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);strings=get_tx(ttsize.num);StaCkK"pointer)J.endchar=s;把保存T*F规约的结果的变量保存至当前字符的终结符elseif(production="r5")(intpo=(*pointer)P规约该表达式,有效变量在E的endchar中,需要找到E的位置,即面的操作StringSf=StaCkpo.endchar;X对应Fpo-=2;stringSt=StaCkpo.endchar;在规约之前记录下要规约的字符所代表的变量。对应Ttsize+;新增临时变量UtSiZe.num=tsize+l;下面四个表达式是按照上面的规约式进行的赋值ttsize.operate=7,;ttsize.var!=st;ttsize.var2=sf;cout<<',t("<<tltsize.operate<<',"<<ttsize.varl<<',',<<ttsize.var2<<,t,<<ttsize.num<<")"intp=(*pointer_state);p-=3;charsecond=state-stackp;inti=getraw(second);intj=getcol(T);charc_out=getraw_content(tableij);CoUtV<"tr5:用TQT/F规约且”;popstack(state_stack,pointer_state,3);popstackc(stack,pointer,3);charc=Tstr(*index);pushstack(stack,pointer,stale_stack,poinier_state,c,c_oul,1);strings=get_tx(ttsizel.num);StaCk(*pointer).endchar=s;把保存T/F规约的结果的变量保存至当前字符的终结符elseif(production="r6")(StringS=StaCkK*poinler).endchar;在规约之前记录下要规约的字符所代表的变量intp=(*pointer.state);P-Scharsecond=state-stacklp;inti=getraw(second);intj=gelcol('T');charc_out=getraw_content(tableij);8仇田山6:用T->F规约且”;popslack(state_stack,pointer_state,1);popstackc(stack,pointer,1);charc=T;/str(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);StaCkK*poinler).endchar=s;将记录下的变量赋值给规约后的字符)elseif(production="r7")(intpo=(*poinier);/AP规约该表达式,有效变量在E的endchar中,需要找到E的位置,即面的操作stringSf=StaCkpo.endchar;X对应Fo-=2;StringSP=StaCkpo.endchar;在规约之前记录下要规约的字符所代表的变量。对应PISize+;/渐增临时变量ttsize.num=tsize+1;下面四个表达式是按照上面的规约式进行的赋值ttsize.operate-a,;ttsize.varl=sp;ttsizel.var2=sf;cout<<',t("<<ltsize.operate<<'"<<llsize.varl<<",',<<ttsize.var2<<"',<<ltsize.num<<")"intp=(*pointer_state);p-=3;charsecond=state-stackp;inti=getraw(second);intj=gelcol('F');charc_out=getraw_content(tableij);8a<<"JJ7:用F->PAF规约且”;popstack(state_stack.pointer_state,3);popstackc(stack,pointer,3);charc='F;/str(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);strings=get_tx(ttsize.num);StaCk(*pointer).endchar=s;把保存PAF规约的结果的变量保存至当前字符的终结符elseif(produclion="r8")(intp=(*pointer_stale);P-;charsecond=state-stackp;inti=getraw(second);intj=getcol('F');charc_out=getraw_content(lableij);3仇<V田山8:用F>P规约且”;stringS=StaCk(*pointer).endchar;/在规约之前记录下要规约的字符所代表的变量popstack(state_stack,pointer_state,1);popstackc(stack,pointer,1);charc='F;/str(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);StaCk(*pointer).endchar=s;将记录下的变量赋值给规约后的字符elseif(roduction="r9")intp=(*pointer_state);p-=3;charsecond=state-stackp;inti=getraw(second);intj=getcol('P');charc_out=getraw_content(tablei|j);COUt<<"Ztr9:用P->(E)规约且“;intpo=(*poinier);/AP规约该表达式,有效变量在E的endchar中,需要找到E的位置,即面的操作po-;stringS=StaCkpoLendchar;/在规约之前记录下要规约的字符所代表的变量popstack(state_stack,pointer_state,3);popstackc(stack,pointer,3);charc='P,str(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_oul,1);StaCk(*poinier).endchar=s;将记录下的变量赋值给规约后的字符elseif(production="rlO")intp=(*pointer_state);P-Scharsecond=state_stackp;inti=getraw(second);intj=getcol(,P');charc-out=getraw-content(tableij);CoUt<<"tttrl:用P>i规约且”;popstack(state_stack,pointer_state,1);popstackc(stack,pointer,1);charc='Pstr(*index);pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);stack(*pointer)j.endchar="i"elseif(pro<luclion="acc")(cout<<"tttacc,分析成功”;(*index)+;1intmain()(charstrsize;/接受字符串的数组Char_stackStaCksizeJ/进行比对的栈intpointer=-1;,指向栈顶的指针intlength=。;记录字符串长度intindex=。;/记录输入字符串chartop;char$1210,512©卜回26»/状态栈intPOinlejstaie=-1;状态栈指针intij;i表示行,j表示列stringproduction;boolmatch=false;cout<<"Pleaseinputcharacterstring:"cin>>str;length=getLength(str);strlength='#'strlength+1=,0,;pointer+;stackIpointer.content='#"Pointer_state+:state_slackpoinler_state='0,;coutvv”步骤t状态栈t符号栈t当前符号t输入串乂四元式tt说明"VVend1;while(strindex!='0")(top=gettop(state_stack,PointeJState);获取状态栈栈顶元素i=getraw(top);j=gelcol(slrindex);roduction=tableijj;switch_method(stack,&pointer,state_stack,&pointer_state,production,str,&index);returnO;璃实脸3eePlease:inputcharacterstring:ii+i*iI步骤状态栈符号栈当前符号输入串四元式说明10i状态6进状态栈i进字符栈206304fliflP-10:用一>1规约且状态4进状态栈P进字符栈状态b进状态栈”进字符栈104b504b6flP,i+i*i#+状态6进状态栈i进字符栈10:用?一>1规约且状态1进状态栈P进字符栈604bl1PP+i*i#通:用1F规约且状态h进状态栈F进字符栈104bh803flP*F那+i*ift+i*i4C,i,i,tl)房:用F->PT规约且状态3进状态栈F进字符栈6:用T汴规约且状态2进状态栈T进字符栈9021001Il01712017613017414017315017d16017dg17017d9618017d9419017d9f20017d2101卜+itp+F+*i*p*F+AT物肥门门门门械械物物门物+i*i4+i*i4i*i#* i¥* i* i* i¥(+,tl,t2,t3)遮:用E->T规约且状态1进状态栈E进字符栈状态7进状态栈+进字符栈状态6进状态栈i进字符栈1。:用一>1规约且状态4进状态栈P进字符栈宣:用F->P规约且状态3进状态栈I-进字符栈通:用TW规约且状态d进状态栈T进字符栈状态9进状态栈*进字符栈状态6进状态栈i进字符栈I氏用?一万规约且状态I进状态栈P进字符栈通:用I;一P规约且状态I'进状态栈-进字符栈M:用T->T*F规约且状态d进状态栈T进字符栈1:用5旭+丁规约且状态I摩态栈I-进字符栈分析成功Processexite