擴充巴科斯範式
此條目翻譯品質稍有不足。 |
在計算機科學中,擴充巴科斯-瑙爾範式(ABNF)是一種基於巴科斯-瑙爾範式(BNF)的元語言,但它有自己的語法和派生規則。ABNF的目的是提供一種用於描述雙向通信協議的語言的形式系統。它是由第68號互聯網標準 (頁面存檔備份,存於互聯網檔案館)("STD 68",大小寫樣式按照原文)定義的,也就是RFC 5234,經常用於互聯網工程任務組(IETF)通信協議的定義語言。[1][2]
RFC 5234取代RFC 4234、2234、733。[3]RFC 7405為RFC 5234提供了支持區分大小寫字符串的擴展。
介紹
一個ABNF規範是一些推導規則的集合,書寫為:
规则 = 定义;注释CR LF
其中:
- 「規則」是不區分大小寫的非最終符號
- 「定義」由定義該規則的一系列符號組成
- 「註釋」用於記錄
- 「CR LF」(回車、換行)用來結束
規則名字是不區分大小寫的: <rulename>
, <Rulename>
, <RULENAME>
和<rUlENamE>
都指的是同一個規則。規則名字由一個字母以及後續的多個字母、數字和連字符(減號)組成。
用尖括號(「<
」,「>
」)包圍規則名並不是必需的(如同它們在BNF里那樣),但是它們可以用來在散文中界定規則名,以方便識別出規則名。
最終值
最終值由一個或多個數值字符指定。
數值字符可按下面的方式指定:先是一個百分號「%
」,緊跟着基數(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」可以使用下列規則:
foo = %x61 ; a
bar = %x62 ; b
mumble = foo bar foo
選擇 /
规则1 / 规则2
一個規則可以通過用斜槓(「/
」)分隔的可供選擇的子規則列表來定義。
要接受規則<foo>或規則<bar>可構造如下規則:
foobar = foo / bar
增量選擇 =/
规则1 =/ 规则2
可以通過在規則名和定義之間使用「=/
」來向一個規則增加補充選擇。
規則
ruleset = alt1 / alt2 / alt3 / alt4 / alt5
等價於
ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt5
值範圍%c##-##
%c##-##
數值範圍可以通過使用連字符(「-
」)來指定。
規則
OCTAL = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7"
等價於
OCTAL = %x30-37
序列組合 ()
(规则1规则2)
在定義中,元素可以放置在圓括號中來將規則組合起來,該組合視為單個元素。
要匹配「elem foobar snafoo」或「elem tarfoo snafoo」可以構造下列規則:
group = elem (foobar / tarfoo) snafoo
要匹配「elem foobar」或「tarfoo snafoo」可以構造下列規則:
group = elem foobar / tarfoo snafoo
group = (elem foobar) / (tarfoo snafoo)
不定量重複m*n
元素前面的星號*
表示重複,其完整形式是:
m*n规则
要表示一個元素的重複,就要使用<m>*<n>元素
形式。可選的<m>
給出要包含的元素的最小數目,默認為0;可選的<n>
給出要包含的元素的最大數目,默認為無窮大。
例子:
*元素
表示零個或更多元素1*元素
表示一個或更多元素2*4元素
表示兩個至四個元素
定量重複n
n规则
要表示特定數目的元素可使用形式<n>元素
,相當於用不定量重複形式表示的<n>*<n>元素
。
使用2DIGIT
得到兩個數字,使用3DIGIT
得到三個數字。(DIGIT在下面的核心規則中定義,也見例子中的zip-code)。
可選序列[]
[规则]
要表示可選元素,下列構造是等價的:
[foobar snafoo]
*1(foobar snafoo)
0*1(foobar snafoo)
註釋;
;注释
註釋從一個分號(「;
」)開始,並持續到此行的結束。
操作符優先級
下面的操作符給出了從高(結合最緊密)到低(結合最鬆散)的優先級:
- 規則名、最終值
- 註釋;
- 值範圍%c##-##
- 重複*
- 組合 ()、可選[]
- 串聯
- 選擇 /
選擇操作符與串聯一起使用會造成混淆,因此建議使用組合來確保串聯組的明確。
例如:
我们 = 你 我/他 她
會產生下面兩種歧義:
(你 我)/(他 她)
(你) (我/他) (她)
所以,使用組合來確保不會產生歧義:
(你 我)/(他 她)
核心規則
核心規則定義於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 | 橫向制表符 |
WSP | SP / HTAB | 空格或橫向制表符 |
LWSP | *(WSP / CRLF WSP) | 直線空白(晚於換行) |
VCHAR | %x21-7E | 可見(打印)字符 |
CHAR | %x01-7F | 任何7-位US-ASCII字符,不包括NUL(%x00) |
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]
隱患
RFC 5234 (頁面存檔備份,存於互聯網檔案館)加入了一條結合LWSP的警告,如下:
若使用該直線空白規則,將允許存在只包含空白字符的行,而這樣的行在郵件頭中已不再合法,並且已在其他環境中導致了互操作問題。 不要在定義郵件頭時使用它,在其他環境下使用時也要格外注意。