Header lexy/dsl/error.hpp
Rules that generate errors.
Rule lexy::dsl::error
lexy/dsl/error.hpp
namespace lexy::dsl
{
template <typename Tag>
constexpr branch-rule auto error;
template <typename Tag>
constexpr branch-rule auto error(rule auto rule);
}
error
is a rule that always fails and reports an error.
- Parsing
The first overload fails immediately without consuming anything. The second overload first tries to match
rule
in a new context. The rule then still fails unconditionally without consuming anything.- Branch parsing
In a branch,
error
fails in the same way, but the branch has been considered taken and no backtracking occurs.- Errors
A generic error with the specified
Tag
. For the first overload, it is raised at the unchanged reader position. For the second overload, its range covers everything matched byrule
. The rule then fails.- Values
None.
Tip | Use error in error production: if a certain ill-formed input is common, create a separate rule for it.
If it is parsed, a custom error is always raised. |
Note | Automatic whitespace skipping is disabled while parsing rule . |
Warning | rule does not have access to any context variables created by the context-sensitive parsing facilities and it can’t use recursion. |
Branch rule lexy::dsl::must
lexy/dsl/error.hpp
namespace lexy::dsl
{
class must-dsl // note: not a rule itself
{
public:
template <typename Tag>
static constexpr branch-rule auto error;
template <typename Tag>
constexpr branch-rule auto error(rule auto capture);
};
constexpr must-dsl must(branch-rule auto rule);
}
must
is a branch rule that tries to parse another branch rule and raises a specific error if that backtracks.
If must(rule).error<Tag>
is used, the associated error rule e
is lexy::dsl::error<Tag>
.
Otherwise, if must(rule).error<Tag>(capture)
is used, the associated error rule e
is lexy::dsl::error<Tag>(capture)
.
- Requires
rule
is a branch rule that is not unconditionally taken (e.g. notlexy::dsl::else_
).- Parsing
Parses the
choice
rule | e
, wheree
is the associated error rule, i.e. it tries to parserule
and raises a specific error if that fails.- Branch parsing
Tries to parse
rule
and produces the same result.- Errors
All errors raised by branch parsing of
rule
. The rule then fails ifrule
has failed.A generic error with the specified
Tag
: if the rule backtracks during non-branch parsing. Its range covers anything consumed by the optionalcapture
rule, just likelexy::dsl::error
.
struct production
{
struct expected_sep
{
static constexpr auto name = "expected separator";
};
static constexpr auto rule = [] {
// A separator is either blank or \ + newline.
// If a separator is not present, raise the specific error.
auto blank = dsl::ascii::blank;
auto escaped_nl = dsl::backslash >> dsl::newline;
auto sep = dsl::must(blank | escaped_nl).error<expected_sep>;
return LEXY_LIT("echo") + sep
+ dsl::identifier(dsl::ascii::alnum)
// Allow an optional separator before EOL.
+ dsl::if_(sep) + dsl::eol;
}();
};
Note | See shell.cpp
for a more complete shell parser. |
Tip | Use must(rule).error<Tag> if you sometimes need to parse rule unconditionally with a specific error, and sometimes as a branch rule. |
Note | The difference between must(rule).error<Tag> and the choice rule | lexy::dsl::error<Tag> is that the former is still a branch condition.
The choice is not a branch condition, as it is unconditionally: it will either parse rule and succeed, or fail, but never backtrack.
must on the other hand will behave exactly the same as rule during branch parsing.
That way, something like lexy::dsl::if_ (must(rule).error<Tag>) is equivalent to lexy::dsl::if_(rule) . |
Note | If rule is a token rule, must(rule).error<Tag> is equivalent to rule.error<Tag> . |