編譯原理-語義分析-實驗報告_第1頁
編譯原理-語義分析-實驗報告_第2頁
編譯原理-語義分析-實驗報告_第3頁
編譯原理-語義分析-實驗報告_第4頁
編譯原理-語義分析-實驗報告_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

編譯原理實驗三:語義分析PAGEPAGE1編譯原理實驗三語義分析實驗報告學院:數(shù)學與計算機科學技術學院專業(yè):計算機科學與技術班級:級計算機班小組組員:姓名:學號:姓名:學號:姓名:學號:姓名:學號:實驗題目一、實驗目的要求學生用與實驗2相同的語言,編制語義分析程序。二、實驗準備微機CPU主頻以上,128M內存,安裝好C語言,PASCAL語言,或C++。三、實驗時間13學時四、實驗內容要求學生用與實驗2相同的語言,編制語義分析程序。定義該語言的語義成分,將語義分析程序編制成子程序,在實驗2分析出各語法單位后,分析其含義,并將可執(zhí)行語句或表達式翻譯為四元式輸出,并將錯誤信息輸出。實驗報告必須包括設計的思路,以及測試報告(輸入測試例子,輸出結果)。五、上交文檔1.實驗報告(書面);2.程序文件(通過網絡提交)。<program>::=<block>.<block>::=<const-decl><var-decl><proc-decl><statement><const-decl>::=const<const-assignment-list>;|ε<const-assignment-list>::=<ident>=<number>|<const-assignment-list>,<ident>=<number><var-decl>::=var<ident-list>;|ε<ident-list>::=<ident>|<ident-list>,<ident><proc-decl>::=<proc-decl>procedure<ident>;<block>;|ε<statement>::=<ident>:=<expression>|call<ident>|begin<statement-list>end|if<condition>then<statement>|while<condition>do<statement>|ε<statement-list>::=<statement>|<statement-list>;<statement><condition>::=odd<expression>|<expression><relation><expression><relation>::==|<>|<|>|<=|>=<expression>::=<term>|<adding-operator><term>|<expression><adding-operator><term><adding-operator>::=+|-<term>::=<factor>|<term><multiplying-operator><factor><multiplying-operator>::=*|/<factor>::=<ident>|<number>|(<expression>)注意:(1)"ε"表示空串。.(2)<ident>和<number>分別表示標識符和數(shù)。。實驗報告一.【需求分析】1.PL/M機器的機器指令LODa棧指針增1。裝入a的值到棧頂。STOa存棧頂?shù)絘。棧指針減1。LITn棧指針增1。裝入數(shù)n到棧頂。ADD棧頂兩個元素相加。彈出這兩個元素。存結果在棧頂。MUL棧頂兩個元素相乘。彈出這兩個元素。存結果在棧頂。這些指令以源碼形式由解釋程序執(zhí)行。2.PL/M程序文本及修改原文本:P→S;P|S;!S→id=EE→E+T|TT→T×F|FF→(E)|id|digitid→a|b|……|zdigit→0|1|……|9添上必要的語義動作print()產生中間代碼,及相應修改某些產生式修改后的文本:P1→S;P2P→S;!{print(END)}S→id=E{print(STOid)}E→T+E{print(ADD)}E→TT→F×T{print(MUL)}T→FF→(E)F→id{print(LODid)}F→digit{print(LITn)}id→a|b|……|zdigit→0|1|……|9(摘至附錄)二.【概要設計】參考附錄:有關編譯程序/解釋程序設計的簡單說明存儲區(qū)采用數(shù)組形式,變量按照說明的先后順序分配存儲單元。解釋程序利用運行棧進行,所有運算都在棧頂(和次棧頂)進行。編譯程序從源程序生成目標代碼。解釋程序基于前面描述的存儲管理方法執(zhí)行目標代碼。變量說明arrayx:保存用戶程序arraym:儲存用戶定義的變量arraystack:運行棧arraycode:存儲目標代碼arrayadr:用作操作數(shù)。如果操作數(shù)是變量,存的是地址。如果操作數(shù)是數(shù),存的是數(shù)值。函數(shù)說明Error():出錯處理程序init():初始讀入用戶程序到數(shù)組x。id()給出變量的地址getsym()讀入下一符號到變量current.S()處理語句。在處理完賦值號左邊后,如果下一符號是“=”,讀入下一符號,然后處理表達式。E()處理表達式。在處理好一個項(term)后,當下一符號是“+”,讀入下一符號,然后處理項。T()處理項。在處理好一個因子(factor)后,當下一符號是“×”,讀入下一符號,然后處理因子。F()處理因子。(1)如果當前符號是“(“,讀入下一符號,處理表達式。此后,如果當前符號是“)”,讀入下一符號,退出。(2)如果當前符號是變量,讀入下個符號,退出。(3)如果都不是,出錯error().Interpret()執(zhí)行用戶的目標代碼。變量“i”作為指令計數(shù)器。就是執(zhí)行code[i]fori=1,...,j-1.三.【詳細的算法描述及源程序清單】主程序main()的流程圖init()init()p()對讀入的源碼進行編譯對編譯得到的源碼進行解釋,并輸出結果開始讀入成功?編譯成功?結束失敗成功失敗成功代碼清單及注釋分析/*頭文件*/#include<stdio.h>#include<fstream.h>#include<stdlib.h>//與exit()相關#include<ctype.h>//與isdigit()和islower()相關/*輸入輸出文件流*/ifstreamfin("source.txt");//source.txt中存放的是要編譯的源碼,ofstreamfout("result.txt");/*數(shù)據(jù)結構*///常量定義,限定數(shù)組的長度#definecodemaxlength512#definexmaxlength512#definesmaxdepth512intcode_line;//寫code[]的時作計數(shù)器intx_line;//讀入文件時作計數(shù)器intn_error;//錯誤處理時作計數(shù)器charcurrent;//當前處理的字符intforward;//當前處理的字符在數(shù)組x[]中的下標intsp;//棧頂指針intsourcelength;//源碼的長度enumoperation//定義機器指令類型為枚舉operation{LOD,STO,LIT,ADD,MUL,END};structnode//數(shù)組code[]的元素結構,包含機器指令類型,{enumoperationop;//包含機器指令類型,chary;//及其操作數(shù)};structnodecode[codemaxlength];//存儲目標代碼charx[xmaxlength];//保存用戶程序intstack[smaxdepth];//運行棧intm[26][2];//變量標,即符號表intadr[2];//用作操作數(shù)/*getsym()*///讀入下一符號到變量currentchargetsym(){forward++;if(forward>sourcelength) exit(1);else returnx[forward];}/*error()*///出錯處理程序voiderror(char*str,inta){n_error++;//處理讀文件到x[]時出現(xiàn)的錯誤if(a==0)printf("(%d)讀入文件錯誤(第%d條語句):%s\n",n_error,x_line,str);//處理編譯目標代碼時出現(xiàn)的錯誤else{printf("(%d)編譯錯誤(第%d語句):%c%s\n",n_error,x_line,current,str);current=getsym();}}/*初始化init()*///初始化,并讀入用戶的源碼到數(shù)組x[]中boolinit(){x_line=1;n_error=0;//初始符號表for(inti=0;i<26;i++)m[i][0]=0;/*讀入文件source.txt中的源碼到x[]數(shù)組*/charc;printf("讀入文件中……\n");fin>>c;i=0;while(!fin.eof()){if(c=='\0'||c=='\n')//去空白符fin>>c;else { x[i]=c; if(c=='!') { fin>>c; if(fin.eof())//讀入文件成功 { sourcelength=i; return1; } else//出現(xiàn)了類似如下的代碼:"a=1;b=3;!;c=5;!", //即代碼中間出現(xiàn)了!的錯誤 { error("程序中間出現(xiàn)'!'/n",0); fin>>c; } } elseif(c==';')x_line++;//對源碼行的計數(shù) fin>>c; i++; if(i==xmaxlength)//x[]數(shù)組溢出檢查 { error("源碼太長,數(shù)組x溢出",0); exit(1);}}}if(i==0)error("source.txt為空文件!請輸入源碼!",0);//空文件elseerror("程序并未以'!'結尾",0);//讀入文件失敗return0;}/*id()*///給出變量的地址intid(charc){ returnc-97;}/*writecode()*///寫入代碼到code數(shù)組voidwritecode(enumoperationa,charb)//寫帶操作數(shù)的指令{code[code_line].op=a;code[code_line].y=b;code_line++;if(code_line==codemaxlength) //溢出檢查{printf("生成的目標代碼太長,code數(shù)組溢出!");exit(1);}}voidwritecode(enumoperationa) //寫不帶操作數(shù)的指令{code[code_line].op=a;code_line++;if(code_line==codemaxlength) //溢出檢查{printf("生成的目標代碼太長,code數(shù)組溢出!");exit(1);}}/*處理因子--F()*/intE();intF(){//處理F->(E)if(current=='('){ current=getsym();E();if(current==')') {current=getsym();return1; }else { error("括號不匹配",1);//類似a=1;b=2+(a*4;!錯誤current=x[--forward]; return0; }}//處理F->idelseif(islower(current)){if(m[id(current)][0]==0){error("變量未定義",1);//賦值語句右值中出現(xiàn)未定義的id,例a=b+1;!中的breturn0;}else{writecode(LOD,current); current=getsym(); return1; }}//處理F->digitelseif(isdigit(current)){writecode(LIT,current);current=getsym();return1;}//a=!情況和a=;!情況elseif(current=='!'||current==';') {error("右值出錯!",1);current=x[--forward];return0;}//非法變量else{error("非法變量",1);return0;}}/*處理項T()*///處理T->F或T->F*TintT(){F();if(current=='*')//處理T->F*T{current=getsym();T();writecode(MUL);//語義動作}return1;}/*處理表達式-E()*///處理E->T或E->T*EintE(){T();if(current=='+'){current=getsym();E();writecode(ADD);//語義動作}return1;}/*處理語句S()*///S→id=Eints(){charc;if(islower(current)){if(m[id(current)][0]==0)//判斷id是否已定義m[id(current)][0]=1;c=current;current=getsym();if(current=='='){current=getsym(); E(); writecode(STO,c);//語義動作 return1;}else{error("缺少'='",1);//a=1;b1;!情況 current=x[--forward]; E(); return0;}}elseif(current=='='){error("缺少左值",1);//a=1;=2;!情況E();return0;;}elseif(current==';'){error("空語句",1);//a=1;;b=2;!情況current=x[--forward];return1;}else{error("非法左值",1);//a=1;A=3;!if(current=='='){current=getsym(); E(); return1;}else{error("缺少'='",1);//a=1;A3;! current=x[--forward]; E(); return0;}}}/*編譯主程序P()*///處理P→S;P|S;!intp(){s();if(current==';'){x_line++;current=getsym();if(current=='!'){writecode(END);return1;}else{p();return1;}}else//a=1;b=2c=a+b;!{error("語句缺少';'",1);current=x[--forward];p();return0;}}/*show()*///輸出執(zhí)行棧中數(shù)據(jù)及將要執(zhí)行的目標指令intshow(enumoperationoper,charc){inti;for(i=0;i<=sp;i++)//輸出棧fout<<stack[i]<<"";fout<<'\t'<<'\t'<<'\t';switch(oper)//輸出指令{caseLOD:fout<<"LOD"<<c<<endl;break;caseSTO:fout<<"STO"<<c<<endl;break;caseLIT:fout<<"LIT"<<c<<endl;break;caseADD:fout<<"ADD"<<endl;break;caseMUL:fout<<"MUL"<<endl;break;}return0;}/*interpret()*///解釋程序,執(zhí)行用戶的目標代碼intinterpret(){code_line=0;sp=0;//用0表示棧底,即實際上棧是從stack[1]開始,這樣方便閱讀charc;enumoperationoper;while(1)//開始執(zhí)行{oper=code[code_line].op;c=code[code_line].y;show(oper,c);switch(oper){caseLOD:stack[++sp]=m[id(c)][1]; break;caseSTO:m[id(c)][1]=stack[sp--]; break;caseLIT:stack[++sp]=int(c)-48; break;caseADD:adr[0]=stack[sp--]; adr[1]=stack[sp]; stack[sp]=adr[0]+adr[1]; break;caseMUL:adr[0]=stack[sp--]; adr[1]=stack[sp]; stack[sp]=adr[0]*adr[1]; break;caseEND:return0;}if(oper==END)break;//執(zhí)行結束code_line++;}return0;}/*主程序*/intmain(){fout.open("code.txt");//建立文件,用來存目標代碼fout.close();fout.open("result.txt");//建立文件,用來顯示目標代碼的執(zhí)行過程fout.close();inti=0;charc;//////////////讀入源碼init();if(n_error){printf("初始讀入文本文件source.txt失敗!\n請修改源碼并重新讀入\n"); return0;}elseprintf("讀入文本文件source.txt成功!\n\n");/////////////編譯源碼,產生目標指令while(1){printf("是否進行編譯(按回車確定)");c=getchar();if(c=='\n')break;}printf("編譯中……\n");n_error=0;x_line=1;forward=-1;current=getsym();p();//編譯if(n_error){ printf("編譯失敗!請修改源碼并重新讀入文件!\n"); return0;}else{……\n\n"); enumoperationoper; fout.open("code.txt");//輸出目標代碼到code.txt文本中 while(1) { oper=code[i].op; c=code[i].y; switch(oper) { caseLOD: fout<<i<<":LOD"<<c<<endl;break; caseSTO: fout<<i<<":STO

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論