Важно знать при написании правил PEG, что они жадные (greedy). Правила, которые могут потреблять переменное количество текста, всегда будут потреблять максимально возможное количество, даже если это приведет к сбою правила, которое в противном случае могло бы совпасть – нет обратного отслеживания (backtracking). Например, это правило никогда не сработает:
(forest (+ "tree" (* [blank])) "tree" (eol))
Выражение PEX (+ "tree" (* [blank])) потребляет все повторения слова ‘tree’, не оставляя ни одного для совпадения с финальным ‘tree’.
В таких ситуациях желаемый результат можно получить, используя предикаты и гварды – а именно выражения not, if и guard – для ограничения поведения. Например:
(forest (+ "tree" (* [blank])) (not (eol)) "tree" (eol))
Операторы if и not принимают выражение парсинга и интерпретируют его как булево значение, не перемещая указатель. Содержимое оператора guard оценивается как обычный Lisp (а не PEX) и должно возвращать булево значение. Значение nil приводит к сбою совпадения.
Другое потенциально неожиданное поведение заключается в том, что парсинг будет перемещать указатель как можно дальше, даже если парсинг в конечном итоге завершится неудачей. Это правило:
(end-game "game" (eob))
при запуске в буфере, содержащем текст “game over” после указателя, переместит указатель сразу после “game”, а затем остановит парсинг, вернув nil. Успешный парсинг всегда вернет t или контексты стека парсинга.