PEGルールを記述する際に留意すべき点は、ルールが貪欲であるということです。可変量のテキストを消費できるルールは、たとえそれによって、本来であればマッチしたはずのルールが後で失敗することになったとしても、常に可能な限り最大量を消費します – バックトラッキングは行われません。例えば、このルールが成功することはありません:
(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))
point の後に「game over」というテキストを含むバッファで実行されると、point
を「game」の直後まで移動させた後、パースを停止し、nil
を返します。パースに成功した場合は、常に t またはパーススタックのコンテキストが返されます。