編譯原理課程設(shè)計(jì)詞法分析器文檔_第1頁(yè)
已閱讀1頁(yè),還剩16頁(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>  2011—2012學(xué)年第一學(xué)期</p><p><b>  目 錄</b></p><p>  第 1 節(jié)課程設(shè)計(jì)目的1</p><p>  第 2 節(jié)課程設(shè)計(jì)要求1</p><p>  第 3 節(jié)課程設(shè)計(jì)內(nèi)容2</p><p>  第 4 節(jié) 狀態(tài)轉(zhuǎn)換圖

2、4</p><p>  第 5 節(jié) 實(shí)現(xiàn)工具4</p><p>  第 6 節(jié)實(shí)現(xiàn)函數(shù)4</p><p>  第 7 節(jié)測(cè)試結(jié)果5</p><p>  第 8 節(jié)實(shí)驗(yàn)源代碼6</p><p>  第 9 節(jié)參考文獻(xiàn)9</p><p><b>  致謝</b

3、></p><p><b>  感設(shè)計(jì)目的</b></p><p> ?、倮斫庠~法分析器的基本功能。詞法分析的任務(wù)是:從左至右逐個(gè)字符地對(duì)源程序進(jìn)行掃描,產(chǎn)生一個(gè)個(gè)的單詞符號(hào)(token),把作為字符串的源程序改造成 單詞符號(hào)串的中間程序。因此,詞法分析是編譯的基礎(chǔ)。</p><p> ?、诶斫庠~法規(guī)則的描述方法。程序設(shè)計(jì)語(yǔ)言一般可以用

4、標(biāo)識(shí)符、關(guān)鍵字、運(yùn)算符、分隔符、常量、字符串和注釋符來(lái)描述</p><p>  ④理解狀態(tài)轉(zhuǎn)換圖及其實(shí)現(xiàn)。一個(gè)狀態(tài)轉(zhuǎn)換圖可用于識(shí)別(或接受)一定的字符。 大多數(shù)程序語(yǔ)言的單詞符號(hào)都可以用轉(zhuǎn)換圖予以識(shí)別。 轉(zhuǎn)換圖非常易于用程序?qū)崿F(xiàn),最簡(jiǎn)單的辦法是讓每個(gè)狀態(tài)結(jié)對(duì)應(yīng)一小段程序。</p><p>  ④能夠編寫(xiě)簡(jiǎn)單的詞法分析器。</p><p><b>  2.課

5、程設(shè)計(jì)的要求</b></p><p>  手工構(gòu)造一個(gè)簡(jiǎn)單的詞法分析程序, 能夠識(shí)別標(biāo)識(shí)符、整數(shù)、關(guān)鍵字、算符、界符。</p><p> ?、佼?huà)出識(shí)別單詞的狀態(tài)轉(zhuǎn)換圖。</p><p>  (若狀態(tài)轉(zhuǎn)換圖過(guò)于復(fù)雜,可以只畫(huà)出主要部分;若依舊復(fù)雜,可只識(shí)別標(biāo)識(shí)符和整數(shù))</p><p> ?、诟鶕?jù)狀態(tài)轉(zhuǎn)換圖手工構(gòu)造詞法分析程序。從以

6、下方法中選一:</p><p>  詞法分析器作為獨(dú)立的一遍。</p><p>  詞法分析結(jié)果輸出到屏幕上或存入文件。</p><p>  詞法分析器作為一個(gè)子程序被語(yǔ)法分析器調(diào)用。</p><p>  每次調(diào)用返回一個(gè)單詞</p><p>  同時(shí)將單詞及屬性存入符號(hào)表</p><p>  

7、③ 實(shí)現(xiàn)狀態(tài)轉(zhuǎn)換圖。從以下方法中選一:</p><p><b>  直接轉(zhuǎn)向法</b></p><p><b>  表驅(qū)動(dòng)法</b></p><p><b>  四、選做實(shí)驗(yàn)</b></p><p><b>  ? 使用緩沖技術(shù)</b></p>

8、<p><b>  3.課程設(shè)計(jì)內(nèi)容</b></p><p>  程序語(yǔ)言的單詞符號(hào)一般可分為下列五種。</p><p><b>  (1)關(guān)鍵字 </b></p><p>  是由程序語(yǔ)言定義的具有固定意義的標(biāo)志符。本程序定義 char,short,int,unsigned,long,float,doub

9、le,struct,union,void,enum,const,typedef,auto,static,break,case,continue,default,do,else,for,if,return,switch,while,sizeof,printf,FILE,fopen,NULL,fclose,exit,read,closef,printf為關(guān)鍵字。</p><p><b> ?。?)標(biāo)識(shí)符&l

10、t;/b></p><p>  用來(lái)表示各種名字,如變量名、數(shù)組名、過(guò)程名等等。</p><p><b> ?。?)常數(shù)</b></p><p>  常數(shù)的類型一般有整型、實(shí)型、布爾型、文字型等等。例如,100,3.14159。</p><p><b> ?。?)運(yùn)算符</b></p&g

11、t;<p>  如+、-、*、/、>=、<=、== 等等</p><p><b> ?。?)界符</b></p><p>  如[、]、{、}、(、)、;、,、.等等。</p><p><b>  具體實(shí)現(xiàn)過(guò)程:</b></p><p>  用c++編寫(xiě)詞法分析程序,從文件

12、中讀入預(yù)分析的源程序經(jīng)詞法分析將結(jié)果寫(xiě)入指定文件中。</p><p>  在設(shè)計(jì)中預(yù)分析文件保存在test.txt中,輸出結(jié)果保存在result.txt中。</p><p><b>  本程序?qū)崿F(xiàn)了</b></p><p>  將詞法分析器作為獨(dú)立的一遍,詞法分析結(jié)果存入文件。</p><p>  用直接轉(zhuǎn)向法實(shí)現(xiàn)狀態(tài)轉(zhuǎn)

13、換圖。</p><p><b>  ?使用緩沖技術(shù)。</b></p><p>  本程序能夠識(shí)別簡(jiǎn)單的運(yùn)算符,界符,常數(shù),標(biāo)示符和關(guān)鍵字。其中關(guān)鍵字由程序所給的關(guān)鍵字表kt(key table)內(nèi)容指定。如有未涉及的關(guān)鍵字還可以通過(guò)修改程序中表內(nèi)容擴(kuò)展。對(duì)未定義的字符(不屬于界符,運(yùn)算符和常數(shù))輸出 并顯示為“其他字符”。文中特別定義了注釋符號(hào),換行符號(hào)和空格。在程序

14、設(shè)計(jì)工程中一開(kāi)始未注意將當(dāng)前指針后退一位的情況,在輸出程序結(jié)果時(shí)發(fā)現(xiàn)一些字符缺漏。通過(guò)查資料【1】發(fā)現(xiàn)了將指針后移的用法并解決了這個(gè)問(wèn)題。設(shè)計(jì)過(guò)程中牽涉到對(duì)文件的使用如c_str(),ios:binary的用法,get()函數(shù)的用法,fstream的兩個(gè)類ifstream和ofstream的用法【2】實(shí)現(xiàn)文件的讀寫(xiě)操作。</p><p>  為了分析大于4kb的程序本程序使用了著名的雙緩沖技術(shù)。設(shè)計(jì)思想如下<

15、;/p><p><b>  4.狀態(tài)轉(zhuǎn)換圖如下</b></p><p><b>  5.實(shí)驗(yàn)工具</b></p><p>  Vc++6.0 ,win7畫(huà)圖工具,</p><p><b>  6. 實(shí)現(xiàn)函數(shù)</b></p><p>  void get_ch

16、ar (); //用于從buffer讀取一個(gè)字符到C </p><p>  int letter (int C); //判斷是否是字母 </p><p>  int digit (int C); //判斷時(shí)候是數(shù)字或者小數(shù)點(diǎn) </p><p>  int underline (int C);

17、 //判斷時(shí)候是下劃線 </p><p>  int reserve (string token); //判斷時(shí)候是關(guān)鍵字 </p><p>  void retract (); //向前指針向后退一個(gè) </p><p>  void returnout (string str1,string str2); //文件打印<

18、/p><p><b>  結(jié)果及測(cè)試分析</b></p><p><b>  實(shí)驗(yàn)代碼</b></p><p>  /////////////////////////////////////////// 詞法分析程序@zhangjinrong///////////////////////////////////////////

19、///////</p><p>  /////////頭文件////////////</p><p>  #include <iostream></p><p>  #include <fstream></p><p>  #include <string></p><p>  us

20、ing namespace std;</p><p>  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p>  //關(guān)鍵字///////////</p><p>

21、  string kt[36] ={"char","short","int","unsigned","long","float","double","struct","union","void",</p><p>

22、  "enum","const","typedef","auto","static","break","case","continue","default","do","else","for",&qu

23、ot;if",</p><p>  "return","switch","while","sizeof","printf","FILE","fopen","NULL",</p><p>  "fclose&quo

24、t;,"exit","read","close","fprintf"};</p><p>  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<

25、/p><p>  //自定義變量,數(shù)組//</p><p>  ifstream infile; //以輸入(從硬盤(pán)到內(nèi)存)方式打開(kāi)文件</p><p>  ofstream outfile; //輸出(從內(nèi)存到硬盤(pán))方式打開(kāi)文件</p><p>  char buffer1 [64];

26、 //兩個(gè)緩沖buffer </p><p>  char buffer2 [64];</p><p>  char C; //用于switch分析 </p><p>  string token=""; //多個(gè)C組成的串 </p><p>

27、;  char *startptr,*forwardptr; //buffer的開(kāi)始指針和向前指針 </p><p>  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p>  //函數(shù)

28、聲明//////////</p><p>  void get_char (); //用于從buffer讀取一個(gè)字符到C </p><p>  int letter (int C); //判斷是否是字母 </p><p>  int digit (int C); //判斷時(shí)候是數(shù)字或者小數(shù)點(diǎn) <

29、/p><p>  int underline (int C); //判斷時(shí)候是下劃線 </p><p>  int reserve (string token); //判斷時(shí)候是關(guān)鍵字 </p><p>  void retract (); //向前指針向后退一個(gè) </p><p>  void ret

30、urnout (string str1,string str2); //文件打印 </p><p>  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p><b>  mai

31、n ()</b></p><p><b>  {</b></p><p>  startptr=buffer1; //數(shù)組頭指針</p><p>  forwardptr=buffer1; //數(shù)組當(dāng)前指針</p><p&

32、gt;  buffer1 [63]=buffer2 [63]=-1; //數(shù)組尾數(shù)值為-1</p><p>  cout<<"輸入源文件的路徑和文件名:(例: F:1.c)"<<endl;</p><p>  string str111;</p><p>  cin>>str111;&l

33、t;/p><p>  infile.open (str111.c_str (),ios::binary);//二進(jìn)制文件</p><p>  cout<<"輸入經(jīng)詞法分析后生成文件的路徑和文件名:"<<endl;</p><p>  string str222;</p><p>  cin>>

34、;str222;</p><p>  outfile.open (str222.c_str (),ios::trunc);//再次寫(xiě)入覆蓋文件已有內(nèi)容</p><p>  //////////////////////////////////////////////////////////////////////////////////////////////////////////////

35、//////////</p><p>  ///將文件內(nèi)容讀入第一緩沖區(qū)/////</p><p>  for (int i=0;i<=62;i++)</p><p>  buffer1 [i]=infile.get ();//將文件中字符放入第一緩沖區(qū)</p><p><b>  while (1)</b><

36、;/p><p><b>  {</b></p><p>  token=""; //多個(gè)C組成的串為空</p><p>  get_char (); //從數(shù)組中傳遞出一個(gè)字符c</p><p>  switch (C)</p><p><b>  { &

37、lt;/b></p><p>  ////當(dāng)首位字符為字母////////////////////////////////////////////////////////////////////////////////////////////////////</p><p>  case 'a':case 'b':case 'c':ca

38、se 'd':case 'e': case 'f': case 'g': case 'h': case 'i': case 'j':</p><p>  case 'k':case 'l':case 'm':case 'n':case &#

39、39;o': case 'p': case 'q': case 'r': case 's': case 't':</p><p>  case 'u':case 'v':case 'w':case 'x':case 'y': case 'z

40、': case 'A': case 'B': case 'C': case 'D':</p><p>  case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':

41、case 'L':case 'M':case 'N':case 'O':</p><p>  case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case '

42、W':case 'X':case 'Y':case 'Z':</p><p><b>  {</b></p><p>  while (letter (C)||digit (C)||underline (C)) //字母后跟字母或數(shù)字或下劃線時(shí)</p><p><b>  {&l

43、t;/b></p><p>  token=token+C; </p><p>  get_char ();</p><p><b>  }</b></p><p>  if (reserve (token)==1) //如果字符串不在關(guān)鍵字表中輸出標(biāo)示符</p><p&g

44、t;<b>  {</b></p><p>  returnout ("關(guān)鍵字",token);</p><p><b>  }else </b></p><p>  returnout (token,"標(biāo)示符"); //如果在關(guān)鍵字表中輸出標(biāo)示符</p>&

45、lt;p>  retract (); /*當(dāng)token已為關(guān)鍵字時(shí)由于執(zhí)行了get_char()已讀取一個(gè)字符。</p><p>  為避免漏掉需回溯一個(gè)字符*/</p><p><b>  break;</b></p><p><b>  }</b></p>

46、<p>  ///// 當(dāng)首字母為數(shù)字時(shí) ////////////////////////////////////////////////////////////////////////////////////////////////</p><p>  case '1':case '2':case '3':case '4':case &#

47、39;5':case '6':case '7':case '8':case '9':case '0':</p><p><b>  {</b></p><p>  while (digit (C)==1||C=='.')</p><p>&l

48、t;b>  {</b></p><p>  token=token+C; </p><p>  get_char (); </p><p><b>  }</b></p><p>  returnout ("常數(shù)",token);</p><p>  re

49、tract ();</p><p><b>  break;</b></p><p><b>  }</b></p><p>  //////本程序定義為運(yùn)算符所以考慮不同情況////////////////////////////////////////////////////////////////////////&l

50、t;/p><p><b>  case '<':</b></p><p><b>  {</b></p><p>  get_char (); //字符為<,<=,<>三種情況</p><p>  if (C=='

51、>')</p><p>  returnout ("<>","空格分界符");</p><p><b>  else</b></p><p><b>  {</b></p><p>  retract ();</p>&

52、lt;p>  returnout ("<","運(yùn)算符");</p><p><b>  }</b></p><p><b>  break;</b></p><p><b>  }</b></p><p>  ////////

53、//////////////////////////////////////////////////////////////////////////////////////////////////</p><p><b>  case '/':</b></p><p><b>  {</b></p><p>

54、;  get_char ();</p><p>  if (C=='*')// 讀到/*的情況一直讀到*/結(jié)束</p><p><b>  {</b></p><p><b>  while (1)</b></p><p><b>  {</b></p&g

55、t;<p>  get_char ();</p><p>  while (C!='*')</p><p>  get_char ();</p><p>  if (C=='/')</p><p><b>  break;</b></p><p>  

56、retract ();</p><p>  } </p><p><b>  }</b></p><p>  else if (C=='/') //讀到//的情況一直讀取字符直到這一行結(jié)束</p><p><b>  {<

57、;/b></p><p>  get_char ();</p><p>  while (C!='\n')</p><p>  get_char ();</p><p>  } </p><p><b>  else</b></p>

58、<p><b>  {</b></p><p>  retract ();</p><p>  returnout ("/","運(yùn)算符");</p><p><b>  }</b></p><p><b>  break;</b&

59、gt;</p><p><b>  }</b></p><p>  ////////////簡(jiǎn)單的運(yùn)算符和界符//////////////////////////////////////////////////////////////////////////////</p><p>  case'+' :{returnout (

60、"+","運(yùn)算符");break;}</p><p>  case'-' :{returnout ("-","運(yùn)算符");break;}</p><p>  case'*' :{returnout ("*","運(yùn)算符");break;}&l

61、t;/p><p>  case'=' :{returnout ("=","運(yùn)算符");break;}</p><p>  case'>' :{returnout (">","運(yùn)算符");break;}</p><p>  //case'/&

62、#39; :{returnout ("/","運(yùn)算符");break;}</p><p>  case'(' :{returnout ("(","界符"); break;}</p><p>  case')' :{returnout (")","界符

63、"); break;}</p><p>  case'[' :{returnout ("[","界符"); break;}</p><p>  case']' :{returnout ("]","界符"); break;} </p>

64、<p>  case';' :{returnout (";","界符"); break;}</p><p>  case'.' :{returnout (".","界符"); break;}</p><p>  case',' :{returnout

65、 (",","界符"); break;}</p><p>  case'{' :{returnout ("{","界符"); break;}</p><p>  case'}' :{returnout ("}","界符"); break;}

66、</p><p>  /////////////換行和空格/////////////////////////////////////////////////////////////////////////////////////////</p><p>  case ' ': break;</p><p>  case '\n': c

67、ase'\r': //遇到換行符</p><p><b>  {</b></p><p>  if (C=='\n')</p><p><b>  break;</b></p><p><b>  }</b></p>

68、<p><b>  default: </b></p><p><b>  {</b></p><p>  outfile<<"< "<<C<<" , 換行符>"<<endl;</p><p><b> 

69、 break;</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  infile.close ();</p><p>  outfile.clos

70、e ();</p><p>  system ("pause");</p><p><b>  return 0;</b></p><p><b>  }</b></p><p>  ////////////////////////////////////////////////

71、//////////////////////////////////////////////////////////////////////////////</p><p>  /////雙緩沖的實(shí)現(xiàn)////</p><p>  void get_char ()</p><p><b>  {</b></p><p> 

72、 if ((* forwardptr)==-1) //當(dāng)前指針在緩沖區(qū)(不知是那個(gè)緩沖區(qū))末尾</p><p><b>  {</b></p><p>  if (forwardptr==buffer1+63) //在第一buffer尾,向第二buffer讀入數(shù)據(jù) </p><

73、;p><b>  {</b></p><p>  for (int i=0;i<=62;i++)</p><p>  buffer2 [i]=infile.get ();</p><p>  forwardptr=buffer2;</p><p>  get_char ();</p><p

74、><b>  }</b></p><p>  else if (forwardptr==buffer2+63) //在第二buffer尾,向第一buffer讀入數(shù)據(jù) </p><p><b>  {</b></p><p>  for (int i=0;i<=62;i++)</p>

75、<p>  buffer1 [i]=infile.get ();</p><p>  forwardptr=buffer1;</p><p>  get_char ();</p><p><b>  }</b></p><p>  else //

76、在不是buffer尾的位置讀到了EOF,說(shuō)明完成了分析 </p><p><b>  {</b></p><p>  infile.close ();</p><p>  outfile.close ();</p><p>  ofstream out;</p><p>  cout<<

77、;"詞法分析結(jié)果已存入文件夾中"<<endl;</p><p>  system ("pause");</p><p>  exit (-1);</p><p><b>  }</b></p><p><b>  }</b></p>

78、<p><b>  {</b></p><p>  C=(*forwardptr); //當(dāng)前字符用于分析</p><p>  forwardptr=forwardptr+1; //當(dāng)前指針改指向下一個(gè)字符 </p><p><b>  }&

79、lt;/b></p><p><b>  }</b></p><p>  /////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p>  ///自定義簡(jiǎn)單函數(shù)///

80、/</p><p>  int letter (int C)</p><p><b>  {</b></p><p>  if ((C>=65&&C<=90)||(C>=97)&&(C<=122))</p><p><b>  return 1;</

81、b></p><p>  else return 0;</p><p><b>  }</b></p><p>  int digit (int C)</p><p><b>  {</b></p><p>  if ((C>=48)&&(C<

82、;=57))</p><p><b>  return 1;</b></p><p>  else return 0;</p><p><b>  }</b></p><p>  int underline (int C)</p><p><b>  {</b

83、></p><p>  if (C=='_')</p><p><b>  return 1;</b></p><p>  else return 0;</p><p><b>  }</b></p><p>  int reserve (string

84、token)</p><p><b>  {</b></p><p>  for (int i=0;i<=35;i++)</p><p><b>  {</b></p><p>  if (token==kt [i])</p><p><b>  return

85、 1;</b></p><p><b>  }</b></p><p><b>  return 0;</b></p><p><b>  }</b></p><p>  void retract ()</p><p><b>  

86、{</b></p><p>  if (forwardptr==buffer1) //向前指針在buffer頭</p><p>  forwardptr=(buffer2+63); //后退一個(gè)字符在第二緩沖區(qū)末尾</p><p><b>  else </b></p>

87、<p><b>  {</b></p><p>  if (forwardptr==buffer2) //使向前指針在第二個(gè)buffer尾</p><p>  forwardptr=(buffer1+63);</p><p>  else forwardptr--;</p><p><b

88、>  }</b></p><p><b>  }</b></p><p>  void returnout (string str1,string str2)</p><p><b>  {</b></p><p>  outfile<<"< "

89、;<<str1<<" , "<<str2<<" >"<<endl;</p><p><b>  }</b></p><p>  ////////////////////////////////////////////////////////////////////

90、//////////////////////////////////////////////////////////////////////////YANTAN//UNIVERSITY///SC/09/1/1/2009/2550/1128/qq/1013415421///////////////////////////////////////////////////////////////////////////////////////

91、///////////////////////////////////////</p><p><b>  參考文獻(xiàn)</b></p><p>  【1】百度文庫(kù)《fseek用法詳解》</p><p>  【2】百度文庫(kù)《c和c++文件讀寫(xiě)操作》</p><p>  【3】程序設(shè)計(jì)語(yǔ)言編譯原理》國(guó)防 陳火旺</p&g

溫馨提示

  • 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)論