2023年全國(guó)碩士研究生考試考研英語(yǔ)一試題真題(含答案詳解+作文范文)_第1頁(yè)
已閱讀1頁(yè),還剩43頁(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è) 計(jì) 報(bào) 告</p><p>  設(shè)計(jì)題目:一個(gè)簡(jiǎn)單文法的編譯器的設(shè)計(jì)與實(shí)現(xiàn)</p><p>  班 級(jí):計(jì)算機(jī)1206班</p><p>  組長(zhǎng)學(xué)號(hào):2012XXX</p><p><b>  組長(zhǎng)姓名:XXX</b></p><p><b> 

2、 指導(dǎo)教師:XXX</b></p><p>  設(shè)計(jì)時(shí)間:2014年12月</p><p><b>  設(shè)計(jì)分工</b></p><p>  組長(zhǎng)學(xué)號(hào)及姓名:2012XXX XXX</p><p>  分工:1)讀取源文件進(jìn)行詞法分析</p><p>  2)進(jìn)行LL(1)分析生

3、成分析表 </p><p>  3)設(shè)計(jì)頂層自動(dòng)機(jī)將源程序分段</p><p>  4)生成可執(zhí)行的匯編程序</p><p>  組員1學(xué)號(hào)及姓名:2012XXXXXX</p><p>  分工:1)設(shè)計(jì)第二層自動(dòng)機(jī)處理程序片段</p><p>  2)生成中間語(yǔ)言四元式</p><p>&l

4、t;b>  3)源程序錯(cuò)誤處理</b></p><p>  組員2學(xué)號(hào)及姓名:2012XXXXXX</p><p>  分工:1)設(shè)計(jì)第三層自動(dòng)機(jī)處理復(fù)合表達(dá)式</p><p>  2)設(shè)計(jì)帶動(dòng)作的LL(1) 文法</p><p><b>  3)源程序錯(cuò)誤處理</b></p><

5、p><b>  摘 要</b></p><p>  編譯原理課程具有很強(qiáng)的理論性和實(shí)踐性,是計(jì)算機(jī)專業(yè)的一門非常重要的專業(yè)基礎(chǔ)課程,在系統(tǒng)軟件中也是占有十分重要的地位。本次課程設(shè)計(jì)我們是在Visual C++的平臺(tái)上應(yīng)用了詞法分析、語(yǔ)法分析、語(yǔ)義分析、中間語(yǔ)言生成以及目標(biāo)語(yǔ)言生成的知識(shí)設(shè)計(jì)了一個(gè)簡(jiǎn)單的編譯器前端。其中設(shè)計(jì)了一個(gè)簡(jiǎn)單的有限自動(dòng)機(jī)來(lái)掃描源程序即進(jìn)行語(yǔ)法分析,并生成了關(guān)鍵字表

6、、標(biāo)志符表、界符表、常數(shù)表和Token串;設(shè)計(jì)了一個(gè)LL(1)文法和一個(gè)帶動(dòng)作的文法來(lái)實(shí)現(xiàn)語(yǔ)法分析,并生成了Select集和LL(1)分析表;采用了四元式序列的設(shè)計(jì)來(lái)生成中間語(yǔ)言;通過(guò)匯編語(yǔ)言設(shè)計(jì)來(lái)生成目標(biāo)語(yǔ)言。最后為了使該編譯器更加完善,我們?cè)O(shè)計(jì)了簡(jiǎn)單的的錯(cuò)誤檢查機(jī)制,能夠?qū)υ闯绦蜻M(jìn)行比較全面的錯(cuò)誤檢查同時(shí)也能夠指出錯(cuò)誤出現(xiàn)的大致位置,增強(qiáng)了該編譯器的健壯性。</p><p>  關(guān)鍵字:編譯器,前端,有限自動(dòng)

7、機(jī),LL(1)文法,匯編語(yǔ)言,錯(cuò)誤處理</p><p><b>  目 錄</b></p><p><b>  摘要3</b></p><p><b>  1、概述5</b></p><p>  2、課程設(shè)計(jì)任務(wù)及要求5</p><p><

8、b>  2.1設(shè)計(jì)任務(wù)5</b></p><p><b>  2.2設(shè)計(jì)要求6</b></p><p>  3、算法與數(shù)據(jù)結(jié)構(gòu)6</p><p>  3.1詞法分析器的算法6</p><p>  3.2 語(yǔ)法分析器的算法12</p><p>  3.2.1 LL(1)文

9、法設(shè)計(jì)算法12</p><p>  3.2.2遞歸下降子程序設(shè)計(jì)算法19</p><p>  3.3中間語(yǔ)言生成器算法20</p><p>  3.4處理復(fù)合表達(dá)式算法24</p><p>  3.5目標(biāo)語(yǔ)言生成器算法30</p><p>  3.6數(shù)據(jù)結(jié)構(gòu)39</p><p>  

10、4、程序設(shè)計(jì)與實(shí)現(xiàn)39</p><p>  4.1編譯程序設(shè)計(jì)與實(shí)現(xiàn)39</p><p>  4.2程序?qū)嶒?yàn)結(jié)果39</p><p>  4.2.1待測(cè)源程序39</p><p>  4.2.2詞法分析結(jié)果40</p><p>  4.2.3語(yǔ)法分析結(jié)果41</p><p>  4.

11、2.4中間語(yǔ)言生成結(jié)果42</p><p>  4.2.5目標(biāo)語(yǔ)言生成結(jié)果43</p><p>  4.2.6程序錯(cuò)誤處理結(jié)果44</p><p><b>  5、參考文獻(xiàn)44</b></p><p><b>  1、概述</b></p><p>  本次課程設(shè)計(jì)的編

12、譯程序主要包括了詞法分析器、語(yǔ)法分析器、中間代碼生成器和目標(biāo)代碼生成器四部分,編譯程序的輸出結(jié)果包括了詞法分析后的關(guān)鍵字表、界符表、標(biāo)識(shí)符表和Token串,語(yǔ)法分析后的Select集和LL(1)分析表;中間代碼生成器產(chǎn)生的四元式序列。最后除了完成設(shè)計(jì)所要求的內(nèi)容之外,我們還做了一些擴(kuò)展例如:設(shè)計(jì)了目標(biāo)代碼生成器來(lái)生成可執(zhí)行的匯編程序;還設(shè)計(jì)了錯(cuò)誤檢查機(jī)制來(lái)查找源程序的錯(cuò)誤并指出錯(cuò)誤產(chǎn)生的大致位置。</p><p>

13、;  詞法分析是編譯程序的第一步操作,它的任務(wù)是:從左至右掃描源程序的字符串,按照一定的詞法規(guī)則識(shí)別出一個(gè)個(gè)正確的字符,并轉(zhuǎn)換成該字符相對(duì)應(yīng)的Token碼,最終生成一個(gè)完整的Token串以供語(yǔ)法分析使用。由此可知,詞法分析是整個(gè)編譯程序的基礎(chǔ),而執(zhí)行詞法分析的一系列操作的就是詞法分析器。</p><p>  語(yǔ)法分析是編譯程序的第二步操作也是編譯程序的核心部分,其主要任務(wù)是:分析語(yǔ)法內(nèi)容,確定語(yǔ)法結(jié)構(gòu)同時(shí)生成Se

14、lect集和LL(1)分析表。</p><p>  中間代碼和目標(biāo)代碼的生成是對(duì)源程序的進(jìn)一步操作,其任務(wù)是:根據(jù)詞法分析產(chǎn)生的Token串和語(yǔ)法分析確定的語(yǔ)法結(jié)構(gòu)來(lái)生成中間語(yǔ)言——四元式和目標(biāo)語(yǔ)言——匯編語(yǔ)言程序。</p><p>  2、課程設(shè)計(jì)任務(wù)及要求</p><p><b>  2.1設(shè)計(jì)任務(wù)</b></p><p

15、>  一個(gè)簡(jiǎn)單文法的編譯器前端的設(shè)計(jì)與實(shí)現(xiàn)</p><p>  定義一個(gè)簡(jiǎn)單程序設(shè)計(jì)語(yǔ)言文法(包括變量說(shuō)明語(yǔ)句、算術(shù)運(yùn)算表達(dá)式、賦值語(yǔ)句;擴(kuò)展包括邏輯運(yùn)算表達(dá)式、If語(yǔ)句、While語(yǔ)句等);</p><p><b>  掃描器設(shè)計(jì)實(shí)現(xiàn);</b></p><p>  語(yǔ)法分析器設(shè)計(jì)實(shí)現(xiàn);</p><p><b

16、>  中間代碼設(shè)計(jì);</b></p><p>  中間代碼生成器設(shè)計(jì)實(shí)現(xiàn)。 </p><p>  目標(biāo)代碼生成器設(shè)計(jì)實(shí)現(xiàn)</p><p><b>  2.2設(shè)計(jì)要求</b></p><p>  給出一個(gè)源程序文件,作為編譯器前端的輸入</p><p>  輸出相關(guān)編譯階段的運(yùn)行結(jié)

17、果</p><p><b>  詞法分析階段:</b></p><p>  生成Token序列;</p><p>  生成關(guān)鍵字表、界符表、符號(hào)表系統(tǒng)。</p><p><b>  中間代碼生成階段:</b></p><p><b>  生成四元式序列;</b

18、></p><p><b>  生成符號(hào)表系統(tǒng)。</b></p><p><b>  算法與數(shù)據(jù)結(jié)構(gòu)</b></p><p>  3.1詞法分析器的算法</p><p>  1)一個(gè)簡(jiǎn)單有限自動(dòng)機(jī)(掃描器)的設(shè)計(jì):</p><p><b>  d</b&

19、gt;</p><p>  其中:⑴ ?(字母),d(數(shù)字),#(源程序結(jié)束符)</p><p>  (2)?(空格,回車,換行)需要濾掉</p><p>  (3)≮(泛指單詞的后繼附)</p><p>  (4)……(表示省略了其他界符的處理)</p><p>  2)一個(gè)簡(jiǎn)單詞法分析器設(shè)計(jì):</p>

20、<p><b>  算法實(shí)現(xiàn)如下:</b></p><p>  Void main(){ //詞法分析部分代碼 </p><p>  char p[10];</p><p>  string TOKEN;</p><p>  string Source;<

21、;/p><p>  string temp;</p><p><b>  FILE* fp;</b></p><p>  fp=fopen("D:\\MySourceFile.txt","r");</p><p>  if(!fp) Source="Cannot open f

22、ile";</p><p><b>  else</b></p><p><b>  {</b></p><p><b>  int i;</b></p><p><b>  char c;</b></p><p>  w

23、hile(!feof(fp))</p><p><b>  {</b></p><p>  c=fgetc(fp);</p><p>  Source+=c;</p><p><b>  }</b></p><p>  fclose(fp);</p><p

24、>  for(i=0;i<Source.size();i++)</p><p><b>  {</b></p><p>  if(Source[i]==13||Source[i]==9||Source[i]==10||Source[i]==-1)</p><p><b>  {</b></p>&

25、lt;p>  Source.replace(i,1," ");</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  Source+='#';<

26、/p><p>  cout<<"處理后源程序\n"<<Source<<endl<<endl;</p><p>  initKTPT();</p><p><b>  int i,j;</b></p><p>  for(i=0;i<Source.siz

27、e();i++)</p><p><b>  {</b></p><p>  switch(kindofchar(Source[i]))</p><p><b>  {</b></p><p><b>  case 'e':</b></p><

28、;p><b>  {</b></p><p>  cout<<"\n非法字符!,位置:"<<i<<"錯(cuò)誤代碼"<<Source[i]<<endl<<endl;</p><p>  for(int k=0;k<=i;k++) cout<<

29、;Source[k];</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p>  case 's':break;</p><p><b>  case 'd':</b></p>

30、<p><b>  {</b></p><p>  temp+=Source[i];</p><p>  for(j=1;Source[i+j]=='.'||kindofchar(Source[i+j])=='d';j++) temp+=Source[i+j];</p><p><b>  

31、i=i+j-1;</b></p><p>  if(inCT(temp)==-1)</p><p><b>  {</b></p><p>  temp="N "+temp;</p><p>  CT.push_back(temp);</p><p><b&g

32、t;  }</b></p><p>  TOKEN+="<CT,";</p><p>  itoa(inCT(temp),p,10);</p><p><b>  TOKEN+=p;</b></p><p>  TOKEN+=">";</p>

33、<p><b>  temp="";</b></p><p><b>  break;</b></p><p><b>  }</b></p><p><b>  case 'w':</b></p><p>&

34、lt;b>  {</b></p><p>  temp+=Source[i];</p><p>  for(j=1;kindofchar(Source[i+j])=='w'||kindofchar(Source[i+j])=='d'||Source[i+j]=='_';j++) temp+=Source[i+j];</

35、p><p><b>  i=i+j-1;</b></p><p>  if(inKT(temp)!=-1)</p><p><b>  {</b></p><p>  TOKEN+="<KT,";</p><p>  itoa(inKT(temp),p,

36、10);</p><p><b>  TOKEN+=p;</b></p><p>  TOKEN+=">";</p><p><b>  temp="";</b></p><p><b>  break;</b></p>

37、<p><b>  }</b></p><p>  if(inIT(temp)==-1) IT.push_back(temp);</p><p>  TOKEN+="<IT,";</p><p>  itoa(inIT(temp),p,10);</p><p><b> 

38、 TOKEN+=p;</b></p><p>  TOKEN+=">";</p><p><b>  temp="";</b></p><p><b>  break;</b></p><p><b>  }</b>&l

39、t;/p><p><b>  case 'f':</b></p><p><b>  {</b></p><p>  temp+=Source[i];</p><p>  if(kindofchar(Source[i+1])=='f'&&inPT(temp

40、+Source[i+1])>=0)</p><p><b>  {</b></p><p>  temp+=Source[i+1];</p><p><b>  i++;</b></p><p><b>  }</b></p><p>  TOKE

41、N+="<PT,";</p><p>  itoa(inPT(temp),p,10);</p><p><b>  TOKEN+=p;</b></p><p>  TOKEN+=">";</p><p><b>  temp="";<

42、/b></p><p><b>  break;</b></p><p><b>  }</b></p><p>  case '\"':</p><p><b>  {</b></p><p><b>  i+

43、+;</b></p><p>  for(j=0;Source[i+j]!='\"'&&(i+j)<(Source.size()-1);j++)</p><p><b>  {</b></p><p>  if(Source[i+j]=='\\'&&So

44、urce[i+j+1]=='\"')</p><p><b>  {</b></p><p>  temp+='\"';</p><p><b>  j++;</b></p><p><b>  }</b></p>

45、<p>  if(Source[i+j]=='\\'&&Source[i+j+1]=='\'')</p><p><b>  {</b></p><p>  temp+='\'';</p><p><b>  j++;</b>&l

46、t;/p><p><b>  }</b></p><p>  if(Source[i+j]=='\\'&&Source[i+j+1]=='\\')</p><p><b>  {</b></p><p>  temp+='\\';</

47、p><p><b>  j++;</b></p><p><b>  }</b></p><p>  if(Source[i+j]=='\\'&&Source[i+j+1]=='\0')</p><p><b>  {</b><

48、/p><p>  temp+='\0';</p><p><b>  j++;</b></p><p><b>  }</b></p><p>  else temp+=Source[i+j];</p><p><b>  }</b><

49、/p><p>  if((i+j)>=(Source.size()-1))</p><p><b>  {</b></p><p>  cout<<"未找到可匹配的雙引號(hào),位置:"<<i<<endl;</p><p>  for(int k=0;k<=i;k

50、++) cout<<Source[k];</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  i=i+j;</b></p><p>  if(inCT(temp)==-1)</p>

51、<p><b>  {</b></p><p>  temp="S "+temp;</p><p>  CT.push_back(temp);</p><p><b>  }</b></p><p>  TOKEN+="<CT,";</p

52、><p>  itoa(inCT(temp),p,10);</p><p><b>  TOKEN+=p;</b></p><p>  TOKEN+=">";</p><p><b>  temp="";</b></p><p>&l

53、t;b>  break;</b></p><p><b>  }</b></p><p>  case '\'':</p><p><b>  {</b></p><p>  if((i+3)<(Source.size()-1)&&So

54、urce[i+1]=='\\'&&Source[i+3]=='\'')</p><p><b>  {</b></p><p>  switch(Source[i+2])</p><p><b>  {</b></p><p>  case &

55、#39;\\':temp+='\\';break;</p><p>  case '\'':temp+='\'';break;</p><p>  case '\"':temp+='\"';break;</p><p>  case '

56、0':temp+="\\0";break;</p><p>  default:cout<<"錯(cuò)誤的單引號(hào)使用(轉(zhuǎn)義錯(cuò)誤),位置:"<<i<<endl;for(int k=0;k<=i;k++) cout<<Source[k];exit(0);</p><p><b>  }&l

57、t;/b></p><p><b>  i+=3;</b></p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  if((i+2)&g

58、t;=(Source.size()-1))</p><p><b>  {</b></p><p>  cout<<"錯(cuò)誤的單引號(hào)使用(越界),位置:"<<i<<endl;</p><p>  for(int k=0;k<=i;k++) cout<<Source[k];&

59、lt;/p><p><b>  exit(0);</b></p><p><b>  }</b></p><p>  temp+=Source[i+1];</p><p><b>  i+=2;</b></p><p><b>  }</b&

60、gt;</p><p>  if(inCT(temp)==-1)</p><p><b>  {</b></p><p>  temp="C "+temp;</p><p>  CT.push_back(temp);</p><p><b>  }</b>

61、</p><p>  TOKEN+="<CT,";</p><p>  itoa(inCT(temp),p,10);</p><p><b>  TOKEN+=p;</b></p><p>  TOKEN+=">";</p><p><b&

62、gt;  temp="";</b></p><p><b>  break;</b></p><p><b>  }</b></p><p>  case '#':break;</p><p>  default:break;</p>&

63、lt;p><b>  }</b></p><p><b>  }</b></p><p>  3.2語(yǔ)法分析器的算法</p><p>  首先介紹一下整個(gè)課程設(shè)計(jì)中我們使用到的一些文法。</p><p>  C--文件 -> void main ( ) C<--程序體</p&

64、gt;<p>  C -> { Y<--語(yǔ)句--> }</p><p>  Y -> S<--聲明語(yǔ)句--> ; I<--語(yǔ)句后繼-->| Z<--賦值語(yǔ)句--> ; I| V<--條件語(yǔ)句-->N<--if后繼-->{B} I| W<--循環(huán)語(yǔ)句--> I</p><p><

65、;b>  I->Y | 空</b></p><p>  S ->類型 標(biāo)識(shí)符 聲明后繼</p><p>  類型 -> int|float|char</p><p>  聲明后繼 -> ,標(biāo)識(shí)符 聲明后繼 | 空</p><p>  Z -> 標(biāo)識(shí)符 = 表達(dá)式</p><p

66、>  V -> if ( E )C </p><p>  N->else C | 空</p><p>  W -> while ( 表達(dá)式 )程序體</p><p>  E -> 詳見rull.txt源文件。</p><p>  語(yǔ)法分析主要是對(duì)LL(1)文法和遞歸下降子程序的設(shè)計(jì),其算法設(shè)計(jì)如下:</p&

67、gt;<p>  3.2.1 LL(1)文法的設(shè)計(jì)</p><p><b>  1)算法原理如下:</b></p><p>  利用一個(gè)分析表,登記如何選擇產(chǎn)生式的知識(shí);</p><p>  利用一個(gè)分析棧,記錄分析過(guò)程;</p><p>  此分析法要求文法必須滿足 LL(1)文法形式。</p>

68、;<p><b>  算法設(shè)計(jì)如下:</b></p><p><b> ?。?)</b></p><p><b> ?。?)</b></p><p><b> ?。?)</b></p><p><b>  算法實(shí)現(xiàn)如下:</b

69、></p><p>  void maketable()//////////////////////////////////////////需要參數(shù)指明所需文法</p><p><b>  {</b></p><p><b>  //打開文件</b></p><p>  //switch()/

70、//////////////////////////////////////根據(jù)參數(shù)選擇文法</p><p>  FILE* fp=fopen("D:/rull.txt","r");</p><p>  if(fp==NULL)</p><p><b>  {</b></p><p&g

71、t;  cout<<"打開文件失敗"<<endl;</p><p>  getchar();</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  //讀取文件</b>

72、;</p><p>  string source="";</p><p>  char readchar;</p><p><b>  do</b></p><p><b>  {</b></p><p>  readchar=fgetc(fp);<

73、;/p><p>  source+=readchar;</p><p><b>  }</b></p><p>  while(readchar!=EOF);</p><p>  fclose(fp);</p><p>  //cout<<"----source流----&quo

74、t;<<endl<<source<<endl;//檢查</p><p>  //從source流中提取有效數(shù)據(jù)</p><p>  Vs=source[3];</p><p><b>  Vn+=Vs;</b></p><p>  int i,j,k,l;</p><

75、;p>  string ps="";</p><p>  for(i=8;source[i]!=';';i++) Vn+=source[i];</p><p><b>  i+=4;</b></p><p>  for(;source[i]!=';';i++) Vt+=source[i]

76、;</p><p><b>  i++;</b></p><p>  while(source[i]!=';')</p><p><b>  {</b></p><p>  for(;source[i]!=' '&&source[i]!=';&

77、#39;;i++)</p><p><b>  {</b></p><p>  ps+=source[i];</p><p><b>  }</b></p><p>  QRULL.push_back(ps);</p><p><b>  ps="&quo

78、t;;</b></p><p>  if(source[i]==' ') i++;</p><p><b>  }</b></p><p><b>  //拆分或符號(hào)</b></p><p>  string ps2="";</p>&l

79、t;p><b>  int flag;</b></p><p>  for(i=0;i<QRULL.size();i++)</p><p><b>  {</b></p><p><b>  flag=0;</b></p><p>  for(j=0;j<QR

80、ULL[i].length();j++)</p><p><b>  {</b></p><p>  if(QRULL[i][j]=='|')</p><p><b>  {</b></p><p><b>  flag=1;</b></p>&l

81、t;p><b>  break;</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  if(flag==0) continue;</p><p>  ps2+=QRULL[i][0];</p><

82、p>  ps2+="->";</p><p>  for(j=0;QRULL[i][j]!='|';j++) ps+=QRULL[i][j];</p><p>  for(j++;j<QRULL[i].length();j++) ps2+=QRULL[i][j];</p><p>  QRULL[i]=ps;&l

83、t;/p><p>  QRULL.push_back(ps2);</p><p><b>  ps="";</b></p><p><b>  ps2="";</b></p><p><b>  }</b></p><p&

84、gt;  cout<<"----有效四元產(chǎn)生式表----"<<endl;//檢查</p><p>  for(i=0;i<QRULL.size();i++)//檢查</p><p><b>  {</b></p><p>  cout<<QRULL[i]<<' &

85、#39;;//檢查</p><p><b>  }</b></p><p>  cout<<endl;//檢查</p><p>  //從四元產(chǎn)生式轉(zhuǎn)化為普通產(chǎn)生式</p><p><b>  ps="";</b></p><p>  for(

86、i=0;i<QRULL.size();i++)</p><p><b>  {</b></p><p>  k=0;ps="";</p><p>  for(j=0;j<QRULL[i].size();j++)</p><p><b>  {</b></p>

87、;<p>  if(QRULL[i][j]!='{') ps+=QRULL[i][j];</p><p>  else j+=2;</p><p><b>  }</b></p><p>  RULL.push_back(ps);</p><p><b>  }</b>

88、</p><p>  cout<<"----有效普通產(chǎn)生式表----"<<endl;//檢查</p><p>  for(i=0;i<RULL.size();i++)//檢查</p><p><b>  {</b></p><p>  cout<<RULL[i

89、]<<' ';//檢查</p><p><b>  }</b></p><p>  cout<<endl;//檢查</p><p><b>  //檢測(cè)直接左遞歸</b></p><p><b>  flag=0;</b></p&g

90、t;<p>  for(i=0;i<RULL.size();i++)</p><p><b>  {</b></p><p>  if(RULL[i][0]==RULL[i][3]) flag=1;</p><p><b>  }</b></p><p>  if(flag==1

91、)</p><p><b>  {</b></p><p>  system("cls");</p><p>  system("color CF");</p><p>  cout<<"檢測(cè)到直接左遞歸文法,系統(tǒng)已停止運(yùn)行,請(qǐng)改正產(chǎn)生式。"<

92、<endl;</p><p>  getchar();</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p>  //產(chǎn)生SELECT表</p><p><b>  Vt+='#';<

93、;/b></p><p>  MAXITERATE=RULL.size()*RULL.size();</p><p>  vector<string> SELECT;</p><p>  SELECT=Select();</p><p>  cout<<"----SELECT集----"<

94、;<endl<<"SELECT"<<endl;//檢查</p><p>  for(i=0;i<SELECT.size();i++)//檢查</p><p><b>  {</b></p><p>  cout<<SELECT[i]<<endl;//檢查</p

95、><p><b>  }</b></p><p>  SelectTable=new int*[Vn.size()];</p><p>  int* intp;</p><p>  for(i=0;i<Vn.size();i++)</p><p><b>  {</b>&l

96、t;/p><p>  intp=new int[Vt.size()];</p><p>  SelectTable[i]=intp;</p><p><b>  }</b></p><p>  for(i=0;i<Vn.size();i++)</p><p><b>  {</b

97、></p><p>  for(j=0;j<Vt.size();j++) SelectTable[i][j]=-1;</p><p><b>  }</b></p><p>  for(k=0;k<SELECT.size();k++)</p><p><b>  {</b><

98、/p><p>  for(l=2;l<SELECT[k].length();l++)</p><p><b>  {</b></p><p>  i=inVn(SELECT[k][0]);</p><p>  j=inVt(SELECT[k][l]);</p><p>  SelectTable

99、[i][j]=k;</p><p><b>  }</b></p><p><b>  }</b></p><p>  cout<<"----SelectTable----"<<endl<<" ";//檢測(cè)</p><p>

100、;  for(i=0;i<Vt.size();i++) cout<<Vt[i]<<' ';//檢測(cè)</p><p>  cout<<endl;//檢測(cè)</p><p>  for(i=0;i<Vn.size();i++)//檢測(cè)</p><p><b>  {</b></p&

101、gt;<p>  cout<<Vn[i]<<' ';//檢測(cè)</p><p>  for(j=0;j<Vt.size();j++) cout<<SelectTable[i][j]<<' ';//檢測(cè)</p><p>  cout<<endl;//檢測(cè)</p><

102、;p><b>  }</b></p><p>  //進(jìn)行選擇集相交檢測(cè)</p><p>  if(check()==0)</p><p><b>  {</b></p><p>  system("cls");</p><p>  system(&

103、quot;color CF");</p><p>  cout<<"選擇集相交,該文法不是LL1文法,請(qǐng)修改產(chǎn)生式"<<endl;</p><p>  getchar();</p><p><b>  exit(0);</b></p><p><b>  }

104、</b></p><p><b>  }</b></p><p>  vector<string> Select()</p><p><b>  {</b></p><p><b>  int i;</b></p><p>  v

105、ector<string> SELECT;</p><p>  string ps="";</p><p>  for(i=0;i<RULL.size();i++)</p><p><b>  {</b></p><p>  ps=RULL[i][0];</p><

106、;p><b>  ps+=" ";</b></p><p>  ps+=first(RULL[i]);</p><p>  SELECT.push_back(ps);</p><p><b>  //迭代器清零</b></p><p>  counter=0;</p&

107、gt;<p><b>  }</b></p><p>  return SELECT;</p><p><b>  }</b></p><p>  string first(string rull)</p><p>  {//cout<<"迭代次數(shù)"&l

108、t;<counter<<endl;//檢測(cè)</p><p>  counter++;</p><p>  if(counter>MAXITERATE)</p><p><b>  {</b></p><p>  system("cls");</p><p&g

109、t;  system("color CF");</p><p>  cout<<"生成選擇集時(shí)迭代次數(shù)過(guò)高,疑似出現(xiàn)遞歸死循環(huán),系統(tǒng)已停止運(yùn)行,請(qǐng)檢查是否有語(yǔ)法錯(cuò)誤"<<endl;</p><p>  cout<<"迭代次數(shù)上限暫設(shè)為產(chǎn)生式數(shù)量的平方。過(guò)多的迭代會(huì)損害設(shè)備,若沒有語(yǔ)法錯(cuò)誤,請(qǐng)簡(jiǎn)化語(yǔ)法樹&q

110、uot;<<endl;</p><p>  getchar();</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  int i,j;</b></p><p>  stri

111、ng pp;</p><p>  string res="";</p><p>  if(inVt(rull[3])>=0) res=rull[3];</p><p>  else if(inVn(rull[3])>=0) </p><p><b>  {</b></p>&

112、lt;p>  for(i=0;i<RULL.size();i++)</p><p><b>  {</b></p><p><b>  pp=rull;</b></p><p>  if(RULL[i][0]==pp[3])</p><p><b>  {</b>&

113、lt;/p><p><b>  pp=pp[0];</b></p><p><b>  pp+="->";</b></p><p>  for(j=3;j<RULL[i].size();j++) pp+=RULL[i][j];</p><p>  for(j=4;j<

114、;rull.size();j++) pp+=rull[j];</p><p>  res+=first(pp);</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  

115、else if(rull[3]=='0') res+=follow(rull);</p><p><b>  else</b></p><p><b>  {</b></p><p>  system("cls");</p><p>  system("

116、color CF");</p><p>  cout<<"產(chǎn)生式關(guān)鍵位置檢測(cè)到非法字符,系統(tǒng)已停止運(yùn)行。"<<endl;</p><p>  getchar();</p><p><b>  exit(0);</b></p><p><b>  }</

117、b></p><p>  return res;</p><p><b>  }</b></p><p>  string follow(string rull)</p><p>  {//cout<<"迭代次數(shù)"<<counter<<endl;//檢測(cè)<

118、;/p><p>  counter++;</p><p>  if(counter>MAXITERATE)</p><p><b>  {</b></p><p>  system("cls");</p><p>  system("color CF");

119、</p><p>  cout<<"生成選擇集時(shí)迭代次數(shù)過(guò)高,疑似出現(xiàn)遞歸死循環(huán),系統(tǒng)已終止運(yùn)行,請(qǐng)檢查是否有語(yǔ)法錯(cuò)誤"<<endl;</p><p>  cout<<"迭代次數(shù)上限暫設(shè)為產(chǎn)生式數(shù)量的平方。過(guò)多的迭代會(huì)損害設(shè)備,若沒有語(yǔ)法錯(cuò)誤,請(qǐng)簡(jiǎn)化語(yǔ)法樹"<<endl;</p><

120、p>  getchar();</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p>  vector<string> p;</p><p>  string res;</p><p>  string

121、pp="";</p><p>  string t="";</p><p>  int i,site,j;</p><p>  if(rull[0]==Vs) res+='#';</p><p>  for(i=0;i<RULL.size();i++)</p><

122、;p><b>  {</b></p><p><b>  pp="";</b></p><p>  for(j=3;j<RULL[i].length();j++) pp+=RULL[i][j];</p><p><b>  pp+='0';</b><

123、;/p><p>  site=pp.find(rull[0],0);</p><p>  while(site<pp.size())</p><p><b>  {</b></p><p>  site=pp.find(rull[0],site);</p><p>  if(site==-1)

124、break;</p><p>  t=RULL[i][0];</p><p><b>  t+="->";</b></p><p>  for(j=site+1;j<pp.length();j++) t+=pp[j];</p><p><b>  pp=t;</b>&

125、lt;/p><p>  if(pp[3]=='0'&&pp[0]==rull[0]) continue;</p><p>  p.push_back(pp);</p><p><b>  site++;</b></p><p><b>  }</b></p>

126、<p><b>  }</b></p><p>  for(i=0;i<p.size();i++) res+=first(p[i]);</p><p>  return res;</p><p><b>  }</b></p><p>  3.2.2遞歸下降子程序的設(shè)計(jì)</p

127、><p><b>  設(shè)計(jì)原理如下:</b></p><p>  對(duì)每一個(gè)非終結(jié)符,構(gòu)造一個(gè)子程序,用以識(shí)別該非終結(jié)符所定義的符號(hào)串。每個(gè)子程序以產(chǎn)生式左部非終結(jié)符命名,以產(chǎn)生式右部構(gòu)造子程序內(nèi)容。</p><p><b>  構(gòu)造算法如下:</b></p><p><b>  ⑴ 擴(kuò)展文法:

128、</b></p><p>  增設(shè)一個(gè)產(chǎn)生式,作為主程序:Z`->Z ,</p><p><b> ?、?入出口約定: </b></p><p>  子程序入口時(shí),其首符號(hào)已經(jīng)讀來(lái)!</p><p>  子程序出口時(shí),其后繼符應(yīng)該讀來(lái)! </p><p> ?、?子程序內(nèi)容設(shè)

129、計(jì):</p><p>  遇終結(jié)符,判定之 ,確認(rèn)后讀下一單詞;</p><p>  遇非終結(jié)符,調(diào)用之,返回后不讀下一單詞; </p><p>  遇空串(e) ,直接出口; </p><p><b>  程序流程圖如下:</b></p><p>  3.3中間語(yǔ)言生成器算法</p>

130、<p>  中間語(yǔ)言生成主要是對(duì)四元式序列的設(shè)計(jì),其算法設(shè)計(jì)如下:</p><p>  1)賦值語(yǔ)句的四元式設(shè)計(jì)</p><p>  設(shè)有賦值語(yǔ)句:v = E ,則有v = E =>quat(E),q(:= res(E) _ v )</p><p><b>  算法實(shí)現(xiàn)如下:</b></p><p>

131、;  void Z(int end){ //賦值語(yǔ)句四元式生成</p><p>  int i;string str;</p><p>  if(VTOKEN[tokenp+3].compare("<PT,21>")!=0)</p><p><b>  {</b></p><p

132、>  tokenp+=2; </p><p>  LL1(end-1);</p><p>  str=VTOKEN[tokenp+1];</p><p>  str+=SEM.top();</p><p>  SEM.pop();</p><p>  str+="<0,0>";&l

133、t;/p><p>  str+=VTOKEN[tokenp];</p><p>  QT.push_back(str);</p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p

134、><p>  str=VTOKEN[tokenp+1];</p><p>  str+=VTOKEN[tokenp+2];</p><p>  str+="<0,0>";</p><p>  str+=VTOKEN[tokenp];</p><p>  QT.push_back(str);&

135、lt;/p><p><b>  }</b></p><p>  cout<<"驗(yàn)證賦值語(yǔ)句并產(chǎn)生四元式"<<endl;</p><p><b>  }</b></p><p>  條件語(yǔ)句的四元式設(shè)計(jì)</p><p>  文法:S -&

136、gt; if(E)S1 [ else S2 ]</p><p>  語(yǔ)義結(jié)構(gòu) : 四元式結(jié)構(gòu): </p><p><b>  算法實(shí)現(xiàn)如下:</b></p><p>  void V(int end){

137、 //if語(yǔ)句四元式生成</p><p>  string str;</p><p>  int p,f=0;tokenp++;</p><p>  if(VTOKEN[tokenp].compare("<PT,0>")==0)</p><p>  { f+=1;p=tokenp+1;}</p>

138、<p>  else {cout<<"源代碼錯(cuò)誤-ERRO:02/if 當(dāng)前TOKEN:"<<tokenp<<endl; getchar();exit(0); } </p><p><b>  do</b></p><p><b>  {</b></p><

139、p>  if(VTOKEN[p].compare("<PT,0>")==0)f+=1;</p><p>  else if(VTOKEN[p].compare("<PT,1>")==0)f-=1;</p><p><b>  p++;</b></p><p>  }while

140、(f!=0);</p><p>  if((p-1-tokenp)==1)</p><p>  {cout<<"源代碼錯(cuò)誤-ERRO:02/if括號(hào) 當(dāng)前TOKEN:"<<tokenp<<endl; getchar();exit(0); }</p><p>  if((p-1-tokenp)==2){</

141、p><p>  string tt;</p><p>  tt=VTOKEN[tokenp+1];</p><p>  str="<KT,3>"; </p><p><b>  str+=tt;</b></p><p>  

142、str+="<0,0>";</p><p>  str+="<0,0>";</p><p>  QT.push_back(str);</p><p>  tokenp+=3;</p><p><b>  }</b></p><p>&

143、lt;b>  else{</b></p><p><b>  tokenp++;</b></p><p><b>  LL1(p-2);</b></p><p><b>  tokenp=p;</b></p><p>  str="<KT,3&

144、gt;"; </p><p>  str+=SEM.top();</p><p>  SEM.pop();</p><p>  str+="<0,0>";</p><p>  str+="<0,0>";</p>

145、<p>  QT.push_back(str);</p><p><b>  }</b></p><p><b>  C(end);</b></p><p>  cout<<"驗(yàn)證if語(yǔ)句并產(chǎn)生四元式"<<endl;</p><p><b

146、>  }</b></p><p>  void N(int end){ //else語(yǔ)句四元式生成</p><p>  string str;</p><p>  str="<KT,1>";</p><p>  str+="&

147、lt;0,0>";</p><p>  str+="<0,0>";</p><p>  str+="<0,0>";</p><p>  QT.push_back(str);</p><p><b>  tokenp++;</b></p&

148、gt;<p><b>  C(end);</b></p><p>  cout<<"驗(yàn)證else語(yǔ)句并產(chǎn)生四元式"<<endl;</p><p><b>  }</b></p><p>  3)循環(huán)語(yǔ)句的四元式設(shè)計(jì)</p><p>  文法:

149、S -> while(E)S</p><p>  語(yǔ)義結(jié)構(gòu): 四元式結(jié)構(gòu):</p><p><b>  算法實(shí)現(xiàn)如下:</b></p><p>  void W(int end){ //循環(huán)語(yǔ)句四元式生成</p><p>  strin

150、g str;</p><p>  int p,f=0;</p><p>  str="<KT,7>";</p><p>  str+="<0,0>";</p><p>  str+="<0,0>";</p><p>  st

151、r+="<0,0>";</p><p>  QT.push_back(str);</p><p><b>  tokenp++;</b></p><p><b>  p=tokenp;</b></p><p><b>  do</b></p

152、><p>  {if(VTOKEN[p].compare("<PT,0>")==0)f+=1;</p><p>  else if(VTOKEN[p].compare("<PT,1>")==0)f-=1;</p><p><b>  p++;</b></p><p&

153、gt;  }while(f!=0);</p><p>  if((p-1-tokenp)==1)</p><p>  {cout<<"源代碼錯(cuò)誤-ERRO:02/while括號(hào)當(dāng)前TOKEN:"<<tokenp<<endl; getchar();exit(0); }</p><p>  if((p-1-toke

154、np)==2){</p><p>  string tt;</p><p>  tt=VTOKEN[tokenp+1];</p><p>  str="<KT,8>"; </p><p><b>  str+=tt;</b></p>

155、<p>  str+="<0,0>";</p><p>  str+="<0,0>";</p><p>  QT.push_back(str);</p><p>  tokenp+=3;</p><p><b>  }</b></p>

156、;<p><b>  else{</b></p><p>  tokenp++;LL1(p-2);</p><p>  str="<KT,8>";</p><p>  str+=SEM.top();</p><p>  SEM.pop();</p><p&

溫馨提示

  • 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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論