Header lexy/dsl/operator.hpp
Define operators of an expression
.
Branch rule lexy::dsl::op
lexy/dsl/operator.hpp
namespace lexy
{
template <auto OperatorRule>
using op = see-below;
}
namespace lexy::dsl
{
constexpr operator-rule auto op(branch-rule auto r); (1)
template <typename Tag>
constexpr operator-rule auto op(branch-rule auto r); (2)
template <auto Tag>
constexpr operator-rule auto op(branch-rule auto r); (3)
}
op
is a branch rule that parses an operator.
- Requires
r
is either a literal rule or abranch
whose condition is a literal rule.- (Branch) parsing
Parses
r
.- Errors
All errors raised by (branch) parsing
r
.- Values
A single value describing the operator that was just parsed (the tag), followed by all values produced by
r
. The type of the tag value is given bylexy::op
, it is:For overload 1, a unique type computed from the rule
r
.For overload 2 and
Tag != void
, an object of the specifiedTag
type. IfTag
is constructible from the iterator type of the input, it constructs it giving it the start position of the operator. Similarly, it is also possible to construct theTag
from the parse state and the iterator. Otherwise, it uses the default constructor.For overload 2 and
Tag == void
, no tag value is produced.For overload 3, an object of implementation-defined type that is implicitly convertible to the type of
Tag
, returning that value.
struct production : lexy::expression_production
{
static constexpr auto atom = dsl::integer<int>;
struct operation : dsl::infix_op_left
{
static constexpr auto op = dsl::op(dsl::lit_c<'+'>);
using operand = dsl::atom;
};
static constexpr auto value
= lexy::callback<int>([](int value) { return value; },
[](int lhs, lexy::op<operation::op>, int rhs) { return lhs + rhs; });
};
struct plus
{
const LEXY_CHAR8_T* pos;
constexpr plus(const LEXY_CHAR8_T* pos) : pos(pos) {}
};
struct production : lexy::expression_production
{
static constexpr auto atom = dsl::integer<int>;
struct operation : dsl::infix_op_left
{
static constexpr auto op = dsl::op<plus>(dsl::lit_c<'+'>);
using operand = dsl::atom;
};
static constexpr auto value = lexy::callback<int>([](int value) { return value; },
[](int lhs, plus op, int rhs) {
LEXY_PRECONDITION(*op.pos == '+');
return lhs + rhs;
});
};
Tip | Use a branch rule as operators to parse a ternary operator, as seen in calculator.cpp
. |
Branch rule lexy::dsl::operator/ (operator)
lexy/dsl/operator.hpp
namespace lexy::dsl
{
constexpr operator-rule auto operator/(operator-rule auto lhs,
operator-rule auto rhs);
}
operator/
is a branch rule that parses one of multiple operators.
- Branch parsing
Let
lset
be thelexy::dsl::literal_set
created by collecting all initial literal rules oflhs
andrhs
, possibly recursively if they themselves are created usingoperator/
. Tries to match and consumelset
, backtracks if that fails. Otherwise, it has selected the initial operator of alexy::dsl::op
rule, parses the remainder of the rule without backtracking.- Parsing
Same as branch parsing, but fails instead of backtracking.
- Errors
lexy::expected_literal_set
: if no initial literal rule matched, at the initial position.All errors raised by parsing the selected operator.
- Values
All values produced by the selected operator, including the tag.
constexpr auto op_plus = dsl::op(dsl::lit_c<'+'>);
constexpr auto op_minus = dsl::op(dsl::lit_c<'-'>);
struct production : lexy::expression_production
{
static constexpr auto atom = dsl::integer<int>;
struct operation : dsl::infix_op_left
{
static constexpr auto op = op_plus / op_minus;
using operand = dsl::atom;
};
static constexpr auto value
= lexy::callback<int>([](int value) { return value; },
[](int lhs, lexy::op<op_plus>, int rhs) { return lhs + rhs; },
[](int lhs, lexy::op<op_minus>, int rhs) { return lhs - rhs; });
};