constexpr BacktrackingParser(const A &parser) : parser_{parser} {}
std::optional<resultType> Parse(ParseState *state) const {
Messages messages{std::move(state->messages())};
- Message::Context context{state->context()};
ParseState backtrack{*state};
std::optional<resultType> result{parser_.Parse(state)};
if (result.has_value()) {
} else {
*state = std::move(backtrack);
state->messages() = std::move(messages);
- state->set_context(std::move(context));
}
return result;
}
constexpr AlternativeParser(const PA &pa, const PB &pb) : pa_{pa}, pb_{pb} {}
std::optional<resultType> Parse(ParseState *state) const {
Messages messages{std::move(state->messages())};
- Message::Context context{state->context()};
ParseState backtrack{*state};
if (std::optional<resultType> ax{pa_.Parse(state)}) {
messages.Annex(state->messages());
}
ParseState paState{std::move(*state)};
*state = std::move(backtrack);
- state->set_context(std::move(context));
if (std::optional<resultType> bx{pb_.Parse(state)}) {
messages.Annex(state->messages());
state->messages() = std::move(messages);
constexpr RecoveryParser(const RecoveryParser &) = default;
constexpr RecoveryParser(const PA &pa, const PB &pb) : pa_{pa}, pb_{pb} {}
std::optional<resultType> Parse(ParseState *state) const {
- Messages messages{std::move(state->messages())};
- Message::Context context{state->context()};
- ParseState backtrack{*state};
bool originallyDeferred{state->deferMessages()};
-#if 0
- state->set_deferMessages(true);
-#endif
- std::optional<resultType> ax{pa_.Parse(state)};
-#if 0
- if (!originallyDeferred && state->anyDeferredMessages()) {
- CHECK(state->messages().empty());
+ ParseState backtrack{*state};
+ if (!originallyDeferred && state->messages().empty() &&
+ !state->anyErrorRecovery()) {
+ state->set_deferMessages(true);
+ if (std::optional<resultType> ax{pa_.Parse(state)}) {
+ if (!state->anyDeferredMessages() && !state->anyErrorRecovery()) {
+ state->set_deferMessages(false);
+ return ax;
+ }
+ }
*state = backtrack;
- state->set_context(context);
- ax = pa_.Parse(state);
- CHECK(!state->messages().empty());
}
-#endif
- if (ax.has_value()) {
+ Messages messages{std::move(state->messages())};
+ if (std::optional<resultType> ax{pa_.Parse(state)}) {
messages.Annex(state->messages());
state->messages() = std::move(messages);
- state->set_context(std::move(context));
- state->set_deferMessages(originallyDeferred);
return ax;
}
- Messages paMessages{std::move(state->messages())};
+ messages.Annex(state->messages());
*state = std::move(backtrack);
state->set_deferMessages(true);
std::optional<resultType> bx{pb_.Parse(state)};
- CHECK(state->messages().empty());
state->messages() = std::move(messages);
- state->set_context(std::move(context));
state->set_deferMessages(originallyDeferred);
if (bx.has_value()) {
- state->messages().Annex(paMessages);
state->set_anyErrorRecovery();
}
return bx;
: p_{&cooked[0]}, limit_{p_ + cooked.size()}, messages_{cooked} {}
ParseState(const ParseState &that)
: p_{that.p_}, limit_{that.limit_}, messages_{that.messages_.cooked()},
- userState_{that.userState_}, inFixedForm_{that.inFixedForm_},
- encoding_{that.encoding_}, strictConformance_{that.strictConformance_},
+ context_{that.context_}, userState_{that.userState_},
+ inFixedForm_{that.inFixedForm_}, encoding_{that.encoding_},
+ strictConformance_{that.strictConformance_},
warnOnNonstandardUsage_{that.warnOnNonstandardUsage_},
warnOnDeprecatedUsage_{that.warnOnDeprecatedUsage_},
anyErrorRecovery_{that.anyErrorRecovery_},
deferMessages_{that.deferMessages_}, anyDeferredMessages_{
that.anyDeferredMessages_} {}
ParseState &operator=(const ParseState &that) {
- p_ = that.p_, limit_ = that.limit_;
+ p_ = that.p_, limit_ = that.limit_, context_ = that.context_;
userState_ = that.userState_, inFixedForm_ = that.inFixedForm_;
encoding_ = that.encoding_, strictConformance_ = that.strictConformance_;
warnOnNonstandardUsage_ = that.warnOnNonstandardUsage_;
}
ParseState &operator=(ParseState &&that) {
p_ = that.p_, limit_ = that.limit_, messages_ = std::move(that.messages_);
+ context_ = std::move(that.context_);
userState_ = that.userState_, inFixedForm_ = that.inFixedForm_;
encoding_ = that.encoding_, strictConformance_ = that.strictConformance_;
warnOnNonstandardUsage_ = that.warnOnNonstandardUsage_;
void set_anyConformanceViolation() { anyConformanceViolation_ = true; }
UserState *userState() const { return userState_; }
- void set_userState(UserState *u) { userState_ = u; }
-
- Message::Context context() const { return context_; }
- ParseState &set_context(const Message::Context &c) {
- context_ = c;
- return *this;
- }
- ParseState &set_context(Message::Context &&c) {
- context_ = std::move(c);
+ ParseState &set_userState(UserState *u) {
+ userState_ = u;
return *this;
}