Previous: Parsing Actions, Up: Parsing Expression Grammars [Contents][Index]
Something to be aware of when writing PEG rules is that they are greedy. Rules which can consume a variable amount of text will always consume the maximum amount possible, even if that causes a rule that might otherwise have matched to fail later on – there is no backtracking. For instance, this rule will never succeed:
(forest (+ "tree" (* [blank])) "tree" (eol))
The PEX (+ "tree" (* [blank])) will consume all
the repetitions of the word ‘tree’, leaving none to match the final
‘tree’.
In these situations, the desired result can be obtained by using
predicates and guards – namely the not, if and
guard expressions – to constrain behavior. For instance:
(forest (+ "tree" (* [blank])) (not (eol)) "tree" (eol))
The if and not operators accept a parsing expression and
interpret it as a boolean, without moving point. The contents of a
guard operator are evaluated as regular Lisp (not a
PEX) and should return a boolean value. A nil value
causes the match to fail.
Another potentially unexpected behavior is that parsing will move point as far as possible, even if the parsing ultimately fails. This rule:
(end-game "game" (eob))
when run in a buffer containing the text “game over” after point,
will move point to just after “game” then halt parsing, returning
nil. Successful parsing will always return t, or the
contexts of the parsing stack.