版權(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> 課 程 設(shè) 計(jì)</b></p><p> 院 系 信息科學(xué)與技術(shù)學(xué)院 </p><p> 專 業(yè) 計(jì)算機(jī)科學(xué)與技術(shù) </p><p> 年 級(jí)
2、 2014級(jí) </p><p> 學(xué) 號(hào) </p><p> 姓 名 </p><p><b> 詞法分析器設(shè)計(jì)</b></p><p><b>
3、 一、設(shè)計(jì)題目</b></p><p> 手工設(shè)計(jì)c語言的詞法分析器(可以是c語言的子集)。</p><p><b> 二、設(shè)計(jì)內(nèi)容</b></p><p> 處理c語言源程序,過濾掉無用符號(hào),判斷源程序中單詞的合法性,并分解出正確的單詞,以二元組形式存放在文件中。</p><p><b>
4、 三、設(shè)計(jì)目的</b></p><p> 了解高級(jí)語言單詞的分類,了解狀態(tài)圖以及如何表示并識(shí)別單詞規(guī)則,掌握狀態(tài)圖到識(shí)別程序的編程。</p><p><b> 四、需求分析</b></p><p> 4.1.源程序的預(yù)處理:源程序中,存在許多編輯用的符號(hào),他們對(duì)程序邏輯功能無任何影響。例如:回車,換行,多余空白符,注釋行等。
5、在詞法分析之前,首先要先剔除掉這些符號(hào),使得詞法分析更為簡單。</p><p> 4.2.單詞符號(hào)的識(shí)別并判斷單詞的合法性:將每個(gè)單詞符號(hào)進(jìn)行不同類別的劃分。單詞符號(hào)可以劃分成5中。</p><p> (1)標(biāo)識(shí)符:用戶自己定義的名字,常量名,變量名和過程名。</p><p> (2)常數(shù):各種類型的常數(shù)。</p><p> (3)
6、保留字(關(guān)鍵字):如if、else、while、int、float等。</p><p> (4) 運(yùn)算符:如+、-、*、<、>、=等。</p><p> (5)界符:如逗號(hào)、分號(hào)、括號(hào)等。</p><p> 5.3.將所有合法的單詞符號(hào)轉(zhuǎn)化為便于計(jì)算機(jī)處理的二元組形式:(單詞分類號(hào),單詞自身值)。</p><p><b
7、> 五、主要源代碼</b></p><p> #include <stdio.h> </p><p> #include <string.h> </p><p> #include <ctype.h> </p><p>
8、 #include <stdlib.h> </p><p> #include <assert.h></p><p> #define LENGTH1 10 //定義保留字的大小 </p><p> FILE * fp=NULL;
9、60;//輸出流指針 </p><p> FILE * fw=NULL; //輸入流指針 </p><p> char /**/ character; //字符 </p><p> char token[16]; //字符數(shù)組,用來存放已讀入的字符序列
10、0; </p><p> //編碼表 /**/</p><p> char* CODE[]={"identifier"/*標(biāo)識(shí)符*/,"constant"/*常數(shù)*/,"keyword"/*保留字*/,</p><p> "+","-&quo
11、t;, "*","/","<","<=",">",">=","!=","==","=","(",")",",",":",";
12、","{","}"}; //保留字表 char </p><p> char*k[]={"for","while","do","else","if","static","int","s
13、izeof","break","continue"}; </p><p><b> //標(biāo)識(shí)符結(jié)構(gòu)體 </b></p><p> typedef struct</p><p><b> { </b></p&g
14、t;<p> char * I[256]; //標(biāo)識(shí)符數(shù)組 </p><p> int len;//標(biāo)識(shí)符數(shù)量</p><p> }identifier; </p><p><b> //常量結(jié)構(gòu)體 </b></p>
15、<p> typedef/**/ struct</p><p><b> { </b></p><p> int cont[300];//存放常量的數(shù)組 </p><p> int len;//常量的數(shù)目 </p><p>
16、}constnumber; </p><p> //讀入一個(gè)字符,從輸入流中讀入一個(gè)字符到變量character中。 </p><p> void getNextChar(FILE *ifp) </p><p><b> { </b></
17、p><p> if((character=getc(ifp))==EOF) </p><p><b> exit(1); </b></p><p><b> }</b></p><p> //讀入非空白字符,檢查變量character中的字符是否為空白
18、字符或回車或換行符。若是, </p><p> //則調(diào)用getNextChar()讀入下一個(gè)字符,直到character中的字符滿足條件. </p><p> void getnbc(FILE *ifp) </p><p><b> { </b><
19、/p><p> while(character==' '|| character=='\n'||character==9) </p><p><b> { </b></p><p> getNextChar(ifp);
20、60;</p><p><b> } </b></p><p><b> } </b></p><p> //連接字符串,把character中的字符連接到token數(shù)組的結(jié)尾。 </p><p> void concat()&
21、#160;</p><p> {
22、; </p><p> char * ct=&character; </
23、p><p> strcat(token,ct); </p><p><b> } </b></p><p> //判斷是否為字母。 </p><p> int letter() </p><p><b> {
24、 </b></p><p> return isalpha(character);</p><p><b> } </b></p><p> //判斷是否為數(shù)字 </p><p> int digit() </p>
25、<p><b> { </b></p><p> return isdigit(character);</p><p><b> } </b></p><p> //回退字符,將剛讀入的character中的字符回退到輸入流中。并把character中
26、的值置為空。 </p><p> void retract(FILE *ifp)</p><p><b> { </b></p><p> (ifp->_cnt)++; </p><p> (ifp->_ptr)--; </p>
27、<p> character=' '; </p><p><b> } </b></p><p> //處理保留字,對(duì)存放在token中的字符串查保留字,若查到,則返回該保留字的類別編碼,否則返回0. </p><p> int reserve(c
28、har **k) </p><p><b> { </b></p><p><b> int i; </b></p><p> for(i=0;i<LENGTH1;i++) </p><p> if(strcmp(token,
29、k[i])==0) </p><p> return i+1; return 0; </p><p><b> } </b></p><p> //處理標(biāo)識(shí)符,對(duì)存放在token中的字符串查找符號(hào)表,若查到,則返回它在符號(hào)表的位置,
30、 </p><p> //存入常數(shù)表中,并返回它在常數(shù)表中的位置編號(hào)。</p><p> int symbol(identifier * id) </p><p><b> { </b></p><p><b> int i;
31、0; </b></p><p> for(i=0;i<id->len;i++) </p><p> if(strcmp(token,id->I[i])==0) </p><p> return i+1; <
32、;/p><p> if(id->len>256) </p><p> assert(0); </p><p> id->I[id->len]=token; </p><p> id->len++; </p><p&
33、gt; return id->len; </p><p><b> } </b></p><p> //將數(shù)字字符串轉(zhuǎn)化為整數(shù)。</p><p> int strtonumber() </p><p><b> {
34、0;</b></p><p><b> int i; </b></p><p> int sum=0; </p><p> for(i=0;i<strlen(token);i++) </p><p><b> {
35、 </b></p><p> sum=10*sum+(token[i]-'0'); </p><p><b> } </b></p><p> return sum; </p><p><b> } &l
36、t;/b></p><p> //存入常數(shù)表中,并返回它在常數(shù)表中的位置編號(hào)。</p><p> int constant(constnumber * con)</p><p><b> { </b></p><p> con->cont
37、[con->len]=strtonumber(); </p><p> con->len++; return con->len;</p><p><b> } </b></p><p> //將整數(shù)值轉(zhuǎn)化為字符串 </p><p>
38、char * numbertoString(int num) </p><p><b> { </b></p><p> char s[3]; </p><p> int i=num/10; </p><p
39、> while(i>0) </p><p><b> { </b></p><p> char c=i+'0'; </p><p> strcat(s,&c); </p><
40、;p> } return s; </p><p><b> }</b></p><p> //將結(jié)果寫入到文件并且輸出到屏幕。 </p><p> void returntofile(int num,int val,identifier *
41、id,constnumber *con)</p><p><b> { </b></p><p><b> int i; </b></p><p> int _num=num; </p><p><b&g
42、t; char c; </b></p><p> c='('; putc(c,fw); </p><p> printf("%c",c); </p><p> i=_num/10; </p><p
43、> while(i>0) </p><p><b> { </b></p><p> _num=_num-10*i; </p><p> c=(i+'0'); </p&
44、gt;<p> printf("%c",c); </p><p> putc(c,fw);</p><p> i=_num/10; } </p><p> c=_num+'0'; </p><p> prin
45、tf("%c",c); </p><p> putc(c,fw); </p><p> printf(","); </p><p> putc(',',fw); </p><p> //如果是標(biāo)識(shí)符或常數(shù) 則放入括號(hào)內(nèi)。
46、;</p><p> if(num==1) //處理標(biāo)識(shí)符 </p><p> { printf("%s",id->I[val-1]); </p><p> printf(")"); printf(&quo
47、t;\n"); </p><p> fputs(id->I[val-1],fw); </p><p> putc(')',fw); </p><p> putc('\n',fw); } <
48、;/p><p> if(num==2) //處理常數(shù) </p><p> { _num=con->cont[val-1]; </p><p> i=_num/10; while(i>0) </p>
49、<p><b> { </b></p><p> _num=_num-10*i; </p><p> c=(i+'0'); </p><p> printf("%c",c); &
50、#160; </p><p> putc(c,fw); </p><p> i=_num/10; } </p><p> c=_num+'0'; </p><p> prin
51、tf("%c",c); </p><p> printf(")"); </p><p> printf("\n"); </p><p> putc(c,fw); </p>&l
52、t;p> putc(')',fw); </p><p> putc('\n',fw); } </p><p> if(num==3) //保留字 </p><p><b> { </b><
53、;/p><p> printf("-"); </p><p> printf(")"); </p><p> printf(" "); </p><p> printf
54、("#"); </p><p> printf("%s",k[val-1]); </p><p> printf("#"); </p><p> printf("\n");
55、0; </p><p> putc('-',fw); </p><p> putc(')',fw); </p><p> fputs(" ",fw); </p><p> putc('#
56、39;,fw); </p><p> fputs(k[val-1],fw); </p><p> putc('#',fw); </p><p> putc('\n',fw); </p><p><b> }
57、</b></p><p> if(num>3) //處理界符 </p><p><b> { </b></p><p> printf("-"); </p><p> prin
58、tf(")"); </p><p> printf(" "); </p><p> printf("#"); </p><p> printf("%s",CO
59、DE[num-1]); </p><p> printf("#"); </p><p> printf("\n"); </p><p> putc('-',fw);
60、160;</p><p> putc(')',fw); </p><p> fputs(" ",fw); </p><p> putc('#',fw);
61、0;</p><p> fputs(CODE[num-1],fw); </p><p> putc('#',fw); </p><p> putc('\n',fw); </p><p><b> }<
62、;/b></p><p><b> }</b></p><p> //將錯(cuò)誤寫入到文件或輸出到屏幕 </p><p> void error() </p><p><b> { </b></p><p> p
63、rintf("(ERROR,"); </p><p> printf("%c",character); </p><p> printf(")"); </p><p> printf("\n");
64、0;</p><p> fputs("(ERROR,",fw); </p><p> putc(character,fw); </p><p> putc(')',fw); </p><p> putc('\n',fw
65、); </p><p><b> }</b></p><p><b> //詞法分析函數(shù) </b></p><p> void LexAnalyze(char **k,char **CODE,identifier *id,constnumber *
66、con,FILE *fp,FILE *fw) </p><p><b> { </b></p><p> int num,val; </p><p> strcpy(token,""); </p><p> ge
67、tNextChar(fp); </p><p> getnbc(fp); </p><p> switch(character) </p><p><b> { </b></p><p> case 'a': </p&g
68、t;<p> case 'b': </p><p> case 'c': </p><p> case 'd': </p><p> case 'e': </p><p> c
69、ase 'f': </p><p> case 'g': </p><p> case 'h': </p><p> case 'i': </p><
70、p> case 'j': </p><p> case 'k': </p><p> case 'l': </p><p> case 'm': </p><p>
71、; case 'n': </p><p> case 'o': </p><p> case 'p': </p><p> case 'q': </p><p> c
72、ase 'r': </p><p> case 's': </p><p> case 't': </p><p> case 'u': </p><p> case &
73、#39;v': </p><p> case 'w': </p><p> case 'x': </p><p> case 'y': </p><p> cas
74、e 'z': </p><p> case 'A': </p><p> case 'B': </p><p> case 'C': </p><p> case
75、60;'D': </p><p> case 'E': </p><p> case 'F': </p><p> case 'G': </p><p> case&
76、#160;'H': </p><p> case 'I': </p><p> case 'J': </p><p> case 'K': </p><p>
77、; case 'L': </p><p> case 'M': </p><p> case 'N': </p><p> case 'O': </p>
78、<p> case 'P': </p><p> case 'Q': </p><p> case 'R': </p><p> case 'S': <
79、/p><p> case 'T': </p><p> case 'U': </p><p> case 'V': </p><p> case 'W': &l
80、t;/p><p> case 'X': </p><p> case 'Y': </p><p><b> case 'Z':</b></p><p> while(letter()||digit())<
81、;/p><p><b> { </b></p><p> concat(); </p><p> getNextChar(fp); </p><p><b> }
82、0; </b></p><p> retract(fp); </p><p> num=reserve(k);//保留字 </p><p> if(num!=0) </p><p> re
83、turntofile(3,num,id,con); </p><p> else { </p><p> val=symbol(id); </p><p> returntofile(1,val,id,con); </p&
84、gt;<p><b> }</b></p><p><b> break; </b></p><p> case '0': </p><p> case '1': </p>
85、<p> case '2': </p><p> case '3': </p><p> case '4': </p><p> case '5': </p&g
86、t;<p> case '6': </p><p> case '7': </p><p> case '8': </p><p><b> case '9':</b>
87、;</p><p> while(digit()) </p><p><b> { </b></p><p> concat(); </p><p> getNextChar(fp);
88、160;</p><p><b> } </b></p><p> retract(fp); </p><p> val=constant(con); </p><p> returntofile(2,val,id,con);
89、; </p><p><b> break; </b></p><p> case '<': </p><p> getNextChar(fp); </p><p> if(character=='
90、=') </p><p> returntofile(9,0,id,con); </p><p><b> else </b></p><p><b> { &l
91、t;/b></p><p> retract(fp); </p><p> returntofile(8,0,id,con); </p><p><b> } </b></p><p><b>
92、break; </b></p><p> case '>': </p><p> getNextChar(fp); </p><p> if(character=='=')
93、160;</p><p> returntofile(11,0,id,con); </p><p><b> else </b></p><p><b> { </b></p><p> retract(fp); &
94、#160; </p><p> returntofile(10,0,id,con); </p><p><b> } </b></p><p><b> break;</b></p><p> case '=':
95、 </p><p> getNextChar(fp); </p><p> if(character=='=') </p><p> returntofile(13,0,id,con); </p><p
96、><b> else </b></p><p><b> { </b></p><p> retract(fp); </p><p> returntofile(14,0,id,con); </p><
97、p><b> } </b></p><p><b> break; </b></p><p> case '!': </p><p> getNextChar(fp); &
98、lt;/p><p> if(character=='=') </p><p> returntofile(12,0,id,con); </p><p><b> else </b></p><p
99、> error(); </p><p><b> break; </b></p><p> case '+': </p><p> returntofile(4,0,id,con); </p><p
100、><b> break; </b></p><p> case '-': </p><p> returntofile(5,0,id,con); </p><p> break; case
101、60;'*': </p><p> returntofile(6,0,id,con); </p><p> break; case '/': </p><p> returntofile(7,0,id,con);
102、0; </p><p> break; case '(': </p><p> returntofile(15,0,id,con); </p><p> break; case ')': &
103、#160;</p><p> returntofile(16,0,id,con); </p><p> break; case ',': </p><p> returntofile(17,0,id,con); </p><p&
104、gt; break; case ':': </p><p> returntofile(18,0,id,con); </p><p> break; case ';': </p><p> retu
105、rntofile(19,0,id,con); </p><p> break; case '{': </p><p> returntofile(20,0,id,con); </p><p> break; case '
106、}': </p><p> returntofile(21,0,id,con);</p><p> break; default: error(); </p><p><b> }</b></p><
107、p><b> }</b></p><p> main(int argc,char *argv[]) </p><p> { //初始化標(biāo)識(shí)符和常數(shù)結(jié)構(gòu)體 </p><p> identifier* id=(identifier*)malloc(si
108、zeof(identifier)); </p><p> constnumber * con=(constnumber*)malloc(sizeof(constnumber)); </p><p> con->len=0; id->len=0;
109、;</p><p> argc=3; argv[1]="E:\\file1.txt";//待分析的文件 </p><p> argv[2]="E:\\file2.txt";//保存分析結(jié)果的文件 //從打開目標(biāo)文件流 </p><
110、;p> if((fp=fopen(argv[1],"r"))==NULL) { </p><p> printf("cat: can't open %s\n",*argv); </p><p> return 1; </p
111、><p> } //打開要寫二元式的文件流 </p><p> if((fw=fopen(argv[2],"w"))==NULL) </p><p><b> { </b></p><p> printf("cat:can&
112、#39;t open %s\n",argv[2]); return 1; </p><p> } while(!feof(fp)) </p><p> { LexAnalyze(k,CODE,id,con,fp,fw);//執(zhí)
113、行詞法分析 } //關(guān)閉流 </p><p> fclose(fp); fclose(fw); </p><p> return 0; </p><p><b> }<
114、/b></p><p><b> 六.實(shí)驗(yàn)結(jié)果 </b></p><p> 要分析的C語言程序(1)</p><p> int i=0,sum=0; </p><p> while(i<10) </p><p><b> {
115、</b></p><p> sum=sum+i; i=i+1;</p><p><b> }</b></p><p><b> 結(jié)果為:</b></p><p> (3,-) #int# (1,i) &l
116、t;/p><p> (14,-) #=# (2,0) </p><p> (17,-) #,# (1,sum) </p><p> (14,-) #=# (2,0) </p><p> (19,-)
117、160;#;# (3,-) #while# (15,-) #(# (1,i) </p><p> (8,-) #<# (2,10) </p><p> (16,-) #)# (20,-) #{#
118、0;(1,sum) </p><p> (14,-) #=# (1,sum) (4,-) #+# (1,i) </p><p> (19,-) #;# (1,i) </p><p> (14,-) #=#
119、 (1,i) </p><p> (4,-) #+# (2,1) </p><p> (19,-) #;# (21,-) #}# </p><p> 要分析的C語言程序(2)</p><p> char
120、0;s[3]; int i=num/10; </p><p> while(i>0) { </p><p> char c=i+'0'; strcat(s,&c); } </p><p&g
121、t;<b> return s;</b></p><p><b> 結(jié)果為:</b></p><p> (1,char) (1,s) </p><p> (ERROR,[) (2,3) </p><p> (ERROR,]) (1
122、9,-) #;# (3,-) #int# (1,i) </p><p> (14,-) #=# (1,num) (7,-) #/# (2,10) </p><p> (19,-) #;# (3,-)
123、 #while# (15,-) #(# (1,i) </p><p> (10,-) #># (2,0) </p><p> (16,-) #)# (20,-) #{# (1,char) (1
124、,c) </p><p> (14,-) #=# (1,i) </p><p> (4,-) #+# (ERROR,') (2,0) </p><p> (ERROR,') (19,-) #;# (1
125、,strcat) (15,-) #(# (1,s) </p><p> (17,-) #,# (ERROR,&) (1,c) </p><p> (16,-) #)# </p><p> (19
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 編譯原理課程設(shè)計(jì)-詞法語法分析器
- 編譯原理課程設(shè)計(jì)--- 語法分析器
- 編譯原理課程設(shè)計(jì)---語法分析器
- 編譯原理課程設(shè)計(jì)--語法分析器
- 編譯原理語法分析器課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)--pascal語言詞法、語法分析器設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)(c++)-語法分析器
- 語法分析課程設(shè)計(jì)---編譯原理語法分析器的設(shè)計(jì)與實(shí)現(xiàn)
- 課程設(shè)計(jì)----編譯原理詞法分析器
- 編譯原理課程設(shè)計(jì)--表達(dá)式語法分析器
- 編譯原理課程設(shè)計(jì)報(bào)告詞法分析器
- 編譯原理課程設(shè)計(jì)詞法分析器文檔
- c-minus詞法分析和語法分析設(shè)計(jì)編譯器編譯原理課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)--c-編譯器詞法分析與語法分析的實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--構(gòu)造lr(0)分析法語法分析器
- 編譯原理課程設(shè)計(jì)報(bào)告之詞法分析器
- 課程設(shè)計(jì)詞法分析器
- 編譯原理課程設(shè)計(jì)詞法分析
- 編譯技術(shù)課程設(shè)計(jì)報(bào)告-詞法分析、語法分析、中間代碼生成
- 編譯原理課程設(shè)計(jì)--詞法分析
評(píng)論
0/150
提交評(píng)論