第三步,進行有限自動機的搭建操做 正則表達式
咱們要構造一個有限自動機,而這個自動機是用一個表達式來構建的,很容易能夠想到,咱們徹底能夠把表達式耳的操做數看作一個小號的自動機(或者說是狀態圖),而操做符的效果是對狀態圖進行修飾,或者鏈接兩個狀態圖,當咱們執行完表達式解析後,就能夠獲得一個完整的表達式的狀態圖了。 架構
像是算術表達式這種給定輸入只有一個結果的,表示成樹的形式就能夠知足要求了,而正則表達式對給定輸入會有多個結果(雖然一般咱們只要第一個結果),也確實只能用圖表示。 函數
操做數有三種,連續字符;包含;分組提取比較。都用以下狀態圖表示: spa
注意我把全部的操做都放在邊上,狀態節點處不作任何行爲。 指針
每個操做數所對應的狀態圖,都各有惟一的進入節點和退出節點(咱們不須要關係狀態圖內部的狀況) 字符串
'?'操做符,也便是可選操做符,它的效果以下(從操做數修飾的來): 模板
'??'的效果相似,可是ε邊的優先級較高(圖中靠上的邊優先級高) 循環
相似的,還有'*'、'*?': 方法
輸出節點爲新建節點,'*?'的ε邊的優先級較高 im
以及'+'、'+?':
輸出節點爲新建節點,'+?'的ε邊的優先級較高
隱藏的「鏈接」操做符:
左倆操做數1,右倆操做數2
選擇操做符,"|":
上面一排爲操做數1,下面一排爲操做數2
分組"( )":
黑色分別表示報告分組的起止點的字符串位置
通常不分組的括號"(: )",這個徹底沒啥操做,不用修飾,直接返回操做數就行了
限定次數的操做符(是的,看作操做符)"{a,b}":
紅色表示進入循環,藍色累計次數,綠色退出循環
如此,咱們就獲得了生成操做數的方法,以及全部操做符的操做效果
結合這些,咱們就能夠經過分析表達式來生成一個完整的有限自動機了。
分析表達式的方法麼,天然是不少的,算術表達式分析器稍微改改就能拿來分析以前獲得的列表了,無非是新的運算符,新的運算函數(函數指針真是棒啊真是棒)、新的操做數而已,總體架構變化極小。
固然,我是用的我以前寫的一個可定製的表達式解析器,那是一個模板類,支持一元運算符(前置、後置)、二元運算符(左結合、右結合)、括號(普通括號、後綴括號),只要把這些運算符和它們對應的處理函數註冊進去就好了。(還能夠註冊操做數生成函數、操做符生成函數、銷燬函數等一系列函數)
因此具體寫法就很少說了,拿個算術表達式解析器慢慢改就是。
下一帖,第四步。