剖析與文法的應用

CYK 演算法(CYK algorithm)

/ C-Y-K, also CKY /

LL 與 LR 剖析器很快卻挑剔:它們只在特殊形狀的文法上有效。有時你手上是任意的上下文無關文法,也許是自然語言用的歧義文法,而你只需知道某字串是否屬於該語言,無論文法多彆扭。CYK 演算法是為此而生的通用主力:給它任何上下文無關文法(化成適當的正規形式)與任何字串,它便判定成員、且能建出所有剖析樹,靠的是動態規劃而非巧妙的前瞻。

CYK 要求文法為喬姆斯基正規形式(Chomsky normal form),其中每條規則為 A -> BC 或 A -> a。其構想是:對輸入的每一個連續片段,找出哪些非終端符號能恰好產生那個片段,並從短片段到長片段填一張三角形的表。對每個單一詞符,你問哪些規則 A -> a 產生它。對較長的片段,你嘗試把它切成左半與右半的每一種方式:若某非終端符號 B 能產生左半、某 C 能產生右半,且有規則 A -> BC,那麼 A 就能產生整個片段。你從長度 1 的片段一路建到完整字串;當起始符號出現在對應整個輸入的格子中時,該字串恰好屬於該語言。對輸入 a b a 與像 S -> AB、A -> a、B -> b 的規則,你標出每格能是哪個符號,並把相鄰的格子向上組合。

CYK 的價值在於通用性與有保證的執行時間:它對任何上下文無關文法都有效,對長度 n 的輸入以 O(n^3) 時間運行(再乘上一個與文法大小有關的因子),空間為平方級。代價是立方時間遠慢於 LL 與 LR 的線性時間,所以 CYK 用在文法無法馴成 LL 或 LR 形狀之處,自然語言剖析、計算生物學的 RNA 文法,以及作為「上下文無關成員問題可判定」的教科書證明。它確認每個上下文無關語言都能被剖析,只是未必便宜。

在喬姆斯基正規形式下以 S -> AB、A -> a、B -> b 對輸入 a b:長度 1 的格給出 a -> A、b -> B;長度 2 的格嘗試切分 a | b,發現左邊 A、右邊 B,且因 S -> AB 存在而標上 S。S 出現在整串的格子裡,故 a b 被接受。

CYK:對所有子字串做動態規劃,O(n^3),對任何喬姆斯基正規形式的 CFG 都有效。

CYK 須先把文法化為喬姆斯基正規形式;你無法在原始文法上跑它。其 O(n^3) 成本使它通用卻慢,所以正式編譯器改用線性時間的 LL 或 LR 剖析器,把 CYK 留給那些方法無法處理的文法。

又称
CKY algorithmCocke-Younger-KasamiCYK 演算法CKY 演算法