

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 編譯原理課程設(shè)計---編譯器的實現(xiàn)
- 編譯原理課程設(shè)計報告-簡單文法的編譯器的設(shè)計與實現(xiàn)
- 編譯原理課程設(shè)計報告--編譯器實現(xiàn)
- 編譯原理課程設(shè)計--編譯器
- 編譯原理課程設(shè)計--c語言編譯器實現(xiàn)
- 編譯原理課程設(shè)計--c語言編譯器實現(xiàn)
- c語言編譯器實現(xiàn)-編譯原理課程設(shè)計
- 編譯原理課程設(shè)計報告_編譯器
- 編譯原理課程設(shè)計____c語言編譯器的實現(xiàn)-
- 編譯原理課程設(shè)計---c語言編譯器的實現(xiàn)
- 編譯原理課程設(shè)計--一個簡單文法的編譯器的設(shè)計與實現(xiàn)
- 編譯原理課程設(shè)計---一個簡單編譯器的設(shè)計與分析
- 編譯原理課程設(shè)計報告---編譯器功能的實現(xiàn)
- 編譯原理課程設(shè)計---s語言的編譯器的設(shè)計與實現(xiàn)
- 編譯原理課程設(shè)計--一個簡單文法的編譯器前端的設(shè)計與實現(xiàn)
- 編譯原理課程設(shè)計---小型程序設(shè)計語言編譯器的設(shè)計與實現(xiàn)
- 編譯原理課程設(shè)計___c語言編譯器的實現(xiàn)畢業(yè)論文
- 編譯原理課程的設(shè)計--c語言編譯器
- 編譯原理課程設(shè)計任務(wù)書--一個簡單的編譯器的設(shè)計與分析
- 編譯原理課程設(shè)計-pl_0編譯器及其擴(kuò)充
評論
0/150
提交評論