Правило ABNF `zero = [" 0 "]" 0 "` соответствует `00`, но не` 0` - PullRequest
0 голосов
/ 21 июня 2019

У меня есть следующая грамматика ABNF:

zero = ["0"] "0"

Я ожидаю, что это будет соответствовать строкам 0 и 00, но это только кажется, что 00? Почему?

repl-it demo: https://repl.it/@DanStevens/abnf-rule-zero-0-0-matches-00-but-not-0

1 Ответ

3 голосов
/ 21 июня 2019

Хороший вопрос.

ABNF ("Augmented Backus Naur Form" 9 определяется RFC 5234 , который является текущей версией документа, предназначенного для пояснения используемой нотации (с вариациями) многими RFC.

К сожалению, в то время как RFC 5234 исчерпывающе описывает синтаксис ABNF, он не дает много ясного утверждения семантики .В частности, в нем не указано, является ли чередование ABNF неупорядоченным (как это происходит в определениях формального языка BNF) или упорядоченным (как в "PEG" - грамматика синтаксического анализа выражения - нотация).Обратите внимание, что опциональность / повторение являются просто типами чередования, поэтому, если вы выберете одно соглашение для чередования, вы, скорее всего, выберете его и для опциональности и повторения.

Разница важна в подобных случаях.чередование упорядочено, тогда синтаксический анализатор не будет делать резервные копии, чтобы попробовать другую альтернативу после успешной альтернативы.Это означает, что если в потоке присутствует необязательный элемент, синтаксический анализатор никогда не пересмотрит решение о принятии необязательного элемента, , даже если некоторый последующий элемент не может быть сопоставлен .Если вы возьмете это представление, то чередование не будет распространяться через конкатенацию.["0"]"0" точно равен ("0"/"")"0", что отличается от "00"/"0".Последнее выражение будет соответствовать одному 0, потому что вторая альтернатива будет опробована после неудачной первой.Предыдущее выражение, которое вы используете, не будет.

Я не верю, что авторы RFC 5234 придерживались этого мнения, хотя было бы намного полезнее, если бы они приняли это решение прямо в документе.Мое единственное реальное доказательство в поддержку моей веры состоит в том, что ABNF, включенный в RFC 5234 для описания самой ABNF, потерпит неудачу, если повторение будет считаться заказанным.В частности, правило для повторений:

repetition     =  [repeat] element
repeat         =  1*DIGIT / (*DIGIT "*" *DIGIT)

не может соответствовать 7*"0", поскольку 7 будет соответствовать первой альтернативе repeat, которая будет принята как удовлетворяющая необязательному [repeat] в repetition, и element впоследствии потерпит неудачу.

Фактически, этот пример (или аналогичный ему) был передан в IETF как ошибка в RFC 5234 ,и ошибка была отклонена как ненужная, потому что верификатор полагал, что должен быть произведен правильный анализ, таким образом предоставляя доказательство того, что официальное мнение состоит в том, что ABNF не является вариантом PEG.По-видимому, это мнение не разделяется автором генератора синтаксических анализаторов APG (который также, похоже, не документирует их интерпретацию). Предлагаемая ошибка выбрала примерно то же решение, что и вы:

repeat         =  *DIGIT ["*" *DIGIT]

хотя это не совсем то же самое;оригинал repeat не может соответствовать пустой строке, но замена может.(Поскольку использование только repeat в грамматике является необязательным, это не имеет никакого практического значения.)

(Примечание к раскрытию: я не фанат PEG. Поэтому возможно, что ответ вышене без предвзятости.)

...