Какая нотация используется при описании конструкций Python?

При чтении документации по языку Python на официальном сайте используется нотация, отличающаяся от стандартной нотации Бекуса-Нура и от расширенной нотации Вирта. Мне так кажется.

Может ли кто кинуть в меня ссылку на ее описание, и второе - объяснить почему не использовалась стандартная нотация. Ну например, фигурные скобки для указания повторяющихся элементов.

Вот пример описания оператора "def":

funcdef                   ::=  [decorators] "def" funcname"(" parameter_list] ")"
                               ["->" expression] ":" suite
decorators                ::=  decorator+
decorator                 ::=  "@" assignment_expression NEWLINE
parameter_list            ::=  defparameter ("," defparameter)* "," "/" ["," [parameter_list_no_posonly]]
                                 | parameter_list_no_posonly
parameter_list_no_posonly ::=  defparameter ("," defparameter)* ["," [parameter_list_starargs]]
                               | parameter_list_starargs
parameter_list_starargs   ::=  "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
                               | "**" parameter [","]
parameter                 ::=  identifier [":" expression]
defparameter              ::=  parameter ["=" expression]
funcname                  ::=  identifier

в стандарте должно было бы быть <funcname>, а не funcname.
Повторение задается фигурными скобками {}. А здесь - кажется -для повторения используется конструкция ()*.

Ссылка на приведенное описание. Пункт 8.7

Вопрос задаю, поскольку студенты спрашивают: "А почему?"


Ответы (1 шт):

Автор решения: GrAnd

В первой главе документации есть описание нотации.

Вольный перевод...

В описаниях лексического анализа и синтаксиса используется модифицированная нотация грамматики BNF. Используется следующий стиль определения:

name      ::=  lc_letter (lc_letter | "_")*
lc_letter ::=  "a"..."z"

В первой строке говорится, что name - это lc_letter, за которым следует последовательность из нуля или более lc_letter и подчеркиваний. lc_letter, в свою очередь, представляет собой любой из одиночных символов от «a» до «z». (Это правило по факту соблюдается для имён, определённых в лексических и грамматических правилах в этом документе.)

Каждое правило начинается с имени (которое описывает правило) и :: =.
Вертикальная черта (|) используется для разделения альтернатив; это наименее связывающий оператор в этой нотации.
Звёздочка (*) означает ноль или более повторений предыдущего элемента;
аналогично, плюс (+) означает одно или несколько повторений,
а фраза, заключённая в квадратные скобки ([]), означает ноль или один повтор (другими словами, заключённая фраза является необязательной).
Операторы * и + связываются настолько плотно, насколько это возможно;
круглые скобки используются для группировки.
Литералы заключаются в кавычки.
Пробел имеет значение только для разделения токенов.
Правила обычно записаны в одну строку; правила со многими альтернативами могут быть отформатированы в несколько строк, каждая строка после первой начинается с вертикальной черты.

В лексических определениях (как в примере выше) используются ещё два соглашения: Два литеральных символа, разделённые тремя точками, означают любой символ в данном (включительном) диапазоне символов ASCII. Фраза между угловыми скобками (<...>) даёт неформальное описание определяемого символа; например, это может быть использовано для описания понятия «управляющий символ», если необходимо.

Несмотря на то, что используемая нотация почти одна и та же, существует большая разница между значением лексического и синтаксического определений: лексическое определение работает с отдельными символами входного источника, в то время как определение синтаксиса работает с потоком токенов, генерируемых лексическим анализом. Все случаи использования BNF в следующей главе («Лексический анализ») являются лексическими определениями; в последующих главах используются синтаксические определения.

→ Ссылка