計算機語言符號集語法規範:BNF與ABNF

寒-寒發表於2015-08-20

語法規範:BNF與ABNF


  BNF     

  巴科斯正規化(BNF: Backus-Naur Form 的縮寫)是由 John Backus 和 Peter Naur 首先引入的用來描述計算機語言語法的符號集。現在,幾乎每一位新程式語言書籍的作者都使用巴科斯正規化來定義程式語言的語法規則。 

  在BNF中,雙引號中的字("word")代表著這些字元本身。而double_quote用來代表雙引號。 

  在雙引號外的字(有可能有下劃線)代表著語法部分。 

  < > : 內包含的為必選項。 
  [ ] : 內包含的為可選項。 
  { } : 內包含的為可重複0至無數次的項。 
  |  : 表示在其左右兩邊任選一項,相當於"OR"的意思。 
  ::= : 是“被定義為”的意思 
  "..." : 術語符號 
   [...] : 選項,最多出現一次 
  {...} : 重複項,任意次數,包括 0 次 
  (...) : 分組 
  |   : 並列選項,只能選一個 
  斜體字: 引數,在其它地方有解釋 

  下面是是用BNF來定義的Java語言中的For語句的例項: 

FOR_STATEMENT ::= 
      "for" "(" ( variable_declaration | 
  ( expression ";" ) | ";" ) 
      [ expression ] ";" 
      [ expression ] ";" 
      ")" statement

  ABNF

  RFC2234 定義了擴充套件的巴科斯正規化(ABNF)。近年來在Internet的定義中 ABNF 被廣泛使用。ABNF 做了更多的改進。擴充巴科斯-瑙爾正規化(ABNF)基於了巴科斯-瑙爾正規化(BNF),但由它自己的語法和推導規則構成。這種元語言的發起原則是描述作為通訊協議(雙向規範)的語言的形式系統。它建檔於 RFC 4234 中通常充當 IETF 通訊協議的定義語言。

  ABNF 規定是一組推導規則,寫為:

規則 = 定義 ; 註釋 CR LF

  這裡的規則是大小寫敏感的非終止符,定義由定義這個規則的符號序列,一個文件註釋組成,並結束於回車換行。

  規則名字是大小寫不敏感的: <rulename><Rulename><RULENAME> 和 <rUlENamE> 都提及同一個規則。規則名字由開始於一個字母的字母、數字和連字元組成。不要求用尖括號(“<”, “>”) (如 BNF 那樣)包圍規則名字。但是它們可以用來界定規則名字,比如在冗文中識別出規則名字的時候。ABNF 使用 7-位 ASCII 編碼,在 8-位域中把高位置零。

  終結符由一個或多個數值字元指定。數值字元可以指定為跟隨著基數(b = 二進位制, d = 十進位制, x = 十六進位制)的一個百分號“%”,隨後是這個數值,或數值的串聯(用“.” 來指示)。例如回車可以指定為十進位制的 %d13 或十六進位制的 %x0D。回車換行可以指定為 %d13.10

  文字正文通過使用包圍在引號(")中字串來指定。這些字串是大小寫不敏感的,使用的字符集是 US-ASCII。所以字串“abc”將匹配“abc”, “Abc”, “aBc”, “abC”, “ABc”, “AbC”, “aBC” 和 “ABC”。對於大小寫敏感匹配,必須定義明確的字元: 要匹配 “aBc” 定義將是 %d97 %d66 %d99

  操作符

  空白被用來分隔定義的各個元素: 要使空格被識別為分割符則必須明確的包含它。

  串聯

規則1 規則2   

  規則可以通過列出一序列的規則名字來定義。

  要匹配字串“aba”可以使用下列規則:

fu = %x61; a
bar = %x62; b
mumble = fu bar fu

  選擇

規則1 / 規則2  

  規則可以通過用反斜槓(“/”)分隔的多選一規則來定義。

  要接受規則 <fu> 或規則 <bar> 可構造如下規則:

fubar = fu / bar    

  遞增選擇

規則1 =/ 規則2  

  可以通過使用在規則名字和定義之間的“=/”來向一個規則增加補充選擇。

  規則

ruleset = alt1 / alt2 / alt3 / alt4 / alt5

  等價於

ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt5

  值範圍

%c##-##     

  數值範圍可以通過使用連字元(“-”)來指定。

  規則

OCTAL = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7"

  等價於

OCTAL = %x30-37

  序列分組

(規則1 規則2)  

  元素可以放置在圓括號中來組合定義中的規則。

  要匹配“elem fubar snafu”或“elem tarfu snafu”可以構造下列規則:

group = elem (fubar / tarfu) snafu

  要匹配“elem fubar”或“tarfu snafu”可以構造下列規則:

group = elem fubar / tarfu snafu
group = (elem fubar) / (tarfu snafu)

  可變重複

n*n規則     

  要指示一個元素的重複可以使用形式 <a>*<b> 元素。可選的 <a> 給出要包括的元素的最小數目,預設為 0。可選的 <b> 給出要包括的元素的最大數目,預設為無窮。

  對零或多個元素使用 *元素,對一或多個元素使用 1*元素,對二或三個元素使用 2*3元素

  特定重複  

n規則       

  要指示明確數目的元素可使用形式 <a> 元素,它等價於 <a>*<a>元素

  使用 2DIGIT 得到兩個數字,使用 3DIGIT 得到三個數字。(DIGIT 在下面的核心規則中定義)。

  可選序列

[規則]        

  要指示可選元素下列構造是等價的:

[fubar snafu]
*1(fubar snafu)
0*1(fubar snafu)

  註釋

; 註釋       

  分號(“;”)開始一個註釋並持續到此行的結束。

  操作符優先順序

  上述操作符有從最緊繫結(binding)到最鬆繫結的給定優先順序:

  1. 字串,名字形成(formation)
  2. 註釋
  3. 值範圍
  4. 重複
  5. 分組,可選
  6. 串聯
  7. 選擇

  與串聯一起使用選擇操作符可以造成混淆,建議使用分組來做明確串聯分組。

  核心規則

  核心規則定義於 ABNF 標準中。

規則 形式定義 意義
ALPHA %x41-5A / %x61-7A 大寫和小寫 ASCII 字母 (A-Z a-z)
DIGIT %x30-39 數字 (0-9)
HEXDIG DIGIT / "A" / "B" / "C" / "D" / "E" / "F" 十六進位制數字 (0-9 A-F a-f)
DQUOTE %x22 雙引號
SP %x20 空格
HTAB %x09 水平tab
WSP SP / HTAB 空格和水平tab
LWSP *(WSP / CRLF WSP) 線性空白(晚於換行)
VCHAR %x21-7E 可見(列印)字元
CHAR %x01-7F 任何 7-位 US-ASCII 字元,不包括 NUL
OCTET %x00-FF 8 位資料
CTL %x00-1F / %x7F 控制字元
CR %x0D 回車
LF %x0A 換行
CRLF CR LF 網際網路標準換行
BIT "0" / "1"  

  例子

  在巴科斯正規化(BNF)條目中的郵政地址的例子可以被指定為:

postal-address = name-part street zip-part
name-part = *(personal-part SP) last-name [SP suffix] CRLF
name-part = / personal-part CRLF
personal-part = first-name / (initial ".")
first-name = *ALPHA
initial = ALPHA
last-name = *ALPHA
suffix = ("Jr." / "Sr." / 1*("I" / "V" / "X"))
street = [apt SP] house-num SP street-name CRLF
apt = 1*4DIGIT
house-num = 1*8(DIGIT / ALPHA)
street-name = 1*VCHAR
zip-part = town-name "," SP state 1*2SP zip-code CRLF
town-name = 1*(ALPHA / SP)
state = 2ALPHA
zip-code = 5DIGIT ["-" 4DIGIT]

  引用

  參考

相關文章