版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> 《編譯技術(shù)》課程設(shè)計(jì) 實(shí)驗(yàn)報(bào)告</p><p> 實(shí)驗(yàn)名稱:編譯器程序</p><p><b> 目錄</b></p><p><b> 一、課設(shè)要求3</b></p><p> 二、總體設(shè)計(jì)思想4</p><p> 三、詳細(xì)算法設(shè)計(jì)
2、4</p><p><b> 四、流程框圖5</b></p><p> 五、函數(shù)相關(guān)說(shuō)明9</p><p> 1.所有函數(shù)一覽9</p><p> 2.void emit(char *res,char *num1,char *op,char *num2)9</p><p>
3、; 3.char *newTemp()10</p><p> 4.int merge(int p1,int p2)10</p><p> 5.void backpatch(int p,int t)11</p><p> 6.void fuzhi()11</p><p> 7.void tiaojian(int *n
4、Chain)12</p><p> 8.void xunhuan()13</p><p> 六、程序運(yùn)行結(jié)果15</p><p> 七、編譯器使用說(shuō)明17</p><p> 八、心得與體會(huì)17</p><p> 九、源程序清單18</p><p><b>
5、; 課設(shè)要求</b></p><p> 用C語(yǔ)言對(duì)下述文法和單詞表定義的語(yǔ)言設(shè)計(jì)編制一個(gè)編譯器。</p><p> (1)單詞符號(hào)及種別表</p><p><b> ?。?)語(yǔ)法結(jié)構(gòu)定義</b></p><p> <程序> ::= main()<語(yǔ)句塊> </p>
6、<p> <語(yǔ)句塊> ::= ‘{‘<語(yǔ)句串>’}’ //程序用括號(hào)括起來(lái)</p><p> <語(yǔ)句串>::=<語(yǔ)句>{;<語(yǔ)句>};</p><p> <語(yǔ)句>::=<賦值語(yǔ)句>|<條件語(yǔ)句>|<循環(huán)語(yǔ)句></p><p> <賦
7、值語(yǔ)句>::=ID=<表達(dá)式> //賦值語(yǔ)句用”=”號(hào)</p><p> <條件語(yǔ)句>::=if<條件><語(yǔ)句塊> //條件怎么沒(méi)有括號(hào),囧(自己加1個(gè))</p><p> <循環(huán)語(yǔ)句>::=do <語(yǔ)句塊>while <條件></p><p> <條件>
8、::=<表達(dá)式><關(guān)系運(yùn)算符><表達(dá)式> //沒(méi)有布爾運(yùn)算,還算簡(jiǎn)單</p><p> <表達(dá)式> ::= <項(xiàng)>{ +<項(xiàng)>|-<項(xiàng)>}</p><p> <項(xiàng)> ::= <因子>{*<因子>|/<因子>}</p><p>
9、 <因子> ::=ID|num|(<表達(dá)式>)</p><p> num::= ( +|-|ε ) 數(shù)字*(.數(shù)字?jǐn)?shù)字* | ε)( e ( +|-|ε ) 數(shù)字?jǐn)?shù)字*|ε)</p><p> ID::=字母(字母|d數(shù)字)*</p><p> 字母::=a|b|c…|z|A|B|C…|Z</p><p> 數(shù)
10、字::=0|1|2…|9</p><p> <關(guān)系運(yùn)算符> ::= <|<=|>|>=|==|!=</p><p><b> 總體設(shè)計(jì)思想</b></p><p> 采用遞歸下降(自上而下)的語(yǔ)法制導(dǎo)翻譯法。</p><p><b> 詳細(xì)算法設(shè)計(jì)</b>
11、</p><p> 在前兩次試驗(yàn)的基礎(chǔ)上改進(jìn)。詞法分析程序 語(yǔ)法分析程序 語(yǔ)義分析程序 編譯器。不斷完善,不斷改進(jìn)。漸變的過(guò)程。</p><p><b> 流程框圖</b></p><p> 圖 I 主函數(shù)示意圖</p><p><b> 函數(shù)相關(guān)說(shuō)明</b></p>&l
12、t;p><b> 所有函數(shù)一覽</b></p><p> void scanner(); //掃描</p><p> void lrparser(); </p><p> void staBlock(int *nChain); //語(yǔ)句塊</p><p> void staString(int *nCha
13、in); //語(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><
14、;p> 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);
15、 //回填</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)
16、</p><p> 該函數(shù)的功能是生成一個(gè)三地址語(yǔ)句送到四元式表中。</p><p> void emit(char *res,char *num1,char *op,char *num2)</p><p><b> {</b></p><p> strcpy(fourCom[q].result,res);<
17、;/p><p> strcpy(fourCom[q].arg1,num1);</p><p> strcpy(fourCom[q].opera,op);</p><p> strcpy(fourCom[q].arg2,num2);</p><p><b> q++;</b></p><p>&
18、lt;b> }</b></p><p> 四元式表中的結(jié)構(gòu)如下:</p><p><b> struct{</b></p><p> char result[10]; //字符串(字符數(shù)組)</p><p> char arg1[10]; //操作數(shù)1</p><p>
19、 char opera[10]; //運(yùn)算符</p><p> char arg2[10]; //操作數(shù)2</p><p> }fourCom[20]; //結(jié)構(gòu)體數(shù)組</p><p> char *newTemp()</p><p> 該函數(shù)的功能是會(huì)動(dòng)一個(gè)新的臨時(shí)變量,臨時(shí)變量名產(chǎn)生的順序是T1,T2,T3,….</p&
20、gt;<p> char *newTemp()</p><p><b> {</b></p><p><b> char *p;</b></p><p> char varTemp[10];</p><p> p=(char *)malloc(10);</p>
21、<p><b> kk++;</b></p><p> itoa(kk,varTemp,10); //整數(shù)轉(zhuǎn)換為字符串</p><p> strcpy(p+1,varTemp);</p><p> p[0]='T'; //字符串前加T,便于識(shí)別</p><p><b> re
22、turn p;</b></p><p><b> }</b></p><p> int merge(int p1,int p2)</p><p> 該函數(shù)的功能是將以P1,P2為鏈?zhǔn)椎膬蓷l鏈合并成一條鏈,返回時(shí)的函數(shù)值作為合并后的鏈?zhǔn)住?lt;/p><p> int merge(int p1,int p2
23、) //合并p1和p2</p><p><b> {</b></p><p> char circle,nResult;</p><p><b> if(p2==0)</b></p><p> nResult=p1;</p><p><b> else&l
24、t;/b></p><p><b> {</b></p><p> nResult=circle=p2;</p><p> while(atoi(fourCom[circle].result)) //四元式第四個(gè)分量不為0</p><p><b> {</b></p>&
25、lt;p> circle=atoi(fourCom[circle].result); </p><p> //strcpy(fourCom[circle].result,p1);</p><p> sprintf(fourCom[circle].result,"%s",p1);</p><p><b> }</b&g
26、t;</p><p> //目的是用p1的值覆蓋0</p><p><b> }</b></p><p> return nResult; //p2是頭,p1覆蓋0,接在p2后邊</p><p><b> }</b></p><p> void backpatch(
27、int p,int t)</p><p> 該函數(shù)的功能是把P所鏈接的每個(gè)四元式的第四區(qū)段(result段)都回填t。</p><p> void backpatch(int p,int t) </p><p><b> {</b></p><p> int w,circle=p;</p><
28、p> while(circle) //circle不為0的時(shí)候</p><p><b> {</b></p><p> w=atoi(fourCom[circle].result); //四元式circle第四分量?jī)?nèi)容</p><p> //strcpy(fourCom[circle].result,t); //把t填進(jìn)四元式ci
29、rcle的第四分量</p><p> sprintf(fourCom[circle].result,"%d",t);</p><p> circle=w; //w記錄的是鏈條上下一個(gè)四元式,移動(dòng)!</p><p><b> }</b></p><p><b> return;<
30、/b></p><p><b> }</b></p><p> void fuzhi()</p><p> 該函數(shù)的功能是對(duì)賦值語(yǔ)句進(jìn)行分析。</p><p> void fuzhi() //賦值語(yǔ)句只有1個(gè)操作數(shù)</p><p><b> {</b><
31、/p><p> char res[10],num[10]; //num操作數(shù)</p><p> if(syn==10) //字符串</p><p><b> {</b></p><p> strcpy(res,token); //結(jié)果</p><p> scanner();</p>
32、;<p> if(syn==21) //=</p><p><b> {</b></p><p> scanner();</p><p> strcpy(num,E());</p><p> emit(res,num,"=","");</p>
33、<p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> printf("缺少=號(hào)\n");</p><p><b> }</b></p&
34、gt;<p><b> }</b></p><p><b> }</b></p><p> void tiaojian(int *nChain)</p><p> 該函數(shù)的功能是對(duì)條件語(yǔ)句進(jìn)行分析。</p><p> //<條件語(yǔ)句>->if(<條件&
35、gt;)<語(yǔ)句塊></p><p> void tiaojian(int *nChain)</p><p><b> {</b></p><p> char res[10],num1[10],num2[10],op[10];</p><p> int nChainTemp;</p>&l
36、t;p> //<條件>-><表達(dá)式><關(guān)系運(yùn)算符><表達(dá)式></p><p> if(syn==6) //if</p><p><b> {</b></p><p> scanner();</p><p> //strcpy(num1,E());<
37、;/p><p> if(syn==26) //(</p><p><b> {</b></p><p> scanner();</p><p> strcpy(num1,E());</p><p> if((syn<=37)&&(syn>=32)) </p&
38、gt;<p><b> {</b></p><p> switch(syn)</p><p><b> {</b></p><p><b> case 32:</b></p><p> strcpy(op,">");</p
39、><p><b> break;</b></p><p><b> case 33:</b></p><p> strcpy(op,">=");</p><p><b> break;</b></p><p><b&g
40、t; case 34:</b></p><p> strcpy(op,"<");</p><p><b> break;</b></p><p><b> case 35:</b></p><p> strcpy(op,"<="
41、;);</p><p><b> break;</b></p><p><b> case 36:</b></p><p> strcpy(op,"==");</p><p><b> break;</b></p><p>&
42、lt;b> case 37:</b></p><p> strcpy(op,"!=");</p><p><b> break;</b></p><p><b> default:</b></p><p> printf("error&quo
43、t;);</p><p><b> }</b></p><p><b> }</b></p><p> scanner();</p><p> strcpy(num2,E());</p><p> strcat(num1,op);</p><p&
44、gt; strcat(num1,num2);</p><p> //nfc=nextq+1;</p><p> ntc=nextq; //記住if語(yǔ)句位置</p><p> emit("0","if",num1,"goto"); </p><p> nfc=nextq; /
45、/if中表達(dá)式為假</p><p> emit("0","","","goto");</p><p><b> //第一個(gè)0已回填</b></p><p> backpatch(ntc,nextq); //ntc鏈接的所有四元式都回填nextq</p&g
46、t;<p><b> }</b></p><p> if(syn==27) //)</p><p> scanner();</p><p> staBlock(&nChainTemp); //語(yǔ)句塊</p><p> *nChain=merge(nChainTemp,nfc);<
47、/p><p><b> }</b></p><p><b> }</b></p><p> void xunhuan()</p><p> 該函數(shù)的功能是對(duì)循環(huán)語(yǔ)句進(jìn)行分析。</p><p> //<循環(huán)語(yǔ)句>::=do <語(yǔ)句塊>while &
48、lt;條件></p><p> void xunhuan()</p><p><b> {</b></p><p> char res[10],num1[10],num2[10],op[10];</p><p> int nChainTemp;</p><p> if(syn==8
49、) //do</p><p><b> {</b></p><p> nnc=nextq; //記住if語(yǔ)句位置,emit之后nextq就變了</p><p> //emit("0","if",num1,"goto"); </p><p> scanne
50、r();</p><p> staBlock(&nChainTemp); //語(yǔ)句塊</p><p> if(syn==9) //while</p><p><b> {</b></p><p> scanner();</p><p> if(syn==26) //(</p
51、><p><b> {</b></p><p> scanner();</p><p> strcpy(num1,E());</p><p> if((syn<=37)&&(syn>=32)) </p><p><b> {</b></
52、p><p> switch(syn)</p><p><b> {</b></p><p><b> case 32:</b></p><p> strcpy(op,">");</p><p><b> break;</b>
53、;</p><p><b> case 33:</b></p><p> strcpy(op,">=");</p><p><b> break;</b></p><p><b> case 34:</b></p><p&g
54、t; strcpy(op,"<");</p><p><b> break;</b></p><p><b> case 35:</b></p><p> strcpy(op,"<=");</p><p><b> break;
55、</b></p><p><b> case 36:</b></p><p> strcpy(op,"==");</p><p><b> break;</b></p><p><b> case 37:</b></p>&
56、lt;p> strcpy(op,"!=");</p><p><b> break;</b></p><p><b> default:</b></p><p> printf("error");</p><p><b> }<
57、/b></p><p><b> }</b></p><p> scanner();</p><p> strcpy(num2,E());</p><p> strcat(num1,op);</p><p> strcat(num1,num2);</p><p&
58、gt; nnb=nextq;</p><p> emit("0","if",num1,"goto"); </p><p> backpatch(nnb,nnc);</p><p> nna=nextq;</p><p> emit("0","&
59、quot;,"","goto");</p><p> backpatch(nna,nextq);</p><p><b> }</b></p><p> if(syn==27) //)</p><p> scanner();</p><p><
60、;b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> 程序運(yùn)行結(jié)果</b></p><p> 圖 VI 賦值語(yǔ)句的分析</p><p> 圖 VII 條件語(yǔ)
61、句的分析</p><p> 圖 VIII 循環(huán)語(yǔ)句的分析</p><p><b> 圖 IX 綜合</b></p><p><b> 編譯器使用說(shuō)明</b></p><p> 程序提示用戶輸入字符串“Please input your source string:”,用戶輸入字符串并以“#”
62、號(hào)結(jié)束?;剀?chē)后,程序顯示運(yùn)行結(jié)果。</p><p><b> 心得與體會(huì)</b></p><p> 剛拿到課設(shè)題目的時(shí)候,感覺(jué)很難,沒(méi)有頭緒。雖然之前實(shí)驗(yàn)時(shí)候,詞法分析程序和語(yǔ)法分析程序的代碼都是自己一個(gè)一個(gè)敲的。但是記得那時(shí)的語(yǔ)法分析程序用的是遞歸下降分析法,而且只判斷輸入串是否是文法的句子(輸出只有簡(jiǎn)單的success或者error)。課設(shè)的要求呢?要加上語(yǔ)義
63、分析,而且要輸出四元式。好像語(yǔ)義分析的部分,我一點(diǎn)印象也沒(méi)有了,老師那一部分上得有點(diǎn)快。運(yùn)動(dòng)會(huì)3天假,時(shí)間全用來(lái)啃課本了。“語(yǔ)義分析與中間代碼生成”,我又一點(diǎn)一點(diǎn)的看。3天時(shí)間,終于可以寫(xiě)出語(yǔ)義程序了。</p><p> 這是課設(shè)的第1個(gè)里程碑。采用遞歸下降的語(yǔ)法制導(dǎo)翻譯法,實(shí)現(xiàn)了對(duì)賦值表達(dá)式的語(yǔ)義分析,并生成四元式。</p><p> 但是后來(lái)發(fā)現(xiàn),更難的東西在后邊。程序語(yǔ)句有3種:
64、賦值語(yǔ)句,條件語(yǔ)句,循環(huán)語(yǔ)句。而賦值語(yǔ)句的翻譯,恰恰是最簡(jiǎn)單的。對(duì)于賦值語(yǔ)句的翻譯,課本上有詳細(xì)的講解,有代碼的簡(jiǎn)單舉例。而對(duì)于條件語(yǔ)句(if…else…)和循環(huán)語(yǔ)句(do…while…),課本講解不那么詳細(xì),沒(méi)有代碼舉例,上課時(shí)候我也沒(méi)太理解老師所講解的。特別是其中鏈nChain的概念,一直看不懂。因?yàn)檫@個(gè)困難,課設(shè)被我擱置了3天。</p><p> 再后來(lái)利用上機(jī)的時(shí)間,請(qǐng)教了一下老師和另外一個(gè)同學(xué),發(fā)現(xiàn)課
65、本后給的樣例程序是錯(cuò)的,而且錯(cuò)得一塌糊涂。只好自己寫(xiě),寫(xiě),寫(xiě)。</p><p> 然后就是課設(shè)的第2個(gè)里程碑。實(shí)現(xiàn)了對(duì)條件語(yǔ)句(if語(yǔ)句)的分析,并生成四元式。</p><p> 接下來(lái)又是開(kāi)發(fā)停滯的一段時(shí)間,直到11月18日。熟悉了一下原先寫(xiě)的代碼,然后開(kāi)始繼續(xù)后邊的部分。</p><p> 迎來(lái)了課設(shè)的第3個(gè)里程碑。實(shí)現(xiàn)了對(duì)循環(huán)語(yǔ)句(while語(yǔ)句)的分析
66、,并生成四元式。而且好像沒(méi)有預(yù)期中困難,可能是有條件語(yǔ)句的鋪墊吧。他們的處理方法其實(shí)很類(lèi)似,也是emit+backpatch+merge。而且由于老師給的語(yǔ)法中沒(méi)有布爾表達(dá)式,所以很多merge的工作也可以省略了,嘿嘿。</p><p> 最后一步就是整合,系統(tǒng)測(cè)試,書(shū)寫(xiě)文檔了。</p><p> 個(gè)人認(rèn)為這次課設(shè)的機(jī)會(huì)非常寶貴,加深了我對(duì)編譯器處理語(yǔ)言的過(guò)程的理解。我想,作為學(xué)軟件的
67、學(xué)生,不應(yīng)該只會(huì)用Java,或者C++,或者C#。一門(mén)高級(jí)語(yǔ)言其實(shí)學(xué)起來(lái)是很容易的,而在校期間,這些計(jì)算機(jī)基礎(chǔ)課程一定要學(xué)好!才能為將來(lái)打好基礎(chǔ)。</p><p><b> 源程序清單</b></p><p> //************編譯器********************</p><p><b> //</b
68、></p><p> //***Erin***</p><p> //***軟件工程0801班***</p><p> //***HUST***</p><p><b> //</b></p><p> //*************************************
69、*</p><p> #include<stdio.h></p><p> #include<string.h></p><p> #include<math.h></p><p> #include<stdlib.h></p><p> char prog[8
70、0]; //存放所有輸入字符 </p><p> char token[8]; //存放詞組 </p><p> char ch; //單個(gè)字符 </p><p> int syn,p,m,n,i; //syn:種別編碼 </p><p> double sum; </p><p&g
71、t; int count; </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><
72、;p> int isExp; //是否是指數(shù) </p><p> int index; //指數(shù)冪 </p><p> int isNegative; //是否帶負(fù)號(hào) </p><p> double temp; </p><p> int temp2;</p><p> int r
73、epeat; //是否連續(xù)出現(xiàn)+,-</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","floa
74、t","double","char","if","else","do","while"};</p><p><b> struct{</b></p><p> char result[10]; //字符串(字符數(shù)組)</p>
75、<p> char arg1[10];</p><p> char opera[10];</p><p> char arg2[10];</p><p> }fourCom[20]; //結(jié)構(gòu)體數(shù)組</p><p> void scanner(); //掃描</p><p> void lrp
76、arser(); </p><p> void staBlock(int *nChain); //語(yǔ)句塊</p><p> void staString(int *nChain); //語(yǔ)句串</p><p> void sta(int *nChain); //語(yǔ)句</p><p> void fuzhi(); //賦值語(yǔ)句</
77、p><p> void tiaojian(int *nChain); //條件語(yǔ)句</p><p> void xunhuan(); //循環(huán)語(yǔ)句</p><p> char* E(); //Expresiion表達(dá)式</p><p> char* T(); //Term項(xiàng)</p><p> char* F();
78、 //Factor因子</p><p> char *newTemp(); //自動(dòng)生成臨時(shí)變量</p><p> void backpatch(int p,int t); //回填</p><p> int merge(int p1,int p2); //合并p1和p2</p><p> void emit(char *res,ch
79、ar *num1,char *op,char *num2); //生成四元式</p><p> void main()</p><p><b> {</b></p><p><b> p=0;</b></p><p><b> count=0;</b></p>
80、;<p> isDecimal=0;</p><p><b> index=0;</b></p><p><b> repeat=0;</b></p><p><b> kk=0;</b></p><p> printf("\nPlease i
81、nput your source string:\n");</p><p><b> do{</b></p><p> ch=getchar();</p><p> prog[p++]=ch;</p><p> }while(ch!='#');</p><p>&
82、lt;b> p=0;</b></p><p> isError=0;</p><p> scanner();</p><p> lrparser();</p><p> for(i=1;i<nextq;i++) //循環(huán)輸出四元式</p><p><b> {</b&
83、gt;</p><p> printf("\n%d\t",i);</p><p> printf("(%5s %5s %5s \t%5s )\n",fourCom[i].arg1,fourCom[i].opera,fourCom[i].arg2,fourCom[i].result);</p><p><b>
84、 }</b></p><p><b> }</b></p><p> void lrparser()</p><p><b> {</b></p><p> int nChain;</p><p> nfc=ntc=1;</p><
85、p><b> nextq=1;</b></p><p> if(syn==1) //main</p><p><b> {</b></p><p> scanner();</p><p> if(syn==26) //(</p><p><b>
86、{</b></p><p> scanner();</p><p> if(syn==27) //)</p><p><b> {</b></p><p> scanner();</p><p> staBlock(&nChain);</p><p
87、><b> }</b></p><p><b> else</b></p><p> printf("缺少右括號(hào)\n");</p><p><b> }</b></p><p><b> else </b></p&
88、gt;<p> printf("缺少左括號(hào)\n");</p><p><b> }</b></p><p><b> else</b></p><p> printf("缺少main\n");</p><p><b> }&l
89、t;/b></p><p> //<語(yǔ)句塊> ::= '{'<語(yǔ)句串>'}'</p><p> void staBlock(int *nChain) //語(yǔ)句塊</p><p><b> {</b></p><p> if(syn==28) //{&l
90、t;/p><p><b> {</b></p><p> scanner();</p><p> staString(nChain);</p><p> //backpatch(*nChain,nextq);</p><p> if(syn==29) //}</p><p
91、> scanner(); //讀下一個(gè)</p><p><b> else</b></p><p> printf("缺少}號(hào)\n");</p><p><b> }</b></p><p><b> else</b></p>
92、<p> printf("缺少{號(hào)\n");</p><p><b> }</b></p><p> //<語(yǔ)句串>::=<語(yǔ)句>{;<語(yǔ)句>};</p><p> void staString(int *nChain) //語(yǔ)句串</p><p&g
93、t;<b> {</b></p><p> sta(nChain);</p><p> backpatch(*nChain,nextq);</p><p> while(syn==31) //;</p><p><b> {</b></p><p> scanne
94、r();</p><p> sta(nChain);</p><p><b> }</b></p><p> //backpatch(*nChain,nextq-1);</p><p><b> }</b></p><p> void sta(int *nChain
95、) //語(yǔ)句</p><p><b> {</b></p><p> if(syn==10)</p><p><b> {</b></p><p><b> fuzhi();</b></p><p> //*nChain=0;</p>
96、;<p><b> }</b></p><p> else if(syn==6) //if</p><p><b> {</b></p><p> tiaojian(nChain);</p><p><b> }</b></p><p
97、> else if(syn==8) //do</p><p> xunhuan();</p><p><b> }</b></p><p> //<條件語(yǔ)句>->if(<條件>)<語(yǔ)句塊></p><p> void tiaojian(int *nChain)&l
98、t;/p><p><b> {</b></p><p> char res[10],num1[10],num2[10],op[10];</p><p> int nChainTemp;</p><p> //<條件>-><表達(dá)式><關(guān)系運(yùn)算符><表達(dá)式></
99、p><p> if(syn==6) //if</p><p><b> {</b></p><p> scanner();</p><p> //strcpy(num1,E());</p><p> if(syn==26) //(</p><p><b>
100、 {</b></p><p> scanner();</p><p> strcpy(num1,E());</p><p> if((syn<=37)&&(syn>=32)) </p><p><b> {</b></p><p> switch(
101、syn)</p><p><b> {</b></p><p><b> case 32:</b></p><p> strcpy(op,">");</p><p><b> break;</b></p><p><
102、;b> case 33:</b></p><p> strcpy(op,">=");</p><p><b> break;</b></p><p><b> case 34:</b></p><p> strcpy(op,"<&
103、quot;);</p><p><b> break;</b></p><p><b> case 35:</b></p><p> strcpy(op,"<=");</p><p><b> break;</b></p><
104、;p><b> case 36:</b></p><p> strcpy(op,"==");</p><p><b> break;</b></p><p><b> case 37:</b></p><p> strcpy(op,"
105、;!=");</p><p><b> break;</b></p><p><b> default:</b></p><p> printf("error");</p><p><b> }</b></p><p&g
106、t;<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;</p
107、><p> ntc=nextq; //記住if語(yǔ)句位置</p><p> emit("0","if",num1,"goto"); </p><p> nfc=nextq; //if中表達(dá)式為假</p><p> emit("0","",&q
108、uot;","goto");</p><p><b> //第一個(gè)0已回填</b></p><p> backpatch(ntc,nextq); //ntc鏈接的所有四元式都回填nextq</p><p><b> }</b></p><p> if(syn=
109、=27) //)</p><p> scanner();</p><p> staBlock(&nChainTemp); //語(yǔ)句塊</p><p> *nChain=merge(nChainTemp,nfc);</p><p><b> }</b></p><p><b&
110、gt; }</b></p><p> //<循環(huán)語(yǔ)句>::=do <語(yǔ)句塊>while <條件></p><p> void xunhuan()</p><p><b> {</b></p><p> char res[10],num1[10],num2[10],
111、op[10];</p><p> int nChainTemp;</p><p> if(syn==8) //do</p><p><b> {</b></p><p> nnc=nextq; //記住if語(yǔ)句位置,emit之后nextq就變了</p><p> //emit("
112、;0","if",num1,"goto"); </p><p> scanner();</p><p> staBlock(&nChainTemp); //語(yǔ)句塊</p><p> if(syn==9) //while</p><p><b> {</b>
113、</p><p> scanner();</p><p> if(syn==26) //(</p><p><b> {</b></p><p> scanner();</p><p> strcpy(num1,E());</p><p> if((syn<
114、;=37)&&(syn>=32)) </p><p><b> {</b></p><p> switch(syn)</p><p><b> {</b></p><p><b> case 32:</b></p><p>
115、 strcpy(op,">");</p><p><b> break;</b></p><p><b> case 33:</b></p><p> strcpy(op,">=");</p><p><b> break;&l
116、t;/b></p><p><b> case 34:</b></p><p> strcpy(op,"<");</p><p><b> break;</b></p><p><b> case 35:</b></p>&
117、lt;p> strcpy(op,"<=");</p><p><b> break;</b></p><p><b> case 36:</b></p><p> strcpy(op,"==");</p><p><b> br
118、eak;</b></p><p><b> case 37:</b></p><p> strcpy(op,"!=");</p><p><b> break;</b></p><p><b> default:</b></p>
119、;<p> printf("error");</p><p><b> }</b></p><p><b> }</b></p><p> scanner();</p><p> strcpy(num2,E());</p><p>
120、 strcat(num1,op);</p><p> strcat(num1,num2);</p><p> nnb=nextq;</p><p> emit("0","if",num1,"goto"); </p><p> backpatch(nnb,nnc);</
121、p><p> nna=nextq;</p><p> emit("0","","","goto");</p><p> backpatch(nna,nextq);</p><p><b> }</b></p><p&g
122、t; if(syn==27) //)</p><p> scanner();</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> void fuzhi() //
123、賦值語(yǔ)句只有1個(gè)操作數(shù)</p><p><b> {</b></p><p> char res[10],num[10]; //num操作數(shù)</p><p> if(syn==10) //字符串</p><p><b> {</b></p><p> strcpy(
124、res,token); //結(jié)果</p><p> scanner();</p><p> if(syn==21) //=</p><p><b> {</b></p><p> scanner();</p><p> strcpy(num,E());</p><p&
125、gt; emit(res,num,"=","");</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> printf("缺少=號(hào)\n
126、");</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> char* E() //Expression表達(dá)式</p><p><b> {&l
127、t;/b></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> n
128、um2=(char *)malloc(10);</p><p> strcpy(num1,T());</p><p> while((syn==22)||(syn==23)) //+ -</p><p><b> {</b></p><p> if(syn==22) //+</p><p>
129、; strcpy(op,"+");</p><p><b> else</b></p><p> strcpy(op,"-");</p><p> scanner();</p><p> strcpy(num2,T());</p><p> st
130、rcpy(res,newTemp());</p><p> emit(res,num1,op,num2);</p><p> strcpy(num1,res);</p><p><b> }</b></p><p> return num1;</p><p><b> }<
131、;/b></p><p> char* T() //Term項(xiàng)</p><p><b> {</b></p><p> char *res,*num1,*op,*num2;</p><p> res=(char *)malloc(10);</p><p> num1=(char *
132、)malloc(10);</p><p> op=(char *)malloc(10);</p><p> num2=(char *)malloc(10);</p><p> strcpy(num1,F());</p><p> while((syn==24)||(syn==25)) //* /</p><p>
133、;<b> {</b></p><p> if(syn==24) </p><p> strcpy(op,"*");</p><p><b> else</b></p><p> strcpy(op,"/");</p><p>
134、; scanner();</p><p> strcpy(num2,F());</p><p> strcpy(res,newTemp());</p><p> emit(res,num1,op,num2);</p><p> strcpy(num1,res);</p><p><b> }<
135、;/b></p><p> return num1;</p><p><b> }</b></p><p> char* F() //Factor因子</p><p><b> {</b></p><p> char *res;</p><
136、p> res=(char *)malloc(10);</p><p> if(syn==10) //字符串</p><p><b> {</b></p><p> strcpy(res,token);</p><p> scanner();</p><p><b> }
137、</b></p><p> else if(syn==20) //二進(jìn)制數(shù)</p><p><b> {</b></p><p> itoa((int)sum,res,10); //整數(shù)轉(zhuǎn)換為字符串</p><p> scanner();</p><p><b>
138、}</b></p><p> else if(syn==26) //(</p><p><b> {</b></p><p> scanner();</p><p><b> res=E();</b></p><p> if(syn==27) //)&l
139、t;/p><p><b> {</b></p><p> scanner();</p><p><b> }</b></p><p> else isError=1;</p><p><b> }</b></p><p>&
140、lt;b> else</b></p><p> isError=1;</p><p> return res;</p><p><b> }</b></p><p> char *newTemp()</p><p><b> {</b></
141、p><p><b> char *p;</b></p><p> char varTemp[10];</p><p> p=(char *)malloc(10);</p><p><b> kk++;</b></p><p> itoa(kk,varTemp,10);&
142、lt;/p><p> strcpy(p+1,varTemp);</p><p><b> p[0]='T';</b></p><p><b> return p;</b></p><p><b> }</b></p><p> //
143、將p所鏈接的每個(gè)四元式的第四個(gè)分量都回填t</p><p> void backpatch(int p,int t) </p><p><b> {</b></p><p> int w,circle=p;</p><p> while(circle) //circle不為0的時(shí)候</p><
144、p><b> {</b></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[cir
145、cle].result,"%d",t);</p><p> circle=w; //w記錄的是鏈條上下一個(gè)四元式,移動(dòng)!</p><p><b> }</b></p><p><b> return;</b></p><p><b> }</b>&l
146、t;/p><p> int merge(int p1,int p2) //合并p1和p2</p><p><b> {</b></p><p> char circle,nResult;</p><p><b> if(p2==0)</b></p><p> nResu
147、lt=p1;</p><p><b> else</b></p><p><b> {</b></p><p> nResult=circle=p2;</p><p> while(atoi(fourCom[circle].result)) //四元式第四個(gè)分量不為0</p>
148、<p><b> {</b></p><p> circle=atoi(fourCom[circle].result); </p><p> //strcpy(fourCom[circle].result,p1);</p><p> sprintf(fourCom[circle].result,"%s",p
149、1);</p><p><b> }</b></p><p> //目的是用p1的值覆蓋0</p><p><b> }</b></p><p> return nResult; //p2是頭,p1覆蓋0,接在p2后邊</p><p><b> }<
150、/b></p><p> void emit(char *res,char *num1,char *op,char *num2)</p><p><b> {</b></p><p> strcpy(fourCom[nextq].result,res);</p><p> strcpy(fourCom[ne
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 編譯原理課程設(shè)計(jì)報(bào)告_編譯器
- 編譯原理課程設(shè)計(jì)---編譯器的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--編譯器
- 編譯原理課程設(shè)計(jì)報(bào)告---編譯器功能的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--c語(yǔ)言編譯器實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--c語(yǔ)言編譯器實(shí)現(xiàn)
- c語(yǔ)言編譯器實(shí)現(xiàn)-編譯原理課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)____c語(yǔ)言編譯器的實(shí)現(xiàn)-
- 編譯原理課程設(shè)計(jì)---c語(yǔ)言編譯器的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)---簡(jiǎn)單編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)報(bào)告-簡(jiǎn)單文法的編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)報(bào)告(一個(gè)完整的編譯器)
- 編譯原理課程設(shè)計(jì)報(bào)告--pl0編譯器的擴(kuò)充
- 編譯原理課程設(shè)計(jì)---s語(yǔ)言的編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)___c語(yǔ)言編譯器的實(shí)現(xiàn)畢業(yè)論文
- 編譯原理課程設(shè)計(jì)-pl_0編譯器及其擴(kuò)充
- 編譯原理課程的設(shè)計(jì)--c語(yǔ)言編譯器
- 編譯原理課程設(shè)計(jì)---小型程序設(shè)計(jì)語(yǔ)言編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--一個(gè)簡(jiǎn)單文法的編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)---一個(gè)簡(jiǎn)單編譯器的設(shè)計(jì)與分析
評(píng)論
0/150
提交評(píng)論