Header lexy/dsl/operator.hpp
Define operators of an expression.
Branch rule lexy::dsl::op
lexy/dsl/operator.hppnamespace 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
ris either a literal rule or abranchwhose 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 specifiedTagtype. IfTagis 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 theTagfrom 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.hppnamespace 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
lsetbe thelexy::dsl::literal_setcreated by collecting all initial literal rules oflhsandrhs, 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::oprule, 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; });
};