9#ifndef FORTRAN_PARSER_BASIC_PARSERS_H_
10#define FORTRAN_PARSER_BASIC_PARSERS_H_
25#include "flang/Common/Fortran-features.h"
26#include "flang/Common/idioms.h"
27#include "flang/Common/indirection.h"
28#include "flang/Parser/char-block.h"
29#include "flang/Parser/message.h"
30#include "flang/Parser/parse-state.h"
31#include "flang/Parser/provenance.h"
32#include "flang/Parser/user-state.h"
54 std::optional<A> Parse(
ParseState &state)
const {
63template <
typename A = Success>
inline constexpr auto fail(
MessageFixedText t) {
76 constexpr explicit PureParser(A &&x) : value_(std::move(x)) {}
77 std::optional<A> Parse(
ParseState &)
const {
return value_; }
83template <
typename A>
inline constexpr auto pure(A x) {
92 std::optional<A> Parse(
ParseState &)
const {
return std::make_optional<A>(); }
95template <
typename A>
inline constexpr auto pure() {
103 using resultType =
typename A::resultType;
106 std::optional<resultType> Parse(
ParseState &state)
const {
107 Messages messages{std::move(state.messages())};
109 std::optional<resultType> result{parser_.Parse(state)};
111 state.messages().Annex(std::move(messages));
113 state = std::move(backtrack);
114 state.messages() = std::move(messages);
123template <
typename A>
inline constexpr auto attempt(
const A &parser) {
134 std::optional<Success> Parse(
ParseState &state)
const {
136 forked.set_deferMessages(
true);
137 if (parser_.Parse(forked)) {
147template <
typename PA,
typename =
typename PA::resultType>
148constexpr auto operator!(PA p) {
159 std::optional<Success> Parse(
ParseState &state)
const {
161 forked.set_deferMessages(
true);
162 if (parser_.Parse(forked)) {
172template <
typename PA>
inline constexpr auto lookAhead(PA p) {
180 using resultType =
typename PA::resultType;
183 : text_{t}, parser_{p} {}
184 std::optional<resultType> Parse(
ParseState &state)
const {
185 state.PushContext(text_);
186 std::optional<resultType> result{parser_.Parse(state)};
196template <
typename PA>
206 using resultType =
typename PA::resultType;
209 : text_{t}, parser_{p} {}
210 std::optional<resultType> Parse(
ParseState &state)
const {
211 if (state.deferMessages()) {
212 std::optional<resultType> result{parser_.Parse(state)};
214 state.set_anyDeferredMessages();
218 Messages messages{std::move(state.messages())};
219 bool hadAnyTokenMatched{state.anyTokenMatched()};
220 state.set_anyTokenMatched(
false);
221 std::optional<resultType> result{parser_.Parse(state)};
222 bool emitMessage{
false};
224 messages.Annex(std::move(state.messages()));
225 if (hadAnyTokenMatched) {
226 state.set_anyTokenMatched();
228 }
else if (state.anyTokenMatched()) {
229 emitMessage = state.messages().empty();
230 messages.Annex(std::move(state.messages()));
233 if (hadAnyTokenMatched) {
234 state.set_anyTokenMatched();
237 state.messages() = std::move(messages);
249template <
typename PA>
260 using resultType =
typename PB::resultType;
263 std::optional<resultType> Parse(
ParseState &state)
const {
264 if (pa_.Parse(state)) {
265 return pb2_.Parse(state);
276template <
typename PA,
typename PB>
277inline constexpr auto operator>>(PA pa, PB pb) {
283 using resultType =
typename PA::resultType;
285 constexpr FollowParser(PA pa, PB pb) : pa_{pa}, pb_{pb} {}
286 std::optional<resultType> Parse(
ParseState &state)
const {
287 if (std::optional<resultType> ax{pa_.Parse(state)}) {
288 if (pb_.Parse(state)) {
300template <
typename PA,
typename PB>
301inline constexpr auto operator/(PA pa, PB pb) {
307 using resultType =
typename PA::resultType;
310 std::optional<resultType> Parse(
ParseState &state)
const {
311 Messages messages{std::move(state.messages())};
313 std::optional<resultType> result{std::get<0>(ps_).Parse(state)};
314 if constexpr (
sizeof...(Ps) > 0) {
316 ParseRest<1>(result, state, backtrack);
319 state.messages().Annex(std::move(messages));
325 void ParseRest(std::optional<resultType> &result,
ParseState &state,
329 result = std::get<J>(ps_).Parse(state);
331 state.CombineFailedParses(std::move(prevState));
332 if constexpr (J <
sizeof...(Ps)) {
333 ParseRest<J + 1>(result, state, backtrack);
338 const std::tuple<PA, Ps...> ps_;
341template <
typename... Ps>
inline constexpr auto first(Ps... ps) {
345template <
typename PA,
typename PB>
346inline constexpr auto operator||(PA pa, PB pb) {
347 return AlternativesParser<PA, PB>{pa, pb};
356 using resultType =
typename PA::resultType;
357 static_assert(std::is_same_v<resultType, typename PB::resultType>);
360 std::optional<resultType> Parse(
ParseState &state)
const {
361 bool originallyDeferred{state.deferMessages()};
363 if (!originallyDeferred && state.messages().empty() &&
364 !state.anyErrorRecovery()) {
368 state.set_deferMessages(
true);
369 if (std::optional<resultType> ax{pa_.Parse(state)}) {
370 if (!state.anyDeferredMessages() && !state.anyErrorRecovery()) {
371 state.set_deferMessages(
false);
377 Messages messages{std::move(state.messages())};
378 if (std::optional<resultType> ax{pa_.Parse(state)}) {
379 state.messages().Annex(std::move(messages));
382 messages.Annex(std::move(state.messages()));
383 bool hadDeferredMessages{state.anyDeferredMessages()};
384 bool anyTokenMatched{state.anyTokenMatched()};
385 state = std::move(backtrack);
386 state.set_deferMessages(
true);
387 std::optional<resultType> bx{pb_.Parse(state)};
388 state.messages() = std::move(messages);
389 state.set_deferMessages(originallyDeferred);
390 if (anyTokenMatched) {
391 state.set_anyTokenMatched();
393 if (hadDeferredMessages) {
394 state.set_anyDeferredMessages();
398 CHECK(state.anyDeferredMessages() || state.messages().AnyFatalError());
399 state.set_anyErrorRecovery();
409template <
typename PA,
typename PB>
410inline constexpr auto recovery(PA pa, PB pb) {
418 using paType =
typename PA::resultType;
421 using resultType = std::list<paType>;
423 constexpr ManyParser(PA parser) : parser_{parser} {}
424 std::optional<resultType> Parse(
ParseState &state)
const {
426 auto at{state.GetLocation()};
427 while (std::optional<paType> x{parser_.Parse(state)}) {
428 result.emplace_back(std::move(*x));
429 if (state.GetLocation() <= at) {
432 at = state.GetLocation();
434 return {std::move(result)};
441template <
typename PA>
inline constexpr auto many(PA parser) {
450 using paType =
typename PA::resultType;
453 using resultType = std::list<paType>;
455 constexpr SomeParser(PA parser) : parser_{parser} {}
456 std::optional<resultType> Parse(
ParseState &state)
const {
457 auto start{state.GetLocation()};
458 if (std::optional<paType> first{parser_.Parse(state)}) {
460 result.emplace_back(std::move(*first));
461 if (state.GetLocation() > start) {
462 result.splice(result.end(), many(parser_).Parse(state).value());
464 return {std::move(result)};
473template <
typename PA>
inline constexpr auto some(PA parser) {
483 std::optional<Success> Parse(
ParseState &state)
const {
484 for (
auto at{state.GetLocation()};
485 parser_.Parse(state) && state.GetLocation() > at;
486 at = state.GetLocation()) {
495template <
typename PA>
inline constexpr auto skipMany(PA parser) {
507 std::optional<Success> Parse(
ParseState &state)
const {
508 while (parser_.Parse(state)) {
517template <
typename PA>
inline constexpr auto skipManyFast(PA parser) {
524 using paType =
typename PA::resultType;
527 using resultType = std::optional<paType>;
529 constexpr MaybeParser(PA parser) : parser_{parser} {}
530 std::optional<resultType> Parse(
ParseState &state)
const {
531 if (resultType result{parser_.Parse(state)}) {
533 return {std::move(result)};
542template <
typename PA>
inline constexpr auto maybe(PA parser) {
551 using resultType =
typename PA::resultType;
554 std::optional<resultType> Parse(
ParseState &state)
const {
555 std::optional<std::optional<resultType>> ax{maybe(parser_).Parse(state)};
557 return std::move(*ax);
566template <
typename PA>
inline constexpr auto defaulted(PA p) {
591template <
typename... PARSER>
592using ApplyArgs = std::tuple<std::optional<typename PARSER::resultType>...>;
594template <
typename... PARSER, std::size_t... J>
595inline bool ApplyHelperArgs(
const std::tuple<PARSER...> &parsers,
596 ApplyArgs<PARSER...> &args, ParseState &state, std::index_sequence<J...>) {
598 (std::get<J>(args) = std::get<J>(parsers).Parse(state),
599 std::get<J>(args).has_value()));
603template <
typename RESULT,
typename... PARSER>
604using ApplicableFunctionPointer = RESULT (*)(
typename PARSER::resultType &&...);
605template <
typename RESULT,
typename... PARSER>
606using ApplicableFunctionObject =
607 const std::function<RESULT(
typename PARSER::resultType &&...)> &;
609template <
template <
typename...>
class FUNCTION,
typename RESULT,
610 typename... PARSER, std::size_t... J>
611inline RESULT ApplyHelperFunction(FUNCTION<RESULT, PARSER...> f,
612 ApplyArgs<PARSER...> &&args, std::index_sequence<J...>) {
613 return f(std::move(*std::get<J>(args))...);
616template <
template <
typename...>
class FUNCTION,
typename RESULT,
619 using funcType = FUNCTION<RESULT, PARSER...>;
622 using resultType = RESULT;
625 : function_{f}, parsers_{p...} {}
626 std::optional<resultType> Parse(
ParseState &state)
const {
627 ApplyArgs<PARSER...> results;
628 using Sequence = std::index_sequence_for<PARSER...>;
629 if (ApplyHelperArgs(parsers_, results, state, Sequence{})) {
630 return ApplyHelperFunction<FUNCTION, RESULT, PARSER...>(
631 function_, std::move(results), Sequence{});
638 const funcType function_;
639 const std::tuple<PARSER...> parsers_;
642template <
typename RESULT,
typename... PARSER>
643inline constexpr auto applyFunction(
644 ApplicableFunctionPointer<RESULT, PARSER...> f,
const PARSER &...parser) {
645 return ApplyFunction<ApplicableFunctionPointer, RESULT, PARSER...>{
649template <
typename RESULT,
typename... PARSER>
650inline auto applyLambda(
651 ApplicableFunctionObject<RESULT, PARSER...> f,
const PARSER &...parser) {
652 return ApplyFunction<ApplicableFunctionObject, RESULT, PARSER...>{
657template <
typename MEMFUNC,
typename OBJPARSER,
typename... PARSER,
659inline auto ApplyHelperMember(MEMFUNC mfp,
660 ApplyArgs<OBJPARSER, PARSER...> &&args, std::index_sequence<J...>) {
661 return ((*std::get<0>(args)).*mfp)(std::move(*std::get<J + 1>(args))...);
664template <
typename MEMFUNC,
typename OBJPARSER,
typename... PARSER>
666 static_assert(std::is_member_function_pointer_v<MEMFUNC>);
667 using funcType = MEMFUNC;
671 std::invoke_result_t<MEMFUNC,
typename OBJPARSER::resultType, PARSER...>;
675 : function_{f}, parsers_{o, p...} {}
676 std::optional<resultType> Parse(
ParseState &state)
const {
677 ApplyArgs<OBJPARSER, PARSER...> results;
678 using Sequence1 = std::index_sequence_for<OBJPARSER, PARSER...>;
679 using Sequence2 = std::index_sequence_for<PARSER...>;
680 if (ApplyHelperArgs(parsers_, results, state, Sequence1{})) {
681 return ApplyHelperMember<MEMFUNC, OBJPARSER, PARSER...>(
682 function_, std::move(results), Sequence2{});
689 const funcType function_;
690 const std::tuple<OBJPARSER, PARSER...> parsers_;
693template <
typename MEMFUNC,
typename OBJPARSER,
typename... PARSER>
694inline constexpr auto applyMem(
695 MEMFUNC memfn,
const OBJPARSER &objParser, PARSER... parser) {
697 memfn, objParser, parser...};
713template <
typename RESULT,
typename... PARSER, std::size_t... J>
714inline RESULT ApplyHelperConstructor(
715 ApplyArgs<PARSER...> &&args, std::index_sequence<J...>) {
716 return RESULT{std::move(*std::get<J>(args))...};
721 using resultType = RESULT;
724 std::optional<resultType> Parse(
ParseState &state)
const {
725 if constexpr (
sizeof...(PARSER) == 0) {
728 if constexpr (
sizeof...(PARSER) == 1) {
729 return ParseOne(state);
731 ApplyArgs<PARSER...> results;
732 using Sequence = std::index_sequence_for<PARSER...>;
733 if (ApplyHelperArgs(parsers_, results, state, Sequence{})) {
734 return ApplyHelperConstructor<RESULT, PARSER...>(
735 std::move(results), Sequence{});
743 std::optional<resultType> ParseOne(
ParseState &state)
const {
744 if constexpr (std::is_same_v<
Success,
typename PARSER::resultType...>) {
745 if (std::get<0>(parsers_).Parse(state)) {
748 }
else if (
auto arg{std::get<0>(parsers_).Parse(state)}) {
749 return RESULT{std::move(*arg)};
754 const std::tuple<PARSER...> parsers_;
757template <
typename RESULT,
typename... PARSER>
758inline constexpr auto construct(PARSER... p) {
764template <
typename PA>
inline constexpr auto indirect(PA p) {
765 return construct<common::Indirection<typename PA::resultType>>(p);
773common::IfNoLvalue<std::list<T>, T> prepend(T &&head, std::list<T> &&rest) {
774 rest.push_front(std::move(head));
775 return std::move(rest);
780 using paType =
typename PA::resultType;
783 using resultType = std::list<paType>;
786 std::optional<resultType> Parse(
ParseState &state)
const {
787 return applyFunction<std::list<paType>>(
788 prepend<paType>, parser_, many(separator_ >> parser_))
797template <
typename PA,
typename PB>
798inline constexpr auto nonemptySeparated(PA p, PB sep) {
809 static constexpr std::optional<Success> Parse(
ParseState &) {
816template <
typename PA,
typename PB>
818 return recovery(withMessage(msg, pa), pb >> pure<typename PA::resultType>());
825 using resultType =
const char *;
827 std::optional<const char *> Parse(
ParseState &state)
const {
828 if (std::optional<const char *> result{state.GetNextChar()}) {
831 state.Say(
"end of file"_err_en_US);
843 using resultType =
typename PA::resultType;
846 : parser_{parser}, message_{msg} {}
848 std::optional<resultType> Parse(
ParseState &state)
const {
849 if (
UserState * ustate{state.userState()}) {
850 if (!ustate->features().IsEnabled(LF)) {
854 auto at{state.GetLocation()};
855 auto result{parser_.Parse(state)};
856 if (result && !message_.empty()) {
858 CharBlock{at, std::max(state.GetLocation(), at + 1)}, LF, message_);
868template <LanguageFeature LF,
typename PA>
873template <LanguageFeature LF,
typename PA>
874inline constexpr auto extension(PA parser) {
875 return NonstandardParser<LF, PA>(parser);
883 using resultType =
typename PA::resultType;
886 std::optional<resultType> Parse(
ParseState &state)
const {
887 if (
UserState * ustate{state.userState()}) {
888 if (!ustate->features().IsEnabled(LF)) {
892 auto at{state.GetLocation()};
893 auto result{parser_.Parse(state)};
895 state.Nonstandard(
CharBlock{at, state.GetLocation()}, LF,
896 "deprecated usage"_port_en_US);
905template <LanguageFeature LF,
typename PA>
906inline constexpr auto deprecated(PA parser) {
913 using resultType =
typename PA::resultType;
916 std::optional<resultType> Parse(
ParseState &state)
const {
917 const char *start{state.GetLocation()};
918 auto result{parser_.Parse(state)};
920 const char *end{state.GetLocation()};
921 for (; start < end && start[0] ==
' '; ++start) {
923 for (; start < end && end[-1] ==
' '; --end) {
934template <
typename PA>
inline constexpr auto sourced(PA parser) {
Definition: basic-parsers.h:305
Definition: basic-parsers.h:719
Definition: basic-parsers.h:618
Definition: basic-parsers.h:665
Definition: basic-parsers.h:101
Definition: char-block.h:28
Definition: basic-parsers.h:549
Definition: basic-parsers.h:881
Definition: basic-parsers.h:49
Definition: basic-parsers.h:281
Definition: basic-parsers.h:154
Definition: basic-parsers.h:417
Definition: basic-parsers.h:523
Definition: basic-parsers.h:178
Definition: message.h:319
Definition: basic-parsers.h:129
Definition: basic-parsers.h:778
Definition: basic-parsers.h:841
Definition: parse-state.h:35
Definition: basic-parsers.h:87
Definition: basic-parsers.h:72
Definition: basic-parsers.h:354
Definition: basic-parsers.h:258
Definition: basic-parsers.h:502
Definition: basic-parsers.h:478
Definition: basic-parsers.h:449
Definition: basic-parsers.h:911
Definition: user-state.h:33
Definition: user-state.h:35
Definition: basic-parsers.h:204
Definition: check-expression.h:19
Definition: basic-parsers.h:824
Definition: basic-parsers.h:806