BNF 表示法(BNF notation)
/ B-N-F (Backus-Naur Form) /
數學家把上下文無關文法寫成一個元組 (V, Σ, R, S);而撰寫實際語言規格的工程師需要某種能在手冊中打字、閱讀的東西。BNF 就是那種實用的表示法——一種乾淨、標準化的方式來寫下文法的產生式規則,全世界的語言參考文件都在用。它不是一種新的文法,只是把文法拼寫出來的一種方便方式。
在經典 BNF(Backus-Naur Form,為 ALGOL 60 報告而引入)中,非終端符號寫在角括號裡如 <expr> 或 <stmt>,重寫箭頭 → 寫成 ::=(讀作「被定義為」),各選項以一條豎線 | 分隔,而終端符號照字面寫出。一條規則看起來像 <expr> ::= <expr> + <term> | <term>。所以數學規則 E → E + T | T 變成 <expr> ::= <expr> + <term> | <term>——完全相同的文法,只是為工程師而盛裝。EBNF(擴展 BNF)加入了向正規表示式借來的便利簡寫:大括號 { X } 表示「零個或多個 X」、方括號 [ X ] 表示「可選的 X」、以及用於分組的圓括號,這讓重複與可選項目之類的常見模式遠不那麼冗長。
BNF 與 EBNF 是實務上傳達語法的方式:幾乎每種程式語言的參考手冊、許多檔案格式,以及網路協定的規格,都以某種 BNF 方言定義其文法。一點誠實的補充:EBNF 的大括號與方括號純粹是便利——任何用 EBNF 寫的東西都可藉引入額外的非終端符號改寫成普通的 CFG(例如 { X } 變成一條全新的遞迴規則),所以 EBNF 並未在上下文無關文法之外增加表達能力。另外當心,有好幾種互不相容的 BNF 方言,記號上有小差異;務必查清楚某份文件用的是哪一種。
BNF:<if-stmt> ::= if <cond> then <stmt> | if <cond> then <stmt> else <stmt>。帶簡寫的 EBNF:<number> ::= <digit> { <digit> } 與 <sign-num> ::= [ - ] <number>,其中 { } 表示「重複零次或多次」,[ ] 表示「可選」。
BNF:::= 表示 →、| 表示選項、<…> 表示非終端符號。EBNF 額外加上 { }(重複)與 [ ](可選)作為簡寫。
EBNF 的 { } 與 [ ] 純屬便利——它們在上下文無關文法之外「不」增加任何能力(各可用額外的非終端符號改寫)。存在好幾種互不相容的 BNF 方言,所以要查清楚文件用的是哪種記號。