版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 編譯原理課程設(shè)計(jì)--一個(gè)簡(jiǎn)單文法的編譯器前端的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)---一個(gè)簡(jiǎn)單編譯器的設(shè)計(jì)與分析
- 編譯原理課程設(shè)計(jì)報(bào)告-簡(jiǎn)單文法的編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)---簡(jiǎn)單編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)報(bào)告(一個(gè)完整的編譯器)
- 編譯原理課程設(shè)計(jì)任務(wù)書--一個(gè)簡(jiǎn)單的編譯器的設(shè)計(jì)與分析
- 編譯原理課程設(shè)計(jì)---編譯器的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)報(bào)告--編譯器實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--編譯器
- 編譯原理課程設(shè)計(jì)____c語(yǔ)言編譯器的實(shí)現(xiàn)-
- 編譯原理課程設(shè)計(jì)---c語(yǔ)言編譯器的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--c語(yǔ)言編譯器實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--c語(yǔ)言編譯器實(shí)現(xiàn)
- c語(yǔ)言編譯器實(shí)現(xiàn)-編譯原理課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)報(bào)告_編譯器
- 編譯原理課程設(shè)計(jì)報(bào)告---編譯器功能的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)---s語(yǔ)言的編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)---小型程序設(shè)計(jì)語(yǔ)言編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程的設(shè)計(jì)--c語(yǔ)言編譯器
- 編譯原理課程設(shè)計(jì)___c語(yǔ)言編譯器的實(shí)現(xiàn)畢業(yè)論文
評(píng)論
0/150
提交評(píng)論