分分鐘看懂 ABNF 以 language tag 為例

Code review 的時候熊熊想戰 naming,戰 naming 最好的就是翻相關的 rfc spec

這樣對同事提出建設性批評就會特有底氣

總之這次要戰 language tag,什麼是 langugage tag 呢?

像是 zh_TW, zh_Hant, en_US 這種都可以說是 language tag,其中會用底線 _ 來區分每一段,

好想知道一段一段切開來要怎麼稱呼人家

相關的 rfc 甚至已經有老中青三代,我卻一個女朋友都沒有 rfc-1766 rfc-3066 rfc-4646

(回到正題),對 language tag 定義中 2*3ALPHA 百思不得其解,一直想要二乘三得六阿法。 看不懂實在很苦惱,這樣還跟人家戰什麼,只好先去看看 rfc 愛用的 ABNF Expression

以前看到這個 ABNF Expression 吼,每次喵過去感覺略懂略懂,日子也就這樣過了

這次終於是避不掉了,所幸看完之後發現還算實用,以後女朋友問你喜歡她哪一點就用 BNF 定義一下 她一定會對你的意見用白眼與沈默表示高度的心悅誠服 (?

投資前請詳閱公開 spec

啊什麼是 ABNF? Augmented-BNF “增強” 的 BNF

啊什麼是 BNF? Backus Normal Form

可以說是描述語言的語言。就文法啦,BNF 利用符號來定義文法,掌握文法就可以說出他的語言 ABNF 擴展了 BNF 新增了若干規則,個人感覺類似於 syntax sugar 拉

ABNF

節錄部分 rfc-4646 如下

   langtag       = (language
                    ["-" script]
                    ["-" region]
                    *("-" variant)
                    *("-" extension)
                    ["-" privateuse])

   language      = (2*3ALPHA [ extlang ]) ; shortest ISO 639 code

   script        = 4ALPHA                 ; ISO 15924 code

   region        = 2ALPHA                 ; ISO 3166 code

   variant       = 5*8alphanum            ; registered variants
                 / (DIGIT 3alphanum)

   alphanum      = (ALPHA / DIGIT)       ; letters and numbers

Rule 就是一條一條的定義拉,比較特別的是 rule naming 不區分大小寫, 也就是 <rulename>, <Rulename>, <RULENAME>, and <rUlENamE> 都是一樣的東西

langtag 就會由後面這些 rule 所組成,遞迴我喜翻你啊!

  1. 串接使用空白 譬如說台灣身分證字號就是 1ALPHA 9DIGIT

  2. 註解 ; 像是 region = 2ALPHA ; e.g. TW 大家有聽過 semicolon 笑話嗎?看過之後每次看到 semicolon 都無法直視呢

  3. 選用 [] 跟 unix command manual 有點像,該不會也用 ABNF 吧? 像是 ls [OPTION]... [FILE]... 這個大家很熟拉

  4. Repetition 重複拉,我覺得英文比較傳神 language 本身定義是 2*3ALPHA* 代表 repetition, 2*3 其實就是 2~3 的意思啦,很反人類

兩碼及三碼代表 ISO 639-1, ISO 639-2 就是 zh, ja, en 等等

script 定義是 4ALPHA,代表固定四碼後面又註解 ISO 15924 這邊應該是代表不同的書寫系統,像是 Hant, Hans

region 2ALPHA 就是 HK, TW 等等,你知我知獨眼龍也知

這樣組合起來就是 zh_Hant_TW 順帶一提 variant 是方言,舉例來說客家話會長這樣 zh_hakka

Alternatives: Rule1 / Rule2

可以看到 alphanum 用這條規則簡單定義出來 e.g. ALPHA / DIGIT

Sequence Group: (Rule1 Rule2)

參考 alphanum 如果沒有用 () 括起來 前後文對照會有問題

Elements enclosed in parentheses are treated as a single element,
   whose contents are strictly ordered.  Thus,

         elem (foo / bar) blat

   matches (elem foo blat) or (elem bar blat), and

         elem foo / bar blat

   matches (elem foo) or (bar blat).

還有一些遺珠的的 ABNF 像是

  • Value Range Alternatives 精確定義是由哪些字母或數字所組成

  • Incremental Alternatives 方便定義一長串的 alternatives

References:

comments powered by Disqus