10#define MPC_FORWARD(x) std::forward<decltype(x)>(x)
15 template <
class T,
class U>
16 concept similar_to = std::same_as<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
18 using String = std::list<char>;
19 using ParseError = std::string;
20 using ParseResult = either<ParseError, std::pair<char, String>>;
21 using Parser = StateT<String, ParseResult>;
28 [](
auto&& m1,
auto&& m2) ->
either<mpc::ParseError, std::pair<T, mpc::String>> {
29 if (m1.index() == 0) {
30 if (m2.index() == 0) {
31 return make_left(*
fst(MPC_FORWARD(m1)) +
" and " + *
fst(MPC_FORWARD(m2)));
33 return MPC_FORWARD(m2);
36 return MPC_FORWARD(m1);
48 partial([](
auto&& parser, std::string_view sv) {
49 auto result = eval_StateT % MPC_FORWARD(parser) % String(sv.begin(), sv.end());
50 if (result.index() == 0) {
55 for (
const auto& c : *
snd(result))
57 std::cout << std::endl;
65 inline constexpr auto left =
67 % lift<Parser> %
partial([](similar_to<ParseError>
auto&& str) -> eval_StateT_t<Parser> {
68 return make_left(MPC_FORWARD(str));
72 inline constexpr auto try1 =
75 return make_StateT<String>(
partial(
76 [](
auto&& parser2, similar_to<String>
auto&& str) {
77 return run_StateT % MPC_FORWARD(parser2) % MPC_FORWARD(str);
79 MPC_FORWARD(parser)));
88 return make_StateT<String>(
partial(
89 [](
auto&& p2, similar_to<String>
auto&& str)
90 ->
decltype(run_StateT % (sequence % std::list{p2}) % str) {
91 const auto parse = run_StateT % MPC_FORWARD(p2);
92 auto result = parse % MPC_FORWARD(str);
93 if (result.index() == 0)
94 return make_left(*
fst(std::move(result)));
95 auto [value,
state] = *
snd(std::move(result));
96 std::list<holding_t<
decltype(p2)>> ret{std::move(value)};
98 for (result = parse %
state; result.index() != 0; result = parse %
state) {
99 std::tie(value,
state) = *
snd(std::move(result));
100 ret.push_back(std::move(value));
102 return make_right(std::make_pair(std::move(ret), std::move(
state)));
113 using namespace operators::alternatives;
114 return many1(MPC_FORWARD(p)) or pure<decltype(p)>(std::list<holding_t<
decltype(p)>>{});
120 partial([](
auto&& open,
auto&& p,
auto&& close) {
127 partial([](
auto&& p,
auto&& sep) {
135 partial([](
auto&& p,
auto&& sep) {
136 using namespace operators::alternatives;
137 return sep_by1(MPC_FORWARD(p), MPC_FORWARD(sep))
138 or pure<decltype(p)>(std::list<holding_t<
decltype(p)>>{});
151 partial([](
auto&& p,
auto&& op) {
152 return make_StateT<String>(
partial(
153 [](
auto&& p2,
auto&& op2, similar_to<String>
auto&& str)
154 ->
decltype(run_StateT % p2 % str) {
155 const auto parse = run_StateT % MPC_FORWARD(p2);
156 const auto parse_op = run_StateT % MPC_FORWARD(op2);
158 auto result = parse % MPC_FORWARD(str);
159 if (result.index() == 0)
160 return make_left(*
fst(std::move(result)));
161 auto [value,
state] = *
snd(std::move(result));
164 auto result_op = parse_op %
state;
165 if (result_op.index() == 0)
167 auto [fn, state_op] = *
snd(std::move(result_op));
168 auto result2 = parse % std::move(state_op);
169 if (result2.index() == 0)
171 auto [value2, state2] = *
snd(std::move(result2));
172 value = fn(std::move(value), std::move(value2));
173 state = std::move(state2);
175 return make_right(std::make_pair(std::move(value), std::move(
state)));
177 MPC_FORWARD(p), MPC_FORWARD(op)));
187 partial([](std::predicate<char>
auto&& pred) {
188 return make_StateT<String>(
partial(
189 [](
auto&& pred2, similar_to<String>
auto&& str) -> ParseResult {
190 using namespace std::string_literals;
192 if (
auto m = uncons(MPC_FORWARD(str)); m.index() == 0) {
193 return make_left(
"unexpected end of input"s);
194 }
else if (
auto [x, xs] = *
snd(std::move(m)); not std::invoke(MPC_FORWARD(pred2), x)) {
195 return make_left(
"unexpected "s +
mpc::quoted(std::move(x)));
197 return make_right(std::make_pair(std::move(x), std::move(xs)));
206 using namespace operators::alternatives;
207 using namespace std::string_literals;
214 inline constexpr auto string =
215 partial([](std::string_view sv) {
218 std::list(sv.begin(), sv.end()));
222 using namespace operators::alternatives;
223 using namespace std::string_literals;
225 inline const auto alnum = satisfy % mpc::isalnum or left %
"expecting alnum"s;
226 inline const auto alpha = satisfy % mpc::isalpha or left %
"expecting alpha"s;
227 inline const auto lower = satisfy % mpc::islower or left %
"expecting lower"s;
228 inline const auto upper = satisfy % mpc::isupper or left %
"expecting upper"s;
229 inline const auto digit = satisfy % mpc::isdigit or left %
"expecting digit"s;
230 inline const auto xdigit = satisfy % mpc::isxdigit or left %
"expecting xdigit"s;
231 inline const auto cntrl = satisfy % mpc::iscntrl or left %
"expecting cntrl"s;
232 inline const auto graph = satisfy % mpc::isgraph or left %
"expecting graph"s;
233 inline const auto space = satisfy % mpc::isspace or left %
"expecting space"s;
234 inline const auto blank = satisfy % mpc::isblank or left %
"expecting blank"s;
235 inline const auto print = satisfy % mpc::isprint or left %
"expecting print"s;
236 inline const auto punct = satisfy % mpc::ispunct or left %
"expecting punct"s;
237 inline const auto any_char = satisfy % (constant %
true);
240 using detail::alnum, detail::alpha, detail::lower, detail::upper, detail::digit, detail::xdigit,
241 detail::cntrl, detail::graph, detail::space, detail::blank, detail::print, detail::punct,
std::basic_string< charT > quoted(charT s, charT delim=charT('\''))
Surrounds a string with delimiter.
Definition: char.hpp:115
std::variant< left_t< T >, right_t< U > > either
data Either a b = Left a | Right b
Definition: either.hpp:35
constexpr partial< detail::fmap_op > fmap
fmap :: (a -> b) -> f a -> f b
Definition: applicative.hpp:161
constexpr partial< detail::liftA2_op > liftA2
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
Definition: applicative.hpp:102
constexpr partial< detail::_fst::get_op< 1 > > snd
Returns the second element of the given tuple-like object.
Definition: fst.hpp:34
constexpr partial< detail::compose_op > compose
Function composition.
Definition: compose.hpp:35
constexpr partial< detail::discard1st_op > discard1st
discard1st :: f a -> f b -> f b
Definition: applicative.hpp:108
constexpr partial< detail::combine_op > combine
combine :: f a -> f a -> f a
Definition: alternative.hpp:74
constexpr partial< detail::discard2nd_op > discard2nd
discard2nd :: f a -> f b -> f a
Definition: applicative.hpp:105
constexpr partial< std::ranges::equal_to > equal_to
Partially applicable std::ranges::equal_to.
Definition: operations.hpp:25
constexpr partial< detail::_fst::get_op< 0 > > fst
Returns the first element of the given tuple-like object.
Definition: fst.hpp:29
constexpr partial< detail::state_op< ST > > state
state :: (s -> (a, s)) -> m a
Definition: class.hpp:61
constexpr auto sep_by1
sepBy1 p sep = liftA2 (:) p (many (sep *> p))
Definition: parser.hpp:125
constexpr auto try1
パーサーを受け取り、パーサーを返す。このパーサーはパースに失敗しても直ちにエラーとならない。
Definition: parser.hpp:72
constexpr auto many1
Definition: parser.hpp:85
constexpr auto char1
文字を受け取り、パーサーを返す。このパーサーは、文字列の先頭が渡した文字に一致する場合にそれを返す。
Definition: parser.hpp:204
constexpr auto chainl1
Definition: parser.hpp:149
constexpr auto left
エラーメッセージを受け取り、必ず失敗するパーサーを返す。
Definition: parser.hpp:65
constexpr auto parse_test
パーサーと文字列を受け取り、パースする。パースに成功した場合、パース結果を表示する。失敗した場合、エラーメッセージを表示する。
Definition: parser.hpp:46
constexpr auto between
between open p close = open *> p <* close
Definition: parser.hpp:118
constexpr auto many
Definition: parser.hpp:110
constexpr auto satisfy
述語を受け取り、パーサーを返す。このパーサーは、文字列の先頭が述語を満たす場合にそれを返す。
Definition: parser.hpp:186
constexpr auto sep_by
sepBy p sep = sepBy1 p sep <|> pure []
Definition: parser.hpp:133
class Applicative f => Alternative f where
Definition: alternative.hpp:14
Implements a perfect-forwarding call wrapper.
Definition: partial.hpp:63