Я пытаюсь придумать грамматику PEG, который разобрать имя хоста в соответствии со следующей BNF из RFC 2396Как можно выразить грамматику из RFC 2396 (около URI) в PEG?
hostname = *(domainlabel ".") toplabel [ "." ]
domainlabel = alphanum | alphanum *(alphanum | "-") alphanum
toplabel = alpha | alpha *(alphanum | "-") alphanum
Там нет никаких проблем с domainlabel
и toplabel
.
Правило для hostname
Однако, похоже, не может быть выражено в ПЭГ.
Вот почему я так думаю:
Если взять грамматику, как написано в BNF весь вход потребляемую *(domainlabel ".")
, который не знает, когда остановиться, так как toplabel [ "." ]
неотличима от него.
упрощен самодостаточная иллюстрация:
h = (d '.')* t '.'?
d = [dt]
t = [t]
Это разобрать t
, d.d.t
и не на d.d.d
который полностью ожидаемый, но он не может разобрать t.
и d.d.t.
которые оба являются допустимыми случаями.
Если мы добавим lookahead, тогда он будет потреблять t.
и d.d.t.
, но сбой на d.t.t.
.
h = (!(t '.'?)d '.')* t '.'?
d = [dt]
t = [t]
Итак, у меня нет идей, есть ли способ выразить этот BNF в PEG?
Меня интересует ваш последний пункт перезаписи 'a | b'. Можете ли вы дать некоторые рекомендации? – Seki
@seki: это просто теория множеств, так как '|' является объединением двух множеств. У набора нет повторяющихся элементов, поэтому, когда вы вычисляете объединение A и B, вы можете удалить из B элементы, уже входящие в объединение, потому что они находятся в A. – rici
Спасибо за объяснение :) – Seki