1. 程式人生 > >正則文法和正則表示式的相互轉化

正則文法和正則表示式的相互轉化

一、正則表示式轉換成正則文法


例1.(a|b)*a(a|b)(a|b)


轉換成左線性正則文法:
(1).S->Aa|Ab
(2).A->Ba|Bb
(3).B->Ca
(4).C->Ca|Cb|ε


由觀察發現,一個正則表示式轉換成左線性正則文法,需要從右邊開始分解。
(1).Aa型最簡單,為一個連線運算,可化為S->Aa。
(2).A(a|b)型為一個選擇運算,根據連線在選擇上的分配律,可化為S->Aa|Ab。
(3).Aa*型,根據*運算的定義,可化為S->Sa,S繼續作為下一級的非終結符號,若已經分析到最左邊,則B->Ba|ε。
(4).遞迴上述步驟。


轉換成右線性正則文法:
(1).S->aS|bS
(2).S->aA
(3).A->aB|bB
(4).B->a|b


由觀察發現,一個正則表示式轉換成右線性正則文法,需要從左邊開始分解。
(1).aA型,可化為S->aA
(2).(a|b)A型,可化為S->aA|bA
(3).a*A型,可化為S->aS,S繼續作為下一級的非終結符號,若已經分析到最右邊,則B->aB|ε。


總結1:
  (1).由上得知,分解的步驟的書目和運算元有關,N個運算元(單個字元或括號組成的字元),需要分解N步。
  (2).由轉換為左線性正則文法和右線性正則文法的過程中得知,連線和選擇都較容易,主要在重複運算當中,需要用上一級到非終結符號來繼續產生下一級,當處於最後一級時,需要另作處理。




例2.a*aba*a


左線性:
(1).S->Aa
(2).A->Aa
(3).A->Bb
(4).B->Ca
(5).D->Da|ε


右線性:
(1).S->aS
(2).S->aA
(3).A->bB
(4).B->aB
(5).B->a


二、正則文法轉換成正則表示式


例3.


(1).S->aS
(2).S->aA
(3).A->bB
(4).B->aB
(5).B->a


兩個轉換互為逆操作,逆向分析而已。
(1).首先觀察得知,該文法為右線性正則文法。
(2).按照轉換規則進行串接。
  S->aS => S->a*aA => S->a*abB => S->a*aba*B => S->a*aba*a