編譯原理課程設(shè)計(jì)報(bào)告--編譯器實(shí)現(xiàn)_第1頁(yè)
已閱讀1頁(yè),還剩33頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論