The Epsilon (epsilon_p and eps_p) is a multi-purpose parser that returns a zero length match.
In its simplest form, epsilon_p matches the null string and always returns a match of zero length:
epsilon_p // always returns a zero-length match
This form is usually used to trigger a semantic action unconditionally. For example, it is useful in triggering error messages when a set of alternatives fail:
r = A | B | C | eps_p[error]; // error if A, B, or C fails to match
Semantic predicates allow you to attach a function anywhere in the grammar. In this role, the epsilon takes a 0-ary (nullary) function/functor. The run-time function/functor is typically a test that is called upon to resolve ambiguity in the grammar. A parse failure will be reported when the function/functor result evaluates to false. Otherwise an empty match will be reported. The general form is:
eps_p(f) >> rest;
The nullary function f is called to do a semantic test (say, checking if a symbol is in the symbol table). If test returns true, rest will be evaluated. Otherwise, the production will return early with a no-match without ever touching rest.
Similar to Semantic predicates, Syntactic predicates assert a certain conditional syntax to be satisfied before evaluating another production. This time, epsilon_p accepts a (conditional) parser. The general form is:
eps_p(p) >> rest;
If p is matched on the input stream then attempt to recognize rest. The parser p is called to do a syntax check. Regardless of p's success, eps_p(p) will always return a zero length match (i.e. the input is not consumed). If test returns true, rest will be evaluated. Otherwise, the production will return early with a no-match without ever touching rest.
eps_p('0') >> oct_p // note that '0' is actually a ch_p('0')
Epsilon here is used as a syntactic predicate. oct_p (see numerics) is parsed only if we see a leading '0'. Wrapping the leading '0' inside an epsilon makes the parser not consume anything from the input. If a '0' is seen, epsilon_p reports a successful match with zero length.
Epsilon allows primitive type arguments such as char, int, wchar_t, char const*, wchar_t const* and so on. Examples:
In a syntactic predicate eps_p(p), any semantic action directly or indirectly attached to the conditional parser p will not be called. However, semantic actions attached to epsilon itself will always be called. The following code snippets illustrates the behavior:
eps_p(c[f]) // f not called
eps_p(c)[f] // f is called
eps_p[f] // f is called
Actually, the conditional parser p is implicitly wrapped in a no_actions_d directive:
The conditional parser is required to be free from side-effects (semantic actions).
The conditional parser's purpose is to resolve ambiguity by looking
ahead in the input stream for a certain pattern. Ambiguity and semantic actions
do not mix well. On an ambiguous grammar, backtracking happens. And when it
happens, we cannot undo the effects of triggered semantic actions.
Operator ~ is defined for parsers constructed by epsilon_p/eps_p. It performs negation by complementing the results reported. ~~eps_p(x) is identical to eps_p(x).
Copyright © 1998-2003 Joel de Guzman
Copyright © 2003 Martin Wille
Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)