Appearance
ABNF - 增强巴科斯范式
Tip
规则定义
规则命名
规则的名称就是名称本身,即一串字符,以字母开头,后跟字母、数字和连字符(破折号)的组合。
规则名称不区分大小写。所以,名称 <rulename>、<Rulename>、<RULENAME> 以及 <rUlENamE> 都指的是同一个规则。
与原始的 BNF 不同,不需要使用尖括号(<、>)。然而,当它们的存在有助于区分规则名称的使用时,可以在规则名称周围使用尖括号。
规则形式
一个规则由以下序列定义:
ABNF
name = elements crlf其中 <name> 是规则的名称,<elements> 是一个或多个规则名称或终端值,<crlf> 是行尾标识符(回车符后跟换行符)。等号将名称与规则的定义分隔开。元素是一个或多个规则名称和/或值定义的序列,根据本文档定义的各种运算符组合,如选择和重复。
为了便于观看,规则定义左对齐。当一个规则需要多行时,续行缩进。左对齐和缩进是相对于 ABNF 规则的第一行,并不一定与文档的左边距对齐。
终端值
规则解析为一个终端值的字符串,有时也称为字符。在 ABNF 中,一个字符只是一个非负整数。在某些上下文中,会明确指定值到字符集(如 ASCII)的特定映射(编码)。
终端值由一个或多个数字字符指定,这些数字字符的含义由基础字符指示。目前定义了以下基础字符:
ABNF
b = 二进制
d = 十进制
x = 十六进制1
2
3
2
3
因此:
ABNF
CR = %d13; 与下方的定义等价
CR = %x0D1
2
2
分别指定了 US-ASCII 中回车符的十进制和十六进制表示。
使用点号 . 来指示值内部的字符分隔,可以紧凑地指定一串这样的值。因此:
ABNF
CRLF = %d13.10ABNF 允许直接用引号括起来的文本字符串来指定字面值。因此:
ABNF
command = "command string"字面文本字符串被解释为一组串联的可打印字符。注意:这些字符串的字符集是 US-ASCII。
ABNF 中的文本字符串可以是区分大小写的,也可以是不区分大小写的。使用引号字符串前面的前缀来表示具体使用的形式。允许使用以下前缀:
ABNF
%s = 区分大小写
%i = 不区分大小写1
2
2
为了与之前的 ABNF 实现保持一致,如果没有前缀,就意味着字符串是不区分大小写的,相当于使用了 %i 前缀。因此:
ABNF
rulename = %i"aBc"和:
ABNF
rulename = "abc"都会匹配 abc、Abc、aBc、abC、ABc、aBC、AbC 和 ABC。
相反:
ABNF
rulename = %s"aBc"只会匹配 aBc,不会匹配 abc、Abc、abC、ABc、aBC、AbC 或 ABC。
或者也可以单独指定每个字符。例如:
ABNF
rulename = %d97 %d66 %d99或者:
ABNF
rulename = %d97.66.99外部编码
终端值字符的外部表示将根据存储或传输环境的约束而有所不同。因此,相同基于 ABNF 的语法可能有多种外部编码,例如在 7 位 US-ASCII 环境中有一种,在二进制八位字节环境中有另一种,当使用 16 位 Unicode 时还有不同的一种。编码细节超出了 ABNF 的范围,尽管附录 B 提供了一个常见于许多 Internet 规范的 7 位 US-ASCII 环境的定义和编码。
通过将外部编码与语法分离,旨在使同一语法可以用于不同的编码环境。
操作符
连接:Rule1 Rule2
一个规则可以通过列出一系列规则名称来定义一个简单的、有序的值的字符串(即相邻字符的连接)。例如:
ABNF
foo = %x61 ; a
bar = %x62 ; b
mumble = foo bar foo1
2
3
2
3
这样,规则 <mumble> 就匹配了小写字符串 aba。
线性空白:连接是 ABNF 解析模型的核心。一串相邻的字符(值)是根据 ABNF 定义的规则进行解析的。对于 Internet 规范,有一些历史上允许在主要结构之间隐含地自由地插入线性空白(空格和水平制表符),如分隔特殊字符或原子字符串。
Tip:本文档对 ABNF 的规范不提供隐含地指定线性空白的方法。
任何希望在分隔符或字符串段周围允许线性空白的语法必须显式地指定它。通常在 “核心” 规则中提供这样的空白,然后在高级规则中各种使用。“核心” 规则可能形成一个词法分析器,或者只是主要规则集的一部分。
选择:Rule1 / Rule2
用正斜杠 / 分隔多个元素的选择。
因此:
ABNF
foo / bar将接受 <foo> 或 <bar>。
注意:包含字母字符的带引号字符串是一种用于指定备选字符的特殊形式,并被解释为表示具有包含的字符的组合字符串集合的非终结符,它按指定的顺序排列,但可以按任意大小写混合。
增量选择:Rule1 =/ Rule2
有时,以碎片的形式指定一系列选择是很方便的。也就是说,一个初始规则可以匹配一个或多个选择,后面的规则定义可以添加到选择集合中。这对于那些从同一个父规则集派生的、相互独立的规范来说是非常有用的,例如经常发生在参数列表中。ABNF 允许通过以下结构进行这种增量定义:
ABNF
oldrule =/ additional-alternatives因此,规则集:
ABNF
ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt51
2
3
2
3
等同于指定
ABNF
ruleset = alt1 / alt2 / alt3 / alt4 / alt5值范围选择:%c##-##
用连字符("-")分隔的两个值是一个值范围选择。因此:
ABNF
DIGIT = %x30-39等同于:
ABNF
DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" /
"7" / "8" / "9"1
2
2
不能在同一字符串中指定连续的数值和数值范围。一个数值可以使用点号符号来进行连接,或者可以使用破折号符号来指定一个数值范围。因此,若要指定在行尾序列之间有一个可打印字符,可以声明为:
ABNF
char-line = %x0D.0A %x20-7E %x0D.0A序列组:(Rule1 Rule2)
用括号括起来的元素被视为一个单一的元素,其内容是严格有序的。因此:
ABNF
elem (foo / bar) blat匹配 elem foo blat 或 elem bar blat,而:
ABNF
elem foo / bar blat匹配 elem foo 或 bar blat。
Warning
强烈建议使用分组符号,而不是依赖于 “裸露” 的选择,当选择由多个规则名称或字面值组成时。因此,建议使用以下形式:
ABNF(elem foo) / (bar blat)它将避免被随意的读者误解。分组符号也用于自由文本中,以将元素序列与散文区分开。
可变重复:*Rule
元素前面的操作符 * 表示重复。完整的形式是:
ABNF
<a>*<b>element其中 <a> 和 <b> 是可选的十进制值,表示元素至少出现 <a> 次,至多出现 <b> 次。默认值是 0 和无穷大,所以:
*<element>:允许任意次数,包括零次;1*<element>:要求至少一次;3*3<element>:只允许恰好 3 次;1*2<element>:允许一次或两次;
特定重复:nRule
形如:
ABNF
<n>element的规则等同于:
ABNF
<n>*<n>element也就是说,元素恰好重复 <n> 次。因此,2DIGIT 是一个两位数,3ALPHA 是一个由三个字母组成的字符串。
可选序列:[RULE]
方括号括起来的元素序列是可选的:
ABNF
[foo bar]等同于:
ABNF
*1(foo bar)注释:; Comment
; 开始一个注释,一直持续到行尾。这是一种在规范中并行地包含有用的注解的简单方法。
操作符优先级
上面描述的各种机制具有以下优先级,从最高(绑定最紧)的在顶部,到最低(最松)的在底部:
- 规则名,散文值(prose-val),终端值
- 注释
- 值范围
- 重复
- 分组,可选
- 连接
- 选择
在连接中自由混合选择可能会造成混淆。再次建议使用分组操作符来明确地表示连接组。
用 ABNF 定义 ABNF
ABNF
rulelist = 1*( rule / (*c-wsp c-nl) )
rule = rulename defined-as elements c-nl
; continues if next line starts with white space
rulename = ALPHA *(ALPHA / DIGIT / "-")
defined-as = *c-wsp ("=" / "=/") *c-wsp
; basic rules definition and incremental alternatives
elements = alternation *c-wsp
c-wsp = WSP / (c-nl WSP)
c-nl = comment / CRLF
; comment or newline
comment = ";" *(WSP / VCHAR) CRLF
alternation = concatenation
*(*c-wsp "/" *c-wsp concatenation)
concatenation = repetition *(1*c-wsp repetition)
repetition = [repeat] element
repeat = 1*DIGIT / (*DIGIT "*" *DIGIT)
element = rulename / group / option /
char-val / num-val / prose-val
group = "(" *c-wsp alternation *c-wsp ")"
option = "[" *c-wsp alternation *c-wsp "]"
char-val = DQUOTE *(%x20-21 / %x23-7E) DQUOTE
; quoted string of SP and VCHAR without DQUOTE
num-val = "%" (bin-val / dec-val / hex-val)
bin-val = "b" 1*BIT
[ 1*("." 1*BIT) / ("-" 1*BIT) ]
; series of concatenated bit values or single ONEOF range
dec-val = "d" 1*DIGIT
[ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ]
hex-val = "x" 1*HEXDIG
[ 1*("." 1*HEXDIG) / ("-" 1*HEXDIG) ]
prose-val = "<" *(%x20-3D / %x3F-7E) ">"
; bracketed string of SP and VCHAR without angles
; prose description, to be used as last resort1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
核心规则
规则基本都是大写的:
ABNF
CHAR = %x01-7F ; any 7-bit US-ASCII character,
; excluding NUL
VCHAR = %x21-7E ; visible (printing) characters
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
BIT = "0" / "1"
OCTET = %x00-FF ; 8 bits of data
DIGIT = %x30-39 ; 0-9
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
SP = %x20
HTAB = %x09 ; horizontal tab
WSP = SP / HTAB ; white space
LWSP = *(WSP / CRLF WSP) ; Use of this linear-white-space rule
; permits lines containing only white
; space that are no longer legal in
; mail headers and have caused
; interoperability problems in other
; contexts.
; Do not use when defining mail
; headers and use with caution in
; other contexts.
DQUOTE = %x22 ; " (Double Quote)
CR = %x0D ; carriage return
LF = %x0A ; linefeed
CRLF = CR LF ; Internet standard newline
CTL = %x00-1F / %x7F ; controls1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40