編譯原理 課程設(shè)計 增加數(shù)據(jù)類型_第1頁
編譯原理 課程設(shè)計 增加數(shù)據(jù)類型_第2頁
編譯原理 課程設(shè)計 增加數(shù)據(jù)類型_第3頁
編譯原理 課程設(shè)計 增加數(shù)據(jù)類型_第4頁
編譯原理 課程設(shè)計 增加數(shù)據(jù)類型_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、山東建筑大學(xué)計算機科學(xué)與技術(shù)學(xué)院課程設(shè)計說明書題 目: 對PL/0語言及其編譯器進行擴充和修改 實現(xiàn)增加數(shù)據(jù)類型的功能課 程: 編譯原理課程設(shè)計院 (部): 計算機科學(xué)與技術(shù)學(xué)院專 業(yè): 計算機科學(xué)與技術(shù)班 級: 計科學(xué)生姓名: 學(xué) 號: 指導(dǎo)教師: 完成日期: 2014年7月8日山東建筑大學(xué)計算機學(xué)院課程設(shè)計說明書目 錄課程設(shè)計任務(wù)書II對PL/0語言及其編譯器進行擴充和修改實現(xiàn)增加數(shù)據(jù)類型的功能3一、問題描述3二、基本要求4三、算法思想4四、數(shù)據(jù)結(jié)構(gòu)4五、模塊劃分5六、源程序5七、測試數(shù)據(jù)15八、測試情況17結(jié) 論18參考文獻19課程設(shè)計指導(dǎo)教師評語20I山東建筑大學(xué)計算機學(xué)院課程設(shè)計說明

2、書山東建筑大學(xué)計算機科學(xué)與技術(shù)學(xué)院課程設(shè)計任務(wù)書設(shè)計題目對PL/0語言及其編譯器進行擴充和修改實現(xiàn)增加數(shù)據(jù)類型的功能已知技術(shù)參數(shù)和設(shè)計要求PL/0程序設(shè)計語言是一個較簡單的語言,它以賦值語句為基礎(chǔ),構(gòu)造概念有順序、條件和重復(fù)(循環(huán))三種。PL/0有子程序概念,包括過程定義(可以嵌套)與調(diào)用且有局部變量說明。PL/0中唯一的數(shù)據(jù)類型是整型,可以用來說明該類型的常量和變量。當然PL/0也具有通常的算術(shù)運算和關(guān)系運算。通過讀懂源程序,全面掌握編譯原理的基本實現(xiàn)過程。對現(xiàn)存的PL/0編譯程序做一些修改或擴充。設(shè)計內(nèi)容與步驟通過讀懂源程序,全面掌握編譯原理的基本實現(xiàn)過程。擴充PL/0增加識別字符型數(shù)據(jù)類

3、型和實型數(shù)據(jù)類型的功能增加的數(shù)據(jù)類型的定義如下:D |integer id |char id |double id設(shè)計工作計劃與進度安排1-4:進行完整的編譯程序全過程的理解5-12:根據(jù)源程序,理解整個編譯器的編寫中涉及到的全局變量及基本函數(shù)的意義。13-20:在讀懂全程序的基礎(chǔ)上,進行擴充功能,并測試。21-24:撰寫課程設(shè)計報告書。設(shè)計考核要求設(shè)計考核方法:課程設(shè)計總成績=算法實現(xiàn)(30%)+課程設(shè)計說明書(50%)+平時考勤(20%)。設(shè)計考核要求:(1) 規(guī)范的課程設(shè)計說明書(2) 所設(shè)計的算法源代碼指導(dǎo)教師(簽字): 教研室主任(簽字):20山東建筑大學(xué)計算機學(xué)院課程設(shè)計說明書對P

4、L/0語言及其編譯器進行擴充和修改實現(xiàn)增加數(shù)據(jù)類型的功能一、問題描述PL/0程序設(shè)計語言是一個較簡單的語言,它以賦值語句為基礎(chǔ),構(gòu)造概念有順序、條件和重復(fù)(循環(huán))三種。PL/0有子程序概念,包括過程定義(可以嵌套)與調(diào)用且有局部變量說明。PL/0中唯一的數(shù)據(jù)類型是整型,可以用來說明該類型的常量和變量。當然PL/0也具有通常的算術(shù)運算和關(guān)系運算。PL/0語言的BNF文法如下所示: <程序> := <程序體>. <程序體> := <常量說明部分>變量說明部分><過程說明部分><語句> <常量說明部分>:= C

5、ONST<常量定義>,<常量定義> <常量定義> := <標識符>=<無符號整數(shù)> <無符號整數(shù)> := <數(shù)字><數(shù)字> <變量說明部分>:= VAR<標識符>,<標識符> <標識符> := <字母><字母>|<數(shù)字> <過程說明部分>:= <過程首部><程序體><過程說明部分> <過程首部> := PROCEDURE<標識符> <語句&

6、gt; := <賦值語句>|<條件語句>|<當型循環(huán)語句>|<過程調(diào)用語句>|<復(fù)合語句>|<空> <賦值語句> := <標識符>:=<表達式> <復(fù)合語句> := BEGIN<語句><語句>END <條件> := <表達式><關(guān)系運算符><表達式>|ODD<表達式> <表達式> := +|-<項><加法運算符><項> <項> :=

7、<因子><乘法運算符><因子> <因子> := <標識符>|<無符號整數(shù)>|'('<表達式>')' <加法運算符> := +|- <乘法運算符> := *|/ <關(guān)系運算符> := =|#|<|<=|>|>= <條件語句> := IF<條件>THEN<語句> <過程調(diào)用語句>:= CALL<標識符> <當型循環(huán)語句>:= WHILE<條件>

8、;DO<語句> <字母> := a|b|.|X|Y|Z <數(shù)字> := 0|1|2|.|8|9對現(xiàn)存的PL/0編譯程序做如下修改或擴充。(1) 擴充識別注釋功能:注釋由(*和*)包含,不允許嵌套。 (2)識別對else子句進行處理的功能<條件語句> := IF<條件>THEN<語句>ELSE<語句>二、基本要求設(shè)計目的:掌握PL/0語言編譯器實現(xiàn)的基本原理和實現(xiàn)方法。能在理解其實現(xiàn)原理的方法的基礎(chǔ)上進行適當?shù)臄U充,使其功能更強大。設(shè)計要求:在理解源代碼的基礎(chǔ)上,根據(jù)文法的要求,采用C語言擴充算法。完成擴充識別注

9、釋功能,和識別對else子句進行處理的功能3、 算法思想 增加數(shù)據(jù)類型的功能:因子語法描述該為 numberinteger ident 因子 char double)( 表達式 EBNF文法為:<因子>:=<標識符>|<無符號整數(shù)>|<整型>|<字符型>| <浮點型>|(<表達式>)4、 數(shù)據(jù)結(jié)構(gòu)#define norw 16/關(guān)鍵字的個數(shù)#define txmax 100/名字表的容量#define nmax 14/數(shù)字的最大位數(shù)#define al 10/符號的最大長度#define amax 2047/地

10、址上界#define levmax 3/最大允許的嵌套聲明層數(shù)#define cxmax 200/最多的虛擬機代碼數(shù)enum symbol /枚舉類型: /nul=0,ident=1,number=2,plus=3,minus=4 /times=5,依次類推,procsym=31 nul, ident, number, /下面的表示的是系統(tǒng)的算數(shù)運算符以及邏輯運算符,知道意思就可以 plus, minus, times,/相乘的意思 slash, oddsym, eql, neq, lss, leq, gtr, geq, lparen,/左括號 rparen, comma, semicolon

11、, period, becomes,/賦值的意思 /下面的表示是系統(tǒng)的保留字 beginsym, endsym, ifsym, thensym, whilesym, writesym, readsym, dosym, callsym, constsym, varsym, procsym, integersym,charactersym,doublesym,;#define symnum 35enum object constant, variable, procedur,integer,character,doubler,;五、模塊劃分過程或函數(shù)名簡要功能說明pl0主程序Error出錯處理,打

12、印出錯位置和錯誤編碼Getsym詞法分析,讀取一個單詞Getch漏掉空格,讀取一個字符Gen生成目標代碼,并送入目標程序區(qū)Test測試當前單詞符號是否合法Block分程序分析處理過程Enter登錄名字表position(函數(shù))查找標識符在名字表中的位置Constdeclaration常量定義處理Vardeclaration變量說明處理Listode列出目標代碼清單Statement語句處理Expression表達式處理Term項處理Factor因子處理Condition條件處理Interpret對目標代碼的解釋執(zhí)行程序base(函數(shù))通過靜態(tài)鏈求出數(shù)據(jù)區(qū)的基地址6、 源程序1、/該函數(shù)的功能就

13、是取一個數(shù)據(jù)單位,通過調(diào)用該函數(shù)可以一次取出一個/數(shù)字或字符串或運算符,這個函數(shù)和getch函數(shù)我覺得應(yīng)該是調(diào)用最經(jīng)常地函數(shù)啦,/每調(diào)用一次該函數(shù),該函數(shù)就會去調(diào)用getch函數(shù)/sym記錄的是語句單位的類型,num中存放的是數(shù)字的大小int getsym() . /取一個數(shù)字單位 else /加入real類型 if (ch>='0'&&ch<='9') k=0; num=0; sym=intsym;/以sym表示這是一個數(shù)字 /*type=integer;*/double count=0.1; doif(ch='.'

14、)getchdo;sym=doublesym;while(ch>='0'&&ch<='9')num=num+(ch-'0')*count;k+;count*=0.1;getchdo;break;else num=10*num+ch-'0' k+; getchdo; while(ch>='0'&&ch<='9'|ch='.'); k-; if(k>nmax)/要求數(shù)字位數(shù)不能超過15位,nmax=14,不過我覺得這有錯誤 e

15、rror(30);/輸出錯誤碼 elseif(int)ch=39)/加入字符類型getchdo;if(ch>='A'&&ch<='Z')|(ch>='a'&&ch<='z')num=(int)ch;getchdo;if(int)ch=39)sym=charsym;elsenum=0;sym=nul;error(49);/類型錯誤elseerror(49);getchdo; .2、/cc=cx=ll=0;cx表示源程序中代碼的第幾行/block(0,0,nxtlev)這是主程序

16、/nxtlev中已有部分值為1,大小為32int block(int lev,int tx,bool* fsys)/lev表示分程序所在層,tx表示當前尾指針,fsys表示當前模塊后跟符號集 . /如果當前字符是變量,則將字符放入table中,形式同上述代碼,如對下面不動的請參照上面的代碼 if(sym=intsym) getsymdo; do intdeclarationdo(&tx,lev,&dx); while(sym=comma) getsymdo; intdeclarationdo(&tx,lev,&dx); if(sym=semicolon) get

17、symdo; else error(5); while(sym=ident); /如果當前字符是變量,則將字符放入table中,形式同上述代碼,如對下面不動的請參照上面的代碼 if(sym=charsym) getsymdo; do chardeclarationdo(&tx,lev,&dx); while(sym=comma) getsymdo; chardeclarationdo(&tx,lev,&dx); if(sym=semicolon) getsymdo; else error(5); while(sym=ident); /如果當前字符是變量,則將字符

18、放入table中,形式同上述代碼,如對下面不動的請參照上面的代碼 if(sym=doublesym) getsymdo; do doubleclarationdo(&tx,lev,&dx); while(sym=comma) getsymdo; doubleclarationdo(&tx,lev,&dx); if(sym=semicolon) getsymdo; else error(5); while(sym=ident); . if(tableswitch)/是否列出table表中的內(nèi)容 printf("TABLE:n"); if(tx0

19、+1>tx)/當table表為空時,只輸出NULL printf("NULLn"); for(i=tx0+1;i<=tx;i+) /自己修改的 switch(tablei.kind) /自己添加的case integer: printf("%d int %s",i,);printf("lev=%d addr=%dn",tablei.level,tablei.adr); fprintf(fas,"%d integer %s",i,);fprintf(fas,&q

20、uot;lev=%d addr=%dn",tablei.level,tablei.adr); break; case character: printf("%d character %s",i,);printf("lev=%d addr=%dn",tablei.level,tablei.adr); fprintf(fas,"%d character %s",i,); fprintf(fas,"lev=%d addr=%dn",tablei.level,table

21、i.adr); break;case doubler: printf("%d doubler %s",i,);printf("lev=%d addr=%dn",tablei.level,tablei.adr); fprintf(fas,"%d doubler %s",i,);fprintf(fas,"lev=%d addr=%dn",tablei.level,tablei.adr); break; .3、/該函數(shù)的功能是將源程序中的常量,變量,分程序符號串輸入到table

22、表中/該table表是從下標1開始的,0號空間另做其它用途/void enter(enum object k,enum datatype t,int* ptx ,int lev ,int * pdx)void enter(enum object k,int* ptx ,int lev ,int * pdx) . /自己修改的/case integer:table(*ptx).level=lev;table(*ptx).adr=(*pdx); (*pdx)+; break;case doubler:table(*ptx).level=lev;table(*ptx).adr=(*pdx); (*p

23、dx)+; break;case character:table(*ptx).level=lev;table(*ptx).adr=(*pdx); (*pdx)+; break; .int characterdeclaration(int * ptx,int lev,int * pdx)/如果當前的符號是一個字符類型,則繼續(xù)執(zhí)行if(sym=ident) enter(character,ptx,lev,pdx); getsymdo;elseerror(4);return 0;int integerdeclaration(int * ptx,int lev,int * pdx)/如果當前的符號是一

24、個字符類型,則繼續(xù)執(zhí)行if(sym=ident) enter(integer,ptx,lev,pdx); getsymdo;elseerror(4);return 0;int doubdeclaration(int * ptx,int lev,int * pdx)/如果當前的符號是一個字符類型,則繼續(xù)執(zhí)行if(sym=ident) enter(doubler,ptx,lev,pdx); getsymdo;elseerror(4);return 0;4、/遞歸讀取分析每一個語句,該函數(shù)會將整個程序的大部分子程序聯(lián)系起來/該程序中大部分是遞歸調(diào)用,雖說代碼很多,但基本都是一個格式,所以讀起來并不復(fù)

25、雜/相對來說還比較簡單/對于代碼實現(xiàn)上差不多的部分,我沒有做過多的注釋int statement(bool* fsys,int * ptx,int lev) . switch(tablei.kind)/輸出處理case character:gendo(opr,0,21);break;case integer:gendo(opr,0,14);break;case doubler:gendo(opr,0,14);break; . if(sym=beginsym) getsymdo; /更改!/if(sym=doublesym)sym=ident; getsymdo;if(sym=intsym)sy

26、m=ident;getsymdo;if(sym=charsym)sym=ident;getsymdo; .5、 /因子處理int factor (bool* fsys,int *ptx,int lev) .case character: gendo(lod,lev-tablei.level,tablei.adr); break; case integer: gendo(lod,lev-tablei.level,tablei.adr); break; case doubler: gendo(lod,lev-tablei.level,tablei.adr); break; . if(sym=num

27、ber|sym=intsym|sym=charsym|sym=doublesym) /如果因子處理時遇到數(shù)字 if(num>amax)/如果數(shù)字大于最大能表示的數(shù)字,則報錯。amax=2047 error(31); num=0; gendo(lit,0,num); getsymdo; .6、void interpret() . case 14: / 14號操作為輸出棧頂值操作 /輸出棧頂值cout<<st-1<<endl;fprintf(fa2,"%lfn",st-1); /同時打印到文件t-; /棧頂下移break;case 15: /15號

28、操作為輸出換行操作printf("n"); /輸出換行fprintf(fa2,"n"); /同時輸出到文件break;case 16: / 16號操作是接受鍵盤值輸入到棧頂printf("輸入整形數(shù):"); /屏顯問號fprintf(fa2,"輸入整形數(shù):"); /同時輸出到文件scanf("%lf",&(st); /獲得輸入fprintf(fa2,"%lfn",st); /把用戶輸入值打印到文件t+; /棧頂上移,分配空間break;case 17: / 17號操作

29、為輸出棧頂值操作printf("%c",(int)st-1); /輸出棧頂值fprintf(fa2,"%cn",st-1); /同時打印到文件t-; /棧頂下移break;case 18: / 18號操作為輸出棧頂值操作printf("%lf",st-1); /輸出棧頂值fprintf(fa2,"%lfn",st-1); /同時打印到文件t-; /棧頂下移break;case 19: / 19號操作是接受鍵盤值輸入到棧頂printf("輸入單字符:"); /屏顯問號fprintf(fa2,&qu

30、ot;輸入單字符:"); /同時輸出到文scanf("%s",&(st);fprintf(fa2,"%cn",st); /把用戶輸入值打印到文件t+; /棧頂上移,分配空間break;case 20: / 20號操作是接受鍵盤值輸入到棧頂printf("輸入雙精度型數(shù):"); /屏顯問號fprintf(fa2,"輸入雙精度型數(shù):"); /同時輸出到文件scanf("%lf",&(st); /獲得輸入fprintf(fa2,"%lfn",st); /把

31、用戶輸入值打印到文件t+; /棧頂上移,分配空間break;case 21: / 14號操作為輸出棧頂值操作 /輸出棧頂值cout<<(char)st-1<<endl;fprintf(fa2,"%lfn",st-1); /同時打印到文件t-; /棧頂下移break; .七、測試數(shù)據(jù)1、運行編譯后的可執(zhí)行文件,輸入用PL/0的源語言寫的代碼文件integer.txt:該文件內(nèi)容如下:integer w;begin integer w:=25; write(w); end.得到程序的運行結(jié)果如圖1所示:圖1 測試數(shù)據(jù)integer.txt的運行結(jié)果2、 運行編譯后的可執(zhí)行文件,輸入用PL/0的源語言寫的代碼文件character.txt:該文件內(nèi)容如下:character m;begin character m:=m; End.得到程

溫馨提示

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

評論

0/150

提交評論