編譯原理課程設計--- 編譯代碼生成器設計_第1頁
已閱讀1頁,還剩29頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p>  《編譯原理》課程設計報告</p><p>  題目 編譯代碼生成器設計</p><p>  學 院 信息科學與工程學院 專 業(yè) 計算機科學與技術</p><p>  班 級 ******** 學 號 ********** </p><p>  學生姓

2、名 ********* 指導教師 ****** </p><p>  課程成績 完成日期 *********** </p><p>  題目 編譯代碼生成器設計</p><p><b>  摘要</b></p><

3、p>  使用過現(xiàn)代計算機的人都知道,多數(shù)用戶是應用高級語言來實現(xiàn)他們所需要的計算的?,F(xiàn)在計算機系統(tǒng)一般都含有不只一個的高級語言的編譯程序,對有些高級語言甚至配置了幾個不同性能的編譯程序,供用戶按不同需要進行選擇。高級語言編譯程序是計算機系統(tǒng)軟件最主要的組成部分之,也是用戶最直接關系的工具之一。 計算機上執(zhí)行一個高級語言程序一般分為兩步:第一,用一個編譯程序把高級語言翻譯成機器語言程序;第二,運行所得的機器語言程序求得計算結(jié)

4、果。 通常說的翻譯程序是指能夠把某一種語言程序轉(zhuǎn)換成另一種語言程序(目標語言程序)。如果源語言諸如Fortran,Pascal,C,Ada或java這樣的高級語言,而目標程序是諸如匯編語言或者機器語言這類的低級語言,這樣的一個翻譯程序就是稱為編譯程序。 一個編譯程序的工作過程一般可以劃分為五個階段:詞法分析、語法分析、語義分析與中間代碼生成、優(yōu)化、目標代碼生成。每個階段都是從上一個階段得到結(jié)果,對他進行分析,并且根據(jù)一些

5、外部環(huán)境(例如符號表等)得到最終的輸出結(jié)果。要構(gòu)造一個編譯程序,可以按照這樣的階段來分別構(gòu)造,最后來連調(diào)。 現(xiàn)在人們已經(jīng)建立了</p><p><b>  一、課程設計的目的</b></p><p>  編譯原理課程兼有很強的理論性和實踐性,是計算機專業(yè)的一門非常重要的專業(yè)基礎課程,它在系統(tǒng)軟件中占有十分重要的地位,是計算機專業(yè)學生的一門主修課。為了讓學生能夠

6、更好地掌握編譯原理的基本理論和編譯程序構(gòu)造的基本方法和技巧,融會貫通本課程所學專業(yè)理論知識,提高他們的軟件設計能力,特設定該課程的課程設計,通過設計一個簡單的PASCAL語言(EL語言)的編譯程序,提高學生設計程序的能力,加深對編譯理論知識的理解與應用。</p><p><b>  二、課程設計的要求</b></p><p>  明確課程設計任務,復習編譯理論知識,查

7、閱復印相關的編譯資料。</p><p>  按要求完成課程設計內(nèi)容,課程設計報告要求文字和圖表工整、思路清晰、算法正確。</p><p>  寫出完整的算法框架。</p><p>  編寫完整的編譯程序。 </p><p><b>  三、課程設計的內(nèi)容</b></p><p>  課程設計是一項

8、綜合性實踐環(huán)節(jié),是對平時實驗的一個補充,課程設計內(nèi)容包括課程的主要理論知識,但由于編譯的知識量較復雜而且綜合性較強,因而對一個完整的編譯程序不適合平時實驗。通過課程設計可以達到綜合設計編譯程序的目的。本課程的課程設計要求學生編寫一個完整的編譯程序,包括詞法分析器、語法分析器以及實現(xiàn)對簡單程序設計語言中的邏輯運算表達式、算術運算表達式、賦值語句、IF語句、While語句以及do…while語句進行編譯,并生成中間代碼和直接生匯編指令的代碼

9、生成器。</p><p>  四、總體設計方案及詳細設計</p><p><b>  總體設計方案:</b></p><p><b>  1.總體模塊</b></p><p><b>  2.</b></p><p>  表2.1 各種單詞符號對應的種別

10、碼</p><p><b>  詳細設計:</b></p><p><b>  4.1界面導入設計</b></p><p>  (1)一共三個選項:</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> ?。?)流程圖設計</b></p><p>  (2)具體功能的具體設計</p><p>  1、cifafenxi( )</p><p>

13、  首先設置prog[n]來接收輸入的語句,以‘#’來結(jié)束;</p><p>  調(diào)用掃描子程序 scaner1( ),每一次得到一個類型碼;</p><p>  用switch判別相應輸出;</p><p>  直到syn1=0為止。</p><p>  2、掃描子程序scaner1( )-----------------掃描輸入的語句&l

14、t;/p><p><b>  首先設置3個變量:</b></p><p> ?、賢oken1用來存放構(gòu)成單詞符號的字符串;</p><p> ?、趕um1用來存放整型單詞;</p><p>  ③syn1用來存放單詞符號的類型碼。</p><p>  有關scaner1()中關鍵點解析:</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、 ;判別標識符</p><p><b> ?、?lt;/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>  } ;標識符是否是關鍵字</p><p><b>  ④</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) 詞法分析的運行結(jié)果 </p><p><b>  輸入</b></p><p>  begin x:=1; y:=1+2;end # </p><p><b>  輸出</b></p><p>

22、;<b>  4.3語法分析程序</b></p><p>  (1) 具體功能的具體設計</p><p>  1.yufafenxi()---------------分析程序</p><p>  給出算術表達式文法,進行適當?shù)奈姆ㄗ儞Q</p><p>  輸入——表達式;輸出——表達式語法是否正確。</p>

23、<p>  2.子程序的功能描述</p><p>  (3) 語法分析的運行結(jié)果 </p><p><b>  分析成功圖</b></p><p><b>  分析失敗圖</b></p><p>  4.4 中間代碼生成程序</p><p><b> 

24、 (1)總體描述</b></p><p>  采用遞歸下降(自上而下)的語法制導翻譯法。</p><p>  在前兩次試驗的基礎上改進。</p><p>  詞法分析程序 語法分析程序 語義分析程序 編譯器。不斷完善,</p><p>  不斷改進。漸變的過程。</p><p><b>  單

25、詞符號及種別表</b></p><p><b>  (2)程序結(jié)構(gòu)描述</b></p><p>  (3) 程序的功能描述</p><p>  從文件中讀入表達式,輸出其四元式的結(jié)果序列 </p><p><b>  遞歸下降示意圖</b></p><p><

26、;b>  (4)詳細功能描述</b></p><p>  void scanner(); //掃描</p><p>  void lrparser(); </p><p>  void staBlock(int *nChain); //語句塊</p><p>  void staString(int *nChain); //

27、語句串</p><p>  void sta(int *nChain); //語句</p><p>  void fuzhi(); //賦值語句</p><p>  void tiaojian(int *nChain); //條件語句</p><p>  void xunhuan(); //循環(huán)語句</p><p> 

28、 char* E(); //Expresiion表達式</p><p>  char* T(); //Term項</p><p>  char* F(); //Factor因子</p><p>  char *newTemp(); //自動生成臨時變量</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ù)的功能是生成一個三地址語句送到四式表中 </p><p>  char *newTemp()</p><p>  該函數(shù)的功能是會動一個新的臨時變量,臨時變量名產(chǎn)生的 順序是T1,T2,T3,….</p><p>  int merge(int p1,int p2)</p><p>  該函數(shù)的功

31、能是將以P1,P2為鏈首的兩條鏈合并成一條鏈,返回時的函數(shù)值作為合并后的鏈首。</p><p>  void backpatch(int p,int t)</p><p>  該函數(shù)的功能是把P所鏈接的每個四元式的第四區(qū)段(result段)都回 填t。</p><p>  void fuzhi()</p><p>  該函數(shù)的功能是對賦值語

32、句進行分析。</p><p>  void tiaojian(int *nChain)</p><p>  該函數(shù)的功能是對條件語句進行分析。</p><p>  void xunhuan()</p><p>  該函數(shù)的功能是對循環(huán)語句進行分析。</p><p><b>  (4) 結(jié)果演示</b&g

33、t;</p><p>  圖一 簡單語句生成四元式 </p><p>  圖二 if語句的四元式生成 </p><p>  圖三 循環(huán)語句四元式生成</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>  五、課程設計的體會與總結(jié)</p><p>  經(jīng)過一個星期的編譯原理課程設計,本人在陳宏建老師的指導下,順利完成該課程設 計。通過該課程設計,收獲頗多。</p><p>  詞法分析的基本任務是

43、從字符串表示的源程序中識別出具有獨立意義的單詞符號,其基本思想是根據(jù)掃描到單詞符號的第一個字符的種類,拼出相應的單詞符號。通過本試驗的完成,更加加深了對詞法分析原理的理解。 </p><p>  通過本次試驗,了解了語法分析的運行過程,主程序大致流程為:“置初值”調(diào)用scaner函數(shù)讀下一個單詞符號調(diào)用IrParse結(jié)束。遞歸下降分析的大致流程為:“先判斷是否為begin”不是則“出錯處理”,若是則“調(diào)用scan

44、er函數(shù)”調(diào)用語句串分析函數(shù)“判斷是否為end”不是則“出錯處理”,若是則調(diào)用scaner函數(shù)“判斷syn=0&&kk=0是否成立”成立則說明分析成功打印出來。不成立則“出錯處理”。</p><p>  一、對實驗原理有更深的理解</p><p>  通過該課程設計,掌握了什么是編譯程序,編譯程序工作的基本過程及其各階段的基本任務,熟悉了編譯程序總流程框圖,了解了編譯程序的

45、生成過程、構(gòu)造工具及其相關的技術對課本上的知識有了更深的理解,課本上的知識師機械的,表面的。通過把該算法的內(nèi)容,算法的執(zhí)行順序在計算機上實現(xiàn),把原來以為很深奧的書本知識變的更為簡單,對實驗原理有更深的理解。</p><p>  二、對該理論在實踐中的應用有深刻的理解</p><p>  通過把該算法的內(nèi)容,算法的執(zhí)行順序在計算機上實現(xiàn),知道和理解了該理論在計算機中是怎樣執(zhí)行的,對該理論在實

46、踐中的應用有深刻的理解。</p><p>  三、激發(fā)了學習的積極性</p><p>  通過該課程設計,全面系統(tǒng)的理解了編譯原理程序構(gòu)造的一般原理和基本實現(xiàn)方法。把死板的課本知識變得生動有趣,激發(fā)了學習的積極性。把學過的計算機編譯原理的知識強化,能夠把課堂上學的知識通過自己設計的程序表示出來,加深了對理論知識的理解。以前對與計算機操</p><p>  在這次課程

47、設計中,我就是按照實驗指導的思想來完成。加深了理解文件系統(tǒng)的內(nèi)部功能及內(nèi)部實現(xiàn),培養(yǎng)實踐動手能力和程序開發(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]; //存儲輸入句子</p><p>  int

49、 temp1=0; //數(shù)組下標</p><p>  int right1; //判斷輸出信息</p><p>  int m2=0,sum2=0;//sum用于計算運算符的個數(shù)</p><p>  //m用于標記輸入表達式中字符的個數(shù) </p><p>  char JG='A

50、9;;</p><p>  char str[MAX];//用于存輸入表達式</p><p>  int tokene=0;//左括號的標志</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; //單個字符 </p><p>  int syn,p,m,n,i; //syn:種別編碼 </p><p>  double sum; </p><p>  int count; </

53、p><p>  int isSignal; //是否帶正負號(0不帶,1負號,2正號)</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; //是否帶負號 </p><p>  double temp; </p><p>  int temp2;</p><p>  int repeat; //是否連續(xù)出現(xiàn)+,-<

55、/p><p>  int nextq;</p><p>  int kk; //臨時變量的標號</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); //語句塊</p><p>  void staString(int *nChain); //語句串</p><p>

60、  void sta(int *nChain); //語句</p><p>  void fuzhi(); //賦值語句</p><p>  void tiaojian(int *nChain); //條件語句</p><p>  void xunhuan(); //循環(huán)語句</p><p>  char* E(); //Expresiion

61、表達式</p><p>  char* T(); //Term項</p><p>  char* F(); //Factor因子</p><p>  char *newTemp(); //自動生成臨時變量</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("缺少右括號\n");</p><p><b>  }</b></p><p><b>  else </b></p><p>  printf("缺少左括號\n");}</p><p>

66、<b>  else</b></p><p>  printf("缺少main\n");</p><p><b>  }</b></p><p>  //<語句塊> ::= '{'<語句串>'}'</p><p>  voi

67、d staBlock(int *nChain) //語句塊</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(); //讀下一個</p><p><b>  else</b></p><p>  printf("缺少}號\n");</p><p><b>  }</b></p><p><b>

69、;  else</b></p><p>  printf("缺少{號\n");</p><p><b>  }</b></p><p>  //<語句串>::=<語句>{;<語句>};</p><p>  void staString(int *nCha

70、in) //語句串</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) //語句</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>  //<條件語句>->if(<條件>)<語句塊></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>  //<條件>-><表達式><關系運算符><表達式></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語句位置</p><p>  emit("0","if",num1,"goto"); </p><p>  nfc=nextq; //if中表達式為假</p><p>  emit("0","&qu

83、ot;,"","goto");</p><p><b>  //第一個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); //語句塊</p><p>  *nChain=merge(nChainTemp,nfc);</p><p><b>  }}</b></p><p>

85、;  //<循環(huán)語句>::=do <語句塊>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語句位置,emit之后nextq就變了</p><p>  //emit("0","if",num1,"goto"); </p><p>  scanner();</p><p>  staBlock(&nC

87、hainTemp); //語句塊</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() //賦值語句只有1個操作數(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("缺少=號\n");</p><p><b>  }}}</b></p><p>  char* E() //Expression表達

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項&

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) //二進制數(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所鏈接的每個四元式的第四個分量都回填t</p><p>  void backpatch(int p,int t) </p><p>  {int w,circle=p;</p><p>  while(circle) //circle不為0的時候&l

114、t;/p><p>  {w=atoi(fourCom[circle].result); //四元式circle第四分量內(nèi)容</p><p>  //strcpy(fourCom[circle].result,t); //把t填進四元式circle的第四分量</p><p>  sprintf(fourCom[circle].result,"%d",t

115、);</p><p>  circle=w; //w記錄的是鏈條上下一個四元式,移動!</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)) //四元式第四個分量不為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中讀出一個字符到ch中 </p><p>  while(ch==' '||ch=='\n') //跳過空字符(無效輸入) </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++]; //讀下一個字符 </p><p><b>

125、;  } </b></p><p>  token[m++]='\0'; </p><p>  p--; //回退一格 </p><p>  syn=10; //標識符 </p><p>  //如果是"begin","if","then",

126、"while","do","end"標識符中的一個 </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ù)字本身是當做字符存放的 </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#兩個浮點數(shù)就無法識別</p><p>  while((ch>='0')&&(ch

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

評論

0/150

提交評論