廣工編譯原理實(shí)驗(yàn)報(bào)告_第1頁
廣工編譯原理實(shí)驗(yàn)報(bào)告_第2頁
廣工編譯原理實(shí)驗(yàn)報(bào)告_第3頁
廣工編譯原理實(shí)驗(yàn)報(bào)告_第4頁
廣工編譯原理實(shí)驗(yàn)報(bào)告_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

.PAGE.<<編譯原理>>課實(shí)驗(yàn)報(bào)告工程名稱PL/0編譯器學(xué)院____計(jì)算機(jī)學(xué)院_______專業(yè)__年級(jí)班別________學(xué)號(hào)_學(xué)生__________輔導(dǎo)教師_______成績______________目錄一、課實(shí)驗(yàn)的容4二、實(shí)驗(yàn)修改局部4三、概述11四、構(gòu)造設(shè)計(jì)說明11五、各功能模塊描述14六、主要成份描述14七、測(cè)試用例16八、開發(fā)過程和完成情況21一、課實(shí)驗(yàn)的容對(duì)PL/0作以下修改擴(kuò)大:〔1〕增加單詞:保存字ELSE,F(xiàn)OR,STEP,RETURN運(yùn)算符+=,-=,++,--,&,|,~〔2〕修改單詞:不等號(hào)#改為<>〔3〕增加條件語句的ELSE子句二、實(shí)驗(yàn)修改局部:1、增加四個(gè)保存字和七個(gè)運(yùn)算符,共十一個(gè)單詞。修改局部:#definesymnum43//保存字從32增加到43個(gè)2、增加五個(gè)保存字:ELSE,F(xiàn)OR,STEP,RETURNeq\o\ac(○,1)頭文件pl0.henumsymbol{新增加單詞:elsesym,forsym,stepsym,returnsym,pluseq/*+=*/,plusone/*++*/,plus/*+*/,minuseq/*-=*/,minusone/*--*/,minus/*-*/,and,or,not}eq\o\ac(○,2)頭文件pl0.h#definenorw24//關(guān)鍵字從13增加到24個(gè)eq\o\ac(○,3)PL0.cppinit();新增加:〔增加后數(shù)組的容要再次根據(jù)字母順序重新排列〕strcpy(&(word[0][0]),"begin");strcpy(&(word[1][0]),"call");strcpy(&(word[2][0]),"const");strcpy(&(word[3][0]),"do"); strcpy(&(word[4][0]),"else");/*增加單詞:保存字else*/ strcpy(&(word[5][0]),"end");strcpy(&(word[6][0]),"for");/*增加單詞:保存字for*/ strcpy(&(word[7][0]),"if");strcpy(&(word[8][0]),"odd");strcpy(&(word[9][0]),"procedure");strcpy(&(word[10][0]),"read"); strcpy(&(word[11][0]),"return");/*增加單詞:保存字return*/ strcpy(&(word[12][0]),"step");/*增加單詞:保存字step*/strcpy(&(word[13][0]),"then");strcpy(&(word[14][0]),"while");strcpy(&(word[15][0]),"write");wsym[0]=beginsym;wsym[1]=callsym;wsym[2]=constsym;wsym[3]=dosym;wsym[4]=elsesym;/*else*/wsym[5]=endsym;wsym[6]=forsym; /*for*/wsym[7]=ifsym;wsym[8]=oddsym;wsym[9]=procsym;wsym[10]=readsym;wsym[11]=returnsym;/*return*/wsym[12]=stepsym;/*step*/wsym[13]=thensym;wsym[14]=whilesym;wsym[15]=writesym;3、增加四個(gè)運(yùn)算符:+=,-=,++,--,∧,∨,┓PL0.cppgetsym();增加對(duì)+,-,++,--,+=,-=的識(shí)別;Statement();增加對(duì)+,-,++,--,-=的語句的處理;eq\o\ac(○,1)Init〔〕中改動(dòng): ssym[‘&’]=and; ssym[‘|’]=or;ssym[‘~’]=not;facbegsys[plusone]=true;//添加前自加運(yùn)算facbegsys[minusone]=true;//添加前自減運(yùn)算eq\o\ac(○,2)Getsym〔〕增加的容:..intgetsym(){ inti,j,k; while(ch==''||ch==10||ch==9) { getchdo; } if(ch>='a'&&ch<='z') { k=0; do{ if(k<al) { a[k]=ch; k++; } getchdo; }while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');a[k]=0; strcpy(id,a); i=0; j=norw-1; do{ k=(i+j)/2; if(strcmp(id,word[k])<=0) { j=k-1; } if(strcmp(id,word[k])>=0) { i=k+1; } }while(i<=j); if(i-1>j) { sym=wsym[k];} else { sym=ident; } } else { if(ch>='0'&&ch<='9') { k=0; num=0; sym=number; do{ num=10*num+ch-'0'; k++; getchdo; }while(ch>='0'&&ch<='9');/*獲取數(shù)字的值*/ k--; if(k>nmax) { error(30); } } else { if(ch==':')/*檢測(cè)賦值符號(hào)*/ { getchdo; if(ch=='=') { sym=bees; getchdo; } else { sym=nul;/*不能識(shí)別的符號(hào)*/ } } else { if(ch=='<')/*檢測(cè)小于或小于等于符號(hào)*/ { getchdo; if(ch=='=') { sym=leq; getchdo; } else { sym=lss; } } elseif(ch=='>')/*檢測(cè)大于或大于等于符號(hào)*/ { getchdo; if(ch=='=') { sym=geq; getchdo; } else { sym=gtr; } }/*這里之間為添加的容*/ elseif(ch=='+'){ /*檢測(cè)+,+=,++符號(hào)*/ getchdo; if(ch=='='){ sym=pluseq; getchdo; }elseif(ch=='+'){ sym=plusone;getchdo; }else{ sym=plus; } }elseif(ch=='-'){/*檢測(cè)-,-=,--符號(hào)*/ getchdo; if(ch=='=') { sym=minuseq; getchdo; } elseif(ch=='-') {sym=minusone; getchdo; } else { sym=minus; } }/*這里之間為添加的容*/else{ sym=ssym[ch];/*當(dāng)符號(hào)不滿足上述條件時(shí),全部按照單字符號(hào)處理*/ //getchdo; //richard if(sym!=period) { getchdo; } //endrichard } } } }return0;}..eq\o\ac(○,3)Statement()增加的容:(將本來"if(sym==bees)……〞局部的容修改為處理++,+=,--,-=),并在Statement()中定義變量intsym2;..if(sym==bees||sym==pluseq||sym==minuseq||sym==plusone||sym==minusone) {sym2=sym; getsymdo; gendo(lod,lev-table[i].level,table[i].adr); } else { error(13); } if(sym2==plusone||sym2==minusone)/*準(zhǔn)備按照a++、a--語句處理,與read類似*/ { if(i!=0) {if(sym2==plusone) { gendo(lit,0,1); gendo(opr,0,2); gendo(sto,lev-table[i].level,table[i].adr); } if(sym2==minusone) { gendo(lit,0,1); gendo(opr,0,3); gendo(sto,lev-table[i].level,table[i].adr); } } } else { memcpy(nxtlev,fsys,sizeof(bool)*symnum); expressiondo(nxtlev,ptx,lev); if(i!=0) { if(sym2==bees) gendo(sto,lev-table[i].level,table[i].adr); if(sym2==pluseq) {gendo(opr,0,2); gendo(sto,lev-table[i].level,table[i].adr); } if(sym2==minuseq) {gendo(opr,0,3); gendo(sto,lev-table[i].level,table[i].adr); } } }//else } }}4、修改單詞:不等號(hào)#改為<>PL0.cppinit();移除:ssym['#']=neq;eq\o\ac(○,1)在getsym()里增加對(duì)<>的識(shí)別(在<或<=根底上修改)。下面為在<根底上修改,注意在if(ch==’<’)中修改,不包括elseif(ch=='>')那局部:if(ch=='<')/*檢測(cè)小于或小于等于符號(hào)*/ { getchdo; if(ch=='=') { sym=leq;getchdo; }/*在之間添加*/ elseif(ch=='>')//addneq { sym=neq; getchdo; }/*在之間添加*/ else { sym=lss; } }5、增加條件語句的ELSE子句PL0.cppeq\o\ac(○,1)在statement()里的"if...then〞語句處理的根底上添加對(duì)else子句的處理,使之能處理if……then……else……的語句。..else { if(sym==ifsym)/*準(zhǔn)備按照if語句處理*/ { getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[thensym]=true; nxtlev[dosym]=true;/*后跟符號(hào)為then或do*/ conditiondo(nxtlev,ptx,lev);/*調(diào)用條件處理〔邏輯運(yùn)算〕函數(shù)*/ if(sym==thensym) { getsymdo; } else { error(16);/*缺少then*/ } cx1=cx;/*保存當(dāng)前指令地址*/ gendo(jpc,0,0);/*生成條件跳轉(zhuǎn)指令,跳轉(zhuǎn)地址暫寫0*//*這里之間開場(chǎng)添加*/ memcpy(nxtlev,fsys,sizeof(bool)*symnum);//添加后跟符號(hào) nxtlev[elsesym]=true; statementdo(nxtlev,ptx,lev);/*處理then后的語句*/ code[cx1].a=cx;/*經(jīng)statement處理后,cx為then后語句執(zhí)行完的位置,它正是前面未定的跳轉(zhuǎn)地址*/ if(sym==elsesym) { cx2=cx; getsymdo; gendo(jmp,0,0); code[cx1].a=cx; statementdo(fsys,ptx,lev); code[cx2].a=cx; } /*這里之間開場(chǎng)添加*/ } else { if(sym==beginsym)/*準(zhǔn)備按照復(fù)合語句處理*/ { getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[semicolon]=true; nxtlev[endsym]=true;/*后跟符號(hào)為分號(hào)或end*/ /*循環(huán)調(diào)用語句處理函數(shù),直到下一個(gè)符號(hào)不是語句開場(chǎng)符號(hào)或收到end*/ statementdo(nxtlev,ptx,lev); while(inset(sym,statbegsys)||sym==semicolon) { if(sym==semicolon) { getsymdo; } else { error(10);/*缺少分號(hào)*/ } statementdo(nxtlev,ptx,lev); } if(sym==endsym) { getsymdo; } else { error(17);/*缺少end或分號(hào)*/ } }..eq\o\ac(○,2)寫出相關(guān)文法:G(S):S→ifSelseS|ifS|aeq\o\ac(○,3)Else語法圖:三、概述源語言:PL/0語言目標(biāo)語言:假想棧式計(jì)算機(jī)的匯編語言實(shí)現(xiàn)工具:VC++6.0運(yùn)行平臺(tái):Windows7四、構(gòu)造設(shè)計(jì)說明1、PL/0編譯程序的構(gòu)造圖如下:由于PL/0編譯程序采用一趟掃描方法,所以語法語義分析過程block是整個(gè)編譯程序的核心。下面給出編譯程序的總體流程圖,以弄清block過程在整個(gè)編譯程序中的作用。在流程圖中可以看出,主程序置初值后先調(diào)整用讀單詞過程getsym取一個(gè)單詞,然后再調(diào)用語法分析過程block,直到遇源程序的完畢符".〞為止。各功能模塊描述eq\o\ac(○,1)GetSym():詞法分析,從源文件中讀出假設(shè)干有效字符,組成token串,識(shí)別它的類型為保存字/標(biāo)識(shí)符/數(shù)字或其它符號(hào)。..eq\o\ac(○,2)GEN():目標(biāo)代碼生成過程,本過程用于把生成的目標(biāo)代碼寫入目標(biāo)代碼數(shù)組,供后面的解釋器解釋執(zhí)行.eq\o\ac(○,3)TEST():測(cè)試當(dāng)前單詞是否合法eq\o\ac(○,4)ENTER():在名字表中參加一項(xiàng)eq\o\ac(○,5)POSITION():查找名字的位置,找到那么返回名字表中的位置,否那么返回0eq\o\ac(○,6)ConstDeclaration():常量聲明處理eq\o\ac(○,7)VarDeclaration():變量聲明處理eq\o\ac(○,8)ListCode():輸出目標(biāo)代碼清單eq\o\ac(○,9)FACTOR():因子處理過程eq\o\ac(○,10)TERM():項(xiàng)處理過程eq\o\ac(○,11)EXPRESSION():表達(dá)式處理過程eq\o\ac(○,12)CONDITION():條件處理過程eq\o\ac(○,13)STATEMENT():語句處理過程..eq\o\ac(○,14)Block():編譯程序主體,參數(shù):lev:這一次語法分析所在的層次,tx:符號(hào)表指針,eq\o\ac(○,15)fsys:用于出錯(cuò)恢復(fù)的單詞集合..eq\o\ac(○,16)BASE():通過過程基址求上一層過程的基址eq\o\ac(○,16)Interpret():解釋程序,PL/0編譯器產(chǎn)生的類PCODE目標(biāo)代碼解釋運(yùn)行過程六、主要成份描述1.符號(hào)表在編譯程序中符號(hào)表用來存放語言程序中出現(xiàn)的有關(guān)標(biāo)識(shí)符的屬性信息,這些信息集中反映了標(biāo)識(shí)符的語義特征屬性.符號(hào)表的主要功能如下:eq\o\ac(○,1)、收集符號(hào)屬性eq\o\ac(○,2)、上下文語義合法性檢查的依據(jù)eq\o\ac(○,3)、作為目標(biāo)代碼生成階段地址分配的依據(jù).eq\o\ac(○,4)、符號(hào)表的數(shù)據(jù)構(gòu)造:structtablestruct{charname[al];/*名字*/enumobjectkind;/*類型:const,var,arrayorprocedure*/intval;/*數(shù)值,僅const使用*/intlevel;/*所處層,僅const不使用*/intadr;/*地址,僅const不使用*/intsize;/*需要分配的數(shù)據(jù)區(qū)空間,僅procedure使用*/}; structtablestructtable[txmax];/*名字表*/2.運(yùn)行時(shí)的存儲(chǔ)組織和管理當(dāng)源程序經(jīng)過語法分析,如果未發(fā)現(xiàn)錯(cuò)誤時(shí),由編譯程序調(diào)用解釋程序,對(duì)存放在CODE中的代碼CODE[0]開場(chǎng)進(jìn)展解釋執(zhí)行.當(dāng)廢棄完畢后,記錄源程序中標(biāo)識(shí)符的TABLE表已沒有作用.因此存儲(chǔ)區(qū)只需以數(shù)組CODE存主的只讀目標(biāo)程序和運(yùn)行機(jī)制時(shí)的數(shù)據(jù)區(qū)S,S是由解釋程序定義的一維整數(shù)型數(shù)組.解釋執(zhí)行時(shí)的數(shù)據(jù)空間S為棧式計(jì)算機(jī)的在座空間,遵循后進(jìn)先出規(guī)那么,對(duì)每個(gè)過程(包括主程序)當(dāng)調(diào)用時(shí),才分配數(shù)據(jù)空間,退出過程進(jìn),那么所分配原那么的數(shù)據(jù)空間被釋放.解釋程序還定義了4個(gè)存放器:1、指令存放器.存放當(dāng)前正在解釋的一條目標(biāo)指令2、程序地址存放器.指向下一條要執(zhí)行的目標(biāo)程序的地址3、棧頂存放器.4、基址存放器.指向每個(gè)過程被調(diào)用時(shí),在數(shù)據(jù)區(qū)S中給它分配原那么的數(shù)據(jù)段起始地址,也稱基地址.為了實(shí)現(xiàn)過程被調(diào)用時(shí)給它分配數(shù)據(jù)段,過程運(yùn)行完畢后釋放數(shù)據(jù)段以及嵌套過程之間結(jié)標(biāo)志符引用的問題,當(dāng)過程被調(diào)用時(shí),在棧頂分配三個(gè)聯(lián)系單元,這三個(gè)聯(lián)系單元存放的容分別為:SL靜態(tài)鏈,動(dòng)態(tài)鏈DL,RA返回地址。3.語法分析方法語法分析的任務(wù)是識(shí)別由詞法分析給出的單詞符號(hào)序列在構(gòu)造上是否符合給定的文法規(guī)那么.PL/0編譯程序的語法分析采用了自頂向下的遞歸子程序法.粗略地說:就是對(duì)應(yīng)每個(gè)非終結(jié)符語法單元,編一個(gè)獨(dú)立的處理過程(或子程序).語法分析研究從讀入第一個(gè)單詞開場(chǎng)由非終結(jié)符’程序即開場(chǎng)符出發(fā),沿語法描述圖箭頭所指出的方向進(jìn)展分析.當(dāng)遇到非終結(jié)符時(shí),那么調(diào)用相應(yīng)的處理過程,從語法描述圖看也就進(jìn)入了一個(gè)語法單元,再沿當(dāng)前所進(jìn)入的語法描述圖的箭頭方向進(jìn)展分析,當(dāng)遇到描述圖中是終結(jié)符時(shí),那么判斷當(dāng)前讀入的單詞是否與圖中的終結(jié)符相匹配,假設(shè)匹配,那么執(zhí)行相應(yīng)的語義程序(就是翻譯程序).再讀取下一個(gè)單詞繼續(xù)分析.遇到分支點(diǎn)時(shí)將當(dāng)前的單詞與分支點(diǎn)上的多個(gè)終結(jié)符逐個(gè)相比擬,假設(shè)都不匹配時(shí)可能是進(jìn)入下一非終結(jié)符語法單位或是出錯(cuò).如果一個(gè)PL/0語言程序的單詞序列在整修語法分析中,都能逐個(gè)得到匹配,直到程序完畢’.’,這時(shí)就說所輸入的程序是正確的.對(duì)于正確的語法分析做相應(yīng)的語義翻譯,最終得出目標(biāo)程序.4.中間代碼表示PL/0編譯程序所產(chǎn)生的目標(biāo)代碼是一個(gè)假想棧式計(jì)算機(jī)的匯編語言,可稱為類pcode指令代碼,它不依賴任何實(shí)際計(jì)算機(jī),其指令集極為簡單,指令格式如下:fLalit0a將常數(shù)值取到棧頂,a為常數(shù)值Lodla將變量值取到棧頂,a為偏移量,l為層差Stola將棧頂容送入某變量單元中,a為偏移量,l為層差Cala調(diào)用過程,a為過程地址,l為層差I(lǐng)nt0a在運(yùn)行棧中為被調(diào)用的過程開辟a個(gè)單元的數(shù)據(jù)區(qū)jmp0a無條件跳轉(zhuǎn)至a地址Jpc0a條件跳轉(zhuǎn),當(dāng)棧頂布爾值非真那么跳轉(zhuǎn)至a地址,否那么順序執(zhí)行o

溫馨提示

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

評(píng)論

0/150

提交評(píng)論