// fail<A>("..."_err_en_US) returns a parser that never succeeds. It reports an
// error message at the current position. The result type is unused,
-// but might have to be specified at the point of call for satisfy
+// but might have to be specified at the point of call to satisfy
// the type checker. The state remains valid.
template<typename A> class FailParser {
public:
return FailParser<A>{t};
}
-// pure(x) returns a parsers that always succeeds, does not advance the
+// pure(x) returns a parser that always succeeds, does not advance the
// parse, and returns a captured value whose type must be copy-constructible.
template<typename A> class PureParser {
public:
private:
template<int J>
- void ParseRest(std::optional<resultType> &result, ParseState &state, ParseState &backtrack) const {
+ void ParseRest(std::optional<resultType> &result, ParseState &state,
+ ParseState &backtrack) const {
ParseState prevState{std::move(state)};
state = backtrack;
result = std::get<J>(ps_).Parse(state);
// instance of T constructed upon the values they returned.
// With a single argument that is a parser with no usable value,
// construct<T>(p) invokes T's default nullary constructor (T(){}).
+// (This means that "construct<T>(Foo >> Bar >> ok)" is functionally
+// equivalent to "Foo >> Bar >> construct<T>()", but I'd like to hold open
+// the opportunity to make construct<> capture source provenance all of the
+// time, and the first form will then lead to better error positioning.)
template<typename RESULT, typename... PARSER, std::size_t... J>
inline RESULT ApplyHelperConstructor(
using resultType = Success;
constexpr FixedParser() {}
static constexpr std::optional<Success> Parse(ParseState &) {
- if (pass) {
+ if constexpr (pass) {
return Success{};
+ } else {
+ return std::nullopt;
}
- return std::nullopt;
}
};
constexpr auto obsoleteExecutionPartConstruct{recovery(ignoredStatementPrefix >>
fail<ExecutionPartConstruct>(
"obsolete legacy extension is not supported"_err_en_US),
- construct<ExecutionPartConstruct>(
+ construct<ExecutionPartConstruct>(construct<ErrorRecovery>(ok /
statement("REDIMENSION" >> name >>
- parenthesized(nonemptyList(Parser<AllocateShapeSpec>{})) >> ok) >>
- construct<ErrorRecovery>()))};
+ parenthesized(nonemptyList(Parser<AllocateShapeSpec>{}))))))};
TYPE_PARSER(recovery(
withMessage("expected execution part construct"_err_en_US,
statement(indirect(dataStmt))),
extension<LanguageFeature::ExecutionPartNamelist>(
construct<ExecutionPartConstruct>(
- statement(indirect(Parser<NamelistStmt>{}))) ||
- obsoleteExecutionPartConstruct)))),
+ statement(indirect(Parser<NamelistStmt>{})))),
+ obsoleteExecutionPartConstruct))),
construct<ExecutionPartConstruct>(executionPartErrorRecovery)))
// R509 execution-part -> executable-construct [execution-part-construct]...