簡易詞法分析器

2021-07-13 09:48:29 字數 2817 閱讀 3532

當我們寫好一段**之後,我們通常的操作是:編譯,鏈結, 執行。

而在編譯階段,我們的編譯器就會進行詞法分析這個階段,來分析有沒有詞法錯誤。

而單詞符號一般分為五大類:

1.關鍵字,也稱保留字,比如:if,else,sizeof等(c語言中由32個關鍵字,在這裡也就不一一枚舉);

2.識別符號,用來表示各種名字,如:常量名,變數名,函式名等;

3.常數,各種型別的常數,如:23,3.1415,ture,"abc"等;

4.運算子,如:+,*,<=等;

5.界符,如:逗號,分號等。

因此,詞法分析程式採用二元式的形式來輸出。

比如:(1,「if」)這就是說當前遇到了乙個關鍵字"if"。

要達到上面的這種輸出模式,那麼首先要進行的就是對一段**我們應該怎樣去識別它到底是屬於上述5種型別的哪一類。

接下來,我們進行乙個簡單的分析:

我們可以利用檔案指標,再使用getchar()來逐個讀取字元來進行判斷。

但是,我們這5種型別的單詞符號不一定都是乙個字元呀!而getchar()只能獲取當前指標所指的下乙個字元。

所以,我們應該首先定義乙個來存放這一串字元的中間陣列。並且可以將它作為乙個全域性變數。

但是,getchar()每次都會自動將檔案指標下移,所以當我們對乙個單詞符號列印完之後,我們應該利用sweek(,,)對指標回退乙個字元,後邊**會介紹這個函式。

在這裡可能有的人就想不通了,為什麼要回退乙個字元呢?

int x=5;

首先,獲取字元'i',判斷其為字母後,相繼獲取'n','t'直到獲取到空格,然後與之前定義好的關鍵字陣列相比較,發現他是關鍵字,並且列印.

此時,檔案指標指向了空格,再一次獲取到'x',同理當判斷到'='的時候,兩者不屬於同一符號.將x列印.

此時,檔案指標指向了'=',這是問題就出現了,當我們要接著判斷時,我們獲取到的字元是'5',而不是'='(getchar()會自動將檔案指標下移動,先移動,再獲取),所以程式就會出現紕漏.所以,就需要引入回退.

之前我提到過,在c語言中有32個關鍵字,所以我們可以定義乙個陣列來存放這些關鍵字。

當我們用中間陣列和這個陣列進行比較時,如果有相同的,那麼我們就可以確定它就是乙個關鍵字;反之,它就是識別符號。

而且,在這裡我們要清楚,識別符號只能是字母或者下劃線開頭。

所以,在這裡我們需要乙個單獨判斷字母的函式和乙個判斷關鍵字的函式。

在這裡我還想說的是:我們還可以將這32個關鍵字按首字母順序排列,並且利用上排序演算法,就可以節約大量的時間。(這個下邊**沒有給出,只作為參考)。

常數相對來說還是比較好判斷的,只要當我們獲取到的第乙個字元是數字,那麼它就是常數。(這裡只考慮數字,不考慮ture等其他常數)

所以,在這裡我們需要乙個判斷數字的函式。

就運算子來說,存在一目,二目(這裡不考慮其他的運算子)。

為什麼我要把這兩個放在一起來說呢。因為,我們可以對這兩個判斷分別寫乙個函式,來利用switch語句一一對比。

所以這裡我們需要兩個函式分別來判斷運算子和界符。

最後,我們對這些函式進行乙個簡單的邏輯拼接就可以實現我們的詞法分析器。具體的操作請看下邊的**,我會進行詳細解釋。

//1.關鍵字,保留字  main int double等 

//2.識別符號 自己定義的變數名,常量名等

//3.常數

//4.運算子+ - < > * /等

//5.界符(,;)

#include #include #include #include #define max 37

char *position[max]=; //自定義關鍵字

char mid[20]; //中間緩衝區

void initfunctionmid() //緩衝區清除 每列印一次就對中間陣列進行清空

int judgeletter(char ch)//判斷字母

int judgenumber(char ch) //判斷數字

int judgedelimiter(char ch) //判斷界符

': case '[':

case ']':

case '"': return 1;

default:return 0; }}

int judgeoperator(char ch) //判斷運算子

} int judgekeyword(char *mid)//判斷關鍵字

if(strlen(mid)!=0)

print(4);

fseek(fp,-1,seek_cur);

initfunctionmid();

i=0;

//判斷界符

ch=fgetc(fp);

if(judgedelimiter(ch)==1)

if(strlen(mid)==0)

fseek(fp,-1,seek_cur);

initfunctionmid();

i=0;

}}int main()

fseek(fp,-1,seek_cur);//seek_end檔案末尾 seek_cur檔案當前指標位置

wholejudge(fp);

fclose(fp);

return 0;

}

最重要的是,這段**執行前,一定要建立乙個文字檔案,將要處理的**放進去哦!!!

比如,判錯,變數名還可以是下劃線開頭,三目運算子判斷等等。

C語言 簡易詞法分析器

include include include int p,m,syn,n,sum p和m,作用相當於指標,用來指向下乙個字元或回退乙個字元,syn用於判別字元種類。n為迴圈控制變數,sum用來判別整型數是否溢位。char token 10 prog 80 全域性變數,乙個陣列用來接收鍵盤輸入,另乙...

詞法分析器

這是我自己的第一篇部落格,就分享一下最近才做完的編譯原理實驗,詞法分析器。本次實驗中我用mysql資料庫儲存自動機狀態表,這樣做的目的只是為了在後續的課設中可以繼續使用現在的 這一段 並不是太完善,發出來只是為了太完善。裡面還有很多問題,比如對字元和字串的識別,不知道為什麼資料庫無法將 和 轉換到我...

詞法分析器

include using namespace std const int maxn 1e3 10 int n 輸入文字的行數 char buffer maxn maxn 緩衝區 int len maxn 輸入文字每行的列數 struct out 輸出格式 out string a,int b re...