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 重建《康熙字典》的編纂規則,
把三百多年前的學術記錄轉化為結構化資料,
使電腦得以在此基礎上繼續進行音韻推導、分析與解釋。