デフォルトでは、パース処理は単に現在のバッファ内のポイントを移動させ、最終的にパースが成功すれば t
を、失敗すれば nil を返します。また、パース済みテキストの特定の箇所で任意の Elisp
を実行できる パースアクション を定義することも可能です。これらのアクションは、オプションで パーススタック(パース処理によって返された値のリスト)に影響を与えることができます。これらのアクションは、パース処理が最終的に成功した場合にのみ実行(および値の返却)され、失敗した場合にはアクションコードは一切実行されません。
アクションは、ルールの定義内の任意の場所に追加できます。アクションは、先頭にバッククォート(‘`’)があり、その後に括弧形式の式が続くことで構文解析式と区別されます。この括弧形式の式の中には、必ずハイフンのペア(‘--’)が含まれていなければなりません。ハイフンの左側にあるシンボルは、スタックからポップされた値にバインドされます(これはラムダ式の引数リストにある程度似ています)。ハイフンの右側にあるコードによって生成された値は、スタックにプッシュされます(ラムダ式の戻り値に相当します)。例えば、前述の文法にアクションを追加することで、解析された数値を実際の整数として返すことができます:
(with-peg-rules ((number sign digit (* digit
`(a b -- (+ (* a 10) b)))
`(sign val -- (* sign val)))
(sign (or (and "+" `(-- 1))
(and "-" `(-- -1))
(and "" `(-- 1))))
(digit [0-9] `(-- (- (char-before) ?0))))
(peg-run (peg number)))
スタック上の値は、ポップして返される前に存在している必要があります。アクションの左辺項にバインドするためのスタック上の値が十分でない場合、それらは
nil
にバインドされます。右辺項のみを持つアクションは値をスタックにプッシュし、左辺項のみを持つアクションはスタックから値を消費(および破棄)します。構文解析の終了時、スタック上の値はフラットなリストとして返されます。
PEXでマッチした文字列を(単にポイントを移動させるのではなく)返すには、文法で次のようなルールを使用できます。
(one-word `(-- (point)) (+ [word]) `(start -- (buffer-substring start (point))))
上記の最初の処理では、pointの初期値がスタックにプッシュされます。その間に行われるPEXにより、pointが次のワードへと移動します。2番目の処理では、スタックから直前の値をポップし(それを変数startにバインドし)、その値を用いてバッファから部分文字列を抽出してスタックにプッシュします。このパターンは非常に一般的であるため、PEGでは上記と全く同じ処理を行う短縮関数に加え、よくあるシナリオ向けのいくつかの短縮関数が提供されています: