C語言的詞法分析器_第1頁
C語言的詞法分析器_第2頁
C語言的詞法分析器_第3頁
C語言的詞法分析器_第4頁
C語言的詞法分析器_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1.實驗?zāi)康募耙?/p>

1、目的

通過設(shè)計、編制、調(diào)試一個具體的詞法分析程序,加深對詞法分析原理的

理解,并掌握在對程序設(shè)計語言源程序進(jìn)行掃描過程中將其分解為各類單

詞的詞法分析方法。

2、要求

?根據(jù)具體情況,由同學(xué)們自己選取C語言的一個適當(dāng)大小的子集(可

取一類典型單詞,也可以盡可能使各種類型的單詞都兼顧到);在實

習(xí)前一定要制出相應(yīng)的表。

?實驗時間:4-8學(xué)時

?檢查內(nèi)容及時間:A)完整的實驗報告。

B)在機(jī)器上調(diào)試成功的源程序。

3、軟件、硬件環(huán)境

?Visualstudic2010,Windows7操作系統(tǒng)

?計算機(jī)一臺

2.實驗步驟

?分析

對于單詞符號我們將其分成四類:保留字K、標(biāo)識符I、常數(shù)C和界符P,每類單詞符

號均可使用一張表格表示.在詞法分析過程中,保留字K和界符P這兩個表格的內(nèi)容是

固定不變的(由語言確定),源程序字符串只能從其中選取,而標(biāo)識符I、常數(shù)C這兩

表是在分析過程中不斷形成的.

對于一個具體源程序而言,在掃描字符串時識別出一個單詞,若這個單詞的類型是

K、I、C或P中之一,那么就以單詞的二元式形式輸出.每次調(diào)用詞法分析程序,它

均能自動繼續(xù)掃描下去,形成下一個單詞,直到整個源程序全部掃描完畢,從而形成相

應(yīng)的單詞串.

各類單詞的二元式表述均具有相同的結(jié)構(gòu)與長度,形式如下:

(單詞種別t,單詞自身的值i)

t是單詞種別,而單詞種別共分為K、1、C、P四類且每類對應(yīng)一張表格.因此,t

實際上就是一個指向這四類中某一類對應(yīng)表格的指針.i則為指向該類表格中一個特定

項目的指針.

所以整個的詞法分析過程就是從源程序中獲得一個個的單詞符號,將這些符號分別

填入四張類表中,并且有一個二元式序列構(gòu)成一個索引,這個索引為以后的語法分析提

供處理上的方便.

為了減少實習(xí)量,可以適量地選取K,P中的一個子集來進(jìn)行.如下表:

表1保留字K表

....I.~

內(nèi)部地址]2345678910

保留字forwhileDOELSEIFSFATICTNTSIZEOFBREAKCONTINUE

表2界符P表

內(nèi)123456789101112131415161718

界+-*/<<=〉>=!====(),:;()

表3單詞符號的編碼

單詞符號類別編碼

標(biāo)識符1

常數(shù)2

保留字3

+4

—5

*6

/7

<8

<=9

>10

>=11

1=12

==13

—14

(15

)16

17

:18

*?19

{20

}21

保留字表包括10個有代表性的保留字,界符表包括關(guān)系運算符,算術(shù)運算符,分隔符

三種,一對圓括號,加上賦值號,花括號,分號,引號.這兩表的內(nèi)容表明C語言的條

件語句,賦值語句,WHILE型循環(huán)語句,復(fù)合語句,過程及變量說明均可作為源程序例

子輸入給詞法分析程序,標(biāo)識符表I中的每一項包含一個標(biāo)識符,常數(shù)表C中的每一項

包含一個整常數(shù),后兩表的內(nèi)容都是在詞法分析過程中產(chǎn)生的.

如何從源程序中識別出一個個的單詞符號呢?圖1中的流圖清晰地反映出這一過

程.

圖1中,雙圓圈的狀態(tài)表示終態(tài),即能到達(dá)終態(tài)就代表識別出一個單詞符號,而帶有火

號的終態(tài)是指處理時應(yīng)回退一字符.

?算法

詞法分析器在掃描過程中,依次從源程序中取出源字符,根據(jù)圖1的掃描過程狀態(tài)轉(zhuǎn)換圖,

當(dāng)碰到終態(tài)時,即雙圓圈的狀態(tài)時就得到一個單詞符號,此時可以根據(jù)第一個字符判斷單詞

屬于K,I,C,P中哪一個類,從而確定單詞的“單詞種別”和“單詞自身的值”。

空白字母與數(shù)字

圖1掃描程序的狀態(tài)轉(zhuǎn)換圖

說明:這個圖只是大概表達(dá)一個詞法分析的思路,由于不知道加入,所以并不完全準(zhǔn)確。

2.實驗內(nèi)容

流程圖、程序

圖2詞法分析算法流圖

源程序

#include<stdio.h>

^include<string.h>

^include<ctype.h>

#include<stdlib.h>

nclude〈assert.h>

^defineLENGTH110〃定義保留字的大小

FILE*fp=NULL;〃輸出流指針

FILE*fw=NULL;〃輸入流指針

charcharacter;〃字符

chartokcn[16];〃字符數(shù)組,用來存放已讀入的字符序列

〃編碼表

char*CODE[]={*identifier*/*標(biāo)識符*/,"constant"/*常數(shù)*/,"keyword"/*保留字

〃保留字表

char

*kLJ=lfor,while,do,else,if,static,int,sizeof,break,continue

};

〃標(biāo)識符結(jié)構(gòu)體

typedefstruct

(

char*I[256];〃標(biāo)識符數(shù)組

intlen;〃標(biāo)識符數(shù)量

}identifier;

〃常量結(jié)構(gòu)體

typedefstruct{

intcont[300];〃存放常量的數(shù)組

intlen;〃常量的數(shù)目

}constnumber;

〃讀入一個字符,從輸入流中讀入一個字符到變量character中。

voidgetNextChar(FILE*ifp)

(

if((character=getc(ifp))==EOF)

exit(1);

)

〃讀入非空白字符,檢查變量character中的字符是否為空白字符或|口|車或換行符。若是,

〃則調(diào)用getNextChar()讀入下一個字符,直到character中的字符滿足條件.

voidgetnbc(FILE*ifp)

(

while(character=,|character==,\n\character==9)

{

getNextChar(ifo);

)

}

〃連接字符串,把character中的字符連接到token數(shù)組的結(jié)尾。

voidconcat()

(

char*ct=&character;

strcat(token,ct);

〃判斷是否為字母。

intletter()

returnisalpha(character);

)

〃判斷是否為數(shù)字

intdigit()

(

returnisdigit(character);

)

〃回退字符,將剛讀入的character中的字符回退到輸入流中。并把character中的值置為

空。

voidretract(FILE*ifp)

(

(ifp->_cnt)++;

(ifp->_ptr)—;

character=,';

)

〃處理保留字,對存放在二。ken中的字符串查保留字,若杳到,則返回該保留字的類別編碼,

否則返回0.

intreserve(char**k)

(

inti;

for(i=0;i<LENGTHl;i++)

if(strcmp(token,k[i])==0)

returni+1;

return0;

)

〃處理標(biāo)識符,對存放在二。ken中的字符串查找符號表,若查到,則返回它在符號表的位置,

〃存入常數(shù)表中,并返回它在常數(shù)表中的位置編號。

intsymbol(identifier*id)

(

inti;

for(i=0;i<id->lcn;L++)

if(stremp(token,id->I[i])=0)

returni+1;

if(id->len>256)

assert(0);

id->I[id->len]=token;

id->len++;

returnid->len;

}

〃將數(shù)字字符串轉(zhuǎn)化為整數(shù)。

intstrtonumber()

inti;

intsum=O;

for(i=0;i<strlen(token);i++)

(

sum=10*sum+(lo《en[i],O');

)

returnsum;

)

〃常數(shù)存入常數(shù)表的函數(shù),將token中的數(shù)字串(實際上是字符串),轉(zhuǎn)化成標(biāo)準(zhǔn)的二進(jìn)制

值(整數(shù)值)

〃存入常數(shù)表中,并返回它在常數(shù)表中的位置編號。

intconstant(constnumber*con)

(

con->cont[con->len]=strtonumber();

con->len++;

returncon->len;

)

〃將整數(shù)值轉(zhuǎn)化為字符串

char*numbertoString(intnum)

(

chars[3];

inti=num/10;

while(i>0)

(

charc=i+*O';

strcat(s,&c);

)

returns;

)

〃將結(jié)果寫入到文件并且輸出到屏幕。

voidreturntofile(intnum,intval,identifier*id,constnumber*con)

(

inti;

int_num=num;

charc;

c='(';

putc(c,fw);

printf(飛c”,c);

i=num/10;

while(i>0)

(

_num=_nuni-10*i;

c=(i+'O');

printf("Sc",c);

putc(c,fw);

i=_num/10;

)

c=num+,0';

printfc);

putc(c,fw);

printf;

putcC,',fw);

〃如果是標(biāo)識符或常數(shù)則放入括號內(nèi)。

if(num=l)//處理標(biāo)識符

(

printf(飛s”,id->I[val-1]);

printf(*)*);

printf(*\n*);

fputs(id->I[val-1],fw);

putc(*),,fw);

putcC\n,fw);

}

if(num-2)〃處理常數(shù)

(

_num=con->cont[val-1];

i=_num/10;

while(i>0)

(

num=num-10*i;

c=(i+'O');

printf("枇”,c);

putc(c,fw);

i=_num/10;

)

c=_num+,0*;

printfc);

printf(*)*);

printf("\n");

putc(c,fw);

putc(')',fw);

putcC\n,fw);

)

if(num==3)〃保留字

(

printf。-");

printfC)");

printf”);

printf("#");

printf(飛s”,k[val-l]);

printfC#*);

printf('\n");

putc(',fw);

putc(*)',fw);

fputs("fw);

putcC,fw);

fputs(k[val-1],fw);

putcC,fw);

putc('\n*,fw);

)

if(num>3)〃處理界符

(

printf(",);

printf(〃)");

printf("");

prinlf(〃#");

printf("與s〃,CODE[num-1]);

printfm;

printf('\n");

putc('-',fw);

putc,fw);

fputsC〃,fw);

putc(',fw);

fputs(CODE[num-1],fw);

putc,fw);

putc('\n,fw);

}

)

〃將錯誤寫入到文件或輸出到屏幕

voiderror0

(

printf("(ERROR,");

printf(,,%c,,?character);

printf(")");

printf("\n");

fputs("(ERROR,",fw);

putc(character,fw);

putc(,)',fw);

putc(?\n,fw);

)

〃詞法分析函數(shù)

voidLexAnalyzeCchar**《,char**CODE,identifier*id,constnumber*con,FILE*fp,FILE

*fw)

(

intnum,val;

strcpy(token,,/,/);

gctNcxtChar(fp);

getnbc(fp);

switch(character)

(

case'a':

case'b':

case'c':

case'd':

case':

case'f':

case'g*:

case'h,:

,?,

casei:

case'j:

case'k':

case'1':

case'm:

case'n:

case'o*:

case'p':

case'q':

case'r:

case's':

case't':

case'u:

case'v':

case'w*:

case'x:

case'y':

case'L:

case'A*:

case'B':

case'C':

case'D':

case'E,:

case'F':

case'G':

case'H*:

case'I*:

case'J':

case'K':

case'L*:

case'M':

case'N':

case'O':

case'P*:

case'Q':

case'R':

case'S':

case'T’:

case'U':

case'V':

case'W':

case'X*:

case'Y':

case'Z':

while(letter()||digit())

{

concat();

getNoxtChar(fp);

)

retract(fp);

num=reserve(k);〃保留字

if(num!=0)

returntofile(3,num,id,con);

else

(

val=symbol(id);

returntofile(l,val,id,con);

)

break;

case'O':

case'1':

case’21:

case'3':

case'4':

case'5':

case'6’:

case'T:

case'8':

case'9':

while(digit0)

(

concatO;

getNextChar(fp);

)

retract(fp);

val=constant(con);

returntofile(2.val,id,con);

break;

case':

getNextChar(fp);

if(character二二'二')

returntofile(9,0,id,con);

else

{

retract(fp);

returntofile(8,0,id,con);

)

break;

case'>’:

getNextChar(fp);

if(charactcr==,=')

returntofile(11,0,id,con);

else

{

retract(fp);

returntofile(10,0,id,con);

)

break;

case

getNextChar(fp);

if(character"'二')

returntofile(13,0,id,con);

else

{

retract(fp);

returntofile(14,0,id,con);

)

break;

case':

getNextChar(fp);

if(character==,=')

relurntofile(12,0,id,con);

else

error();

break;

case'+':

returntofile(4.0,id,con);

break;

case':

returntofile(5,0,id,con);

break;

case'*':

returntofile(6.0,id,con);

break;

case'/':

returntofilc(7.0,id,con);

break;

case'(':

returntofile(15,0,id,con);

break;

case')':

returntofile(16,0,id,con);

break;

case',':

returntofile(17,0,id,con);

break;

case':

returntofilc(18,0,id,con);

break;

case':

returntofile(19,0,id,con);

break;

case'{':

returntofile(29,0,id,con);

break;

case'}':

returntofile(21,0,id,con);

break;

default:

error();

}

)

main(intargc,char*argv[])

(

〃初始化標(biāo)識符和常數(shù)結(jié)構(gòu)體

identifier*id=(identifier*)malloc(sizeof(identifier));

constnumber*con=(conslnumber*)malloc(sizeof(constnumber));

con->len=0;

id->len=0;

argc=3;

argv[l]=*E:\\filel.txt";〃待分析的文件

argv[2]=,,E:\\file2.txt”;〃保存分析結(jié)果的文件

〃從打開目標(biāo)文件流

if((fp=fopen(argv[l],)==NULL)

{^^

printf(〃cat:can'topen%s\n",*argv);

return1;

)

〃打開要寫二元式的文件流

if((fw=fopen(argv[2],"w"))=NULL)

(

printf(z,cat:can,topenargv[2]);

return1;

)

while(!feof(fp))

(

LexAnalyze(k,CODE,id,con,fp,fw);〃執(zhí)行詞法分析

)

〃關(guān)閉流

fclose(fp);

fclose(fw);

return0;

}

4.實驗結(jié)果

要分析的C語言程序(1)

inti=0,sum=0;

while(i<10)

(

sum=sum+i;

i=i+l;

結(jié)果為:

⑶-)#int#

(1.i)

(14,-)#=#

(2,0)

(17,-)#,#

(1,sum)

(14,-)#=#

(2,0)

(19,-)#;#

⑶-)#whiIe#

(15,-)#(#

(1,i)

(8,-)#<#

(2,10)

(16,-)#)#

(20,-)#{#

(1,sum)

(14,-)#=#

(1,sum)

(4,-)#+#

(1,i)

(19,-)#;#

(1.i)

(14,-)#=#

(1,i)

(4,-)#+#

(2.1)

(19,-)#;#

(21,-)#}#

要分析的源程序(2)

chars[3];

inti=num/10;

while(i>0)

charc=i+,0';

strcat(s,&c);

)

returns;

結(jié)果為:

(1,char)

(l,s)

(ERROR,[)

(2,3)

(ERROR,])

(19,-)#;#

(3,-)#int#

(3)

(14,-)#=#

(l,num)

(7,?)#/#

(2,10)

(19,-)#;#

(3,-)#while#

(15,-)#(#

d,i)

(10,-)#>#

(2,0)

(16,-)#)#

(20,-)#{#

(1,char)

(l,c)

(14,-)#=#

(l,i)

(4,-)#+#

(ERROR;)

(2,0)

(ERROR;)

(19,-)#;#

(1,strcat)

(15,-)#(#

(l,s)

(17,-)#,#

(ERROR,&)

(he)

(16,-)#)#

(19,-)#;#

(21,-)#}#

(1,return)

(l,s)

(19,-)#;#

5.實瞼總結(jié)分析

上機(jī)前應(yīng)做好準(zhǔn)備.即根據(jù)實習(xí)目的、要求和分析,選擇相應(yīng)的數(shù)據(jù)結(jié)構(gòu),使用c語言

參照算法中的流程編寫詞法分析的程序.將編好的程序上機(jī)進(jìn)行調(diào)試.注意調(diào)試的例子應(yīng)有

詞法正確的,也應(yīng)有詞法錯誤的或是超出所選數(shù)據(jù)結(jié)構(gòu)他國的.

現(xiàn)在我談一下關(guān)于做這個詞法分析程序的心得。這個詞法分析程序是全部用c語言的語

法寫的,幸虧我以前學(xué)過c語言。我認(rèn)為c語言是很好的語言。這次寫這個程序算是對我所

學(xué)的C語言的一次的檢驗,在寫程序的過程中,也遇

溫馨提示

  • 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. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論