五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

編譯原理中一個實用的詞法分析程序

2022-03-22 20:55 作者:我愛計算機科學(xué)  | 我要投稿

要進行程序的詞法分析,就要先看看自動機的定義:


圖2

那么,一個自動機到底起什么作用呢?用人話說,就是判斷計算機程序里面的每一個單詞是否輸入正確,以及這個單詞屬于什么類型。

本文在上述理論基礎(chǔ)上,借用一個網(wǎng)絡(luò)上的實用詞法分析程序,對編譯中的詞法分析原理進行一些解讀。

假設(shè)輸入如下一段待編譯的程序:

main()

{

int a=-5,b=4,j;

if(a>=b)

j=a-b;

else j=b-a;

}

圖3

對照這個程序,我們來理解圖1圖2的內(nèi)容。

假設(shè)我們現(xiàn)在碰到了這個程序的第一個字母m,那么這個m就是圖1中的初態(tài)S0,因為m后面既可以跟字母、數(shù)字,又可以跟符號什么的,而后面跟隨的字符類型不同,就可能決定了m開頭的這個字符串屬于不同的類型集合,比如m1、m=可能是一個變量,而ma可能是一個函數(shù)名,也可能是一個字符串等等,圖1中的K就代表不同類型的集合(變量、數(shù)字、字符串、保留字等等),那么,圖2的意思就是,由開始的字符出發(fā),當把這一串字符都讀入以后,然后判斷讀入的這串字符屬于什么類型(進入終態(tài)),當然,在逐個讀入字符的過程中,這個字符串有可能進入不同的狀態(tài),比如,i->變量;in->變量;int->關(guān)鍵字,讀到空格鍵結(jié)束。這個分析過程叫詞法分析。

圖3的程序經(jīng)過詞法分析以后要求輸出如下:

(2,”main”)?(5,”(”)?(5,”)”)

(5,”{”)?(1,”int”)?(2,”a”)

(4,”=”)?(3,”-5”)?(5,”,”)

(2,”b”)?(4,”=”)?(3,”4”)

(5,”,”)?(2,”j”)?(5,”;”)

(1,”if”)?(5,”(”)?(2,”a”)

(4,”>=”)?(2,”b”)?(5,”)”)

(2,”j”)?(4,”=”)?(2,”a”)

(4,”-”)?(2,”b”)?(5,”;”)

(1,”else”)?(2,”j”)?(4,”=”)

(2,”b”)?(4,”-”)?(2,”a”)

(5,”;”)?(5,”}”)

一、?實驗理論依據(jù)

(一)識別各種單詞符號

程序語言的單詞符號一般分為五種類型:

1:關(guān)鍵字(保留字/ 基本字)if 、while 、begin…

2:標識符:常量名、變量名、函數(shù)名…

3:常數(shù):34 、56.78 、true 、‘a(chǎn)’ 、…

4:運算符:+ 、- 、* 、/ 、〈 、and 、or 、….

5:界限符:, ; ( ) { } /*…

識別單詞:掌握單詞的構(gòu)成規(guī)則很重要

標識符的識別:字母| 下劃線+( 字母/ 數(shù)字/ 下劃線)

關(guān)鍵字的識別:與標識符相同,最后查表

常數(shù)的識別

界符和算符的識別

大多數(shù)程序設(shè)計語言的單詞符號都可以用轉(zhuǎn)換圖來識別,如圖4

圖4

詞法分析器輸出的單詞符號常常表示為二元式:(單詞種別,單詞符號的屬性值)

單詞種別通常用整數(shù)編碼,如1 代表關(guān)鍵字,2 代表標識符等

(二)超前搜索方法

詞法分析時,常常會用到超前搜索方法。

如當前待分析字符串為“a>+” ,當前字符為“>” ,此時,分析器倒底是將其分析為大于關(guān)系運算符還是大于等于關(guān)系運算符呢?

顯然,只有知道下一個字符是什么才能下結(jié)論。于是分析器讀入下一個字符’+’ ,這時可知應(yīng)將’>’ 解釋為大于運算符。但此時,超前讀了一個字符’+’ ,所以要回退一個字符,詞法分析器才能正常運行。又比如:‘+’ 分析為正號還是加法符號

(三)預(yù)處理

預(yù)處理工作包括對空白符、跳格符、回車符和換行符等編輯性字符的處理,及刪除注解等。由一個預(yù)處理子程序來完成。

二、詞法分析器的設(shè)計

1、 設(shè)計方法:

2、 寫出該語言的詞法規(guī)則。

3、 把詞法規(guī)則轉(zhuǎn)換為相應(yīng)的狀態(tài)轉(zhuǎn)換圖。

4、 把各轉(zhuǎn)換圖的初態(tài)連在一起,構(gòu)成識別該語言的自動機

5、 設(shè)計掃描器

6、 把掃描器作為語法分析的一個過程,當語法分析需要一個單詞時,就調(diào)用掃描器。

掃描器從初態(tài)出發(fā),當識別一個單詞后便進入終態(tài),送出二元式

#include <stdio.h>

#include <string.h>

FILE *fp;

char cbuffer;

char *key[8]={"if","else","for","while","do","return","break","continue"};

int atype,id=4;

int isalpha( char c) 判斷讀入的字符是否是字母

{

if((c<='z')&&(c>='a')||(c<='Z')&&(c>='A'))

return 1;

else return 0;

}

int isdigit(char c)

{

if(c>='0'&&c<='9')

return 1;

else return 0;

}

int search(char searchchar[ ],int wordtype) /*判斷單詞是保留字還是標識符*/

{ 保留字有8個

int i=0;

int p;

switch (wordtype)

{

case 1:for (i=0;i<=7;i++)

{

if (strcmp(key[i],searchchar)==0)

{ p=i+1; break; } /*是保留字則p為非0且不重復(fù)的整數(shù)*/

else p=0; /*不是保留字則用于返回的p=0*/

}

return(p);

}

}

char alphaprocess(char buffer)

{ int atype; /*保留字數(shù)組中的位置*/

int i=-1;

char alphatp[20];

while ((isalpha(buffer))||(isdigit(buffer))||buffer=='_')

{

alphatp[++i]=buffer;

buffer=fgetc(fp);

} /*讀一個完整的單詞放入alphatp數(shù)組中*/

alphatp[i+1]='\0';

atype=search(alphatp,1);/*對此單詞調(diào)用search函數(shù)判斷類型*/

if(atype!=0)

{ printf("(%d,\"%s\")\n",atype-1,alphatp); id=1; } 是保留字則輸出類型1

else

{ printf("(2,\"%s\")\n",alphatp); id=2; } 是函數(shù)名、標識符等則輸出類型2

return (buffer);

}

char digitprocess(char buffer) 數(shù)字只能全部由0-9構(gòu)成

{

int i=-1;

char digittp[20];

while ((isdigit(buffer))||buffer=='.')?/*1 判斷小數(shù)*/

{

digittp[++i]=buffer;

buffer=fgetc(fp);

}

digittp[i+1]='\0';

printf("(3,\"%s\")\n",digittp); 是數(shù)字則輸出類型3

id=3;

return(buffer);

}

char otherprocess(char buffer)

{

char ch[20];

ch[0]=buffer;

ch[1]='\0';

if(ch[0]==','||ch[0]==';'||ch[0]=='{'||ch[0]=='}'||ch[0]=='('||ch[0]==')')

{ printf("(5,\"%s\")\n",ch); 是界符則輸出類型5

buffer=fgetc(fp);

id=5;

return(buffer);}

if(ch[0]=='/')

{

buffer=fgetc(fp);

if(buffer=='*') /*2 區(qū)分注釋符號和除號*/

{

ch[1]=buffer;

buffer=fgetc(fp);

while(buffer!='*')

{

buffer=fgetc(fp);

}

ch[2]=buffer;

buffer=fgetc(fp);

if(buffer=='/')

{

ch[3]=buffer;

ch[4]='\0';

}

printf("(5,\"%s\")\n",ch);

}

else{

printf("(4,\"%s\")\n",ch); 是運算符輸出類型4

id=4;

return(buffer);

}

buffer=fgetc(fp);

id=5;

return(buffer);

}

if(ch[0]=='*')

{ printf("(4,\"%s\")\n",ch);

buffer=fgetc(fp);

id=4;

return(buffer);

}

if(ch[0]=='='||ch[0]=='!'||ch[0]=='<'||ch[0]=='>')

{ buffer=fgetc(fp);

if(buffer=='=')

{ ch[1]=buffer;

ch[2]='\0';

printf("(4,\"%s\")\n",ch);

}

else

{ printf("(4,\"%s\")\n",ch);

id=4;

return(buffer);

}

buffer=fgetc(fp);

id=4;

return(buffer);

}

if(ch[0]=='+'||ch[0]=='-')

{ if(id==4) /*在當前符號以前是運算符,則此時為正負號*/

{ buffer=fgetc(fp);

ch[1]=buffer;

ch[2]='\0';

printf("(3,\"%s\")\n",ch);

id=3;

buffer=fgetc(fp);

return(buffer);

}

ch[1]='\0';

printf("(4,\"%s\")\n",ch);

buffer=fgetc(fp);

id=4;

return(buffer);

}

if(ch[0]=='#')?/*3 識別頭文件*/

{

char t[20];

int i=0;

t[0]=ch[0];

buffer=fgetc(fp);

while((isalpha(buffer))||buffer==' '||buffer=='<'||buffer=='>')

{

t[++i]=buffer;

buffer=fgetc(fp);

}

t[i+1]='\0';

printf("(6,\"%s\")\n",t);

id=6;

return (buffer);

}

if(ch[0]=='\\')?/*4 識別轉(zhuǎn)義符號*/

{

buffer=fgetc(fp);

ch[1]=buffer;

printf("(6,\"%s\")\n",ch); 轉(zhuǎn)義符號輸出類型6

buffer=fgetc(fp);

return(buffer);

}

if(ch[0]=='|'||ch[0]=='&')?/*5 判斷或與*/

{

buffer=fgetc(fp);

if(ch[0]==buffer)

{

ch[1]=buffer;

}

ch[2]='\0';

printf("(4,\"%s\")\n",ch);

buffer=fgetc(fp);

return(buffer);

}

if(ch[0]=='"'||ch[0]=='\'')?/*6 判斷雙引號和單引號*/

{

printf("(5,\"%s\")\n",ch);

id=5;

buffer=fgetc(fp);

return(buffer);

}

}

int main()

{

if ((fp=fopen("example.c","r"))==NULL) /*只讀方式打開一個文件*/

printf("error");

else

{

cbuffer = fgetc(fp); /*fgetc( )函數(shù):從磁盤文件讀取一個字符*/

while (cbuffer!=EOF)

{

if(cbuffer==' '||cbuffer=='\n') /*掠過空格和回車符*/

cbuffer=fgetc(fp);

else

if(isalpha(cbuffer))

cbuffer=alphaprocess(cbuffer);

else

if (isdigit(cbuffer))

cbuffer=digitprocess(cbuffer);

else cbuffer=otherprocess(cbuffer);

}

}

return 0;

}

程序運行結(jié)果:

縱觀整個詞法分析程序,難度并不大,就是判斷保留字、標識符、數(shù)字、運算符和界符,程序里面還有判斷轉(zhuǎn)義字符和注釋符的功能,這么一個簡單的程序,卻可以讓我們真正了解實際的編譯程序大概是怎么構(gòu)成的,在此基礎(chǔ)上,就可以開發(fā)出新的語言,等等。


編譯原理中一個實用的詞法分析程序的評論 (共 條)

分享到微博請遵守國家法律
米易县| 兴和县| 桐柏县| 卓尼县| 平邑县| 荥经县| 惠来县| 新丰县| 吴川市| 阆中市| 霞浦县| 响水县| 双牌县| 瑞昌市| 安顺市| 海口市| 常熟市| 北碚区| 盐城市| 余干县| 蚌埠市| 远安县| 常州市| 靖安县| 东至县| 灯塔市| 刚察县| 朔州市| 赤壁市| 东乡| 山西省| 那曲县| 曲阳县| 德惠市| 偃师市| 鄂温| 铁岭县| 永春县| 健康| 南丰县| 梅河口市|