這一章的內容有:
這一章大家會看到乙個完整的大的狀態機,用於識別redy語言中的所有詞文。
在前面我們基本上講完了redy中大部份詞文,其中有變數,字串,注釋,整數,長整數,浮點數,運算子。但還有一小部份詞文在前面還沒有提到過,分別為:關鍵字(如if,else,while,for等)
語句分隔符(符號『;『和換行符),在redy中每一條語句占用一行(組合語句除外),如果相把多條語句寫在一行的,那麼就需要用『;』來分開。
白空格(由多個空格或製表符組成),白空格對於我們語言來說沒有用處,所以當我們識別到白空格時就把它拋棄。
因為變數識別裡面,會一同識別關鍵字,所以關鍵字和識別是在識別到詞文變數以後再來進行第二次判斷,最終到底裡什麼型別的關鍵字,或者還是變數。
對於分隔符和白空格,這裡就不細說,他們的識別都非常的簡單,我只是給出他們的狀態機
在前面我們已經講過整數,長整數,浮點數的合併,其實這已經完成了七成的工作了,後面的幾個狀態機的合併要簡單得多,為了表述方便,我們把整數,長整數,浮點數都稱為數。下一步的目標是得到乙個大的狀態機。
現在我們總共有字串,變數,數,運算子,注釋,語句分格符,白空格這麼七個小的狀態機,為了實現綜合識別,我們需要把它們合併在一起,相比前面的整數與浮點數的合併來說,這次合併要簡單的多,如果仔細觀察可以發現,字串識別的狀態機的開始狀態只在雙引號下發生狀態轉移
語句分格符狀態機的開始狀態只在符號『;』和符號『\n『發生狀態轉移
數識別的汰態機的開始狀態只在數字0到9和點號下發生狀態轉移
變數識別的狀態機的開始狀態只在字母a到z,字母a到z,下劃線,符號『@'下發生狀態轉移
白空格識別的狀態機的開始狀態只在空白符和製表符下發生狀態轉移
注釋識別的狀態機的開始符叼只在符號『/』下發生狀態轉移
上面這6個狀態機的開始狀態能識別的輸入型別兩兩不同,沒有衝突,所以合併這6個非常的簡單
七個狀態機已經討論了6個,只剩下乙個運算子,而這6個狀態機與運算子突衝的也只有數的點號,這次衝突處理起來都很簡單。只需要為衝突的狀態建立乙個等價的新狀態,新狀態的後繼狀態者是單個,沒有組合狀態。具體的合併就不細講,下面我給出狀態圖:
圖1
圖2
由於在一張圖中不好繪製,所以繪製了兩張狀態圖。從上面的狀態圖,大家可以看出,七個狀態機在合併後,總共增加了二個狀態,為這二個狀態構造狀態鏈,把這7個狀態機連線在一起,乙個大的綜合性的狀態機就這麼形成了。
二個狀態裡面,最複雜的是lexicalbegin,因為它能接受的輸入型別最多,第二個狀態lexicaipoint能接受的型別只有乙個,構造成來非常簡單首先,我們來申明這兩個狀態
/*merge parts*/
extern struct state me_begin;
extern struct state me_period;
第二步,為每乙個狀態構造狀態鏈a)狀態lexicalbegin
輸入型別有下面這麼27種:符號@,下畫線,以及字母 (to_id)
數字0 (d_0)
數字1到9 (d1_9)
雙引號 (d_quote)
空格和製表符 (ws)
換行符 (newline)
分號 (semicolon)
19種運算子
除以上字元以外的所有字元'(' ')' '[' ']' '.' ','
'+' '-' '~' '*' '/' '%'
'' '=' '!'
'&' '^' '|'
狀態lexicalbegin的輸入型別對映陣列為:
enum merge_input_type
;char merge_input_map[ascii_num]=
;
後繼狀態為:
struct state* me_begin_targets=
;
狀態lexicalbegin為:
struct state me_begin=
;
b)狀態lexicalpoint只在輸入型別d0_9下轉移到float::fractionbegin.
我們也為lexicalpoint建立乙個輸入對映陣列
char me_period_input_map[ascii_num]=
;
後繼狀態為:
狀態lexicalpointstruct state* me_period_targtes=
;
到現在為止,我們已經把兩個狀態的狀態鏈資料構造完成,七個小的狀態機就被這兩個狀態鏈結了在一起,形成乙個大的綜合性的狀態機,該狀態機可以識別redy語言中的所有詞文。struct state me_period=
;
這裡貼幾張執行的結果圖來結大家看看,這部份的**可以在tutorial/lexical/merge2下面找到
詞法分析 NFA語言識別
對於給出的nfa和輸入的字串,判斷字串是否是nfa識別的語言。輸入有多組資料。每組資料的第一行是兩個整數n n 50 和m m 27 表示nfa有n個狀態,以及字母表有m 1個字元。nfa的n個狀態用整數0 n 1表示,狀態0為起始狀態。字母表包含小寫英文本母的前m 1個字元。接下來的n行,每行有m...
關鍵字詞法識別
本人想做乙個自己的指令碼語言,但是又不想使用lex之類的詞法分析器,又不想自己畫狀態轉換圖,所以,寫了下面的一段程式,它的功能是 有如下若干個關鍵字 char keywords 1024 通過迴圈呼叫 bool addfsm char reg,int nstart,int nfinal 會自動產生乙...
視覺識別入門之識別 口罩識別
時隔多月未動筆寫文,一是自己初學很多不明白的地方都在快速地學習,從現在開始定期寫文,我是水彩筆一根,但確是對著生活和學習充滿極度熱情的人,希望能帶著讀者們一起進步,一起學習,三人行必有我師焉!都說寫文的都是大佬級的人物才寫的,我這種水彩筆本不應該淌這趟水,不過在自己學習道路上有很多碩博的朋友以及現在...