




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
.PAGE.<<編譯原理>>課實驗報告工程名稱PL/0編譯器學院____計算機學院_______專業(yè)__年級班別________學號_學生__________輔導教師_______成績______________目錄一、課實驗的容4二、實驗修改局部4三、概述11四、構(gòu)造設(shè)計說明11五、各功能模塊描述14六、主要成份描述14七、測試用例16八、開發(fā)過程和完成情況21一、課實驗的容對PL/0作以下修改擴大:〔1〕增加單詞:保存字ELSE,F(xiàn)OR,STEP,RETURN運算符+=,-=,++,--,&,|,~〔2〕修改單詞:不等號#改為<>〔3〕增加條件語句的ELSE子句二、實驗修改局部:1、增加四個保存字和七個運算符,共十一個單詞。修改局部:#definesymnum43//保存字從32增加到43個2、增加五個保存字: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個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、增加四個運算符:+=,-=,++,--,∧,∨,┓PL0.cppgetsym();增加對+,-,++,--,+=,-=的識別;Statement();增加對+,-,++,--,-=的語句的處理;eq\o\ac(○,1)Init〔〕中改動: ssym[‘&’]=and; ssym[‘|’]=or;ssym[‘~’]=not;facbegsys[plusone]=true;//添加前自加運算facbegsys[minusone]=true;//添加前自減運算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==':')/*檢測賦值符號*/ { getchdo; if(ch=='=') { sym=bees; getchdo; } else { sym=nul;/*不能識別的符號*/ } } else { if(ch=='<')/*檢測小于或小于等于符號*/ { getchdo; if(ch=='=') { sym=leq; getchdo; } else { sym=lss; } } elseif(ch=='>')/*檢測大于或大于等于符號*/ { getchdo; if(ch=='=') { sym=geq; getchdo; } else { sym=gtr; } }/*這里之間為添加的容*/ elseif(ch=='+'){ /*檢測+,+=,++符號*/ getchdo; if(ch=='='){ sym=pluseq; getchdo; }elseif(ch=='+'){ sym=plusone;getchdo; }else{ sym=plus; } }elseif(ch=='-'){/*檢測-,-=,--符號*/ getchdo; if(ch=='=') { sym=minuseq; getchdo; } elseif(ch=='-') {sym=minusone; getchdo; } else { sym=minus; } }/*這里之間為添加的容*/else{ sym=ssym[ch];/*當符號不滿足上述條件時,全部按照單字符號處理*/ //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)/*準備按照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、修改單詞:不等號#改為<>PL0.cppinit();移除:ssym['#']=neq;eq\o\ac(○,1)在getsym()里增加對<>的識別(在<或<=根底上修改)。下面為在<根底上修改,注意在if(ch==’<’)中修改,不包括elseif(ch=='>')那局部:if(ch=='<')/*檢測小于或小于等于符號*/ { 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〞語句處理的根底上添加對else子句的處理,使之能處理if……then……else……的語句。..else { if(sym==ifsym)/*準備按照if語句處理*/ { getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[thensym]=true; nxtlev[dosym]=true;/*后跟符號為then或do*/ conditiondo(nxtlev,ptx,lev);/*調(diào)用條件處理〔邏輯運算〕函數(shù)*/ if(sym==thensym) { getsymdo; } else { error(16);/*缺少then*/ } cx1=cx;/*保存當前指令地址*/ gendo(jpc,0,0);/*生成條件跳轉(zhuǎn)指令,跳轉(zhuǎn)地址暫寫0*//*這里之間開場添加*/ memcpy(nxtlev,fsys,sizeof(bool)*symnum);//添加后跟符號 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; } /*這里之間開場添加*/ } else { if(sym==beginsym)/*準備按照復合語句處理*/ { getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[semicolon]=true; nxtlev[endsym]=true;/*后跟符號為分號或end*/ /*循環(huán)調(diào)用語句處理函數(shù),直到下一個符號不是語句開場符號或收到end*/ statementdo(nxtlev,ptx,lev); while(inset(sym,statbegsys)||sym==semicolon) { if(sym==semicolon) { getsymdo; } else { error(10);/*缺少分號*/ } statementdo(nxtlev,ptx,lev); } if(sym==endsym) { getsymdo; } else { error(17);/*缺少end或分號*/ } }..eq\o\ac(○,2)寫出相關(guān)文法:G(S):S→ifSelseS|ifS|aeq\o\ac(○,3)Else語法圖:三、概述源語言:PL/0語言目標語言:假想棧式計算機的匯編語言實現(xiàn)工具:VC++6.0運行平臺:Windows7四、構(gòu)造設(shè)計說明1、PL/0編譯程序的構(gòu)造圖如下:由于PL/0編譯程序采用一趟掃描方法,所以語法語義分析過程block是整個編譯程序的核心。下面給出編譯程序的總體流程圖,以弄清block過程在整個編譯程序中的作用。在流程圖中可以看出,主程序置初值后先調(diào)整用讀單詞過程getsym取一個單詞,然后再調(diào)用語法分析過程block,直到遇源程序的完畢符".〞為止。各功能模塊描述eq\o\ac(○,1)GetSym():詞法分析,從源文件中讀出假設(shè)干有效字符,組成token串,識別它的類型為保存字/標識符/數(shù)字或其它符號。..eq\o\ac(○,2)GEN():目標代碼生成過程,本過程用于把生成的目標代碼寫入目標代碼數(shù)組,供后面的解釋器解釋執(zhí)行.eq\o\ac(○,3)TEST():測試當前單詞是否合法eq\o\ac(○,4)ENTER():在名字表中參加一項eq\o\ac(○,5)POSITION():查找名字的位置,找到那么返回名字表中的位置,否那么返回0eq\o\ac(○,6)ConstDeclaration():常量聲明處理eq\o\ac(○,7)VarDeclaration():變量聲明處理eq\o\ac(○,8)ListCode():輸出目標代碼清單eq\o\ac(○,9)FACTOR():因子處理過程eq\o\ac(○,10)TERM():項處理過程eq\o\ac(○,11)EXPRESSION():表達式處理過程eq\o\ac(○,12)CONDITION():條件處理過程eq\o\ac(○,13)STATEMENT():語句處理過程..eq\o\ac(○,14)Block():編譯程序主體,參數(shù):lev:這一次語法分析所在的層次,tx:符號表指針,eq\o\ac(○,15)fsys:用于出錯恢復的單詞集合..eq\o\ac(○,16)BASE():通過過程基址求上一層過程的基址eq\o\ac(○,16)Interpret():解釋程序,PL/0編譯器產(chǎn)生的類PCODE目標代碼解釋運行過程六、主要成份描述1.符號表在編譯程序中符號表用來存放語言程序中出現(xiàn)的有關(guān)標識符的屬性信息,這些信息集中反映了標識符的語義特征屬性.符號表的主要功能如下:eq\o\ac(○,1)、收集符號屬性eq\o\ac(○,2)、上下文語義合法性檢查的依據(jù)eq\o\ac(○,3)、作為目標代碼生成階段地址分配的依據(jù).eq\o\ac(○,4)、符號表的數(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.運行時的存儲組織和管理當源程序經(jīng)過語法分析,如果未發(fā)現(xiàn)錯誤時,由編譯程序調(diào)用解釋程序,對存放在CODE中的代碼CODE[0]開場進展解釋執(zhí)行.當廢棄完畢后,記錄源程序中標識符的TABLE表已沒有作用.因此存儲區(qū)只需以數(shù)組CODE存主的只讀目標程序和運行機制時的數(shù)據(jù)區(qū)S,S是由解釋程序定義的一維整數(shù)型數(shù)組.解釋執(zhí)行時的數(shù)據(jù)空間S為棧式計算機的在座空間,遵循后進先出規(guī)那么,對每個過程(包括主程序)當調(diào)用時,才分配數(shù)據(jù)空間,退出過程進,那么所分配原那么的數(shù)據(jù)空間被釋放.解釋程序還定義了4個存放器:1、指令存放器.存放當前正在解釋的一條目標指令2、程序地址存放器.指向下一條要執(zhí)行的目標程序的地址3、棧頂存放器.4、基址存放器.指向每個過程被調(diào)用時,在數(shù)據(jù)區(qū)S中給它分配原那么的數(shù)據(jù)段起始地址,也稱基地址.為了實現(xiàn)過程被調(diào)用時給它分配數(shù)據(jù)段,過程運行完畢后釋放數(shù)據(jù)段以及嵌套過程之間結(jié)標志符引用的問題,當過程被調(diào)用時,在棧頂分配三個聯(lián)系單元,這三個聯(lián)系單元存放的容分別為:SL靜態(tài)鏈,動態(tài)鏈DL,RA返回地址。3.語法分析方法語法分析的任務(wù)是識別由詞法分析給出的單詞符號序列在構(gòu)造上是否符合給定的文法規(guī)那么.PL/0編譯程序的語法分析采用了自頂向下的遞歸子程序法.粗略地說:就是對應(yīng)每個非終結(jié)符語法單元,編一個獨立的處理過程(或子程序).語法分析研究從讀入第一個單詞開場由非終結(jié)符’程序即開場符出發(fā),沿語法描述圖箭頭所指出的方向進展分析.當遇到非終結(jié)符時,那么調(diào)用相應(yīng)的處理過程,從語法描述圖看也就進入了一個語法單元,再沿當前所進入的語法描述圖的箭頭方向進展分析,當遇到描述圖中是終結(jié)符時,那么判斷當前讀入的單詞是否與圖中的終結(jié)符相匹配,假設(shè)匹配,那么執(zhí)行相應(yīng)的語義程序(就是翻譯程序).再讀取下一個單詞繼續(xù)分析.遇到分支點時將當前的單詞與分支點上的多個終結(jié)符逐個相比擬,假設(shè)都不匹配時可能是進入下一非終結(jié)符語法單位或是出錯.如果一個PL/0語言程序的單詞序列在整修語法分析中,都能逐個得到匹配,直到程序完畢’.’,這時就說所輸入的程序是正確的.對于正確的語法分析做相應(yīng)的語義翻譯,最終得出目標程序.4.中間代碼表示PL/0編譯程序所產(chǎn)生的目標代碼是一個假想棧式計算機的匯編語言,可稱為類pcode指令代碼,它不依賴任何實際計算機,其指令集極為簡單,指令格式如下:fLalit0a將常數(shù)值取到棧頂,a為常數(shù)值Lodla將變量值取到棧頂,a為偏移量,l為層差Stola將棧頂容送入某變量單元中,a為偏移量,l為層差Cala調(diào)用過程,a為過程地址,l為層差I(lǐng)nt0a在運行棧中為被調(diào)用的過程開辟a個單元的數(shù)據(jù)區(qū)jmp0a無條件跳轉(zhuǎn)至a地址Jpc0a條件跳轉(zhuǎn),當棧頂布爾值非真那么跳轉(zhuǎn)至a地址,否那么順序執(zhí)行o
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 齒輪銷售員崗位面試問題及答案
- 游樂設(shè)施檢驗員崗位面試問題及答案
- 安徽省阜陽市潁上縣第二中學2025屆化學高一下期末教學質(zhì)量檢測模擬試題含解析
- 江西省永豐中學2025年高一下化學期末達標檢測試題含解析
- 河北省深州市中學2025屆高二化學第二學期期末質(zhì)量跟蹤監(jiān)視模擬試題含解析
- 條形碼管理辦法規(guī)定為
- 農(nóng)家書屋維護管理辦法
- 材料外放加工管理辦法
- 晉安白蟻防治管理辦法
- 華為電子發(fā)票管理辦法
- 河北省2025年中考數(shù)學真題試卷(含答案)
- 福建福州金山中學2024~2025學年高一下冊期末考試數(shù)學試題含解析
- 2025年廣東省高考生物真題(解析版)
- 2024年哈爾濱市道里區(qū)執(zhí)法輔助人員招聘考試真題
- 學堂在線 研究生的壓力應(yīng)對與健康心理 期末考試答案
- 2025年7月自考13811績效管理試題及答案含解析
- 企業(yè)環(huán)境監(jiān)測管理制度
- 試藥員知情協(xié)議書
- 2025年嘉興市恒光電力建設(shè)有限責任公司招聘筆試參考題庫附帶答案詳解
- 2025內(nèi)蒙古鄂爾多斯農(nóng)商行烏海各機構(gòu)員工社會招聘37人筆試歷年典型考題及考點剖析附帶答案詳解
- XX林場20XX年度森林質(zhì)量精準提升項目實施方案(范文)
評論
0/150
提交評論