В информатике расширенная форма Бэкуса–Наура ( ABNF ) — это метаязык, основанный на форме Бэкуса–Наура (BNF), но состоящий из собственных правил синтаксиса и вывода. Принципиальная схема ABNF — описать формальную систему языка, используемого в качестве двунаправленного протокола связи . Она определена стандартом Интернета 68 («STD 68», type case sic), который по состоянию на декабрь 2010 года [обновлять]был RFC 5234, и часто служит языком определения для протоколов связи IETF . [1] [2]
RFC 5234 заменяет RFC 4234, 2234 и 733. [3] RFC 7405 обновляет его, добавляя синтаксис для указания строковых литералов с учетом регистра.
Спецификация ABNF представляет собой набор правил вывода, записанных как
правило = определение ; комментарий 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». RFC 7405 добавил синтаксис для строк, чувствительных к регистру: %s"aBc"
будет соответствовать только «aBc». До этого чувствительную к регистру строку можно было указать только путем перечисления отдельных символов: для соответствия «aBc» определение было бы %d97.66.99
. Строку также можно явно указать как нечувствительную к регистру с помощью %i
префикса.
Пробел используется для разделения элементов определения; чтобы пробел был распознан как разделитель, он должен быть явно включен. Явная ссылка на одиночный символ пробела — WSP
(линейный пробел), и LWSP
для нуля или более символов пробела с разрешенными переводами строк. Определение LWSP
в RFC5234 является спорным [4], поскольку для формирования разделителя между двумя полями необходим по крайней мере один символ пробела.
Определения выравниваются по левому краю. Если требуется несколько строк (для удобства чтения), строки продолжения отступают пробелами.
; comment
Точка с запятой ( ;
) начинает комментарий, который продолжается до конца строки.
Rule1 Rule2
Правило можно определить, перечислив последовательность имен правил.
Для сопоставления строки «aba» можно использовать следующие правила:
fu = %x61; a
bar = %x62; b
mumble = fu bar fu
Rule1 / Rule2
Правило может быть определено списком альтернативных правил, разделенных косой чертой ( ) /
.
Чтобы принять правило fu или правило bar , можно построить следующее правило:
fubar = fu / bar
Rule1 =/ Rule2
Дополнительные альтернативы могут быть добавлены к правилу путем использования =/
между именем правила и определением.
Правило
ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt5
поэтому эквивалентно
ruleset = alt1 / alt2 / alt3 / alt4 / alt5
%c##-##
Диапазон числовых значений может быть указан с помощью дефиса ( -
).
Правило
OCTAL = %x30-37
эквивалентно
OCTAL = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7"
(Rule1 Rule2)
Элементы могут быть заключены в скобки для группировки правил в определении.
Для сопоставления «ab d» или «ac d» можно построить следующее правило:
group = a (b / c) d
Для сопоставления «ab» или «cd» можно построить следующие правила:
group = a b / c d
group = (a b) / (c d)
n*nRule
Для указания повторения элемента <a>*<b>element
используется форма. Необязательный параметр <a>
указывает минимальное количество включаемых элементов (по умолчанию 0). Необязательный параметр <b>
указывает максимальное количество включаемых элементов (по умолчанию бесконечность).
Используйте *element
для нуля или более элементов, *1element
для нуля или одного элемента, 1*element
для одного или более элементов и 2*3element
для двух или трех элементов, см. регулярные выражения e*
, e?
, e+
и e{2,3}
.
nRule
Для указания явного количества элементов <a>element
используется форма , эквивалентная <a>*<a>element
.
Используйте 2DIGIT
для получения двухзначного числа и 3DIGIT
для получения трехзначного числа. ( DIGIT
определено ниже в разделе «Основные правила». Также см. почтовый индекс в примере ниже.)
[Rule]
Для указания необязательного элемента следующие конструкции эквивалентны:
[fubar snafu]
*1(fubar snafu)
0*1(fubar snafu)
Следующие операторы имеют заданный приоритет от наиболее тесной связи к наиболее свободной:
Использование альтернативного оператора с конкатенацией может привести к путанице, поэтому рекомендуется использовать группировку для создания явных групп конкатенации.
Основные правила определены в стандарте ABNF.
Обратите внимание, что в диаграмме основных правил набор символов CHAR2 встроен в char-val , а CHAR3 встроен в prose-val в спецификации RFC. Они названы здесь для ясности в основной диаграмме синтаксиса.
Пример почтового адреса (США), приведенный на странице расширенной формы Бэкуса–Наура (ABNF), может быть указан следующим образом:
почтовый-адрес = часть имени часть улицы почтовый индекс часть-имени = * ( личная-часть SP ) фамилия [ суффикс SP ] CRLF часть-имени =/ личная-часть CRLF личная-часть = имя / ( инициал "." ) имя = * ALPHA инициал = ALPHA фамилия = * ALPHA суффикс = ( "мл." / "ст." / 1* ( "I" / "V" / "X" )) улица = [ кв SP ] номер-дома SP название-улицы CRLF кв = 1*4 ЦИФРА номер-дома = 1*8 ( ЦИФРА / АЛЬФА ) название-улицы = 1* VCHAR zip-часть = название города "," SP штат 1*2 SP почтовый индекс CRLF название города = 1* ( ALPHA / SP ) штат = 2 ALPHA почтовый индекс = 5 ЦИФР [ "-" 4 ЦИФРЫ ]
RFC 5234 добавляет предупреждение в связи с определением LWSP следующим образом:
Использование этого правила линейного пробела разрешает строки, содержащие только пробелы, которые больше не являются допустимыми в заголовках почты и вызвали проблемы взаимодействия в других контекстах. Не используйте при определении заголовков почты и используйте с осторожностью в других контекстах.