版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> 《編譯原理》課程設(shè)計(jì)報(bào)告</p><p> 題目 編譯代碼生成器設(shè)計(jì)</p><p> 學(xué) 院 信息科學(xué)與工程學(xué)院 專(zhuān) 業(yè) 計(jì)算機(jī)科學(xué)與技術(shù)</p><p> 班 級(jí) ******** 學(xué) 號(hào) ********** </p><p> 學(xué)生姓
2、名 ********* 指導(dǎo)教師 ****** </p><p> 課程成績(jī) 完成日期 *********** </p><p> 題目 編譯代碼生成器設(shè)計(jì)</p><p><b> 摘要</b></p><
3、p> 使用過(guò)現(xiàn)代計(jì)算機(jī)的人都知道,多數(shù)用戶(hù)是應(yīng)用高級(jí)語(yǔ)言來(lái)實(shí)現(xiàn)他們所需要的計(jì)算的?,F(xiàn)在計(jì)算機(jī)系統(tǒng)一般都含有不只一個(gè)的高級(jí)語(yǔ)言的編譯程序,對(duì)有些高級(jí)語(yǔ)言甚至配置了幾個(gè)不同性能的編譯程序,供用戶(hù)按不同需要進(jìn)行選擇。高級(jí)語(yǔ)言編譯程序是計(jì)算機(jī)系統(tǒng)軟件最主要的組成部分之,也是用戶(hù)最直接關(guān)系的工具之一。 計(jì)算機(jī)上執(zhí)行一個(gè)高級(jí)語(yǔ)言程序一般分為兩步:第一,用一個(gè)編譯程序把高級(jí)語(yǔ)言翻譯成機(jī)器語(yǔ)言程序;第二,運(yùn)行所得的機(jī)器語(yǔ)言程序求得計(jì)算結(jié)
4、果。 通常說(shuō)的翻譯程序是指能夠把某一種語(yǔ)言程序轉(zhuǎn)換成另一種語(yǔ)言程序(目標(biāo)語(yǔ)言程序)。如果源語(yǔ)言諸如Fortran,Pascal,C,Ada或java這樣的高級(jí)語(yǔ)言,而目標(biāo)程序是諸如匯編語(yǔ)言或者機(jī)器語(yǔ)言這類(lèi)的低級(jí)語(yǔ)言,這樣的一個(gè)翻譯程序就是稱(chēng)為編譯程序。 一個(gè)編譯程序的工作過(guò)程一般可以劃分為五個(gè)階段:詞法分析、語(yǔ)法分析、語(yǔ)義分析與中間代碼生成、優(yōu)化、目標(biāo)代碼生成。每個(gè)階段都是從上一個(gè)階段得到結(jié)果,對(duì)他進(jìn)行分析,并且根據(jù)一些
5、外部環(huán)境(例如符號(hào)表等)得到最終的輸出結(jié)果。要構(gòu)造一個(gè)編譯程序,可以按照這樣的階段來(lái)分別構(gòu)造,最后來(lái)連調(diào)。 現(xiàn)在人們已經(jīng)建立了</p><p><b> 一、課程設(shè)計(jì)的目的</b></p><p> 編譯原理課程兼有很強(qiáng)的理論性和實(shí)踐性,是計(jì)算機(jī)專(zhuān)業(yè)的一門(mén)非常重要的專(zhuān)業(yè)基礎(chǔ)課程,它在系統(tǒng)軟件中占有十分重要的地位,是計(jì)算機(jī)專(zhuān)業(yè)學(xué)生的一門(mén)主修課。為了讓學(xué)生能夠
6、更好地掌握編譯原理的基本理論和編譯程序構(gòu)造的基本方法和技巧,融會(huì)貫通本課程所學(xué)專(zhuān)業(yè)理論知識(shí),提高他們的軟件設(shè)計(jì)能力,特設(shè)定該課程的課程設(shè)計(jì),通過(guò)設(shè)計(jì)一個(gè)簡(jiǎn)單的PASCAL語(yǔ)言(EL語(yǔ)言)的編譯程序,提高學(xué)生設(shè)計(jì)程序的能力,加深對(duì)編譯理論知識(shí)的理解與應(yīng)用。</p><p><b> 二、課程設(shè)計(jì)的要求</b></p><p> 明確課程設(shè)計(jì)任務(wù),復(fù)習(xí)編譯理論知識(shí),查
7、閱復(fù)印相關(guān)的編譯資料。</p><p> 按要求完成課程設(shè)計(jì)內(nèi)容,課程設(shè)計(jì)報(bào)告要求文字和圖表工整、思路清晰、算法正確。</p><p> 寫(xiě)出完整的算法框架。</p><p> 編寫(xiě)完整的編譯程序。 </p><p><b> 三、課程設(shè)計(jì)的內(nèi)容</b></p><p> 課程設(shè)計(jì)是一項(xiàng)
8、綜合性實(shí)踐環(huán)節(jié),是對(duì)平時(shí)實(shí)驗(yàn)的一個(gè)補(bǔ)充,課程設(shè)計(jì)內(nèi)容包括課程的主要理論知識(shí),但由于編譯的知識(shí)量較復(fù)雜而且綜合性較強(qiáng),因而對(duì)一個(gè)完整的編譯程序不適合平時(shí)實(shí)驗(yàn)。通過(guò)課程設(shè)計(jì)可以達(dá)到綜合設(shè)計(jì)編譯程序的目的。本課程的課程設(shè)計(jì)要求學(xué)生編寫(xiě)一個(gè)完整的編譯程序,包括詞法分析器、語(yǔ)法分析器以及實(shí)現(xiàn)對(duì)簡(jiǎn)單程序設(shè)計(jì)語(yǔ)言中的邏輯運(yùn)算表達(dá)式、算術(shù)運(yùn)算表達(dá)式、賦值語(yǔ)句、IF語(yǔ)句、While語(yǔ)句以及do…while語(yǔ)句進(jìn)行編譯,并生成中間代碼和直接生匯編指令的代碼
9、生成器。</p><p> 四、總體設(shè)計(jì)方案及詳細(xì)設(shè)計(jì)</p><p><b> 總體設(shè)計(jì)方案:</b></p><p><b> 1.總體模塊</b></p><p><b> 2.</b></p><p> 表2.1 各種單詞符號(hào)對(duì)應(yīng)的種別
10、碼</p><p><b> 詳細(xì)設(shè)計(jì):</b></p><p><b> 4.1界面導(dǎo)入設(shè)計(jì)</b></p><p> (1)一共三個(gè)選項(xiàng):</p><p> ?、賑hoice 1--------cifafenxi</p><p> ?、赾hoice 2-------
11、-yufafenxi </p><p> ?、踓hoice 3--------zhongjiandaima</p><p><b> (2)界面演示</b></p><p><b> 圖一</b></p><p><b> 圖二</b></p><p&
12、gt;<b> 圖三</b></p><p><b> 4.2詞法分析程序</b></p><p><b> ?。?)流程圖設(shè)計(jì)</b></p><p> (2)具體功能的具體設(shè)計(jì)</p><p> 1、cifafenxi( )</p><p>
13、 首先設(shè)置prog[n]來(lái)接收輸入的語(yǔ)句,以‘#’來(lái)結(jié)束;</p><p> 調(diào)用掃描子程序 scaner1( ),每一次得到一個(gè)類(lèi)型碼;</p><p> 用switch判別相應(yīng)輸出;</p><p> 直到syn1=0為止。</p><p> 2、掃描子程序scaner1( )-----------------掃描輸入的語(yǔ)句&l
14、t;/p><p><b> 首先設(shè)置3個(gè)變量:</b></p><p> ?、賢oken1用來(lái)存放構(gòu)成單詞符號(hào)的字符串;</p><p> ?、趕um1用來(lái)存放整型單詞;</p><p> ?、踫yn1用來(lái)存放單詞符號(hào)的類(lèi)型碼。</p><p> 有關(guān)scaner1()中關(guān)鍵點(diǎn)解析:</p&
15、gt;<p><b> ?、?lt;/b></p><p> while((ch==' ')||(ch=='\n')) ch=prog[p++]; ;忽略空格</p><p><b> ?、?lt;/b></p><p> if(((ch<=
16、9;z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))</p><p> { while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>=&
17、#39;A'))||((ch>='0')&&(ch<='9')))</p><p> { token[m++]=ch;</p><p> ch=prog[p++];</p><p> }
18、 ;判別標(biāo)識(shí)符</p><p><b> ③</b></p><p> for(n=0;n<6;n++)</p><p> if(strcmp(token,rwtab[n])==0)</p><p> { syn=n+1;</p><p><b> break;</
19、b></p><p> } ;標(biāo)識(shí)符是否是關(guān)鍵字</p><p><b> ?、?lt;/b></p><p> if((ch>='0')&&(ch<='9'))</p><p&
20、gt; { while((ch>='0')&&(ch<='9'))</p><p> { sum=sum*10+ch-'0';</p><p> ch=prog[p++];</p><p><b> } }</b></p><p>&l
21、t;b> ;判別整數(shù) </b></p><p> (3) 詞法分析的運(yùn)行結(jié)果 </p><p><b> 輸入</b></p><p> begin x:=1; y:=1+2;end # </p><p><b> 輸出</b></p><p>
22、;<b> 4.3語(yǔ)法分析程序</b></p><p> (1) 具體功能的具體設(shè)計(jì)</p><p> 1.yufafenxi()---------------分析程序</p><p> 給出算術(shù)表達(dá)式文法,進(jìn)行適當(dāng)?shù)奈姆ㄗ儞Q</p><p> 輸入——表達(dá)式;輸出——表達(dá)式語(yǔ)法是否正確。</p>
23、<p> 2.子程序的功能描述</p><p> (3) 語(yǔ)法分析的運(yùn)行結(jié)果 </p><p><b> 分析成功圖</b></p><p><b> 分析失敗圖</b></p><p> 4.4 中間代碼生成程序</p><p><b>
24、 (1)總體描述</b></p><p> 采用遞歸下降(自上而下)的語(yǔ)法制導(dǎo)翻譯法。</p><p> 在前兩次試驗(yàn)的基礎(chǔ)上改進(jìn)。</p><p> 詞法分析程序 語(yǔ)法分析程序 語(yǔ)義分析程序 編譯器。不斷完善,</p><p> 不斷改進(jìn)。漸變的過(guò)程。</p><p><b> 單
25、詞符號(hào)及種別表</b></p><p><b> (2)程序結(jié)構(gòu)描述</b></p><p> (3) 程序的功能描述</p><p> 從文件中讀入表達(dá)式,輸出其四元式的結(jié)果序列 </p><p><b> 遞歸下降示意圖</b></p><p><
26、;b> (4)詳細(xì)功能描述</b></p><p> void scanner(); //掃描</p><p> void lrparser(); </p><p> void staBlock(int *nChain); //語(yǔ)句塊</p><p> void staString(int *nChain); //
27、語(yǔ)句串</p><p> void sta(int *nChain); //語(yǔ)句</p><p> void fuzhi(); //賦值語(yǔ)句</p><p> void tiaojian(int *nChain); //條件語(yǔ)句</p><p> void xunhuan(); //循環(huán)語(yǔ)句</p><p>
28、 char* E(); //Expresiion表達(dá)式</p><p> char* T(); //Term項(xiàng)</p><p> char* F(); //Factor因子</p><p> char *newTemp(); //自動(dòng)生成臨時(shí)變量</p><p> void backpatch(int p,int t); //回填&l
29、t;/p><p> int merge(int p1,int p2); //合并p1和p2</p><p> void emit(char *res,char *num1,char *op,char *num2); //生成四元式</p><p> void emit(char *res,char *num1,char *op,char *num2)</p&
30、gt;<p> 該函數(shù)的功能是生成一個(gè)三地址語(yǔ)句送到四式表中 </p><p> char *newTemp()</p><p> 該函數(shù)的功能是會(huì)動(dòng)一個(gè)新的臨時(shí)變量,臨時(shí)變量名產(chǎn)生的 順序是T1,T2,T3,….</p><p> int merge(int p1,int p2)</p><p> 該函數(shù)的功
31、能是將以P1,P2為鏈?zhǔn)椎膬蓷l鏈合并成一條鏈,返回時(shí)的函數(shù)值作為合并后的鏈?zhǔn)住?lt;/p><p> void backpatch(int p,int t)</p><p> 該函數(shù)的功能是把P所鏈接的每個(gè)四元式的第四區(qū)段(result段)都回 填t。</p><p> void fuzhi()</p><p> 該函數(shù)的功能是對(duì)賦值語(yǔ)
32、句進(jìn)行分析。</p><p> void tiaojian(int *nChain)</p><p> 該函數(shù)的功能是對(duì)條件語(yǔ)句進(jìn)行分析。</p><p> void xunhuan()</p><p> 該函數(shù)的功能是對(duì)循環(huán)語(yǔ)句進(jìn)行分析。</p><p><b> (4) 結(jié)果演示</b&g
33、t;</p><p> 圖一 簡(jiǎn)單語(yǔ)句生成四元式 </p><p> 圖二 if語(yǔ)句的四元式生成 </p><p> 圖三 循環(huán)語(yǔ)句四元式生成</p><p><b> ?。?)匯編生成</b></p><p> if(strcmp(fourCom[i].
34、opera,"=")==0)</p><p> {printf("Move AX,%1s\n",fourCom[i].arg1);</p><p> printf("Move %5s,Ax\n",fourCom[i].result);</p><p><b> }</b>&
35、lt;/p><p> if(strcmp(fourCom[i].opera,"+")==0)</p><p><b> {</b></p><p> printf("Mov AX,%1s\n",fourCom[i].arg1);</p><p> printf("AD
36、D Ax,%1s\n",fourCom[i].arg2);</p><p> printf("Mov %1s,Ax\n",fourCom[i].result);</p><p><b> }</b></p><p> if(strcmp(fourCom[i].opera,"-")==0)&
37、lt;/p><p> {printf("Mov AX,%1s\n",fourCom[i].arg1);</p><p> printf("SUB Ax,%1s\n",fourCom[i].arg2);</p><p> printf("Mov %1s,Ax\n",fourCom[i].result);&l
38、t;/p><p><b> }</b></p><p> if(strcmp(fourCom[i].opera,"*")==0)</p><p> {printf("Mov AL,%1s\n",fourCom[i].arg1);</p><p> printf("MU
39、L %1s\n",fourCom[i].arg2);</p><p> printf("Mov %1s,Ax\n",fourCom[i].result);</p><p><b> }</b></p><p> if(strcmp(fourCom[i].opera,"/")==0)<
40、/p><p> { printf("Mov AX,%1s\n",fourCom[i].arg1);</p><p> printf("DIv %1s\n",fourCom[i].arg2);</p><p> printf("Mov %1s,AL\n",fourCom[i].result);</p&
41、gt;<p><b> }</b></p><p> if(strcmp(fourCom[i].opera,"goto")==0)</p><p><b> {</b></p><p> printf("jmp L%1s\n",i);</p>&
42、lt;p><b> }</b></p><p><b> 結(jié)果演示</b></p><p> 五、課程設(shè)計(jì)的體會(huì)與總結(jié)</p><p> 經(jīng)過(guò)一個(gè)星期的編譯原理課程設(shè)計(jì),本人在陳宏建老師的指導(dǎo)下,順利完成該課程設(shè) 計(jì)。通過(guò)該課程設(shè)計(jì),收獲頗多。</p><p> 詞法分析的基本任務(wù)是
43、從字符串表示的源程序中識(shí)別出具有獨(dú)立意義的單詞符號(hào),其基本思想是根據(jù)掃描到單詞符號(hào)的第一個(gè)字符的種類(lèi),拼出相應(yīng)的單詞符號(hào)。通過(guò)本試驗(yàn)的完成,更加加深了對(duì)詞法分析原理的理解。 </p><p> 通過(guò)本次試驗(yàn),了解了語(yǔ)法分析的運(yùn)行過(guò)程,主程序大致流程為:“置初值”調(diào)用scaner函數(shù)讀下一個(gè)單詞符號(hào)調(diào)用IrParse結(jié)束。遞歸下降分析的大致流程為:“先判斷是否為begin”不是則“出錯(cuò)處理”,若是則“調(diào)用scan
44、er函數(shù)”調(diào)用語(yǔ)句串分析函數(shù)“判斷是否為end”不是則“出錯(cuò)處理”,若是則調(diào)用scaner函數(shù)“判斷syn=0&&kk=0是否成立”成立則說(shuō)明分析成功打印出來(lái)。不成立則“出錯(cuò)處理”。</p><p> 一、對(duì)實(shí)驗(yàn)原理有更深的理解</p><p> 通過(guò)該課程設(shè)計(jì),掌握了什么是編譯程序,編譯程序工作的基本過(guò)程及其各階段的基本任務(wù),熟悉了編譯程序總流程框圖,了解了編譯程序的
45、生成過(guò)程、構(gòu)造工具及其相關(guān)的技術(shù)對(duì)課本上的知識(shí)有了更深的理解,課本上的知識(shí)師機(jī)械的,表面的。通過(guò)把該算法的內(nèi)容,算法的執(zhí)行順序在計(jì)算機(jī)上實(shí)現(xiàn),把原來(lái)以為很深?yuàn)W的書(shū)本知識(shí)變的更為簡(jiǎn)單,對(duì)實(shí)驗(yàn)原理有更深的理解。</p><p> 二、對(duì)該理論在實(shí)踐中的應(yīng)用有深刻的理解</p><p> 通過(guò)把該算法的內(nèi)容,算法的執(zhí)行順序在計(jì)算機(jī)上實(shí)現(xiàn),知道和理解了該理論在計(jì)算機(jī)中是怎樣執(zhí)行的,對(duì)該理論在實(shí)
46、踐中的應(yīng)用有深刻的理解。</p><p> 三、激發(fā)了學(xué)習(xí)的積極性</p><p> 通過(guò)該課程設(shè)計(jì),全面系統(tǒng)的理解了編譯原理程序構(gòu)造的一般原理和基本實(shí)現(xiàn)方法。把死板的課本知識(shí)變得生動(dòng)有趣,激發(fā)了學(xué)習(xí)的積極性。把學(xué)過(guò)的計(jì)算機(jī)編譯原理的知識(shí)強(qiáng)化,能夠把課堂上學(xué)的知識(shí)通過(guò)自己設(shè)計(jì)的程序表示出來(lái),加深了對(duì)理論知識(shí)的理解。以前對(duì)與計(jì)算機(jī)操</p><p> 在這次課程
47、設(shè)計(jì)中,我就是按照實(shí)驗(yàn)指導(dǎo)的思想來(lái)完成。加深了理解文件系統(tǒng)的內(nèi)部功能及內(nèi)部實(shí)現(xiàn),培養(yǎng)實(shí)踐動(dòng)手能力和程序開(kāi)發(fā)能力的目的。</p><p> 附錄-----程序清單</p><p> #include<math.h></p><p> #include<stdlib.h></p><p> #include<
48、fstream></p><p> #include<iostream></p><p> using namespace std;</p><p> #define MAX 100</p><p> char inputstream[50]; //存儲(chǔ)輸入句子</p><p> int
49、 temp1=0; //數(shù)組下標(biāo)</p><p> int right1; //判斷輸出信息</p><p> int m2=0,sum2=0;//sum用于計(jì)算運(yùn)算符的個(gè)數(shù)</p><p> //m用于標(biāo)記輸入表達(dá)式中字符的個(gè)數(shù) </p><p> char JG='A
50、9;;</p><p> char str[MAX];//用于存輸入表達(dá)式</p><p> int tokene=0;//左括號(hào)的標(biāo)志</p><p> char prog1[80],token1[8],ch1;</p><p> int syn1,p1,m1,n1,sum1;</p><p> char
51、 *rwtab1[6]={"begin","if","then","while","do","end"};</p><p><b> int r1 ;</b></p><p> char prog[80]; //存放所有輸入字符 </p
52、><p> char token[8]; //存放詞組 </p><p> char ch; //單個(gè)字符 </p><p> int syn,p,m,n,i; //syn:種別編碼 </p><p> double sum; </p><p> int count; </
53、p><p> int isSignal; //是否帶正負(fù)號(hào)(0不帶,1負(fù)號(hào),2正號(hào))</p><p> int isError;</p><p> int isDecimal; //是否是小數(shù) </p><p> double decimal; //小數(shù) </p><p> int isExp; //
54、是否是指數(shù) </p><p> int index; //指數(shù)冪 </p><p> int isNegative; //是否帶負(fù)號(hào) </p><p> double temp; </p><p> int temp2;</p><p> int repeat; //是否連續(xù)出現(xiàn)+,-<
55、/p><p> int nextq;</p><p> int kk; //臨時(shí)變量的標(biāo)號(hào)</p><p> int ntc,nfc,nnc,nnb,nna;</p><p> char *rwtab[9]={"main","int","float","double&q
56、uot;,"char","if","else","do","while"};</p><p><b> struct{</b></p><p> char result[10]; //字符串(字符數(shù)組)</p><p> char arg1
57、[10];</p><p> char opera[10];</p><p> char arg2[10];</p><p> }fourCom[20]; //結(jié)構(gòu)體數(shù)組</p><p> cifafenxi();</p><p> yufafenxi();</p><p> zho
58、ngjiandaima();</p><p> scaner1();</p><p><b> void e();</b></p><p> void e1();</p><p><b> void t();</b></p><p> void t1();</
59、p><p><b> void f();</b></p><p> void lrparser(); </p><p> void staBlock(int *nChain); //語(yǔ)句塊</p><p> void staString(int *nChain); //語(yǔ)句串</p><p>
60、 void sta(int *nChain); //語(yǔ)句</p><p> void fuzhi(); //賦值語(yǔ)句</p><p> void tiaojian(int *nChain); //條件語(yǔ)句</p><p> void xunhuan(); //循環(huán)語(yǔ)句</p><p> char* E(); //Expresiion
61、表達(dá)式</p><p> char* T(); //Term項(xiàng)</p><p> char* F(); //Factor因子</p><p> char *newTemp(); //自動(dòng)生成臨時(shí)變量</p><p> void backpatch(int p,int t); //回填</p><p> int
62、 merge(int p1,int p2); //合并p1和p2</p><p> void emit(char *res,char *num1,char *op,char *num2); //生成四元式</p><p> void scanner(); //掃描</p><p> void lrparser()</p><p> {
63、int nChain;</p><p> nfc=ntc=1;</p><p><b> nextq=1;</b></p><p> if(syn==1) //main</p><p> {scanner();</p><p> if(syn==26) //(</p>&l
64、t;p> {scanner();</p><p> if(syn==27) //)</p><p> {scanner();</p><p> staBlock(&nChain);</p><p><b> }</b></p><p><b> else<
65、/b></p><p> printf("缺少右括號(hào)\n");</p><p><b> }</b></p><p><b> else </b></p><p> printf("缺少左括號(hào)\n");}</p><p>
66、<b> else</b></p><p> printf("缺少main\n");</p><p><b> }</b></p><p> //<語(yǔ)句塊> ::= '{'<語(yǔ)句串>'}'</p><p> voi
67、d staBlock(int *nChain) //語(yǔ)句塊</p><p> {if(syn==28) //{</p><p> {scanner();</p><p> staString(nChain);</p><p> //backpatch(*nChain,nextq);</p><p> if(s
68、yn==29) //}</p><p> scanner(); //讀下一個(gè)</p><p><b> else</b></p><p> printf("缺少}號(hào)\n");</p><p><b> }</b></p><p><b>
69、; else</b></p><p> printf("缺少{號(hào)\n");</p><p><b> }</b></p><p> //<語(yǔ)句串>::=<語(yǔ)句>{;<語(yǔ)句>};</p><p> void staString(int *nCha
70、in) //語(yǔ)句串</p><p> {sta(nChain);</p><p> backpatch(*nChain,nextq);</p><p> while(syn==31) //;</p><p> {scanner();</p><p> sta(nChain);</p><p
71、><b> }</b></p><p> //backpatch(*nChain,nextq-1);</p><p><b> }</b></p><p> void sta(int *nChain) //語(yǔ)句</p><p> {if(syn==10)</p><
72、;p><b> {fuzhi();</b></p><p> //*nChain=0;</p><p><b> }</b></p><p> else if(syn==6) //if</p><p> {tiaojian(nChain);</p><p>&
73、lt;b> }</b></p><p> else if(syn==8) //do</p><p> xunhuan();</p><p><b> }</b></p><p> //<條件語(yǔ)句>->if(<條件>)<語(yǔ)句塊></p>&
74、lt;p> void tiaojian(int *nChain)</p><p> {char res[10],num1[10],num2[10],op[10];</p><p> int nChainTemp;</p><p> //<條件>-><表達(dá)式><關(guān)系運(yùn)算符><表達(dá)式></p>
75、;<p> if(syn==6) //if</p><p> {scanner();</p><p> //strcpy(num1,E());</p><p> if(syn==26) //(</p><p> {scanner();</p><p> strcpy(num1,E());<
76、;/p><p> if((syn<=37)&&(syn>=32)) </p><p> {switch(syn)</p><p><b> {case 32:</b></p><p> strcpy(op,">");</p><p><
77、;b> break;</b></p><p><b> case 33:</b></p><p> strcpy(op,">=");</p><p><b> break;</b></p><p><b> case 34:</b
78、></p><p> strcpy(op,"<");</p><p><b> break;</b></p><p><b> case 35:</b></p><p> strcpy(op,"<=");</p><
79、;p><b> break;</b></p><p><b> case 36:</b></p><p> strcpy(op,"==");</p><p><b> break;</b></p><p><b> case 37:
80、</b></p><p> strcpy(op,"!=");</p><p><b> break;</b></p><p><b> default:</b></p><p> printf("error");</p>&l
81、t;p><b> }}</b></p><p> scanner();</p><p> strcpy(num2,E());</p><p> strcat(num1,op);</p><p> strcat(num1,num2);</p><p> //nfc=nextq+1;
82、</p><p> ntc=nextq; //記住if語(yǔ)句位置</p><p> emit("0","if",num1,"goto"); </p><p> nfc=nextq; //if中表達(dá)式為假</p><p> emit("0","&qu
83、ot;,"","goto");</p><p><b> //第一個(gè)0已回填</b></p><p> backpatch(ntc,nextq); //ntc鏈接的所有四元式都回填nextq</p><p><b> }</b></p><p> i
84、f(syn==27) //)</p><p> scanner();</p><p> staBlock(&nChainTemp); //語(yǔ)句塊</p><p> *nChain=merge(nChainTemp,nfc);</p><p><b> }}</b></p><p>
85、; //<循環(huán)語(yǔ)句>::=do <語(yǔ)句塊>while <條件></p><p> void xunhuan()</p><p> {char res[10],num1[10],num2[10],op[10];</p><p> int nChainTemp;</p><p> if(syn==8)
86、 //do</p><p> {nnc=nextq; //記住if語(yǔ)句位置,emit之后nextq就變了</p><p> //emit("0","if",num1,"goto"); </p><p> scanner();</p><p> staBlock(&nC
87、hainTemp); //語(yǔ)句塊</p><p> if(syn==9) //while</p><p> {scanner();</p><p> if(syn==26) //(</p><p> {scanner();</p><p> strcpy(num1,E());</p><p
88、> if((syn<=37)&&(syn>=32)) </p><p> {switch(syn)</p><p><b> {case 32:</b></p><p> strcpy(op,">");</p><p><b> break;
89、</b></p><p><b> case 33:</b></p><p> strcpy(op,">=");</p><p><b> break;</b></p><p><b> case 34:</b></p>
90、<p> strcpy(op,"<");</p><p><b> break;</b></p><p><b> case 35:</b></p><p> strcpy(op,"<=");</p><p><b>
91、; break;</b></p><p><b> case 36:</b></p><p> strcpy(op,"==");</p><p><b> break;</b></p><p><b> case 37:</b><
92、/p><p> strcpy(op,"!=");</p><p><b> break;</b></p><p><b> default:</b></p><p> printf("error");</p><p><b&g
93、t; }</b></p><p><b> }</b></p><p> scanner();</p><p> strcpy(num2,E());</p><p> strcat(num1,op);</p><p> strcat(num1,num2);</p>
94、;<p> nnb=nextq;</p><p> emit("0","if",num1,"goto"); </p><p> backpatch(nnb,nnc);</p><p> nna=nextq;</p><p> emit("0"
95、;,"","","goto");</p><p> backpatch(nna,nextq);</p><p><b> }</b></p><p> if(syn==27) //)</p><p> scanner();</p><
96、;p><b> }}}</b></p><p> void fuzhi() //賦值語(yǔ)句只有1個(gè)操作數(shù)</p><p> {char res[10],num[10]; //num操作數(shù)</p><p> if(syn==10) //字符串</p><p> {strcpy(res,token); //結(jié)果
97、</p><p> scanner();</p><p> if(syn==21) //=</p><p> {scanner();</p><p> strcpy(num,E());</p><p> emit(res,num,"=","");</p>
98、<p><b> }</b></p><p><b> else</b></p><p> {printf("缺少=號(hào)\n");</p><p><b> }}}</b></p><p> char* E() //Expression表達(dá)
99、式</p><p> {char *res,*num1,*op,*num2;</p><p> res=(char *)malloc(10);</p><p> num1=(char *)malloc(10);</p><p> op=(char *)malloc(10);</p><p> num2=(c
100、har *)malloc(10);</p><p> strcpy(num1,T());</p><p> while((syn==22)||(syn==23)) //+ -</p><p> {if(syn==22) //+</p><p> strcpy(op,"+");</p><p>
101、;<b> else</b></p><p> strcpy(op,"-");</p><p> scanner();</p><p> strcpy(num2,T());</p><p> strcpy(res,newTemp());</p><p> emit(
102、res,num1,op,num2);</p><p> strcpy(num1,res);</p><p><b> }</b></p><p> return num1;</p><p><b> }</b></p><p> char* T() //Term項(xiàng)&
103、lt;/p><p> {char *res,*num1,*op,*num2;</p><p> res=(char *)malloc(10);</p><p> num1=(char *)malloc(10);</p><p> op=(char *)malloc(10);</p><p> num2=(char
104、 *)malloc(10);</p><p> strcpy(num1,F());</p><p> while((syn==24)||(syn==25)) //* /</p><p> {if(syn==24) </p><p> strcpy(op,"*");</p><p><b
105、> else</b></p><p> strcpy(op,"/");</p><p> scanner();</p><p> strcpy(num2,F());</p><p> strcpy(res,newTemp());</p><p> emit(res,nu
106、m1,op,num2);</p><p> strcpy(num1,res);</p><p><b> }</b></p><p> return num1;</p><p><b> }</b></p><p> char* F() //Factor因子<
107、/p><p> {char *res;</p><p> res=(char *)malloc(10);</p><p> if(syn==10) //字符串</p><p> {strcpy(res,token);</p><p> scanner();</p><p><b>
108、; }</b></p><p> else if(syn==20) //二進(jìn)制數(shù)</p><p> {itoa((int)sum,res,10); //整數(shù)轉(zhuǎn)換為字符串</p><p> scanner();</p><p><b> }</b></p><p> else
109、 if(syn==26) //(</p><p> {scanner();</p><p><b> res=E();</b></p><p> if(syn==27) //)</p><p> {scanner();</p><p><b> }</b></
110、p><p> else isError=1;</p><p><b> }</b></p><p><b> else</b></p><p> isError=1;</p><p> return res;</p><p><b>
111、 }</b></p><p> char *newTemp()</p><p><b> {char *p;</b></p><p> char varTemp[10];</p><p> p=(char *)malloc(10);</p><p><b> kk+
112、+;</b></p><p> itoa(kk,varTemp,10);</p><p> strcpy(p+1,varTemp);</p><p><b> p[0]='T';</b></p><p><b> return p;</b></p>
113、<p><b> }</b></p><p> //將p所鏈接的每個(gè)四元式的第四個(gè)分量都回填t</p><p> void backpatch(int p,int t) </p><p> {int w,circle=p;</p><p> while(circle) //circle不為0的時(shí)候&l
114、t;/p><p> {w=atoi(fourCom[circle].result); //四元式circle第四分量?jī)?nèi)容</p><p> //strcpy(fourCom[circle].result,t); //把t填進(jìn)四元式circle的第四分量</p><p> sprintf(fourCom[circle].result,"%d",t
115、);</p><p> circle=w; //w記錄的是鏈條上下一個(gè)四元式,移動(dòng)!</p><p><b> }</b></p><p><b> return;</b></p><p><b> }</b></p><p> int mer
116、ge(int p1,int p2) //合并p1和p2</p><p> {char circle,nResult;</p><p><b> if(p2==0)</b></p><p> nResult=p1;</p><p><b> else</b></p><p&
117、gt; {nResult=circle=p2;</p><p> while(atoi(fourCom[circle].result)) //四元式第四個(gè)分量不為0</p><p> {circle=atoi(fourCom[circle].result); </p><p> //strcpy(fourCom[circle].result,p1);<
118、/p><p> sprintf(fourCom[circle].result,"%s",p1);</p><p> }//目的是用p1的值覆蓋0</p><p><b> }</b></p><p> return nResult; //p2是頭,p1覆蓋0,接在p2后邊</p>&
119、lt;p><b> }</b></p><p> void emit(char *res,char *num1,char *op,char *num2)</p><p> {strcpy(fourCom[nextq].result,res);</p><p> strcpy(fourCom[nextq].arg1,num1);&l
120、t;/p><p> strcpy(fourCom[nextq].opera,op);</p><p> strcpy(fourCom[nextq].arg2,num2);</p><p><b> nextq++;</b></p><p><b> }</b></p><p&
121、gt; void scanner() </p><p> { sum=0; </p><p> decimal=0; </p><p><b> m=0; </b></p><p> for(n=0;n<8;n++) </p><p> token[n]=NU
122、LL; </p><p> ch=prog[p++]; //從prog中讀出一個(gè)字符到ch中 </p><p> while(ch==' '||ch=='\n') //跳過(guò)空字符(無(wú)效輸入) </p><p> ch=prog[p++]; </p><p> if(((ch>=
123、9;a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))) //ch是字母字符 </p><p> { while(((ch>='a')&&(ch<='z'))||((ch>='A')&
124、;&(ch<='Z'))||((ch>='0')&&(ch<='9'))) </p><p> { token[m++]=ch; //ch=>token </p><p> ch=prog[p++]; //讀下一個(gè)字符 </p><p><b>
125、; } </b></p><p> token[m++]='\0'; </p><p> p--; //回退一格 </p><p> syn=10; //標(biāo)識(shí)符 </p><p> //如果是"begin","if","then",
126、"while","do","end"標(biāo)識(shí)符中的一個(gè) </p><p> for(n=0;n<9;n++) </p><p> if(strcmp(token,rwtab[n])==0) </p><p> { syn=n+1; </p><p><
127、;b> break; </b></p><p><b> } </b></p><p><b> } </b></p><p> else if((ch>='0')&&(ch<='9')) </p><
128、p><b> { IsNum:</b></p><p> if(isSignal==1)</p><p> { //token[m++]='-';</p><p><b> }</b></p><p> while((ch>='0')&&
129、amp;(ch<='9')) </p><p> { sum=sum*10+ch-'0'; //ch中數(shù)字本身是當(dāng)做字符存放的 </p><p> ch=prog[p++]; </p><p><b> } </b></p><p> if(ch=='
130、.') </p><p> { isDecimal=1; </p><p> ch=prog[p++]; </p><p> count=0; //之前忘了清零,123.123+123.123#兩個(gè)浮點(diǎn)數(shù)就無(wú)法識(shí)別</p><p> while((ch>='0')&&(ch
131、<='9')) </p><p> { //pow(x,y)計(jì)算x的y次冪 </p><p> temp=(ch-'0')*pow(0.1,++count); </p><p> decimal=decimal+temp; </p><p> //AddToDec(); &
132、lt;/p><p> ch=prog[p++]; </p><p><b> } </b></p><p> sum=sum+decimal; </p><p><b> } </b></p><p> if(ch=='e'||ch==&
133、#39;E') </p><p> { isExp=1; </p><p> ch=prog[p++]; </p><p> if(ch=='-') </p><p> { isNegative=1; </p><p> ch=prog[p++]; <
134、/p><p><b> } </b></p><p> while((ch>='0')&&(ch<='9')) </p><p><b> { </b></p><p><b> //指數(shù) </b>
135、</p><p> index=index*10+ch-'0'; </p><p> ch=prog[p++]; </p><p><b> } </b></p><p><b> //10的冪 </b></p><p> //123
136、e3代表123*10(3) </p><p> //sum=sum*pow(10,index);是錯(cuò)誤的 </p><p> if(isNegative) </p><p> sum=sum*pow(0.1,index); </p><p><b> else </b></p>&
137、lt;p> sum=sum*pow(10,index); </p><p><b> } </b></p><p> if(isSignal==1)</p><p><b> {</b></p><p><b> sum=-sum;</b></p&g
138、t;<p> isSignal=0;</p><p><b> }</b></p><p><b> p--; </b></p><p> syn=20; </p><p><b> } </b></p><p> el
139、se switch(ch) </p><p> { case '<': </p><p><b> m=0; </b></p><p> token[m++]=ch; </p><p> ch=prog[p++]; </p><p> if(c
140、h=='=') </p><p> { syn=35; </p><p> token[m++]=ch; </p><p><b> } </b></p><p><b> else </b></p><p> { syn=34
141、; </p><p><b> p--; </b></p><p><b> } </b></p><p><b> break; </b></p><p> case '>': </p><p><
142、b> m=0; </b></p><p> token[m++]=ch; </p><p> ch=prog[p++]; </p><p> if(ch=='=') </p><p> { syn=33; </p><p> token[m++]=ch;
143、 </p><p><b> } </b></p><p><b> else </b></p><p> { syn=32; </p><p><b> p--; </b></p><p><b> } <
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 編譯原理課程設(shè)計(jì)--中間代碼生成器設(shè)計(jì)---逆波蘭式的生成
- 編譯原理課程設(shè)計(jì)--編譯器
- 編譯原理課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)報(bào)告_編譯器
- 編譯原理課程設(shè)計(jì)報(bào)告
- 編譯原理課程設(shè)計(jì) (2)
- 編譯原理課程設(shè)計(jì)報(bào)告
- 編譯原理課程設(shè)計(jì)---編譯器的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)報(bào)告--編譯器實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)報(bào)告-編譯程序構(gòu)造
- 編譯原理課程設(shè)計(jì)--c語(yǔ)言編譯器實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--c語(yǔ)言編譯器實(shí)現(xiàn)
- c語(yǔ)言編譯器實(shí)現(xiàn)-編譯原理課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)報(bào)告 (2)
- 編譯原理課程設(shè)計(jì)詞法分析
- 編譯原理課程設(shè)計(jì)--詞法分析
- 編譯原理課程設(shè)計(jì)---簡(jiǎn)單編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)---c語(yǔ)言編譯器的實(shí)現(xiàn)
評(píng)論
0/150
提交評(píng)論