【計算理論】上下文無關語法 CFG ( CFG 設計示例 | CFG 歧義性 | Chomsky 範式 | 上下文無關語法 轉爲 Chomsky 範式 )





I . 上下文無關語法 設計 示例



1 . 上下文無關語法 設計要求 : 設計一個語法 , 使用該語法生成語言 ww , 該 ww 語言的字符串的開始和結尾的字符是相同的 ;


2 . 設計方法 : 非確定性優先自動機 ( NFA ) 識別某語言 , 將 NFA 轉爲 確定性優先自動機 ( DFA ) , 然後將 DFA 轉爲 上下文無關語法 ;


3 . 語法設計要求分析 :

  • 開始字符 要麼是 00 , 要麼就是 11 ;

  • 如果開始字符是 00 , 對應的結尾字符也是 00 ;

  • 如果開始字符是 11 , 對應的結尾字符也是 11 ;


4 . 初始狀態 SS 規則 : 上述語法描述轉爲規則 如下 , 其中 SS 爲初始狀態 ;

S0S01S1S \to 0S'0 | 1S'1


5 . SS' 規則 : SS' 表示中間的字符串 , 這個 SS' 字符串可以是任意字符串 , 根據下面的規則可以生成任意的 0,10,1 組成的字符串 ;

S0S1SεS' \to 0S' | 1S' | \varepsilon





II . 上下文無關語法 的歧義性



給出如下上下文無關語法 ( CFG ) :

ExpressionExpression+ExpressionExpression×ExpressionExpressionaExpression \to Expression + Expression | Expression \times Expression | Expression | a

語法的含義是 :

  • ExpressionExpression 可以被 Expression+ExpressionExpression + Expression 替換 ;
  • ExpressionExpression 可以被 Expression×ExpressionExpression \times Expression 替換 ;
  • ExpressionExpression 可以被 ExpressionExpression 替換 ;
  • ExpressionExpression 可以被 aa 替換 ;

1 . 語法的有歧義性 : 同樣的一個字符串 , 可以有不同的語法分析樹 ;


① 語法分析樹 1 :

在這裏插入圖片描述

2 . 在上述的 語法分析樹中 , 加法優先級高於乘法 , 這是錯誤的分析 ;


② 語法分析樹 2 :

在這裏插入圖片描述

在上述的 語法分析樹中 , 乘法優先級高於加法 , 這是正確的分析 ;


3 . 語法歧義性分析 : 上述語法中是無法區分 加法 和 乘法的優先級的 , 因此這裏得到兩個完全不一致得我語法分析樹 , 那麼該語法是有歧義的 ;


4 . 與代數表達式語法對比 : 之前講的代數表達式是好的語法 , 乘法 和 加法的優先級 也體現出來 , 乘法優先級高於加法 , 括號的優先級高於乘法 ;


① 代數表達式語法 :

  • ExpressionExpression+TermTermExpression \to Expression + Term \quad | \quad Term
  • TermTerm×FactorFactorTerm \to Term \times Factor \quad | \quad Factor
  • FactorExpressionaFactor \to Expression \quad | \quad a

② 代數表達式語法分析樹 : 這個語法分析樹是唯一的 , 沒有其它的形式 , 該語法是沒有歧義的 ;

在這裏插入圖片描述

③ 有歧義的語法 : 在本節的語法中 , 無法區分 加法 和 乘法的優先級 , 該語法是有歧義的 ;


5 . 總結 : 如果語法有歧義 , 那麼中間的字符串有歧義 ; 沒有算法 可以判定 上下文無關語法 是否有歧義 ; 有些語法天生就是有歧義的 , 但可以通過某種方法去掉語法中的歧義性 ;





III . Chomsky 範式



1 . Chomsky 範式 : 上下文無關語法中的任何規則都是如下格式 ;


ABCA \to BC : AA 是 變元 , B,CB,C 也是變元 ;

AaA \to a : AA 是 變元 , aa 是常元 , AA 可以被終端字符替換 ;

B,CB ,C 變元要求 : B,CB, C 變元一定不能是開始變元 ;

SεS \to \varepsilon : SS 開始變元可以爲空 ;

不能出現 變元 \to 變元 單個變元 到 單個變元不允許出現 ;


2 . SεS \to \varepsilon 規則 說明 :


① 語言包含空字符串 : 如果上下文無關語法包含空字符串時 , 一定需要 SεS \to \varepsilon 規則 ;

② 語言不包含空字符串 : 如果上下文無關語法不包含空字符串時 , 一定不需要 SεS \to \varepsilon 規則 ;

③ 規則總結 : 該規則決定 上下文無關語法 所生成的語言 是否包含 空字符串 , 如果包含必須要這個規則 , 如果不包含空字符串一定不要這個規則 ;





IV . 上下文無關語法 轉爲 Chomsky 範式



Chomsky 範式規則 的 上下文無關語法 生成的語言 的語法分析樹 除葉子節點之外 都 是二叉樹 , 葉子節點 與 上一層都是 一對一的節點 ;

任何 上下文無關語法 , 都可以找到一個 Chomsky 範式 與其等價 ;

任何 上下文無關語法 的語法分析樹 都可以進行修剪 , 修剪後的樹都是二叉樹 ;



上下文無關語法 轉爲 Chomsky 範式 步驟 :



1 . 添加開始變元及規則 : 添加一個新的開始變元 S0S_0 , 以及配套的規則 S0SS_0 \to S , SS 是舊的開始變元 ;


① 目的 : 添加開始變元的目的是 開始變元 永遠出現在左邊 ;

② Chomsky 範式 中 , 開始變元始終在規則的左邊 , 不允許開始變元在規則的右側 ;

③ 對應 Chomsky 範式 規則 : ABCA \to BC 規則 , AA 是 變元 , B,CB,C 也是變元 , 並且 B,CB,C 不允許是開始變元 ;


2 . 消除所有的 ε\varepsilon 規則 : 消除所有從 變元 到 空字符 的規則 ;


3 . 消除所有的 ABA \to B 規則 : 消除所有從 單個變元 到 單個變元的 單條規則 , 允許從 單個變元 到 多個變元或常元 ;

ABA \to B 是需要刪除的 , ABSA \to BS 可以保留 ;





V . 上下文無關語法 轉爲 Chomsky 範式 示例



將 上下文無關語法 G6G6 轉爲 Chomsky 範式 :

  • SASAaBS \to ASA | aB
  • ABSA \to B|S
  • BbεB \to b|\varepsilon

轉換過程如下 :


1 . 添加新的開始變元 : S0S_0 , 舊的開始變元 SS 就不是開始變元了 ;

當前的語法格式如下 :

  • S0SS_0 \to S
  • SASAaBS \to ASA | aB
  • ABSA \to B|S
  • BbεB \to b|\varepsilon

2 . 消除 ε\varepsilon 規則 :


消除 ε\varepsilon 規則 原則 : 假設有規則 CεC \to \varepsilon , DuCvD \to uCv , 如果要刪除 ε\varepsilon 規則 , 需要實現 消除前後具有 相同的替換效果 , 將規則改爲 DuvD \to uv 即可刪除 ε\varepsilon 相關規則 ;
( 消除前後 , 替換效果必須一致 )



3 . 消除 BbεB \to b|\varepsilon 中的 ε\varepsilon : 會影響 SASAaBS \to ASA | aBABSA \to B|S 兩條規則中涉及到了 BB 變元 , 消除的原則是 " 消除前後 , 替換效果必須一致 " ;


3.1 . SASAaBS \to ASA | aB 規則消除 ε\varepsilon 分析 : 這裏討論 消除 BbεB \to b|\varepsilon 規則中的 BεB \to \varepsilon 規則 對 aBaB 的影響 ;


① 消除 BεB \to \varepsilon 規則前分析 : 使用 BbεB \to b|\varepsilon 規則 對 aBaB 進行替換 有兩種情況 , 分別是 abab , aa , 兩種情況 ;


② 消除 BεB \to \varepsilon 規則後分析 : 如果要消除 BεB \to \varepsilon 規則 , 那麼消除後的規則是 BbB \to b , 使用 BbB \to b 規則對 aBaB 進行替換 , 其替換 結果必須是 abab , aa , 兩種情況 ;


分析 abab , aa 兩種結果 :

  • aBaB 使用 BbB \to b 規則替換 , 可以得到 abab ;

  • aa 替換結果無法獲取 , 此時需要在 aBaB 的平級 , 再次添加 aa 即可達到上述效果 ;

aBaB 最終修改方案 :aBaB 改爲 aBaaB|a , 使用 BbB \to b 規則替換 aBaaB|a 的結果是 abab , aa , 與上述消除 BεB \to \varepsilon 規則 前的結果一致 ;


SASAaBS \to ASA | aB 規則對應的消除 BεB \to \varepsilon 規則後的結果爲

SASAaBaS \to ASA | aB | a


④ 當前的語法格式如下 : 注意 還沒有討論 ABSA \to B|S 規則中的 BB , BbεB \to b|\varepsilon 規則中的 ε\varepsilon 還不能刪除 ;

  • S0SS_0 \to S
  • SASAaBaS \to ASA | aB | a
  • ABSA \to B|S : 注意此時該規則不完善 , 還沒有刪除 ε\varepsilon ;
  • BbB \to b


3.2 . ABSA \to B|S 規則消除 ε\varepsilon 分析 : 這裏討論 消除 BbεB \to b|\varepsilon 規則中的 BεB \to \varepsilon 規則 對 BB 的影響 ;


① 消除 BεB \to \varepsilon 規則前分析 : 使用 BbεB \to b|\varepsilon 規則 對 BB 進行替換 有兩種情況 , 分別是 bb , ε\varepsilon , 兩種情況 ;


② 消除 BεB \to \varepsilon 規則後分析 : 如果要消除 BεB \to \varepsilon 規則 , 那麼消除後的規則是 BbB \to b , 使用 BbB \to b 規則對 BB 進行替換 , 其替換 結果必須是 bb , ε\varepsilon , 兩種情況 ;


分析 bb , ε\varepsilon 兩種結果 :

  • BB 使用 BbB \to b 規則替換 , 可以得到 bb ;

  • ε\varepsilon 替換結果無法獲取 , 此時需要在 BB 的平級 , 再次添加 ε\varepsilon 即可達到上述效果 ;

BB 最終修改方案 :BB 改爲 BεB|\varepsilon , 使用 BbB \to b 規則替換 BεB|\varepsilon 的結果是 bb , ε\varepsilon , 與上述消除 BεB \to \varepsilon 規則 前的結果一致 ;


ABSA \to B|S 規則對應的消除 BεB \to \varepsilon 規則後的結果爲

ABεSA \to B| \varepsilon|S


④ 當前的語法格式如下 : 注意 還沒有討論 ABSA \to B|S 規則中的 BB , BbεB \to b|\varepsilon 規則中的 ε\varepsilon 還不能刪除 ;

  • S0SS_0 \to S
  • SASAaBaS \to ASA | aB | a
  • ABεSA \to B| \varepsilon |S
  • BbB \to b


4 . 消除 ABεSA \to B| \varepsilon |S 中的 ε\varepsilon : 會影響 SASAaBaS \to ASA | aB | a 規則中涉及到了 AA 變元 , 消除的原則是 " 消除前後 , 替換效果必須一致 " ;


① 消除 ASAASA 中的 ε\varepsilon , 添加以下項即可 :

  • 第一個 AA 通過 ε\varepsilon 代替 : 添加 SASA 項 ;

  • 第二個 AA 通過 ε\varepsilon 代替 : 添加 ASAS 項 ;

  • 兩個 AA 都通過 ε\varepsilon 代替 : 是 SS , 可以不同寫 , SSS \to S 沒啥意義 ;


SASAaBaS \to ASA | aB | a 規則對應的消除 AεA \to \varepsilon 規則後的結果爲 :

SASAASSAaBaS \to ASA | AS | SA | aB | a


③ 當前的語法格式如下 :

  • S0SS_0 \to S
  • SASAASSAaBaS \to ASA | AS | SA | aB | a
  • ABSA \to B| S
  • BbB \to b


5 . 消除 ABA \to B 規則 :


假設要消除 CDC \to D 規則 : 如果語法中有 DWD \to W 規則 , 那麼如果消除 CDC \to D , 需要將 CWC \to W 體現出來 ;


消除 ABA \to B 規則 , 檢查 BB 出現在規則左邊的情況 , 這裏有 BbB \to b 規則 , 需要 添加 AbA\to b 規則後 , 即可刪除 ABA \to B 規則 ;


刪除前規則 :

  • S0SS_0 \to S
  • SASAASSAaBaS \to ASA | AS | SA | aB | a
  • ABSA \to B| S
  • BbB \to b

刪除後規則如下 :

  • S0SS_0 \to S
  • SASAASSAaBaS \to ASA | AS | SA | aB | a
  • AbSA \to b| S


6 . 消除 ASA \to S 規則 :


① 消除 ASA \to S 規則 , 檢查 SS 出現在規則左邊的情況 , 這裏有 SASAASSAaBaS \to ASA | AS | SA | aB | a 規則 , 需要 添加 AASAASSAaBaA\to ASA | AS | SA | aB | a 規則後 , 即可刪除 ASA \to S 規則 ;


② 刪除前規則 :

  • S0SS_0 \to S
  • SASAASSAaBaS \to ASA | AS | SA | aB | a
  • AbSA \to b | S

③ 刪除後規則如下 :

  • S0SS_0 \to S
  • SASAASSAaBaS \to ASA | AS | SA | aB | a
  • AbASAASSAaBaA \to b| ASA | AS | SA | aB | a


7 . 分解規則 :


① 分解示例 : SASAS \to ASA 可以分解爲 SRS \to R , RSAR \to SA

② 分解前的規則 :

  • S0SS_0 \to S
  • SASAASSAaBaS \to ASA | AS | SA | aB | a
  • AbASAASSAaBaA \to b| ASA | AS | SA | aB | a

③ 分解後的規則 :

  • S0SS_0 \to S

下面的規則 是 SASAASSAaBaS \to ASA | AS | SA | aB | a 分解後的規則 :

  • SRS \to R
  • RSAR \to SA
  • SASS \to AS
  • SSAS \to SA
  • SaBS \to aB
  • SaS \to a

下面的規則 是 AbASAASSAaBaA \to b| ASA | AS | SA | aB | a 分解後的規則 :

  • AbA \to b
  • ARA \to R
  • ASAA \to SA
  • AASA \to AS
  • ASAA \to SA
  • AaBA \to aB
  • AaA \to a
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章