課程設(shè)計(jì)----編譯原理詞法分析器_第1頁
已閱讀1頁,還剩13頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、<p><b>  目 錄</b></p><p><b>  第1章 概述2</b></p><p>  1.1 編譯原理概述2</p><p>  1.1.1 詞法分析器概述2</p><p>  第2章 詞法分析器課程設(shè)計(jì)2</p><p>  2.

2、1課程設(shè)計(jì)目的2</p><p>  2.2 課程設(shè)計(jì)要求及內(nèi)容2</p><p>  第3章 問題分析及相關(guān)原理介紹3</p><p>  3.1 設(shè)計(jì)思想及算法3</p><p>  3.2 算法實(shí)現(xiàn)及模擬4</p><p>  第4章 設(shè)計(jì)思路及關(guān)鍵問題的解決方法5</p><p&

3、gt;  4.1 設(shè)計(jì)流程圖5</p><p>  第5章 運(yùn)行結(jié)果及測(cè)試分析6</p><p>  5.1運(yùn)行結(jié)果及功能說明6</p><p><b>  心得體會(huì)7</b></p><p>  附 錄 源程序8</p><p><b>  第1章 概述</b>

4、</p><p>  1.1 編譯原理概述</p><p>  編譯原理是介紹編譯器構(gòu)造的一般原理和實(shí)現(xiàn)方法的課程,其中包括詞法分析、語法分析、語義分析、中間代碼生成、目標(biāo)代碼生成優(yōu)化、獨(dú)立于機(jī)器的優(yōu)化和依賴于機(jī)器的優(yōu)化等。編譯器技術(shù)的發(fā)展,特別是計(jì)算機(jī)體系結(jié)構(gòu)的發(fā)展對(duì)編譯技術(shù)的推動(dòng),使其成為計(jì)算機(jī)專業(yè)人士所必需具備的基礎(chǔ)知識(shí)之一。</p><p>  1.1.1

5、詞法分析器概述</p><p>  詞法分析器是通過詞法分析程序?qū)?gòu)成源程序的字符串從左到右的掃描,逐個(gè)字符地讀入源程序字符并按照構(gòu)詞規(guī)則切分成一個(gè)一個(gè)具有獨(dú)立意義的單詞。并確定其屬性(如保留字、標(biāo)識(shí)符、運(yùn)算符、界限符和常量等)。再把它們轉(zhuǎn)換稱長度統(tǒng)一的標(biāo)準(zhǔn)形式——屬性字(TOKEN)。而詞法分析器的功能是輸入源程序,輸出單詞符號(hào),并且詞法分析器有兩種處理結(jié)構(gòu):一種是把詞法分析器作為主程序;另一種是把詞法分析器作

6、為語法分析程序調(diào)用的子程序。下面我所要介紹的詞法分析器是第一種把它作為主程序。</p><p>  第2章 詞法分析器課程設(shè)計(jì)</p><p><b>  2.1課程設(shè)計(jì)目的</b></p><p>  通過課程設(shè)計(jì)進(jìn)一步理解高級(jí)語言在計(jì)算機(jī)中的執(zhí)行過程,加深對(duì)編譯原理中重點(diǎn)算法和編譯技術(shù)的理解,提高自己的編程能力,培養(yǎng)好的程序設(shè)計(jì)風(fēng)格。同時(shí)

7、通過某種可視化編程語言的應(yīng)用,具備初步的Windows環(huán)境下的編程思想</p><p>  2.2 課程設(shè)計(jì)要求及內(nèi)容</p><p>  2.2.1詞法分析器設(shè)計(jì)內(nèi)容及要求</p><p><b> ?。?)設(shè)計(jì)內(nèi)容:</b></p><p>  運(yùn)用所學(xué)習(xí)的編程工具編寫詞法分析器,本次設(shè)計(jì)我采用C++編寫實(shí)現(xiàn)其輸入輸

8、出功能。</p><p> ?。?)設(shè)計(jì)要求及說明:</p><p>  完成下述文法所描述的單詞符號(hào)的詞法分析程序。</p><p>  <標(biāo)識(shí)符>--><字母>|<標(biāo)識(shí)符><字母>|<標(biāo)識(shí)符><數(shù)字></p><p>  <無符號(hào)整數(shù)>-->&

9、lt;數(shù)字>|<無符號(hào)整數(shù)><數(shù)字></p><p>  <分界符>-->+|-|*|/|;|(|)|{|}|<|<=|=|!=|>=|>|=|<空格></p><p>  <字母>-->a|…|z|A|…|Z</p><p>  <數(shù)字>-->0

10、|…|9</p><p>  <空格>-->’ ’</p><p><b>  說明:</b></p><p>  1> 假定該語言對(duì)字母的大小寫不敏感,由指定文件讀入預(yù)分析的源程序,分析結(jié)果再寫入指定文件;</p><p>  2> 語言關(guān)鍵字為:"if","

11、else","then","for","while","do";</p><p>  第3章 問題分析及相關(guān)原理介紹</p><p>  3.1 設(shè)計(jì)思想及算法</p><p> ?。?)主要算法的設(shè)計(jì):該詞法分析器首先掃描文件,識(shí)別出一系列具有獨(dú)立意義的基本語法單位——單詞,

12、包括關(guān)鍵字、保留字、標(biāo)識(shí)符、各種常數(shù)、各種運(yùn)算符及界符等。由于我們規(guī)定的c++語言程序語句中涉及單詞較少,所以在詞法分析階段忽略了單詞輸入錯(cuò)誤的檢查,并在掃描后輸出單詞符號(hào)。規(guī)定輸出的單詞符號(hào)格式為如下的二元式:(單詞種別,單詞自身的值)。c++ 語言中定義了屬于這五種類型的大量的單詞,但是由于預(yù)編譯器只識(shí)別我們自定義的注釋,因此預(yù)編譯器處理的單詞集只是c++ 語言中定義的單詞集的一個(gè)真子集。</p><p>&

13、lt;b>  (2)算法實(shí)現(xiàn)</b></p><p>  <1>fopen()打開源文件,讀入字符,對(duì)文件進(jìn)行掃描,把讀入的字符放入緩沖區(qū)中,然后對(duì)該字符進(jìn)行判斷。</p><p>  <2>若是字母開頭,則可能是關(guān)鍵字或者標(biāo)識(shí)符,因此進(jìn)入letterprocess()進(jìn)行識(shí)別。識(shí)別的過程為:將以字母開頭的字母數(shù)字串放入char letter[30

14、]中,然后進(jìn)行識(shí)別。識(shí)別的過程是先讓它與保留關(guān)鍵字表中的所有關(guān)鍵字進(jìn)行匹配,若獲得成功則說明它是關(guān)鍵字,則輸出其二元式;否則說明其為標(biāo)識(shí)符,這時(shí),將它與標(biāo)識(shí)符表char *label[20]中的元素進(jìn)行匹配,如沒有與之相匹配的,則為其申請(qǐng)空間,將其放入標(biāo)識(shí)符表中。并輸出其二元式。</p><p>  <3>若是數(shù)字開頭,則可能是常量,因此進(jìn)入numberprocess()進(jìn)行識(shí)別。識(shí)別的過程為:將其與

15、常量表char num[20]中的元素進(jìn)行匹配,如沒有與之相匹配的,則為其申請(qǐng)空間,將其放入標(biāo)識(shí)符表中。并輸出其二元式。</p><p>  <4>否則進(jìn)入otherprocess()識(shí)別當(dāng)前是其它字符。在識(shí)別關(guān)系運(yùn)算符的時(shí)候,有可能是兩個(gè)字符為一個(gè)關(guān)系運(yùn)算符,所以在識(shí)別的時(shí)候要判斷連續(xù)的兩個(gè)是否為一個(gè)關(guān)系運(yùn)算符。</p><p>  3.2 算法實(shí)現(xiàn)及模擬</p>

16、<p><b>  3.1.1數(shù)據(jù)結(jié)構(gòu)</b></p><p><b>  (1)關(guān)鍵字:</b></p><p>  char*keyword[6]={"if","else","then","for","while","d

17、o"};</p><p><b>  (2)運(yùn)算符和界符</b></p><p>  char *operatornum[16]={"+","-","*","/","<","<=",">","

18、>=","!","=","{","}",</p><p>  ";","(",")"};//運(yùn)算符和界符</p><p>  (3)常量表和標(biāo)識(shí)符表</p><p>  char *num[20]:用于存放文件

19、中的常量;</p><p>  char *label[20]:用于存放文件中的標(biāo)識(shí)符。</p><p>  3.1.2 數(shù)據(jù)模塊及功能及說明</p><p>  (1) search():查找并識(shí)別當(dāng)前單詞類別,并給定單詞類別二元式碼,決定給定字符串類別碼(即單詞種別)和記錄次序碼。</p><p>  (2)letterprocess()

20、: 識(shí)別當(dāng)前是數(shù)組、保留字、標(biāo)識(shí)符。</p><p>  (3)numprocess(): 識(shí)別當(dāng)前是常整數(shù)、小數(shù)、負(fù)小數(shù)。</p><p>  (4) otherprocess(): 識(shí)別當(dāng)前是其它(標(biāo)點(diǎn)符號(hào)等)。</p><p>  (5) fopen(): 在默認(rèn)路徑下打開分析程序并讀入字符串。</p><p>  第4章 設(shè)計(jì)思路及關(guān)

21、鍵問題的解決方法</p><p><b>  4.1 設(shè)計(jì)流程圖</b></p><p>  畫出總控流程圖以及取符號(hào)、取字符、查找關(guān)鍵字表等子程序的控制流圖。</p><p>  第5章 運(yùn)行結(jié)果及測(cè)試分析</p><p>  5.1運(yùn)行結(jié)果及功能說明 </p><p><b>  …

22、…</b></p><p><b>  心得體會(huì)</b></p><p>  本次課程設(shè)計(jì)初步培養(yǎng)設(shè)計(jì)者對(duì)編譯器設(shè)計(jì)的思想的了解,加深對(duì)編譯原理和應(yīng)用程序的理解。通過設(shè)計(jì)調(diào)試詞法分析程序,實(shí)現(xiàn)了從程序中分出各種單詞的方法,從而加深了對(duì)該知識(shí)的理解,提高了詞法分析的實(shí)踐能力。</p><p>  程序的關(guān)鍵點(diǎn)在于對(duì)對(duì)給出一段程序中的各

23、種單詞的分離。在每段程序中,單詞種類可以分為:關(guān)鍵字,分界符,算術(shù)運(yùn)算符,關(guān)系運(yùn)算符,標(biāo)識(shí)符和常數(shù)。關(guān)鍵字的判斷則是通過與已知數(shù)組中列出的元素進(jìn)行對(duì)比,得出該單詞是否為關(guān)鍵字;分解符,算術(shù)運(yùn)算符,關(guān)系運(yùn)算符的判斷與接受到的字符進(jìn)行比較,得出該字符是否為分解符,算術(shù)運(yùn)算符或者為關(guān)系運(yùn)算符。</p><p>  同時(shí)在編寫程序過程中也遇到了許多問題,如在vc++6.0中運(yùn)行是出現(xiàn)了錯(cuò)誤或是運(yùn)行結(jié)果沒有達(dá)到預(yù)期的效果,

24、而出現(xiàn)了中斷等其他的問題,在不斷解決問題和發(fā)現(xiàn)問題的過程中,我學(xué)到了很多,我體會(huì)到實(shí)踐和理論的巨大差別,并且也有所成長。</p><p><b>  附 錄 源程序</b></p><p><b>  源程序代碼:</b></p><p>  // Lex.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。</p>

25、<p><b>  //</b></p><p>  #include "stdafx.h"</p><p>  #include <iostream></p><p>  #include <string></p><p>  using namespace std

26、;</p><p>  #define NULL 0</p><p><b>  FILE *fp;</b></p><p><b>  char ch;</b></p><p>  char *keyword[6]={"if","else","th

27、en","for","while","do"};//關(guān)鍵字</p><p>  char *operatornum[16]={"+","-","*","/","<","<=",">",&

28、quot;>=","!=","=","{","}",";","(",")","#"};//運(yùn)算符和界符</p><p>  bool search(char searchstr[],int wordtype){//查找是否是系統(tǒng)關(guān)

29、鍵字或運(yùn)算符或界符</p><p><b>  int i;</b></p><p>  switch(wordtype){</p><p>  case 1:for(i=0;i<=5;i++){//判斷是否是關(guān)鍵字</p><p>  if(strcmp(keyword[i],searchstr)

30、==0)</p><p>  return true;</p><p><b>  }</b></p><p>  case 2:for(i=0;i<=15;i++){//判斷是否是運(yùn)算符或界符</p><p>  if(strcmp(operatornum[i],searchstr)==0)&l

31、t;/p><p>  return true;</p><p><b>  }</b></p><p><b>  }</b></p><p>  return false;</p><p><b>  }</b></p><p> 

32、 /*******************************************************************/</p><p>  char letterprocess (char ch)//字母處理程序</p><p><b>  {</b></p><p><b>  int i=-1;</b

33、></p><p>  char letter[30];//定義一個(gè)字符串最大長度為30</p><p>  while (isalnum(ch)!=0)//判斷是否為數(shù)字或字母,從文件中獲得一個(gè)字符串</p><p><b>  {</b></p><p>  letter[++i]=ch;</p

34、><p>  ch=fgetc(fp);</p><p><b>  };</b></p><p>  letter[i+1]='\0';//字符串結(jié)束</p><p>  if (search(letter,1))//調(diào)用search方法,判斷是否是系統(tǒng)關(guān)鍵字</p><p&

35、gt;<b>  {</b></p><p>  if(strcmp(keyword[0],letter)==0)</p><p>  cout<<"(1,"<<keyword[0]<<")"<<endl;</p><p>  else if(strcmp(

36、keyword[1],letter)==0)</p><p>  cout<<"(2,"<<keyword[1]<<")"<<endl;</p><p>  else if(strcmp(keyword[2],letter)==0)</p><p>  cout<<&

37、quot;(3,"<<keyword[2]<<")"<<endl;</p><p>  else if(strcmp(keyword[3],letter)==0)</p><p>  cout<<"(4,"<<keyword[3]<<")"<&

38、lt;endl;</p><p>  else if(strcmp(keyword[4],letter)==0)</p><p>  cout<<"(5,"<<keyword[4]<<")"<<endl;</p><p>  else if(strcmp(keyword[5],l

39、etter)==0)</p><p>  cout<<"(6,"<<keyword[5]<<")"<<endl;</p><p><b>  }</b></p><p>  else//若不是關(guān)鍵字,則為一般字符串</p>&l

40、t;p><b>  {</b></p><p>  cout<<"(10,'"<<letter<<"')"<<endl;</p><p><b>  }</b></p><p>  return(ch);</

41、p><p><b>  }</b></p><p>  /***********************************************************************************/</p><p>  char numberprocess(char ch)//數(shù)字處理程序</p>&l

42、t;p><b>  {</b></p><p><b>  int i=-1;</b></p><p>  char num[20];</p><p>  while (isdigit(ch)!=0)</p><p><b>  {</b></p><

43、p>  num[++i]=ch;</p><p>  ch=fgetc(fp);</p><p><b>  }</b></p><p>  if(isalpha(ch)!=0)//判斷是否為字母</p><p><b>  {</b></p><p>  whi

44、le(isspace(ch)==0)//判斷是否為空格之類的,如/t,/n,/r等</p><p><b>  {</b></p><p>  num[++i]=ch;</p><p>  ch=fgetc(fp);</p><p><b>  }</b></p><p>

45、;  num[i+1]='\0';</p><p>  cout<<"錯(cuò)誤!非法標(biāo)識(shí)符:"<<num<<endl;</p><p><b>  goto u;</b></p><p><b>  }</b></p><p>  

46、num[i+1]='\0';//數(shù)字結(jié)束</p><p>  cout<<"(11,"<<num<<")"<<endl;</p><p>  u: return(ch);</p><p><b>  }</b></p>

47、<p>  /************************************************************************************/</p><p>  char otherprocess(char ch)//運(yùn)算符和界符處理程序</p><p><b>  {</b></p><p&

48、gt;<b>  int i=-1;</b></p><p>  char other[20];</p><p>  if (isspace(ch)!=0)//判斷是否為空格之類的,如/t,/n,/r等</p><p><b>  {</b></p><p>  ch=fgetc(fp);&l

49、t;/p><p>  goto u;//若是,就返回該字符</p><p><b>  }</b></p><p>  while ((isspace(ch)==0)&&(isalnum(ch)==0))//判斷字符串是否結(jié)束</p><p><b>  {</b><

50、/p><p>  other[++i]=ch;</p><p>  ch=fgetc(fp);</p><p><b>  }</b></p><p>  other[i+1]='\0';//標(biāo)示符結(jié)束</p><p>  if (search(other,2)){

51、//調(diào)用search方法,判斷是否是運(yùn)算符或界符</p><p>  if(strcmp(operatornum[0],other)==0)</p><p>  cout<<"(13,"<<operatornum[0]<<")"<<endl;</p><p>  else

52、if(strcmp(operatornum[1],other)==0)</p><p>  cout<<"(14,"<<operatornum[1]<<")"<<endl;</p><p>  else if(strcmp(operatornum[2],other)==0)</p><

53、;p>  cout<<"(15,"<<operatornum[2]<<")"<<endl;</p><p>  else if(strcmp(operatornum[3],other)==0)</p><p>  cout<<"(16,"<<operat

54、ornum[3]<<")"<<endl;</p><p>  else if(strcmp(operatornum[4],other)==0)</p><p>  cout<<"(20,"<<operatornum[4]<<")"<<endl;</p&g

55、t;<p>  else if(strcmp(operatornum[5],other)==0)</p><p>  cout<<"(22,"<<operatornum[5]<<")"<<endl;</p><p>  else if(strcmp(operatornum[6],other

56、)==0)</p><p>  cout<<"(23,"<<operatornum[6]<<")"<<endl;</p><p>  else if(strcmp(operatornum[7],other)==0)</p><p>  cout<<"(24,

57、"<<operatornum[7]<<")"<<endl;</p><p>  else if(strcmp(operatornum[8],other)==0)</p><p>  cout<<"(21,"<<operatornum[8]<<")"&

58、lt;<endl;</p><p>  else if(strcmp(operatornum[9],other)==0)</p><p>  cout<<"(25,"<<operatornum[9]<<")"<<endl;</p><p>  else if(strcmp(

59、operatornum[10],other)==0)</p><p>  cout<<"(17,"<<operatornum[10]<<")"<<endl;</p><p>  else if(strcmp(operatornum[11],other)==0)</p><p> 

60、 cout<<"(18,"<<operatornum[11]<<")"<<endl;</p><p>  else if(strcmp(operatornum[12],other)==0)</p><p>  cout<<"(26,"<<operatornum

61、[12]<<")"<<endl;</p><p>  else if(strcmp(operatornum[13],other)==0)</p><p>  cout<<"(27,"<<operatornum[13]<<")"<<endl;</p>

62、<p>  else if(strcmp(operatornum[14],other)==0)</p><p>  cout<<"(28,"<<operatornum[14]<<")"<<endl;</p><p>  else if(strcmp(operatornum[15],oth

63、er)==0) </p><p>  cout<<"(0,"<<operatornum[15]<<")"<<endl;</p><p><b>  }else{</b></p><p>  cout<<"錯(cuò)誤!非法標(biāo)示符:"&

64、lt;<other<<endl;</p><p><b>  }</b></p><p>  u: return (ch);</p><p><b>  }</b></p><p>  /***********************************************

65、************************************/</p><p>  int _tmain(int argc, _TCHAR* argv[])</p><p><b>  {</b></p><p><b>  char str;</b></p><p>  cout<

66、;<"**********************************************************************\n";</p><p>  cout<<"* *\n";</p>

67、<p>  cout<<"* 詞法分析器 *\n";</p><p>  cout<<"* *\n&q

68、uot;;</p><p>  cout<<"**********************************************************************\n";</p><p>  if ((fp=fopen("lex.txt","r"))==NULL)</p><

69、p>  cout<<"源程序無法打開!\n";</p><p><b>  else</b></p><p><b>  {</b></p><p>  str=fgetc(fp);</p><p>  while (str!=EOF)</p>&

70、lt;p><b>  {</b></p><p>  if (isalpha(str)!=0)//判斷是否為字母(A – Z or a – z)</p><p>  str=letterprocess(str);</p><p><b>  else</b></p><p><b&

71、gt;  {</b></p><p>  if (isdigit(str)!=0)//判斷字符是否是數(shù)字(0 – 9)</p><p>  str=numberprocess(str);</p><p>  else//若不是,則執(zhí)行其他字符處理程序</p><p>  str=otherprocess(str);

72、</p><p><b>  }</b></p><p><b>  };</b></p><p>  cout<<"詞法分析結(jié)束,謝謝使用!\n";</p><p>  cout<<"點(diǎn)任意鍵退出!\n";</p>&l

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲(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)論