編譯原理課程設(shè)計---簡單編譯器的設(shè)計與實現(xiàn)_第1頁
已閱讀1頁,還剩20頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、<p>  計算機(jī)科學(xué)系課程設(shè)計任務(wù)書</p><p>  題 目: 簡單編譯器的設(shè)計與實現(xiàn) </p><p>  姓 名: </p><p>  學(xué) 號: </p><p>  年 級:

2、 </p><p>  專 業(yè): 計算機(jī)科學(xué)與技術(shù) </p><p>  指導(dǎo)教師: </p><p>  職 稱: </p><p><b>  計算機(jī)科學(xué)系</b></p><p&g

3、t;  2009年 12 月 25 日</p><p><b>  課程設(shè)計的目的 </b></p><p>  在學(xué)習(xí)《程序設(shè)計語言編譯原理》課程過程中,結(jié)合各章節(jié)構(gòu)造編譯程序的基本理論分別完成詞法分析器、語法分析器和語義分析器實驗,在基本實驗完成的基礎(chǔ)上,逐步完成課程設(shè)計。針對自己的理解和學(xué)習(xí),實現(xiàn)一個小編譯器括符號表的構(gòu)造,詞法分析,語法分析,目標(biāo)代碼生成等重要

4、子程序,其中詞法分析、語法分析及語義分析功能必須完成),并對其進(jìn)行分析解釋和總結(jié),同時將理論與實際應(yīng)用結(jié)合起來,接受軟件設(shè)計等開發(fā)過程的全面訓(xùn)練,從而提高軟件開發(fā)的能力。</p><p><b>  課程設(shè)計的任務(wù)</b></p><p><b> ?。?)設(shè)計符號表</b></p><p>  確定符號表的組織方式,一般

5、應(yīng)包括名字欄和信息欄,其中名字欄作為關(guān)鍵字。要考慮能夠存儲有關(guān)名字的信息,并可以高效地完成如下操作:</p><p>  a.查找:根據(jù)給定的名字,在符號表中查找其信息。如果該名字在符號表中不存在,則將其加入到符號表中,否則返回指向該名字的指針;</p><p>  b.刪除:從符號表中刪除給定名字的表項。</p><p> ?。?)設(shè)計詞法分析器</p>

6、;<p>  設(shè)計各單詞的狀態(tài)轉(zhuǎn)換圖,并為不同的單詞設(shè)計種別碼。將詞法分析器設(shè)計成供語法分析器調(diào)用的子程序。功能包括:</p><p>  具備預(yù)處理功能。將不翻譯的注釋等符號先濾掉,只保留要翻譯的符號串,即要求設(shè)計一個供詞法分析調(diào)用的預(yù)處理子程序;</p><p>  能夠拼出語言中的各個單詞;</p><p>  將拼出的標(biāo)識符填入符號表;<

7、/p><p>  返回(種別碼, 屬性值)。</p><p><b> ?。?)語法分析器</b></p><p>  要求用預(yù)測分析法、遞歸下降分析法、算符優(yōu)先分析法、SLR分析法(幾種方法任選),實現(xiàn)對表達(dá)式、各種說明語句、控制語句進(jìn)行語法分析。</p><p> ?。?)目標(biāo)代碼生成器</p><p

8、>  能完成指定寄存器個數(shù)的情況下將一中間代碼程序段翻譯成匯編語言目標(biāo)代碼(匯編指令應(yīng)包括加、減、乘、除),要求指令條數(shù)最少的情況下,盡量使用寄存器,盡量少訪問內(nèi)存,這樣才能做到運(yùn)行效率高。</p><p><b>  三、課程設(shè)計要求</b></p><p>  樣本語言為C-語言,實現(xiàn)簡單的編譯器,其中基本的語句要求必須實現(xiàn),其余部分可根據(jù)自己的實際情況選擇

9、實現(xiàn)。對主要代碼給予解釋和理解注釋,各函數(shù)和過程應(yīng)有簡要描述,有功能說明,有入口和出口參數(shù)說明。</p><p>  簡單編譯器的實現(xiàn)流程圖</p><p><b>  實現(xiàn)環(huán)境</b></p><p>  Windows XP操作系統(tǒng)、win-TC運(yùn)行環(huán)境</p><p>  六、課程設(shè)計的詳細(xì)過程</p>

10、<p><b>  設(shè)計詞法分析器</b></p><p><b>  設(shè)計思想:</b></p><p>  要求:1. 對單詞的構(gòu)詞規(guī)則有明確的定義;</p><p>  2. 編寫的分析程序能夠正確識別源程序中的單詞符號;</p><p>  3. 識別出的單詞以<種別碼,

11、值>的形式保存在符號表中;</p><p>  4. 詞法分析中源程序的輸入以.c格式,分析后的符號表保存在.txt文件中。</p><p>  5. 對于源程序中的詞法錯誤,能夠做出簡單的錯誤處理,給出簡單的錯誤提示,保證順利完成整個源程序的詞法分析;</p><p>  6. 輸入:由符合規(guī)定單詞類別結(jié)構(gòu)的各類單詞組成的源程序。</p>&l

12、t;p><b>  實現(xiàn)方法:</b></p><p>  根據(jù)加入語義過程的狀態(tài)轉(zhuǎn)換圖直接編寫詞法分析程序。根據(jù)每一組狀態(tài)轉(zhuǎn)換關(guān)系(標(biāo)識符)組織程序結(jié)構(gòu),并將所有公共處理過程分別實現(xiàn)即可。在掃描源程序字符串時,一旦識別出關(guān)鍵字、運(yùn)算符、標(biāo)識符、無符號常數(shù)中之一,即以二元式形式(類別編碼,值)輸出單詞。每次調(diào)用詞法分析程序,它均能自動繼續(xù)掃描下去,形成下一個單詞。</p>

13、<p>  實現(xiàn)過程及主要代碼:</p><p>  定義主要函數(shù): </p><p>  1. char Scanin[100],Scanout[100]; //用于接收輸入輸出文件名</p><p>  FILE *fin,*fout; //用于指向輸入輸出文件的指針</p><p>  2. //下面定義保留,

14、為簡化程序,使用字符指針數(shù)組保存所有保留字。</p><p>  //如果想增加保留字,可繼續(xù)添加,并修改保留字?jǐn)?shù)目</p><p>  #define keywordSum 8</p><p>  char *keyword[keywordSum]={ "if","else","for","w

15、hile","do","int","read","write"};</p><p>  3. //下面定義純單分界符,如需要可添加</p><p>  char singleword[50]="+-*(){};,:";</p><p>  4. //下面定義

16、雙分界符的首字符</p><p>  char doubleword[10]="><=!";</p><p>  5. scanf("%s",Scanin);</p><p>  printf("請輸入詞法分析輸出文件名(包括路徑):");</p><p>  scan

17、f("%s",Scanout);</p><p>  6. if ((fin=fopen(Scanin,"r"))==NULL) //判斷輸入文件名是否正確</p><p>  {printf("\n打開詞法分析輸入文件出錯!\n");</p><p>  return(1);//輸入文件出錯返回錯誤代碼

18、1</p><p><b>  }</b></p><p>  if ((fout=fopen(Scanout,"w"))==NULL) //判斷輸出文件名是否正確</p><p>  { printf("\n創(chuàng)建詞法分析輸出文件出錯!\n");</p><p>  return(

19、2); //輸出文件出錯返回錯誤代碼2</p><p><b>  }</b></p><p>  7. ch=getc(fin);//讀取文件里的一個字符</p><p>  8. isalpha(ch) //字母判斷函數(shù)</p><p>  isalnum(ch)) //數(shù)字判斷函數(shù)</p>&

20、lt;p>  strcmp(token,keyword[n]) //串比較</p><p>  fprintf(fout,"%s\t%s\n","ID",token); //輸出標(biāo)識符符號到fout指定的文件</p><p>  strchr(singleword,ch) //聲明: char *strchr( const char *str

21、ing, int c );</p><p><b>  實現(xiàn)函數(shù)代碼:</b></p><p><b>  初始化函數(shù):</b></p><p><b>  init()</b></p><p>  {char *key[]={" ","case&

22、quot;,"char","const","do","double",</p><p>  "else","float","for","if","int","long","short" };

23、 </p><p>  char *limit[]={" ","(",")",".","!", "*","/","%","+","-",</p><p>  "=",&q

24、uot;,",";","{","}","#","'"};</p><p>  FILE *fp;int i;char c;fp=fopen("key.txt","w");</p><p>  for(i=1;i<=12;i++)

25、</p><p>  fprintf(fp,"%s\n",key[i]);</p><p>  fclose(fp);/*初始化關(guān)鍵字*/</p><p>  fp=fopen("limit.txt","w");</p><p>  for(i=1;i<=17;i++)<

26、/p><p>  fprintf(fp,"%s\n",limit[i]); c='"';</p><p>  fprintf(fp,"%c\n",c);</p><p>  fclose(fp); /*初始化運(yùn)算、限界符表*/</p><p>  fp=

27、fopen("id.txt","w");</p><p>  fclose(fp); /*初始化標(biāo)識符表*/</p><p>  fp=fopen("constant.txt","w");</p><p>  fclose(fp);

28、 /*初始化常數(shù)表*/</p><p>  fp=fopen("output.txt","w");</p><p>  fclose(fp); /*初始化輸出文件*/</p><p><b>  }</b></p><p>  根據(jù)不同命令查表或造表函數(shù)

29、:</p><p>  int find(char *buf,int type,int command)</p><p>  { int number=0;FILE *fp; char c; char temp[30]; int i=0;switch(type)</p><p>  {case 1: fp=fopen("key.txt",&q

30、uot;r");break;</p><p>  case 2: fp=fopen("id.txt","r");break;</p><p>  case 3: fp=fopen("constant.txt","r");break;</p><p>  case 4: fp=f

31、open("limit.txt","r");</p><p><b>  }</b></p><p>  c=fgetc(fp);</p><p>  while(c!=EOF)</p><p>  {while(c!='\n')</p><p&

32、gt;  {temp[i++]=c;c=fgetc(fp);}</p><p>  temp[i]='\0';</p><p><b>  i=0;</b></p><p><b>  number++;</b></p><p>  if(strcmp(temp,buf)==0)&l

33、t;/p><p>  { fclose(fp);</p><p>  return(number); /*若找到,返回在相應(yīng)表中的序號*/</p><p><b>  }</b></p><p><b>  else</b></p><p>  c=fgetc(f

34、p);</p><p><b>  }</b></p><p>  if(command==1)</p><p>  { fclose(fp); </p><p>  return(0); /*找不到,當(dāng)只需查表,返回0,否則還需造表*/</p><p><b>  }&

35、lt;/b></p><p>  switch(type)</p><p>  {case 1: fp=fopen("key.txt","a");break;</p><p>  case 2: fp=fopen("id.txt","a");break;</p>&l

36、t;p>  case 3: fp=fopen("constant.txt","a");break;</p><p>  case 4: fp=fopen("limit.txt","a");</p><p><b>  }</b></p><p>  fprin

37、tf(fp,"%s\n",buf);</p><p>  fclose(fp);</p><p>  return(number+1); /*造表時,將字符串添加到表尾并返回序號值*/</p><p><b>  }</b></p><p><b>  串處理函數(shù):</b>&l

38、t;/p><p>  void cs_manage(char *buffer)</p><p>  { FILE *fp;</p><p>  char *pointer;</p><p>  int result;</p><p>  result=find(buffer,3,2);/*先查常數(shù)表,若找不到則造入常數(shù)

39、表并返回序號值*/fp=fopen("output.txt","a");</p><p>  fprintf(fp,"%s\t\t\t3\t\t\t%d\n",buffer,result);</p><p>  fclose(fp); /*寫入輸出文件*/}</p><p>  

40、void ch_manage(char *buffer)</p><p>  { FILE *fp;</p><p>  int result;</p><p>  result=find(buffer,1,1); /*先查關(guān)鍵字表*/</p><p>  fp=fopen("output.txt","

41、;a");</p><p>  if(result!=0)</p><p>  fprintf(fp,"%s\t\t\t1\t\t\t%d\n",buffer,result); /*若找到,寫入輸出文件*/else</p><p>  {result=find(buffer,2,2); /*若找不到,則非關(guān)鍵字,查標(biāo)識符表,還找

42、不到則造入標(biāo)識符表*/</p><p>  fprintf(fp,"%s\t\t\t2\t\t\t%d\n",buffer,result);</p><p>  } /*寫入輸出文件*/</p><p>  fclose(fp);</p><p><b>

43、;  }</b></p><p><b>  掃描功能:</b></p><p>  int scanner()</p><p>  { FILE *fpin,*fpout;</p><p>  char filename[20];</p><p><b>  char ch

44、;</b></p><p>  int i=0,line=1;</p><p>  int count,result;</p><p>  char array[30];</p><p>  char *word;</p><p>  /*輸入要編譯文件的名字和路徑*/</p><p&g

45、t;  if((fpin=fopen("c:\\source.txt","r"))==NULL)</p><p>  {printf("the file you input is not exist!");</p><p><b>  getch();</b></p><p><

46、b>  return 0;</b></p><p><b>  }</b></p><p>  ch=fgetc(fpin);</p><p>  while(ch!=EOF) /*按字符依次掃描源程序,直至結(jié)束*/</p><p><b>  { i=0;</b></

47、p><p>  if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_'))</p><p><b>  /*以字母開頭*/</b></p><p> 

48、 { while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||((ch>='0')&&(ch<='9')))</p><p>  {array[

49、i++]=ch;</p><p>  ch=fgetc(fpin);</p><p><b>  }</b></p><p>  word=(char *)malloc((i+1)*sizeof(char));</p><p>  memcpy(word,array,i);</p><p>  w

50、ord[i]='\0';</p><p>  ch_manage(word);</p><p>  if(ch!=EOF)</p><p>  fseek(fpin,-1L,SEEK_CUR);</p><p><b>  }</b></p><p>  else if(ch>

51、;='0'&&ch<='9') /*以數(shù)字開頭*/</p><p>  { while(ch>='0'&&ch<='9')</p><p>  { array[i++]=ch;</p><p>  ch=fgetc(fpin);</p>&

52、lt;p><b>  }</b></p><p>  word=(char *)malloc((i+1)*sizeof(char));</p><p>  memcpy(word,array,i);</p><p>  word[i]='\0';</p><p>  cs_manage(word);

53、</p><p>  if(ch!=EOF)</p><p>  fseek(fpin,-1L,SEEK_CUR);</p><p><b>  }</b></p><p>  else if((ch==' ')||(ch=='\t'))</p><p>  ;

54、 /*消除空格符和水平制表符*/</p><p>  else if(ch=='\n')</p><p>  line++; /*消除回車并記錄行數(shù)*/</p><p>  else if(ch=='/')</p><p>  { /*消除注釋*/

55、</p><p>  ch=fgetc(fpin);</p><p>  if(ch=='=')</p><p>  { /*判斷是否為‘/=’符號*/</p><p>  fpout=fopen("output.txt","a");</p>&l

56、t;p>  fprintf(fpout,"/=\t\t\t4\t\t\t32\n");</p><p>  fclose(fpout);</p><p><b>  }</b></p><p>  else if(ch!='*')</p><p>  {

57、 /*若為除號,寫入輸出文件*/</p><p>  fpout=fopen("output.txt","a");</p><p>  fprintf(fpout,"/\t\t\t4\t\t\t13\n");</p><p>  fclose(fpout);</p><p>  fs

58、eek(fpin,-1L,SEEK_CUR);</p><p><b>  }</b></p><p><b>  }</b></p><p>  else if(ch=='"') /*消除包含在雙引號中的字符串常量*/</p><p>  { fpout=fopen(&

59、quot;output.txt","a");</p><p>  fprintf(fpout,"%c\t\t\t4\t\t\t37\n",ch);</p><p>  ch=fgetc(fpin);</p><p>  while(ch!='"')</p><p> 

60、 ch=fgetc(fpin);</p><p>  fprintf(fpout,"%c\t\t\t4\t\t\t37\n",ch);</p><p>  fclose(fpout);</p><p><b>  }</b></p><p>  else /*首字符為其它字符,即運(yùn)算限界符或非法字符

61、*/</p><p>  { array[0]=ch;</p><p>  ch=fgetc(fpin); /*再讀入下一個字符,判斷是否為雙字符運(yùn)算、限界符*/</p><p>  if(ch!=EOF) /*若該字符非文件結(jié)束符*/</p><p>  { array[1]=ch;</p><p>  wo

62、rd=(char *)malloc(3*sizeof(char));</p><p>  memcpy(word,array,2);</p><p>  word[2]='\0';</p><p>  result=find(word,4,1);/*先檢索是否為雙字符運(yùn)算、限界符*/</p><p>  if(result==

63、0) /*若不是*/</p><p>  { word=(char *)malloc(2*sizeof(char));</p><p>  memcpy(word,array,1);</p><p>  word[1]='\0';</p><p>  result=find(word,4,1); /*檢索是否為單字

64、符運(yùn)算、限界符*/</p><p>  /*若為單字符運(yùn)算、限界符,寫入輸出文件并將掃描文件指針回退一個字符*/</p><p>  fpout=fopen("output.txt","a");</p><p>  fprintf(fpout,"%s\t\t\t4\t\t\t%d\t\n",word,res

65、ult);</p><p>  fclose(fpout);</p><p>  fseek(fpin,-1L,SEEK_CUR);</p><p><b>  }</b></p><p>  else /*若為雙字符運(yùn)算、限界符,寫輸出文件*/</p><p>  { fpout=f

66、open("output.txt","a");</p><p>  fprintf(fpout,"%s\t\t\t4\t\t\t%d\n",word,result);</p><p>  fclose(fpout);</p><p><b>  }</b></p><

67、;p><b>  }</b></p><p><b>  else</b></p><p>  { /*若讀入的下一個字符為文件結(jié)束符*/</p><p>  word=(char *)malloc(2*sizeof(char));</p><p>  memcpy

68、(word,array,1);</p><p>  word[1]='\0';</p><p>  result=find(word,4,1); /*只考慮是否為單字符運(yùn)算、限界符*/</p><p>  /*若是,寫輸出文件*/</p><p>  fpout=fopen("output.txt&quo

69、t;,"a");</p><p>  fprintf(fpout,"%s\t\t\t4\t\t\t%d\n",word,result);</p><p>  fclose(fpout);</p><p><b>  }</b></p><p><b>  }</b&

70、gt;</p><p>  ch=fgetc(fpin); </p><p><b>  }</b></p><p>  fclose(fpin);return 1;</p><p><b>  }</b></p><p><b>  主函數(shù):</b>&

71、lt;/p><p><b>  main()</b></p><p>  { int i;</p><p>  init(); /*初始化*/</p><p>  i=scanner(); /*掃描源程序*/</p><p><b>  if(i==

72、1)</b></p><p>  printf("The answer is in 'output.txt':");</p><p><b>  getch();</b></p><p><b>  }</b></p><p> ?。?)設(shè)計語法、語義

73、分析器</p><p><b>  設(shè)計思想:</b></p><p>  要求:1. 對語法規(guī)則有明確的定義;</p><p>  2. 編寫的分析程序能夠?qū)嶒炓坏慕Y(jié)果進(jìn)行正確的語法分析;</p><p>  3.編寫的分析程序能夠?qū)嶒灦慕Y(jié)果進(jìn)行正確的語義分析;</p><p>  4.對

74、于遇到的語法、語義錯誤,能夠做出簡單的錯誤處理,給出簡單的錯誤提示,保證語義分析過程;</p><p><b>  實現(xiàn)方法: </b></p><p>  在詞法分析識別出單詞符號的基礎(chǔ)上分析并規(guī)定程序的語法結(jié)構(gòu)是否符合語法規(guī)則。其工作本質(zhì)就是按文法的產(chǎn)生式,識別輸入符號串是否為一個句子。首先定義語法規(guī)則,然后按照規(guī)則實現(xiàn)語法分析。</p><p

75、>  實現(xiàn)過程及主要代碼:</p><p>  插入符號表動作@name-def↓n, t的程序如下:</p><p> ?。?)定義符號表結(jié)構(gòu)</p><p><b>  struct{</b></p><p>  char name[8];</p><p>  int address;&

76、lt;/p><p>  }vartable[maxvartablep];//改符號表最多容納maxvartablep個記錄</p><p>  int vartablep=0,labelp=0,datap=0;</p><p>  //插入符號表動作@name-def↓n, t的程序如下:</p><p>  int name_def(char

77、*name)</p><p>  { int i,es=0;</p><p>  if (vartablep>=maxvartablep) return(21);</p><p>  for(i=vartablep-1;i==0;i--)//查符號表</p><p>  { if (strcmp(vartab

78、le[i].name,name)==0)</p><p>  { es=22;//22表示變量重復(fù)聲明</p><p><b>  break;</b></p><p><b>  }</b></p><p><b>  }</b></p>

79、<p>  if (es>0) return(es);</p><p>  strcpy(vartable[vartablep].name,name);</p><p>  vartable[vartablep].address=datap;</p><p>  datap++;//分配一個單元,數(shù)據(jù)區(qū)指針加1</p><p&

80、gt;  vartablep++;</p><p>  return(es);</p><p><b>  }</b></p><p> ?。?)查詢符號表返回地址</p><p>  int lookup(char *name,int *paddress)</p><p>  { int

81、 i,es=0;</p><p>  for(i=0;i<vartablep;i++)</p><p>  { if (strcmp(vartable[i].name,name)==0)</p><p>  { *paddress=vartable[i].address;</p><p>  retur

82、n(es);</p><p><b>  }</b></p><p><b>  }</b></p><p>  es=23;//變量沒有聲明</p><p>  return(es);</p><p><b>  }</b></p>&l

83、t;p>  (3)語法、語義分析及代碼生成程序</p><p>  int TESTparse()</p><p>  { int es=0;</p><p>  if((fp=fopen(Scanout,"r"))==NULL)</p><p>  { printf("\n打開%s錯誤!

84、\n",Scanout);</p><p><b>  es=10;</b></p><p>  return(es);</p><p>  }if (es==0) es=program();</p><p>  switch(es)</p><p>  { case 0: prin

85、tf("語法分析成功!\n");break;</p><p>  case 10: printf("打開文件 %s失敗!\n",Scanout);break;</p><p>  case 1: printf("缺少{!\n");break;</p><p>  case 2: printf("缺

86、少}!\n");break;</p><p>  case 3: printf("缺少標(biāo)識符!\n");break;</p><p>  case 4: printf("少分號!\n");break;</p><p>  case 5: printf("缺少(!\n");break;</p&

87、gt;<p>  case 6: printf("缺少)!\n");break;</p><p>  case 7: printf("缺少操作數(shù)!\n");break;</p><p>  case 21: printf("符號表溢出!\n");break;</p><p>  case 22

88、: printf("變量重復(fù)定義!\n");break;</p><p>  case 23: printf("變量未聲明!\n");break; }</p><p>  fclose(fp);fclose(fout);return(es);}</p><p>  //program::={<declaration_li

89、st><statement_list>}</p><p>  int program()</p><p>  { int es=0,i;</p><p>  fscanf(fp,"%s %s\n",token,token1);</p><p>  printf("%s %s\n"

90、,token,token1);</p><p>  if(strcmp(token,"{"))//判斷是否'{'</p><p>  { es=1;return(es);}</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p>

91、;<p>  printf("%s %s\n",token,token1);</p><p>  es=declaration_list();</p><p>  if (es>0) return(es);</p><p>  es=statement_list();</p><p>  if (es&

92、gt;0) return(es);</p><p>  if(strcmp(token,"}"))//判斷是否'}'</p><p>  { es=2;return(es);}</p><p>  return(es);</p><p><b>  }</b></p&

93、gt;<p>  //<declaration_list>::=</p><p>  //<declaration_list><declaration_stat>|<declaration_stat></p><p>  //改成<declaration_list>::={<declaration_stat&g

94、t;}</p><p>  int declaration_list()</p><p>  { int es=0;</p><p>  while (strcmp(token,"int")==0)</p><p>  { es=declaration_stat();</p><p&

95、gt;  if (es>0) return(es);</p><p><b>  }</b></p><p>  return(es);</p><p>  }//<declaration_stat>↓vartablep,datap,codep ->int ID↑n@name-def↓n,t;</p>&l

96、t;p>  int declaration_stat()</p><p>  { int es=0; </p><p>  fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token,token1);</p><p>  if (strc

97、mp(token,"ID")) return(es=3); //不是標(biāo)識符</p><p>  es=name_def(token1);//插入符號表</p><p>  if (es>0) return(es);</p><p>  fscanf(fp,"%s%s\n",&token,&token1)

98、;printf("% %s\n",token,token1);</p><p>  if (strcmp(token,";") ) return(es=4);</p><p>  fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token

99、,token1);</p><p>  return(es);</p><p><b>  }</b></p><p>  //<statement_list>::=<statement_list><statement>|<statement></p><p>  //改成

100、<statement_list>::={<statement>}</p><p>  int statement_list()</p><p>  { int es=0;</p><p>  while (strcmp(token,"}"))</p><p>  { es=sta

101、tement();</p><p>  if (es>0) return(es);</p><p><b>  }</b></p><p>  return(es);</p><p><b>  }</b></p><p>  //<statement>::

102、= <if_stat>|<while_stat>|<for_stat></p><p>  // |<compound_stat> |<expression_stat></p><p>  int statement()</p><p>  { int es=0;</

103、p><p>  if (es==0 && strcmp(token,"if")==0) es=if_stat();//<IF語句></p><p>  if (es==0 && strcmp(token,"while")==0) es=while_stat();//<while語句></p&g

104、t;<p>  if (es==0 && strcmp(token,"do")==0) es=do_stat();//<do_while語句></p><p>  if (es==0 && strcmp(token,"for")==0) es=for_stat();//<for語句></p>

105、<p>  if (es==0 && strcmp(token,"read")==0) es=read_stat();//<read語句></p><p>  if (es==0 && strcmp(token,"write")==0) es=write_stat();//<write語句></p&g

106、t;<p>  if (es==0 && strcmp(token,"{")==0) es=compound_stat();//<復(fù)合語句></p><p>  if (es==0 && (strcmp(token,"ID")==0||strcmp(token,"NUM")==0)) es=exp

107、ression_stat();//<表達(dá)式語句></p><p>  return(es);</p><p><b>  }</b></p><p>  //<IF_stat>::= if (<expr>) <statement > [else < statement >]</p

108、><p><b>  /*</b></p><p>  if (<expression>)@BRF↑label1 <statement > @BR↑label2 @SETlabel↓label1 [ else < statement >] @SETlabel↓label2</p><p>  其中動作符號的含義如

109、下</p><p>  @BRF↑label1 :輸出 BRF label1, </p><p>  @BR↑label2:輸出 BR label2, </p><p>  @SETlabel↓label1:設(shè)置標(biāo)號label1 </p><p>  @SETlabel↓label2:設(shè)置標(biāo)號label2 */</p><

110、p>  int if_stat(){</p><p>  int es=0,label1,label2; //if</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p

111、><p>  if (strcmp(token,"(")) return(es=5); //少左括號</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p&

112、gt;<p>  es=expression();</p><p>  if (es>0) return(es);</p><p>  if (strcmp(token,")")) return(es=6); //少右括號</p><p>  label1=labelp++;//用label1記住條件為假時要轉(zhuǎn)向的標(biāo)號<

113、;/p><p>  fprintf(fout," BRF LABEL%d\n",label1);//輸出假轉(zhuǎn)移指令</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,tok

114、en1);</p><p>  es=statement(); </p><p>  if (es>0) return(es);</p><p>  label2=labelp++;//用label2記住要轉(zhuǎn)向的標(biāo)號</p><p>  fprintf(fout," BR LABEL%d\n",labe

115、l2);//輸出無條件轉(zhuǎn)移指令</p><p>  fprintf(fout,"LABEL%d:\n",label1);//設(shè)置label1記住的標(biāo)號</p><p>  if (strcmp(token,"else")==0)//else部分處理</p><p>  { fscanf(fp,"%s %

116、s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p><p>  es=statement(); </p><p>  if (es>0) return(es);</p><p><b>  }<

117、;/b></p><p>  fprintf(fout,"LABEL%d:\n",label2);//設(shè)置label2記住的標(biāo)號</p><p>  return(es);</p><p><b>  }</b></p><p>  //<do_while_stat>::=do<

118、;statement>while(<exper>)</p><p>  //<do_while_stat>::=do @SET↑labellabel1<statement></p><p>  // while(<表達(dá)式>)</p><p>  // @BRF↑label2@BR↑label1@SETlabel↓

119、label2</p><p><b>  //動作解釋如下:</b></p><p>  //@SETlabel↑label1:設(shè)置標(biāo)號label1</p><p>  //@BRF↑label2 :輸出 BRF label2,</p><p>  //@BR↓label1:輸出 BR label1,</p>

120、<p>  //@SETlabel↓label2:設(shè)置標(biāo)號label2</p><p>  int do_stat(){</p><p>  int es,label1,label2;</p><p><b>  es=0;</b></p><p>  label1=labelp++;</p>

121、<p>  fprintf(fout,"LABEL%d:\n",label1);//設(shè)置label1標(biāo)號</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p>

122、<p>  es=statement();</p><p>  if (es>0) return(es);</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</

123、p><p>  if(strcmp(token,"while")==0)//while 部分</p><p>  { fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p>

124、<p>  if (strcmp(token,"(")) return(es=5); //少左括號</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p>

125、<p>  es=expression();</p><p>  if (es>0) return(es);</p><p>  if (strcmp(token,")")) return(es=6); //少右括號</p><p><b>  } else</b></p><p>

126、;  printf("缺少while");</p><p>  label2=labelp++;</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p>

127、;<p>  return(es);</p><p><b>  }</b></p><p>  //<while_stat>::= while (<expr >) < statement ></p><p>  //<while_stat>::=while @SET↑labella

128、bel1(<expression>) @BRF↑label2 </p><p>  // <statement >@BR↓label1 @SETlabel↓label2</p><p><b>  //動作解釋如下:</b></p><p>  //@SETlabel↑label1:設(shè)置標(biāo)號la

129、bel1</p><p>  //@BRF↑label2 :輸出 BRF label2,</p><p>  //@BR↓label1:輸出 BR label1,</p><p>  //@SETlabel↓label2:設(shè)置標(biāo)號label2</p><p>  int while_stat()</p><p>  {

130、 int es=0,label1,label2; </p><p>  label1=labelp++;</p><p>  fprintf(fout,"LABEL%d:\n",label1);//設(shè)置label1標(biāo)號</p><p>  fscanf(fp,"%s %s\n",&token,&toke

131、n1);</p><p>  printf("%s %s\n",token,token1);</p><p>  if (strcmp(token,"(")) return(es=5); //少左括號</p><p>  fscanf(fp,"%s %s\n",&token,&token

132、1);</p><p>  printf("%s %s\n",token,token1);</p><p>  es=expression();</p><p>  if (es>0) return(es);</p><p>  if (strcmp(token,")")) return(es=

133、6); //少右括號</p><p>  label2=labelp++;</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p><p>  es=stat

134、ement();</p><p>  if (es>0) return(es);</p><p>  fscanf(fp,"%s %s\n",&token,&token1);</p><p>  printf("%s %s\n",token,token1);</p><p>  r

135、eturn(es);</p><p><b>  }</b></p><p>  //<for_stat>::= for(<expr>,<expr>,<expr>)<statement></p><p>  <for_stat>::=for (<expression&

136、gt;;</p><p>  @SETlabel↑label1< expression >@BRF↑label2@BR↑label3;</p><p>  @SETlabel↑label4 < expression >@BR↓label1) </p><p>  @SETlabel↓label3 <語句 >@BR↓label4@S

137、ETlabel↓label2 </p><p><b>  動作解釋:</b></p><p>  1. @SETlabel↓label1:設(shè)置標(biāo)號label1</p><p>  2. @BRF↑label2 :輸出 BRF label2,</p><p>  3. @BR↑label3:輸出 BR label3

138、,</p><p>  4. @SETlabel↓label4:設(shè)置標(biāo)號label4</p><p>  5. @BR↑label1:輸出 BR label1,</p><p>  6. @SETlabel↓label3:設(shè)置標(biāo)號label3</p><p>  7. @BR↑label4:輸出 BR label4,</p>

139、;<p>  8. @SETlabel↓label2:設(shè)置標(biāo)號label2 </p><p>  int for_stat()</p><p>  { int es=0,label1,label2,label3,label4; </p><p>  fscanf(fp,"%s %s\n",&token,&t

溫馨提示

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

評論

0/150

提交評論