擴展巴科斯-瑙爾範式(EBNF)是表達做爲描述計算機編程語言和形式語言的正規方式的上下文無關文法的元語法符號表示法。它是基本巴科斯範式(BNF)元語法符號表示法的一種擴展。php
它最初由尼古拉斯·沃斯開發,最經常使用的 EBNF 變體由標準,特別是 ISO-14977 所定義。html
目錄[隱藏] |
代碼,如由終結符便可視字符、數字、標點符號、空白字符等組成的計算機程序的源代碼。git
EBNF 定義了把各符號序列分別指派到非終結符的產生規則:正則表達式
digit excluding zero = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; digit = "0" | digit excluding zero ;
這個產生規則定義了在這個指派的左端的非終結符 digit。豎槓表示可供選擇,而終結符被引號包圍,最後跟着分號做爲終止字符。因此 digit 是一個 0 或能夠是 1 或 2 或 3 直到 9 的一個 digit excluding zero。express
產生規則還能夠包括由逗號分隔的一序列終結符或非終結符:編程
twelve = "1" , "2" ; two hundred one = "2" , "0" , "1" ; three hundred twelve = "3" , twelve ; twelve thousand two hundred one = twelve , two hundred one ;
能夠省略或重複的表達式能夠經過花括號 { ... } 表示:app
natural number = digit excluding zero , { digit } ;
在這種狀況下,字符串 1, 2, ...,10,...,12345,... 都是正確的表達式。要表示這種狀況,於花括號內設立的全部東西能夠重複任何次,包括根本不出現。編程語言
可選項能夠經過方括號 [ ... ] 表示:ide
integer = "0" | [ "-" ] , natural number ;
因此 integer 是一個零(0)或可能前導可選的負號的一個天然數。函數
EBNF 還包括描述指定次數的重複,和排除產生式的某部分或向 EBNF 文法插入註釋的語法。
依據 ISO 14977 標準,提供了兩個設施來擴展 EBNF。其一是在 EBNF 文法部分的特殊序列,它是在問號包圍內的任意文本,其解釋超出了 EBNF 標準的範圍。例如,空格字符能夠用以下規則定義:
space = ? US-ASCII character 32 ?;
其二利用圓括號在 EBNF 中不能放置到緊隨標識符以後的事實。下列不是有效的 EBNF:
something = foo ( bar );
因此 EBNF 的擴展可使用這種表示法。例如,在 Lisp 文法中,函數應用能夠用以下規則定義:
function application = list( symbol , [ { expression } ] );
BNF 有着可選項和重複不能直接表達的問題。做爲替代,它們須要利用中介規則或兩選一規則,對於可選項,定義要麼是空的要麼是可選的產生式的規則,對於重複,遞歸的定義要麼是被重複的產生式要麼是自身的規則。一樣的構造仍可用在 EBNF 中。
可選項:
signed number = [ sign , ] number ;
可按 BNF-風格定義爲:
signed number = sign , number | number ;
或
signed number = optional sign , number ; optional sign = ε | sign ; (* 使用 ε 來更清晰的指示空產生式 *)
重複:
number = { digit } ;
可按 BNF-風格定義爲:
number = digit | number digit;
EBNF 排除了 BNF 的一些缺陷:
EBNF 解決了這些問題:
進一步還提供了定義重複次數,排除法選擇(好比除了引號的全部字符)和註釋等的加強機制。
無論全部這些加強,EBNF 在能定義的語言的意義上不比 BNF 更強大。在原理上用 EBNF 定義的任何文法均可以用 BNF 表達。可是常常致使可觀的更多規則的表示。
EBNF 已經被ISO用代碼 ISO/IEC 14977:1996(E) 標準化了。
在某些場合任何擴展的 BNF 都被稱爲 EBNF。例如 W3C 使用 one EBNF 來規定 XML。
只容許賦值的簡單編程語言能夠用 EBNF 定義爲:
(* a simple program in EBNF − Wikipedia *) program = 'PROGRAM' , white space , identifier , white space , 'BEGIN' , white space , { assignment , ";" , white space } , 'END.' ; identifier = alphabetic character , [ { alphabetic character | digit } ] ; number = [ "-" ] , digit , [ { digit } ] ; string = '"' , { all characters − '"' } , '"' ; assignment = identifier , ":=" , ( number | identifier | string ) ; alphabetic character = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" ; digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; white space = ? white space characters ? ; all characters = ? all visible characters ? ;
一個語法上正確的程序:
PROGRAM DEMO1 BEGIN A0:=3; B:=45; H:=-100023; C:=A; D123:=B34A; BABOON:=GIRAFFE; TEXT:="Hello world!"; END.
這個語言能夠輕易的擴展上控制流,算術表達式和輸入/輸出指令。就能夠開發出一個小的、可用的編程語言了。
使用了在標準中提議爲正規表示的下列字符:
用途 | 符號表示 |
---|---|
定義 | = |
串接 | , |
終止 | ; |
分隔 | | |
可選 | [ ... ] |
重複 | { ... } |
分組 | ( ... ) |
雙引號 | " ... " |
單引號 | ' ... ' |
註釋 | (* ... *) |
特殊序列 | ? ... ? |
除外 | - |
1. 使用了以下約定:
2. 表示擴展 BNF 的每一個操做符的正常字符和它所蘊涵的優先級(頂部爲最高優先級)爲:
* repetition-symbol - except-symbol , concatenate-symbol | definition-separator-symbol = defining-symbol ; terminator-symbol
3. 下列括號對超越正常優先級:
´ first-quote-symbol first-quote-symbol ´ " second-quote-symbol second-quote-symbol " (* start-comment-symbol end-comment-symbol *) ( start-group-symbol end-group-symbol ) [ start-option-symbol end-option-symbol ] { start-repeat-symbol end-repeat-symbol } ? special-sequence-symbol special-sequence-symbol ?
做爲例子,下列語法規則展現了表達重複的設施:
aa = "A"; bb = 3 * aa, "B"; cc = 3 * [aa], "C"; dd = {aa}, "D"; ee = aa, {aa}, "E"; ff = 3 * aa, 3 * [aa], "F"; gg = {3 * aa}, "D";
這些規則定義的終結字符串以下:
aa: A bb: AAAB cc: C AC AAC AAAC dd: D AD AAD AAAD AAAAD etc. ee: AE AAE AAAE AAAAE AAAAAE etc. ff: AAAF AAAAF AAAAAF AAAAAAF gg: D AAAD AAAAAAD etc.