版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、課 程 設 計 課程名稱_編譯原理_ _題目名稱_對PL0進行擴充和修改學生學院_計算機學院 _專業(yè)班級_計算機科學與技術_學 號 3106006475 學生姓名_楊振風 _ _指導教師_ 吳偉民_2009 年 1 月 7 日一、 課程設計概述 PL0語言是Pascal語言的一個子集,它的編譯程序是一個編譯解釋執(zhí)行系統(tǒng),PL0的目標程序為假想棧式計算機的匯編語言,與具體的計算機無關。編譯程序采用一趟掃描方式,已語法語義分析程序為核心,詞法分析程序和代碼生成的程序都作為一個獨立的過程,當語法分析需要讀單詞的時候就調用詞法分析程序,而當語法分析正確需要生成相應的目標代碼時候 ,就調用代碼生成程序。
2、此外用表格管理程序建立變量,常量和過程標識符的說明與引用之間的信息聯(lián)系,用出錯處理程序對詞法和語義分析遇到的錯誤給出在源程序中出錯的位置和錯誤性質。PL0源程序出錯處理程序表格管理程序詞法分析程序語法語義分析程序目標程序代碼生成程序 本課程設計通過對PL/0(C語言版)進行修改和添加功能完成設計,通過修改詞法分析程序、語法分析、程序編譯主體block和解釋執(zhí)行等各部分的修改擴充,完成基本內容和選做內容。擴充了賦值運算+=、-=,運算+、-,以及擴充語句 repeat<語句序列>dowhile<條件>。二、 操作平臺操作系統(tǒng)Windows XP SP3,硬件:AMD at
3、hlon 3600+ 1.9GHZ,1G內存三、 主要成分的描述1、 符號表根據符號變量的存儲類別定義及他們除向的位置和次序來確定每一個變量應分配的存儲區(qū)及在該區(qū)的具體位置。編譯程序有兩類的存儲區(qū),即靜態(tài)的存儲區(qū)和動態(tài)的存儲區(qū)。由于本課程設計沒有添加其他的數據類型暫時不需要在符號表里面處理。2、 運行時存儲組織和管理采用棧式存儲分配,運行時每進入一個過程,就在棧頂為該過程分配所需的數據空間,當一個過程工作完畢返回時,它在棧頂的數據空間也即釋放程序運行時的存儲空間,棧中在某一個時刻可能會包含某個過程的幾個活動記錄,即某個過程遞歸調用的情況,另外同樣一個存儲的位置,可能會不同運行時刻分配給不同的數
4、據對象。3、 詞法分析的過程PL0的詞法分析程序GETSYM是一個獨立的過程,其功能是為語法語義分析提供單詞,把輸入的字符串形式的源程序分割成一個個單詞符號傳遞給語法語義分析為此PL0設置了3個全程變量SYM 存放每個單詞的類別,用內部編碼表示ID 存放用戶所定義的標識符的值。NUM 存放用戶定義的數4、 語法分析方法在PL/0中是采用遞歸子程序法進行語法分析的,具體實現方法是為每個非終結符寫一個函數,如遇到變量聲明時調用變量聲明函數,遇到常量聲明時調用常量聲明函數等。5、 中間代碼表示編譯程序所使用的中間代碼有多種形式。常見的有逆波蘭式,三元式,四元式和樹形表示。6、 目標代碼PL0編譯程序
5、所產生的目標代碼是一個假想的棧式計算機匯編語言,可稱為類PCODE指令代碼,它不依賴于任何的實際計算機指令的格式如下:fla 其中f代表功能碼,l代表層次差,也就是引用變量或過程的分程序與說明該變量或過程的分程序之間的層次差。a的含義對不同的指令有所區(qū)別。這里我們需要用到的有關目標指令有:LIT LOD STO CAL INT JMP JPC OPR四、 詳細設計1、 擴充賦值運算首先在頭文件的enum symbol中添加自己定義的+=,-=運算的關鍵字peq和meq。還有#defiine symnum以便詞法分析時能夠正確的識別這些關鍵字。在詞法分析程序中添加對+=和-=的識別,也就是在程序
6、中找到getsym函數,添加如下:else if(ch='+')getchdo;if(ch='=') sym=peq;這里是自己的定義的+=的標識符getchdo;else if(ch='+')sym=ppl;getchdo;elsesym=plus; 同理對于-=的標識符: else if(ch='-')getchdo;if(ch='=') sym=meq;這里是自己的定義的+=的標識符getchdo;else if(ch='-')sym=mmi;getchdo;elsesym=minus;接著在
7、語句處理函數statement添加如下的代碼:if(sym=becomes|sym=peq|sym=meq) peqop=sym;這是自己定義的標識符,識別運算符 getsymdo; else error(13); memcpy(nxtlev,fsys,sizeof(bool)* symnum); expressiondo(nxtlev,ptx,lev); if(i!=0&&peqop=becomes)/賦值 gendo(sto,lev-tablei.level,tablei.adr);/將棧頂的內容送入變量中 if(i!=0&&peqop=peq)/+=運算
8、gendo(lod,lev-tablei.level,tablei.adr);/將變量放到棧頂 gendo(opr,0,2); /加法運算 endo(sto,lev-tablei.level,tablei.adr);/將棧頂的內容送入變量中 if(i!=0&&peqop=meq)/-=運算 gendo(lod,lev-tablei.level,tablei.adr);/將變量放到棧頂gendo(opr,0,3);gendo(opr,0,1); /減法運算gendo(sto,lev-tablei.level,tablei.adr);/將棧頂的內容送入變量中2、擴充語句repeat
9、 dowhile 首先在頭文件中的enum symbol中添加repeatsym 和dowhilesym之后同樣在#define symnum名字表的類型數相應的增加,還有在#define norw變化相應的數字。以便在詞法分析時能夠識別。 來到初始化函數void init()中新增設置保留字,按照字母順序,便于折半查找: strcpy(&(word40),"dowhile"); strcpy(&(word40),"repeat"); 接下來在設置保留字符號: wsym4=dowhilesym; wsym4=repeatsym; 接下來到
10、語句處理函數statement中添加如下的代碼: else if(sym=repeatsym)/*準備按照repeat語句處理*/cx1=cx; /*保存判斷條件超作的位置*/getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlevdowhilesym=true;/*后跟符號為do*/statementdo(fsys,ptx,lev); /*循環(huán)體*/cx2=cx; /*保存循環(huán)體的結束的下一個位置*/gendo(jmp,0,cx1);/*回頭重新判斷條件*/if(sym=dowhilesym)getsymdo;elseerror(34);
11、 /*缺少dowhile*/conditiondo(nxtlev,ptx,lev); /*調用條件處理*/cx2=cx; /*保存循環(huán)體的結束的下一個位置*/gendo(jpc,0,0);/*生成條件跳轉,但跳出循環(huán)的地址未知*/gendo(jmp,0,cx1);/*回頭重新判斷條件*/codecx2.a=cx; /*反填跳出循環(huán)的地址,與if類似*/3、增加運算+和-首先來到頭文件中找到enum symbol添加自己定義的+,-運算符關鍵字ppl和mmi。有#defiine symnum以便詞法分析時能夠正確的識別這些關鍵字。這里跟前面不一樣的地方就是還要添加:facbegsysppl=tr
12、ue;facbegsysmmi=true;這是一個關鍵的地方,因為如果把+或當作表達式的開始符號時候,首先能夠正常的標識符一樣。在詞法分析程序中添加對+=和-=的識別,也就是在程序中找到getsym函數,添加如下:else if(ch='+')getchdo;if(ch='=') sym=peq;這里是自己的定義的+=的標識符getchdo;else if(ch='+')sym=ppl; 這里是自己的定義的+=的標識符getchdo;elsesym=plus; 同理對于-=的標識符: else if(ch='-')getchdo;
13、if(ch='=') sym=meq;這里是自己的定義的+=的標識符getchdo;else if(ch='-')sym=mmi; 這里是自己的定義的+=的標識符getchdo;elsesym=minus;根據前面語法描述,可以看出我這里是把i+或i作為語句或因子來進行處理的,這就得在相應地方添加語句處理功能。作為語句處理時,在statement中添加代碼如下:情況一:如a+,a運算符在后面:if(sym=ident)這里是以變量開始 i=position(id,*ptx);變量在符號表的位置 if(i=0) error(11);出錯處理 else if(tab
14、lei.kind!=variable)只有對變量才可以做自增自減運算 error(12); i=0; else getsymdo; if(sym=ppl)+運算 gendo(lod,lev-tablei.level,tablei.adr);把變量放入棧頂 gendo(lit,0,1);將常量1取到運行棧頂 gendo(opr,0,2);將棧頂和次棧頂的內容作算術加運算結果存放在次棧頂gendo(sto,lev-tablei.level,tablei.adr);將棧頂的內容送入變量中 getsymdo; elseif(sym=mmi)運算 gendo(lod,lev-tablei.level,t
15、ablei.adr); 把變量放入棧頂gendo(lit,0,1); 將常量1取到運行棧頂 gendo(opr,0,3); 將棧頂和次棧頂的內容作算術減運算結果存放在次棧頂 gendo(sto,lev-tablei.level,tablei.adr); 將棧頂的內容送入變量中 getsymdo; 情況二:如+a,a運算符在前面:if(sym=ppl) i=position(id,*ptx);if(i=0) error(11); /參考書上面的例子,即I為標識符在符號表的位置elsegetsymdo; gendo(lod,lev-tablei.level,tablei.adr);把變量放入棧頂
16、gendo(lit,0,1);將常量1取到運行棧頂 gendo(opr,0,2);將棧頂和次棧頂的內容作算術加運算結果存放在次棧頂gendo(sto,lev-tablei.level,tablei.adr);將棧頂的內容送入變量中 getsymdo;if(sym=mmi) i=position(id,*ptx); if(i=0) error(11); /同理,elsegetsymdo;gendo(lod,lev-tablei.level,tablei.adr); 把變量放入棧頂gendo(lit,0,1); 將常量1取到運行棧頂gendo(opr,0,3); 將棧頂和次棧頂的內容作算術減運算結
17、果存放在次棧頂gendo(sto,lev-tablei.level,tablei.adr); 將棧頂的內容送入變量中getsymdo; 作為因子處理時,在factor中添加代碼如下:情況一:如a+,a運算符在后面:作為因子處理時,得在因子處理函數factor中當檢測到當前單詞是標識符時,通過查找名字表確定類型,然后再通過switch進行選擇操作,在switch中添加代碼如下:switch(tablei.kind)case constant: /*名字為常量*/gendo(lit,0,tablei.val); getsymdo; /*直接把常量的值入棧*/break;case variable:
18、 /*名字為變量*/gendo(lod,lev-tablei.level,tablei.adr); /*找到變量地址并將其值入棧*/getsymdo;if(sym=ppl)+運算 gendo(lod,lev-tablei.level,tablei.adr);把變量放入棧頂gendo(lit,0,1);將常量1取到運行棧頂gendo(opr,0,2);將棧頂和次棧頂的內容作算術加運算結果存放在次棧頂gendo(sto,lev-tablei.level,tablei.adr);將棧頂的內容送入變量中getsymdo;elseif(sym=mmi)運算 gendo(lod,lev-tablei.le
19、vel,tablei.adr); 把變量放入棧頂gendo(lit,0,1); 將常量1取到運行棧頂gendo(opr,0,3); 將棧頂和次棧頂的內容作算術減運算結果存放在次棧頂gendo(sto,lev-tablei.level,tablei.adr); 將棧頂的內容送入變量中getsymdo; case procedur: getsymdo;/*名字為過程*/error(21); /*不能為過程*/break;情況二:如+a,a運算符在前面:if(sym=ppl)getsymdo; if(sym=ident)i=position(id,*ptx);if(i=0)error(11);/參考
20、書上面的例子,即I為標識符在符號表的位置else if(tablei.kind=variable) gendo(lod,lev-tablei.level,tablei.adr);把變量放入棧頂gendo(lit,0,1);將常量1取到運行棧頂gendo(opr,0,2);將棧頂和次棧頂的內容作算術加運算結果存放在次棧頂gendo(sto,lev-tablei.level,tablei.adr);將棧頂的內容送入變量中getsymdo;elseif(sym=mmi)getsymdo;if(sym=ident)i=position(id,*ptx);if(i=0)error(11);/參考書上面的
21、例子,即I為標識符在符號表的位置else if(tablei.kind=variable) gendo(lod,lev-tablei.level,tablei.adr); 把變量放入棧頂gendo(lit,0,1); 將常量1取到運行棧頂gendo(opr,0,3); 將棧頂和次棧頂的內容作算術減運算結果存放在次棧頂gendo(sto,lev-tablei.level,tablei.adr); 將棧頂的內容送入變量中getsymdo;五、測試用例測試時,完成一個功能就先測試,保證后面的程序不會因前面的不通過而影響到后面的。由于把全部的例子寫在一個PL0文件中,提示程序太長所以就寫了兩個例子,這里就只測試+=,-=賦值運算,+,-運算以及repeat dowhile語句:六、開發(fā)過程和完成情況 開發(fā)過程:這次編譯原理課程設計是在昨晚實驗的基礎上完成的總體來說難度不是很。之前在做實驗時已對基本的關鍵字進行了添加,這次課程設計主要是對一些功能進行擴充和修改。在做+=和-=運算時關
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年糊化淀粉行業(yè)深度研究分析報告
- 2025年留置擔保合同范本:保障影視制作項目資金安全3篇
- 二零二五年度智能電網變壓器安裝及維護一體化服務協(xié)議書2篇
- 2025年食糖項目可行性分析報告
- 2025年臨時工社會保險繳納及待遇保障合同4篇
- 2025年度學術論文評審專家保密責任協(xié)議3篇
- 2020-2025年中國乳糖酸阿奇霉素行業(yè)投資潛力分析及行業(yè)發(fā)展趨勢報告
- 2025年電子車牌市場分析現狀
- 2025年刀具鉚釘項目投資可行性研究分析報告
- 2025年金屬構架項目可行性研究報告
- 中國聯(lián)合網絡通信有限公司招聘筆試題庫2024
- 【社會工作介入精神障礙社區(qū)康復問題探究的文獻綜述5800字】
- 節(jié)前停工停產與節(jié)后復工復產安全注意事項課件
- 設備管理績效考核細則
- 中國人民銀行清算總中心直屬企業(yè)2023年招聘筆試上岸歷年典型考題與考點剖析附帶答案詳解
- (正式版)SJT 11449-2024 集中空調電子計費信息系統(tǒng)工程技術規(guī)范
- 人教版四年級上冊加減乘除四則混合運算300題及答案
- 合成生物學技術在生物制藥中的應用
- 消化系統(tǒng)疾病的負性情緒與心理護理
- 高考語文文學類閱讀分類訓練:戲劇類(含答案)
- 協(xié)會監(jiān)事會工作報告大全(12篇)
評論
0/150
提交評論