грамматика CFG является недетерминированной, что означает, что некоторые входные данные могут привести к двум или более возможным деревьям разбора.Хотя большинство генераторов парсеров на основе CFG имеют ограничения по определимости грамматики.Он выдаст предупреждение или ошибку, если у него будет два или более выбора.
Грамматика PEG является детерминированной, что означает, что любой вход может быть проанализирован только одним способом.
Взять классический пример;Грамматика
if_statement := "if" "(" expr ")" statement "else" statement
| "if" "(" expr ")" statement;
, примененная к входу
if (x1) if (x2) y1 else y2
, может быть проанализирована как
if_statement(x1, if_statement(x2, y1, y2))
или
if_statement(x1, if_statement(x2, y1), y2)
A CFG-parser генерирует конфликт Shift / Reduce, так как он не может решить, должен ли он сдвигаться (читать другой токен) или уменьшать (завершать узел) при достижении ключевого слова "else".Конечно, есть способы обойти эту проблему.
PEG-парсер всегда будет выбирать первый выбор.
Какой из них лучше для вас решить.Мое мнение таково, что часто PEG-грамматику легче писать, а грамматику CFG легче анализировать.