為什麼《康熙字典》Parser 比 HTML Parser 更困難?逆向工程一部三百多年古籍的歷程

Series 2 · 第 10 篇——《康熙字典》Parser 與 HTML Parser:Reverse Engineering 上一篇:為什麼一個漢字會有多個反切?

為什麼《康熙字典》Parser 比 HTML Parser 更困難?逆向工程一部三百多年古籍的歷程

一提到「Parser」,許多程式設計師首先想到的都是 HTML、XML、JSON 或 Markdown。這些格式都有明確定義的語法(Grammar),只要依照官方規範便能實作 Parser。然而,Quizzman Fanqie Engine 面對的是完全不同的問題:如何讓電腦理解《康熙字典》這部十八世紀初以文言文編纂、沒有正式 Grammar、沒有技術規格,並充滿各種音韻註記方式的古代字典。 這也是 Fanqie Engine 開發過程中最耗時的研究工作之一。

HTML Parser 有一項巨大優勢

如果要開發一個 HTML Parser,

工作流程其實十分清楚。

HTML 具有:

  • 官方 Specification;
  • 正式 Grammar;
  • 標籤巢狀規則;
  • 開閉標籤規則;
  • 錯誤恢復機制。

例如:

<div class="card">
    <h1>Hello</h1>
</div>

Parser 很清楚知道:

  • 哪裡是開始標籤;
  • 哪裡是結束標籤;
  • 哪裡是屬性;
  • 哪裡是內容。

整套 Grammar 都已公開定義。

程式設計師需要做的,

只是忠實實作這套 Grammar。


但《康熙字典》沒有 Grammar

《康熙字典》完全不同。

沒有任何文件會告訴你:

遇到這種文字,就應該這樣理解。

沒有 BNF。

沒有 EBNF。

沒有 RFC。

也沒有專門描述反切的 Unicode 標準。

每一條字頭,

都是三百多年前學者依照當時學術慣例所編寫。

因此,

在寫 Parser 之前,

必須先回答一個更困難的問題:

古人究竟依照什麼規律來記錄這些資料?


不能一開始就寫 Parser

最容易犯的錯誤就是:

打開《康熙字典》。

直接開始寫 Regex。

例如:

(.)(.)切

看起來似乎足夠。

但只分析幾百條資料後,

Parser 就會開始失敗。

因為資料並沒有統一格式。

例如:

  • AB切
  • AB切某聲
  • AB切又音
  • AB切讀若……
  • 讀若……
  • 叶某韻
  • 俗音……
  • 又作……
  • 古作……

如果全部都視為標準反切,

整份資料都會被錯誤解析。


第一步不是寫程式,而是做調查

因此,

Quizzman 並沒有立即開始寫 Parser。

而是先進行一項更接近語言學研究的工作。

也就是調查數萬條字頭,

分析:

  • 哪些 Pattern 最常出現;
  • 哪些內容屬於音韻資料;
  • 哪些只是編者註解。

整個流程可以表示為:

《康熙字典》

觀察

統計

Pattern

Grammar

Parser

Parser 只是最後一步。


第一個目標:辨識資料來源

《康熙字典》的每一條字頭,

通常不只包含一個反切。

還會引用多部韻書。

例如:

《廣韻》

……

《集韻》

……

《唐韻》

……

對讀者而言,

這只是註解。

對 Quizzman 而言,

卻是極為重要的 Metadata。

Parser 必須知道:

  • 反切來自哪一部韻書;
  • 正在引用哪個來源;
  • 哪一個是主要反切;
  • 哪一些只是補充資料。

如果來源辨識錯誤,

Candidate Ranking 將失去重要依據。


並非所有「切」都代表同一種意思

另一個困難,

就在反切本身。

很多人認為,

只要看到:

就直接取前面兩個字即可。

實際上,

經過大量調查,

Quizzman 發現存在許多不同 Pattern。

例如:

AB切

這是最標準的反切格式。

但還有:

  • AB切某聲
  • AB切又音
  • AB切音某
  • AB切讀若……

雖然都包含「切」,

它們的語義卻完全不同。


最困難的是「AB切某聲」

這是建立 Parser 過程中的重要發現之一。

第一眼看起來,

AB切某聲

似乎只是:

AB切

再加上一段說明。

但經過大量樣本分析,

Quizzman 發現事實並非如此。

許多情況下,

「某聲」

並不是附註。

它實際上會修改整個音韻資訊。

換句話說,

Parser 必須理解:

  • 聲母仍來自反切;
  • 韻母仍來自反切;
  • 聲調則必須依照後面的註記覆寫(Tone Override)。

如果忽略這個細節,

Middle Chinese Reconstruction 從第一步就會錯誤。


「讀若」不是反切

另一組容易混淆的 Pattern 是:

讀若……

字面意思只是:

「讀音近似……」

它並沒有完整描述:

  • 聲母;
  • 韻母;
  • 聲調。

因此,

它不能直接用來重建 Middle Chinese。

Parser 必須辨識:

讀若

Phonetic Hint

而不是:

讀若

Fanqie


「叶韻」也不是標準讀音

另一種特殊情況是:

  • 叶韻
  • 協韻

這些註記主要出現在詩歌中。

它們描述的是:

  • 為了押韻而調整讀音;
  • 或特殊文學用途的變體。

如果 Parser 將它們視為標準發音,

Engine 就會產生大量錯誤資料。

因此,

Quizzman 將它們獨立分類為:

叶韻

Rhyme Annotation

不會送入 Hán Việt Projection Pipeline。


Parser 本質上是一個 Grammar Classifier

經過多次重構,

Quizzman 已不再把 Parser 視為 Regex 集合。

Parser 更接近一個 Grammar Classifier。

例如:

| Pattern | 分類 | |----------|------| | AB切 | Fanqie | | AB切某聲 | Fanqie + Tone Override | | 讀若 | Phonetic Hint | | 叶韻 | Rhyme Annotation | | 又音 | Alternate Reading | | 古音 | Historical Reading | | 俗音 | Colloquial Reading |

只有完成分類之後,

Engine 才知道應採用哪一種處理流程。


與其說是 Parsing,不如說是 Reverse Engineering

Quizzman 最大的特殊之處在於:

開發團隊一開始根本沒有官方 Grammar 可以參考。

整套 Grammar,

都是反向推導出來的。

數萬條字頭

觀察

統計

發現規律

抽象化

Grammar

Parser

在電腦科學中,

這個過程稱為:

Reverse Engineering(逆向工程)

並不是實作既有規格,

而是:

從資料本身重建規格。


Parser 決定整個 Fanqie Engine 的品質

很多人認為,

Quizzman Fanqie Engine 最困難的是 Hán Việt Projection。

事實上,

所有後續演算法,

都建立在 Parser 的結果之上。

如果 Parser 對《康熙字典》的理解出錯:

  • Fanqie Record 會錯;
  • Middle Chinese Profile 會錯;
  • Tone Resolution 會錯;
  • Candidate Ranking 也會錯。

因此,

Parser 並不是單純的資料讀取工具,

而是整個系統的基礎。

Quizzman Fanqie Engine 與其他工具最大的不同,

不只是能夠解析反切,

更重要的是透過 Reverse Engineering 重建《康熙字典》的編纂規則,

把三百多年前的學術記錄轉化為結構化資料,

使電腦得以在此基礎上繼續進行音韻推導、分析與解釋。