簡體   English   中英

將 CFG 轉換為正則表達式

[英]converting CFG to regular expression

這是一個 CFG,它生成 0、1 或 0 和 1 這樣排列的字符串(001, 011) ,其中一個字符的計數必須大於另一個,例如0001111100000111

S → 0S1 | 0A | 0 | 1B | 1
A → 0A | 0
B → 1B | 1

我嘗試使用本指南將其轉換為正則表達式,但我被0S1 ,因為我在轉換0S1遇到了麻煩,因為在該指南中找不到與它類似的任何內容。

S → 0S1 | 0+ | 0 | 1+ | 1    
A → 0A | 0    = 0+
B → 1B | 1    = 1+

我之前的嘗試之一是0+0+1|0+1+1|1+|0+但它不接受我上面提到的字符串,如0001111100000111

即插即用

^(?!01$)(?!0011$)(?!000111$)(?!00001111$)(?=[01]{1,8}$)0*1*$

您無法將其完美地轉換為正則表達式,但您可以通過確保輸入的01數量不同來接近。 這最多匹配 8 位數字。

這個怎么運作

  • ^首先你從一行的開頭開始
  • (?!01$)確保字符不是01
  • (?!0011$)確保字符不是0011
  • 00011100001111相同
  • 然后確保有18零和一個(這是必需的,以確保輸入不是由更多數字組成,如000000111111 ,因為它們的對稱性未經驗證)
  • 然后匹配這些零和一直到行尾
  • 對於更長的輸入,您需要添加更多文本,最多10 位數字是這樣的: ^(?!01$)(?!0011$)(?!000111$)(?!00001111$)(?!0000011111$)(?=[01]{1,10}$)0*1*$ (通過再添加一個對稱驗證,你跳了 2)
  • 僅使用正則表達式是不可能通過其他方式實現的,請參閱說明。

解釋

AB很簡單,正如您看到的0+1+ S中第一個之后的連接也很容易: 00+ , 0 , 11+ , 1 ,所有這些都混合成一個導致(0+|1+) 問題在於第一個連接0S1

所以問題可以縮短為S = 0S1 這個語法是遞歸的。 但既不是left linear也不是right linear 要識別此語法的輸入,您需要“記住”您找到了多少個0 ,以便能夠匹配相同數量的1 ,但從正則語法(通常和正則表達式)創建的有限狀態機) 沒有計算歷史。 它們只是狀態和轉換,機器從一種狀態“跳躍”到另一種狀態,並且不記得在轉換中經過的“路徑”。

出於這個原因,您需要強大的機器(如下推自動機),可以從上下文無關的語法(如您的)構建。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM