Augmented Backus–Naur form
From Wikipedia, the free encyclopedia
The augmented Backus–Naur form (ABNF) extends the Backus-Naur form.
The augmented Backus–Naur form (ABNF) is based on Backus–Naur form (BNF), but consists of its own syntax and derivation rules. The motive principle for this metalanguage is to describe a formal system of a language which is a protocol (bidirectional specification). It is documented in RFC 4234 and often serves as the definition language for IETF communication protocol.
RFC 4234 corrects problems in and obsoletes RFC 2234.
Contents |
[edit] Introduction
An ABNF specification is a set of derivation rules, written as rule = definition ; comment CR LF
: where rule is a case-sensitive nonterminal, the definition consists of sequences of symbols that define the rule, a comment for documentation, and ending with a carriage return and line feed.
Rule names are case insensitive: <rulename>
, <Rulename>
, <RULENAME>
, and <rUlENamE>
all refer to the same rule. Rule names consist of a letter followed by letters, numbers, and hyphens.
Angle brackets (“<
”, “>
”) are not required around rule names (as they are in BNF). However they may be used to delimit a rule name when used in prose to discern a rule name.
ABNF is encoded in 7-bit ASCII in an 8-bit field with the high bit set to zero.
[edit] Terminal values
Terminals are specified by one or more numeric characters.
Numeric characters may be specified as the percent sign “%
”, followed by the base (b = binary, d = decimal, and x = hexadecimal), followed by the value, or concatenation of values (indicated by “.
”). For example a carriage return is specified by %d13
in decimal or %x0D
in hexadecimal. A carriage return followed by a line feed may be specified with concatenation as %d13.10
.
Literal text is specified through the use of a string enclosed in quotation-marks ("
). These strings are case-insensitive and the character set used is US-ASCII. Therefore the string “abc” will match “abc”, “Abc”, “aBc”, “abC”, “ABc”, “AbC”, “aBC”, and “ABC”. For a case-sensitive match the explicit characters must be defined: to match “aBc” the definition will be %d97 %d66 %d99
.
[edit] Operators
[edit] Whitespace
Whitespace is used to separate elements of a definition: for space to be recognized as a delimiter it must be explicitly included.
[edit] Concatenation:
Rule1 Rule2
A rule may be defined by listing a sequence of rule names.
To match the string “aba” the following rules could be used:
fu = %x61 ; a
bar = %x62 ; b
mumble = fu bar fu
[edit] Alternation:
Rule1 / Rule2
A rule may be defined by a list of alternative rules separated by a solidus (“/
”).
To accept the rule <fu> or the rule <bar> the following rule could be constructed:
fubar = fu / bar
[edit] Incremental alternatives:
Rule1 =/ Rule2
Additional alternatives may be added to a rule through the use of “=/
” between the rule name and the definition.
The rule
ruleset = alt1 / alt2 / alt3 / alt4 / alt5
is equivalent to
ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt5
[edit] Value range:
%c##-##
A range of numeric values may be specified through the use of a hyphen (“-
”).
The rule
OCTAL = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7"
is equivalent to
OCTAL = %x30-37
[edit] Sequence group:
(Rule1 Rule2)
Elements may be placed in parentheses to group rules in a definition.
To match “elem fubar snafu” or “elem tarfu snafu” the following rule could be constructed:
group = elem (fubar / tarfu) snafu
To match “elem fubar” or “tarfu snafu” the following rules could be constructed:
group = elem fubar / tarfu snafu
group = (elem fubar) / (tarfu snafu)
[edit] Variable repetition:
n*nRule
To indicate repetition of an element the form <a>*<b>element
is used. The optional <a>
gives the minimum number of elements to be included with the default of 0. The optional <b>
gives the maximum number of elements to be included with the default of infinity.
Use *element
for zero or more elements, 1*element
for one or more elements, and 2*3element
for two or three elements.
[edit] Specific repetition:
nRule
To indicate an explicit number of elements the form <a>element
is used and is equivalent to <a>*<a>element
.
Use 2DIGIT
to get two numeric digits and 3DIGIT
to get three numeric digits.
[edit] Optional sequence:
[Rule]
To indicate an optional element the following constructions are equivalent:
[fubar snafu]
*1(fubar snafu)
0*1(fubar snafu)
[edit] Comment:
; comment
A semi-colon (“;
”) starts a comment that continues to the end of the line.
[edit] Operator precedence
The above operators have the given precedence from tightest binding to loosest binding:
- Strings, Names formation
- Comment
- Value range
- Repetition
- Grouping, Optional
- Concatenation
- Alternative
Use of the alternative operator with concatenation may be confusing and it is recommended that grouping be used to make explicit concatenation groups.
[edit] Core rules
The core rules are defined in the ABNF standard.
Rule | Formal Definition | Meaning |
---|---|---|
ALPHA | %x41-5A / %x61-7A | Upper and lowercase ASCII letters (A-Z a-z) |
DIGIT | %x30-39 | Decimal digits (0-9) |
HEXDIG | DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | Hexadecimal digits (0-9 A-F) |
DQUOTE | %x22 | Double Quote |
SP | %x20 | space |
HTAB | %x09 | horizontal tab |
WSP | SP / HTAB | space and horizontal tab |
LWSP | *(WSP / CRLF WSP) | linear white space (past newline) |
VCHAR | %x21-7E | visible (printing) characters |
CHAR | %x01-7F | any 7-bit US-ASCII character, excluding NUL |
OCTET | %x00-FF | 8 bits of data |
CTL | %x00-1F / %x7F | controls |
CR | %x0D | carriage return |
LF | %x0A | linefeed |
CRLF | CR LF | Internet standard newline |
BIT | "0" / "1" |
[edit] Example
The postal address example given in the Backus-Naur (BNF) page may be specified as:
postal-address = name-part street zip-part name-part = *(personal-part SP) last-name [SP jr-part] CRLF name-part =/ personal-part CRLF personal-part = first-name / (initial ".") first-name = *ALPHA initial = ALPHA last-name = *ALPHA jr-part = ("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]