GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Writing-PEG-Rules.html ・ emacs-doc.conao3.com

37.3 PEGルールの記述

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 またはパーススタックのコンテキストが返されます。