следующая грамматика (из RFC 2396):
domainlabel = 'a' / ('a' ('a' / '-')* 'a')
не может разобрать это:
aa
Почему?
следующая грамматика (из RFC 2396):
domainlabel = 'a' / ('a' ('a' / '-')* 'a')
не может разобрать это:
aa
Почему?
Потому что ПЭГ - это не BNF. Использование / вместо обычного оператора чередования BNF | (как видно из RFC 2396) было преднамеренной попыткой избежать путаницы (хотя это не помогает, что старые стандарты например, RFC 822 также используется /).
В PEG / - это "упорядоченный strong > -выбор "оператор. В отличие от оператора чередования BNF, / не является симметричным. Если первая альтернатива успешна, она принимается. Только если первая альтернатива терпит неудачу, PEG откатывается и пробует вторую альтернативу.
Таким образом, когда 'a' / ('a' ('a' / '-')* 'a')
применяется к aa
, первая альтернатива успешно поглощает первый a, а вторая альтернатива никогда не выполняется. Тот факт, что синтаксический анализ впоследствии не соответствует всей строке, не имеет значения; / выполняет возврат только в том случае, если не удается сопоставить первую альтернативу, а не в случае сбоя какой-либо последующей части синтаксического анализа.
Короче говоря, если вы используете PEG, вам нужно быть осторожным, чтобы записывать свои варианты в правильном порядке.