編譯原理課程設計 編譯代碼生成器設計_第1頁
編譯原理課程設計 編譯代碼生成器設計_第2頁
編譯原理課程設計 編譯代碼生成器設計_第3頁
編譯原理課程設計 編譯代碼生成器設計_第4頁
編譯原理課程設計 編譯代碼生成器設計_第5頁
已閱讀5頁,還剩26頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

1、編譯原理課程設計報告題目 編譯代碼生成器設計學院信息科學與工程學院專業計算機科學與技術班級 * 學號 * 學生姓名*指導教師 * 課程成績完成日期 * 課程設計成績評定學院信息學院專業計算機科學與技術班級* 學號*學生姓名*指導教師 * 課程成績完成日期 * 指導教師對學生在課程設計中的評價評分項目優良中及格不及格課程設計中的創造性成果學生掌握課程內容的程度課程設計完成情況課程設計動手能力文字表達學習態度規范要求課程設計論文的質量指導教師對課程設計的評定意見綜合成績 指導教師簽字 *年 月 題目編譯代碼生成器設計學生姓名:*指導老師:*摘要使用過現代計算機的人都知道,多數用戶是應用高級語言來實

2、現他們所需要的計算的。現在計算機系統一般都含有不只一個的高級語言的編譯程序,對有些高級語言甚至配置了幾個不同性能的編譯程序,供用戶按不同需要進行選擇。高級語言編譯程序是計算機系統軟件最主要的組成部分之,也是用戶最直接關系的工具之一。計算機上執行一個高級語言程序一般分為兩步:第一,用一個編譯程序把高級語言翻譯成機器語言程序;第二,運行所得的機器語言程序求得計算結果。通常說的翻譯程序是指能夠把某一種語言程序轉換成另一種語言程序(目標語言程序)。如果源語言諸如Fortran,Pascal,C,Ada或java這樣的高級語言,而目標程序是諸如匯編語言或者機器語言這類的低級語言,這樣的一個翻譯程序就是稱

3、為編譯程序。一個編譯程序的工作過程一般可以劃分為五個階段:詞法分析、語法分析、語義分析與中間代碼生成、優化、目標代碼生成。每個階段都是從上一個階段得到結果,對他進行分析,并且根據一些外部環境(例如符號表等)得到最終的輸出結果。要構造一個編譯程序,可以按照這樣的階段來分別構造,最后來連調?,F在人們已經建立了多種編制部分編譯程序或整個編譯程序的有效工具。有些能用于自動生成掃描器(如LEX),有些可以用于自動產生語法分析器(如YACC),有些甚至可以用來自動產生整個的編譯程序。這些構造編譯程序的工具成為編譯程序編譯程序、編譯程序產生器或翻譯程序書寫系統,他們是按照編譯程序和目標語言的形式描述而自動產

4、生編譯程序的。編譯程序是一極其龐大而又復雜的系統,掌握它比較苦難。但是一旦對其掌握,對以后的程序語言設計,系統軟件分析,系統軟件設計,形式語言研究等方面都是非常有好處的。關鍵字:C語言、編譯、掃描器、語法分析一、課程設計的目的編譯原理課程兼有很強的理論性和實踐性,是計算機專業的一門非常重要的專業基礎課程,它在系統軟件中占有十分重要的地位,是計算機專業學生的一門主修課。為了讓學生能夠更好地掌握編譯原理的基本理論和編譯程序構造的基本方法和技巧,融會貫通本課程所學專業理論知識,提高他們的軟件設計能力,特設定該課程的課程設計,通過設計一個簡單的PASCAL語言(EL語言)的編譯程序,提高學生設計程序的

5、能力,加深對編譯理論知識的理解與應用。二、課程設計的要求1、 明確課程設計任務,復習編譯理論知識,查閱復印相關的編譯資料。2、 按要求完成課程設計內容,課程設計報告要求文字和圖表工整、思路清晰、算法正確。3、 寫出完整的算法框架。4、 編寫完整的編譯程序。 三、課程設計的內容課程設計是一項綜合性實踐環節,是對平時實驗的一個補充,課程設計內容包括課程的主要理論知識,但由于編譯的知識量較復雜而且綜合性較強,因而對一個完整的編譯程序不適合平時實驗。通過課程設計可以達到綜合設計編譯程序的目的。本課程的課程設計要求學生編寫一個完整的編譯程序,包括詞法分析器、語法分析器以及實現對簡單程序設計語言中的邏輯運

6、算表達式、算術運算表達式、賦值語句、IF語句、While語句以及dowhile語句進行編譯,并生成中間代碼和直接生匯編指令的代碼生成器。四、總體設計方案及詳細設計主程序詞法分析程序語法分析程序中間代碼生成程序總體設計方案:1.總體模塊2.表2.1 各種單詞符號對應的種別碼單詞符號種別碼 單詞符號種別碼bgin1:17If2:=18Then320wile421do523lettet(letter|digit)*10=24dight dight*11=25+13;2614(27*15)28/16#0詳細設計: 4.1界面導入設計(1)一共三個選項:choice 1-cifafenxichoice

7、2-yufafenxichoice 3-zhongjiandaima (2)界面演示 圖一 圖二 圖三4.2詞法分析程序置初值調用掃描子程序輸出單詞二元組輸入串結束結束否是(1)流程圖設計(2)具體功能的具體設計1、cifafenxi( ) 首先設置progn來接收輸入的語句,以#來結束; 調用掃描子程序 scaner1( ),每一次得到一個類型碼; 用switch判別相應輸出; 直到syn1=0為止。2、掃描子程序scaner1( )-掃描輸入的語句首先設置3個變量:token1用來存放構成單詞符號的字符串;sum1用來存放整型單詞;syn1用來存放單詞符號的類型碼。有關scaner1()中

8、關鍵點解析:while(ch= )|(ch=n)ch=progp+; ;忽略空格if(ch=a)|(ch=A) while(ch=a)|(ch=A)|(ch=0)&(ch=9)tokenm+=ch; ch=progp+;;判別標識符for(n=0;n=0)&(ch=0)&(ch32=3334=35=36!=37(2)程序結構描述(3) 程序的功能描述從文件中讀入表達式,輸出其四元式的結果序列 是否為main?調用scanner是否為(?調用scanner是否為)?調用scanner調用語句塊分析函數staBlock出錯處理 遞歸下降示意圖 (4)詳細功能描述void scanner(); /掃

9、描void lrparser(); void staBlock(int *nChain); /語句塊void staString(int *nChain); /語句串void sta(int *nChain); /語句void fuzhi(); /賦值語句void tiaojian(int *nChain); /條件語句void xunhuan(); /循環語句char* E(); /Expresiion表達式char* T(); /Term項char* F(); /Factor因子char *newTemp(); /自動生成臨時變量void backpatch(int p,int t); /

10、回填int merge(int p1,int p2); /合并p1和p2void emit(char *res,char *num1,char *op,char *num2); /生成四元式void emit(char *res,char *num1,char *op,char *num2) 該函數的功能是生成一個三地址語句送到四式表中 char *newTemp()該函數的功能是會動一個新的臨時變量,臨時變量名產生的 順序是T1,T2,T3,.int merge(int p1,int p2)該函數的功能是將以P1,P2為鏈首的兩條鏈合并成一條鏈,返回時的函數值作為合并后的鏈首。void ba

11、ckpatch(int p,int t)該函數的功能是把P所鏈接的每個四元式的第四區段(result段)都回 填t。void fuzhi()該函數的功能是對賦值語句進行分析。void tiaojian(int *nChain)該函數的功能是對條件語句進行分析。void xunhuan()該函數的功能是對循環語句進行分析。(4) 結果演示 圖一 簡單語句生成四元式 圖二if語句的四元式生成圖三循環語句四元式生成(5)匯編生成if(strcmp(fourComi.opera,=)=0) printf(Move AX,%1sn,fourComi.arg1); printf(Move %5s,Axn,

12、fourComi.result);if(strcmp(fourComi.opera,+)=0) printf(Mov AX,%1sn,fourComi.arg1); printf(ADD Ax,%1sn,fourComi.arg2);printf(Mov %1s,Axn,fourComi.result);if(strcmp(fourComi.opera,-)=0) printf(Mov AX,%1sn,fourComi.arg1); printf(SUB Ax,%1sn,fourComi.arg2); printf(Mov %1s,Axn,fourComi.result);if(strcmp(

13、fourComi.opera,*)=0) printf(Mov AL,%1sn,fourComi.arg1); printf(MUL %1sn,fourComi.arg2); printf(Mov %1s,Axn,fourComi.result);if(strcmp(fourComi.opera,/)=0) printf(Mov AX,%1sn,fourComi.arg1); printf(DIv %1sn,fourComi.arg2); printf(Mov %1s,ALn,fourComi.result);if(strcmp(fourComi.opera,goto)=0) printf(j

14、mp L%1sn,i);結果演示五、課程設計的體會與總結 經過一個星期的編譯原理課程設計,本人在陳宏建老師的指導下,順利完成該課程設 計。通過該課程設計,收獲頗多。 詞法分析的基本任務是從字符串表示的源程序中識別出具有獨立意義的單詞符號,其基本思想是根據掃描到單詞符號的第一個字符的種類,拼出相應的單詞符號。通過本試驗的完成,更加加深了對詞法分析原理的理解。 通過本次試驗,了解了語法分析的運行過程,主程序大致流程為:“置初值”調用scaner函數讀下一個單詞符號調用IrParse結束。遞歸下降分析的大致流程為:“先判斷是否為begin”不是則“出錯處理”,若是則“調用scaner函數”調用語句串

15、分析函數“判斷是否為end”不是則“出錯處理”,若是則調用scaner函數“判斷syn=0&kk=0是否成立”成立則說明分析成功打印出來。不成立則“出錯處理”。 一、對實驗原理有更深的理解通過該課程設計,掌握了什么是編譯程序,編譯程序工作的基本過程及其各階段的基本任務,熟悉了編譯程序總流程框圖,了解了編譯程序的生成過程、構造工具及其相關的技術對課本上的知識有了更深的理解,課本上的知識師機械的,表面的。通過把該算法的內容,算法的執行順序在計算機上實現,把原來以為很深奧的書本知識變的更為簡單,對實驗原理有更深的理解。二、對該理論在實踐中的應用有深刻的理解通過把該算法的內容,算法的執行順序在計算機上

16、實現,知道和理解了該理論在計算機中是怎樣執行的,對該理論在實踐中的應用有深刻的理解。三、激發了學習的積極性通過該課程設計,全面系統的理解了編譯原理程序構造的一般原理和基本實現方法。把死板的課本知識變得生動有趣,激發了學習的積極性。把學過的計算機編譯原理的知識強化,能夠把課堂上學的知識通過自己設計的程序表示出來,加深了對理論知識的理解。以前對與計算機操在這次課程設計中,我就是按照實驗指導的思想來完成。加深了理解文件系統的內部功能及內部實現,培養實踐動手能力和程序開發能力的目的。附錄-程序清單#include#include#include#includeusing namespace std;#

17、define MAX 100char inputstream50; /存儲輸入句子int temp1=0; /數組下標int right1; /判斷輸出信息int m2=0,sum2=0;/sum用于計算運算符的個數 /m用于標記輸入表達式中字符的個數char JG=A;char strMAX;/用于存輸入表達式int tokene=0;/左括號的標志char prog180,token18,ch1;int syn1,p1,m1,n1,sum1;char *rwtab16=begin,if,then,while,do,end;int r1 ;char prog80; /存放所有輸入字符 cha

18、r token8; /存放詞組 char ch; /單個字符 int syn,p,m,n,i; /syn:種別編碼 double sum; int count; int isSignal; /是否帶正負號(0不帶,1負號,2正號)int isError;int isDecimal; /是否是小數 double decimal; /小數 int isExp; /是否是指數 int index; /指數冪 int isNegative; /是否帶負號 double temp; int temp2;int repeat; /是否連續出現+,-int nextq;int kk; /臨時變量的標號int

19、 ntc,nfc,nnc,nnb,nna;char *rwtab9=main,int,float,double,char,if,else,do,while; structchar result10; /字符串(字符數組)char arg110;char opera10;char arg210;fourCom20; /結構體數組cifafenxi();yufafenxi();zhongjiandaima();scaner1();void e();void e1();void t();void t1();void f();void lrparser(); void staBlock(int *nC

20、hain); /語句塊void staString(int *nChain); /語句串void sta(int *nChain); /語句void fuzhi(); /賦值語句void tiaojian(int *nChain); /條件語句void xunhuan(); /循環語句char* E(); /Expresiion表達式char* T(); /Term項char* F(); /Factor因子char *newTemp(); /自動生成臨時變量void backpatch(int p,int t); /回填int merge(int p1,int p2); /合并p1和p2voi

21、d emit(char *res,char *num1,char *op,char *num2); /生成四元式void scanner(); /掃描void lrparser()int nChain;nfc=ntc=1;nextq=1;if(syn=1) /mainscanner();if(syn=26) /(scanner();if(syn=27) /)scanner();staBlock(&nChain);elseprintf(缺少右括號n);else printf(缺少左括號n);elseprintf(缺少mainn);/ := void staBlock(int *nChain) /

22、語句塊if(syn=28) /scanner();staString(nChain);/backpatch(*nChain,nextq);if(syn=29) /scanner(); /讀下一個elseprintf(缺少號n);elseprintf(缺少號n);/:=;void staString(int *nChain) /語句串sta(nChain);backpatch(*nChain,nextq);while(syn=31) /;scanner();sta(nChain);/backpatch(*nChain,nextq-1);void sta(int *nChain) /語句if(sy

23、n=10)fuzhi();/*nChain=0;else if(syn=6) /iftiaojian(nChain);else if(syn=8) /doxunhuan();/-if()void tiaojian(int *nChain)char res10,num110,num210,op10;int nChainTemp;/-if(syn=6) /ifscanner();/strcpy(num1,E();if(syn=26) /(scanner();strcpy(num1,E();if(syn=32) switch(syn)case 32:strcpy(op,);break;case 33

24、:strcpy(op,=);break;case 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(num2,E();strcat(num1,op);strcat(num1,num2);/nfc=nextq+1;ntc=nextq; /記住if語句位置emit(0,if,num1,goto); nfc=nextq; /if中表達式為假emit(0,goto);/第

25、一個0已回填backpatch(ntc,nextq); /ntc鏈接的所有四元式都回填nextqif(syn=27) /)scanner();staBlock(&nChainTemp); /語句塊*nChain=merge(nChainTemp,nfc);/:=do while void xunhuan()char res10,num110,num210,op10;int nChainTemp;if(syn=8) /donnc=nextq; /記住if語句位置,emit之后nextq就變了/emit(0,if,num1,goto); scanner();staBlock(&nChainTemp

26、); /語句塊if(syn=9) /whilescanner();if(syn=26) /(scanner();strcpy(num1,E();if(syn=32) switch(syn)case 32:strcpy(op,);break;case 33:strcpy(op,=);break;case 34:strcpy(op,);break;case 35:strcpy(op,=);break;case 36:strcpy(op,=);break;case 37:strcpy(op,!=);break;default:printf(error);scanner();strcpy(num2,E

27、();strcat(num1,op);strcat(num1,num2);nnb=nextq;emit(0,if,num1,goto); backpatch(nnb,nnc);nna=nextq;emit(0,goto);backpatch(nna,nextq);if(syn=27) /)scanner();void fuzhi() /賦值語句只有1個操作數char res10,num10; /num操作數if(syn=10) /字符串strcpy(res,token); /結果scanner();if(syn=21) /=scanner();strcpy(num,E();emit(res,n

28、um,=,);elseprintf(缺少=號n);char* E() /Expression表達式char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);num2=(char *)malloc(10);strcpy(num1,T();while(syn=22)|(syn=23) /+ -if(syn=22) /+strcpy(op,+);elsestrcpy(op,-);scanner();strcpy(num2,T();strcpy(res,newTemp()

29、;emit(res,num1,op,num2);strcpy(num1,res);return num1;char* T() /Term項char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);num2=(char *)malloc(10);strcpy(num1,F();while(syn=24)|(syn=25) /* /if(syn=24) strcpy(op,*);elsestrcpy(op,/);scanner();strcpy(num2,F();st

30、rcpy(res,newTemp();emit(res,num1,op,num2);strcpy(num1,res);return num1;char* F() /Factor因子char *res;res=(char *)malloc(10);if(syn=10) /字符串strcpy(res,token);scanner();else if(syn=20) /二進制數itoa(int)sum,res,10); /整數轉換為字符串scanner();else if(syn=26) /(scanner();res=E();if(syn=27) /)scanner();else isError=

31、1;elseisError=1;return res;char *newTemp()char *p;char varTemp10;p=(char *)malloc(10);kk+;itoa(kk,varTemp,10);strcpy(p+1,varTemp);p0=T;return p;/將p所鏈接的每個四元式的第四個分量都回填tvoid backpatch(int p,int t) int w,circle=p;while(circle) /circle不為0的時候w=atoi(fourComcircle.result); /四元式circle第四分量內容/strcpy(fourComcir

32、cle.result,t); /把t填進四元式circle的第四分量sprintf(fourComcircle.result,%d,t);circle=w; /w記錄的是鏈條上下一個四元式,移動!return;int merge(int p1,int p2) /合并p1和p2char circle,nResult;if(p2=0)nResult=p1;elsenResult=circle=p2;while(atoi(fourComcircle.result) /四元式第四個分量不為0circle=atoi(fourComcircle.result); /strcpy(fourComcircle

33、.result,p1);sprintf(fourComcircle.result,%s,p1);/目的是用p1的值覆蓋0return nResult; /p2是頭,p1覆蓋0,接在p2后邊void emit(char *res,char *num1,char *op,char *num2)strcpy(fourComnextq.result,res);strcpy(fourComnextq.arg1,num1);strcpy(fourComnextq.opera,op);strcpy(fourComnextq.arg2,num2);nextq+;void scanner() sum=0; de

34、cimal=0; m=0; for(n=0;n=a)&(ch=A)&(ch=a)&(ch=A)&(ch=0)&(chtoken ch=progp+; /讀下一個字符 tokenm+=0; p-; /回退一格 syn=10; /標識符 /如果是begin,if,then,while,do,end標識符中的一個 for(n=0;n=0)&(ch=0)&(ch=0)&(ch=0)&(ch=9) /指數 index=index*10+ch-0; ch=progp+; /10的冪 /123e3代表123*10(3) /sum=sum*pow(10,index);是錯誤的 if(isNegative) s

35、um=sum*pow(0.1,index); else sum=sum*pow(10,index); if(isSignal=1)sum=-sum;isSignal=0; p-; syn=20; else switch(ch) case : m=0; tokenm+=ch; ch=progp+; if(ch=) syn=33; tokenm+=ch; else syn=32; p-; break; case =: m=0; tokenm+=ch; ch=progp+; if(ch=) syn=36; tokenm+=ch; else syn=21; p-; break; case +:temp

36、2=progp;tokenm+=ch;if(temp2=0)&(temp2=0)&(temp2=9)&(repeat=1)isSignal=1;ch=progp+; /讀-下一個字符repeat=0;goto IsNum; /轉到數字的識別if(temp2=+)|(temp2=-)&(repeat=0) /如果重復出現符號,才將后邊的+,-視為正負號repeat=1; /預言會重復/ch=progp+; /讀下一個字符syn=23;break; case *:temp2=progp;tokenm+=ch;if(temp2=+)isSignal=2;repeat=1;else if(temp2=-)isSignal=1;repeat=1;syn=24;break; case /: syn=25; tokenm+=ch; break; case (:temp2=progp;tokenm+=ch;if(temp2=+)isSignal=2;repeat=1;else if(temp2=-)isSignal=1;repeat=1;syn=26;break; case ): syn=27; tokenm+=ch; break; case : syn=28; token

溫馨提示

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

評論

0/150

提交評論