В информатике расширенная форма Бэкуса-Наура ( ABNF ) — это метаязык, основанный на форме Бэкуса-Наура (BNF), но состоящий из собственного синтаксиса и правил вывода. Основным принципом ABNF является описание формальной системы языка, который будет использоваться в качестве протокола двунаправленной связи . Он определен Интернет-стандартом 68 («STD 68», тип регистра так в оригинале), который по состоянию на декабрь 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 или панель правил , можно создать следующее правило:
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 личная часть = имя / ( начальная "." ) имя = * АЛЬФА начальная = АЛЬФА фамилия = * АЛЬФА- суффикс = ( "Младший" / "Старший" / 1* ( "Я" / " В" / "Х" ) )) улица = [ apt SP ] номер дома SP название улицы CRLF apt = 1*4 ЦИФРА номер дома = 1*8 ( ЦИФРА / АЛЬФА ) название улицы = 1* VCHAR zip-part = название города "," Штат SP 1*2 Почтовый индекс SP CRLF Название города = 1* ( ALPHA / SP ) State = 2 Почтовый индекс ALPHA = 5 ЦИФР [ "-" 4 ЦИФРЫ ]
RFC 5234 добавляет предупреждение к определению LWSP следующим образом:
Использование этого правила линейных пробелов разрешает строки, содержащие только пробелы, которые больше недопустимы в заголовках сообщений и вызывают проблемы совместимости в других контекстах. Не используйте при определении заголовков сообщений и используйте с осторожностью в других контекстах.