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