mpc
Haskell-like feature supports in C++
parser.hpp File Reference
#include <iostream>
#include <string>
#include <string_view>
#include <mpc/control.hpp>
#include <mpc/data.hpp>

Go to the source code of this file.

Classes

struct  mpc::alternative_traits< mpc::either< mpc::ParseError, std::pair< T, mpc::String > > >
 

Namespaces

namespace  mpc::detail
 Implementation details are here.
 

Macros

#define MPC_FORWARD(x)   std::forward<decltype(x)>(x)
 

Typedefs

using mpc::String = std::list< char >
 
using mpc::ParseError = std::string
 
using mpc::ParseResult = either< ParseError, std::pair< char, String > >
 
using mpc::Parser = StateT< String, ParseResult >
 

Functions

template<class T >
mpc::decay (T)
 

Variables

constexpr auto mpc::parse_test
 パーサーと文字列を受け取り、パースする。パースに成功した場合、パース結果を表示する。失敗した場合、エラーメッセージを表示する。 More...
 
constexpr auto mpc::left
 エラーメッセージを受け取り、必ず失敗するパーサーを返す。 More...
 
constexpr auto mpc::try1
 パーサーを受け取り、パーサーを返す。このパーサーはパースに失敗しても直ちにエラーとならない。 More...
 
constexpr auto mpc::many1
 
constexpr auto mpc::many
 
constexpr auto mpc::between
 between open p close = open *> p <* close More...
 
constexpr auto mpc::sep_by1
 sepBy1 p sep = liftA2 (:) p (many (sep *> p)) More...
 
constexpr auto mpc::sep_by
 sepBy p sep = sepBy1 p sep <|> pure [] More...
 
constexpr auto mpc::chainl1
 
constexpr auto mpc::satisfy
 述語を受け取り、パーサーを返す。このパーサーは、文字列の先頭が述語を満たす場合にそれを返す。 More...
 
constexpr auto mpc::char1
 文字を受け取り、パーサーを返す。このパーサーは、文字列の先頭が渡した文字に一致する場合にそれを返す。 More...
 
constexpr auto mpc::string
 文字列を受け取り、パーサーを返す。このパーサーは、文字列の先頭が渡した文字列から始まる場合にその文字列を返す。 More...
 
const auto mpc::detail::alnum = satisfy % mpc::isalnum or left % "expecting alnum"s
 
const auto mpc::detail::alpha = satisfy % mpc::isalpha or left % "expecting alpha"s
 
const auto mpc::detail::lower = satisfy % mpc::islower or left % "expecting lower"s
 
const auto mpc::detail::upper = satisfy % mpc::isupper or left % "expecting upper"s
 
const auto mpc::detail::digit = satisfy % mpc::isdigit or left % "expecting digit"s
 
const auto mpc::detail::xdigit = satisfy % mpc::isxdigit or left % "expecting xdigit"s
 
const auto mpc::detail::cntrl = satisfy % mpc::iscntrl or left % "expecting cntrl"s
 
const auto mpc::detail::graph = satisfy % mpc::isgraph or left % "expecting graph"s
 
const auto mpc::detail::space = satisfy % mpc::isspace or left % "expecting space"s
 
const auto mpc::detail::blank = satisfy % mpc::isblank or left % "expecting blank"s
 
const auto mpc::detail::print = satisfy % mpc::isprint or left % "expecting print"s
 
const auto mpc::detail::punct = satisfy % mpc::ispunct or left % "expecting punct"s
 
const auto mpc::detail::any_char = satisfy % (constant % true)
 

Variable Documentation

◆ between

constexpr auto mpc::between
inlineconstexpr
Initial value:
=
partial([](auto&& open, auto&& p, auto&& close) {
return discard2nd(discard1st(std::forward<decltype( open )>( open ), std::forward<decltype( p )>( p )), std::forward<decltype( close )>( close ));
})
constexpr partial< detail::discard1st_op > discard1st
discard1st :: f a -> f b -> f b
Definition: applicative.hpp:108
constexpr partial< detail::discard2nd_op > discard2nd
discard2nd :: f a -> f b -> f a
Definition: applicative.hpp:105
partial(Op, Args...) -> partial< Op, Args... >
A deduction guide for partial.

between open p close = open *> p <* close

◆ chainl1

constexpr auto mpc::chainl1
inlineconstexpr
Initial value:
=
partial([](auto&& p, auto&& op) {
return make_StateT<String>(partial(
[](auto&& p2, auto&& op2, similar_to<String> auto&& str)
-> decltype(run_StateT % p2 % str) {
const auto parse = run_StateT % std::forward<decltype( p2 )>( p2 );
const auto parse_op = run_StateT % std::forward<decltype( op2 )>( op2 );
auto result = parse % std::forward<decltype( str )>( str );
if (result.index() == 0)
return make_left(*fst(std::move(result)));
auto [value, state] = *snd(std::move(result));
for (;;) {
auto result_op = parse_op % state;
if (result_op.index() == 0)
break;
auto [fn, state_op] = *snd(std::move(result_op));
auto result2 = parse % std::move(state_op);
if (result2.index() == 0)
break;
auto [value2, state2] = *snd(std::move(result2));
value = fn(std::move(value), std::move(value2));
state = std::move(state2);
}
return make_right(std::make_pair(std::move(value), std::move(state)));
},
std::forward<decltype( p )>( p ), std::forward<decltype( op )>( op )));
})
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::_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

chainl1 p op = do { x <- p; rest x } where rest x = do { f <- op; y <- p; rest (f x y) } <|> return x

◆ char1

constexpr auto mpc::char1
inlineconstexpr
Initial value:
=
partial([](char c) {
using namespace operators::alternatives;
using namespace std::string_literals;
auto c2 = c;
return satisfy % (equal_to % std::move(c))
or left % ("expecting char "s + mpc::quoted(std::move(c2)));
})
constexpr partial< std::ranges::equal_to > equal_to
Partially applicable std::ranges::equal_to.
Definition: operations.hpp:25
constexpr auto satisfy
述語を受け取り、パーサーを返す。このパーサーは、文字列の先頭が述語を満たす場合にそれを返す。
Definition: parser.hpp:186

文字を受け取り、パーサーを返す。このパーサーは、文字列の先頭が渡した文字に一致する場合にそれを返す。

◆ left

constexpr auto mpc::left
inlineconstexpr
Initial value:
=
% lift<Parser> % partial([](similar_to<ParseError> auto&& str) -> eval_StateT_t<Parser> {
return make_left(std::forward<decltype( str )>( str ));
})
constexpr partial< detail::compose_op > compose
Function composition.
Definition: compose.hpp:35

エラーメッセージを受け取り、必ず失敗するパーサーを返す。

◆ many

constexpr auto mpc::many
inlineconstexpr
Initial value:
=
partial([](auto&& p) {
using namespace operators::alternatives;
return many1(std::forward<decltype( p )>( p )) or pure<decltype(p)>(std::list<holding_t<decltype(p)>>{});
})
constexpr auto many1
Definition: parser.hpp:85

パーサーを受け取り、パーサーを返す。このパーサーは受け取ったパーサーを可能な限り適用した結果をリストで返す。 many :: f a -> f [a] many v = some v <|> pure []

◆ many1

constexpr auto mpc::many1
inlineconstexpr
Initial value:
=
partial([](auto&& p) {
return make_StateT<String>(partial(
[](auto&& p2, similar_to<String> auto&& str)
-> decltype(run_StateT % (sequence % std::list{p2}) % str) {
const auto parse = run_StateT % std::forward<decltype( p2 )>( p2 );
auto result = parse % std::forward<decltype( str )>( str );
if (result.index() == 0)
return make_left(*fst(std::move(result)));
auto [value, state] = *snd(std::move(result));
std::list<holding_t<decltype(p2)>> ret{std::move(value)};
for (result = parse % state; result.index() != 0; result = parse % state) {
std::tie(value, state) = *snd(std::move(result));
ret.push_back(std::move(value));
}
return make_right(std::make_pair(std::move(ret), std::move(state)));
},
std::forward<decltype( p )>( p )));
})

パーサーを受け取り、パーサーを返す。このパーサーは受け取ったパーサーを1回以上可能な限り適用した結果をリストで返す。 some :: f a -> f [a] some v = (:) <$> v <*> many v

◆ parse_test

constexpr auto mpc::parse_test
inlineconstexpr
Initial value:
=
partial([](auto&& parser, std::string_view sv) {
auto result = eval_StateT % std::forward<decltype( parser )>( parser ) % String(sv.begin(), sv.end());
if (result.index() == 0) {
std::cout << mpc::quoted(sv) << ' ' << *fst(result) << std::endl;
} else {
for (const auto& c : *snd(result))
std::cout << c;
std::cout << std::endl;
}
})
std::basic_string< charT > quoted(charT s, charT delim=charT('\''))
Surrounds a string with delimiter.
Definition: char.hpp:115

パーサーと文字列を受け取り、パースする。パースに成功した場合、パース結果を表示する。失敗した場合、エラーメッセージを表示する。

◆ satisfy

constexpr auto mpc::satisfy
inlineconstexpr
Initial value:
=
partial([](std::predicate<char> auto&& pred) {
return make_StateT<String>(partial(
[](auto&& pred2, similar_to<String> auto&& str) -> ParseResult {
using namespace std::string_literals;
if (auto m = uncons(std::forward<decltype( str )>( str )); m.index() == 0) {
return make_left("unexpected end of input"s);
} else if (auto [x, xs] = *snd(std::move(m)); not std::invoke(std::forward<decltype( pred2 )>( pred2 ), x)) {
return make_left("unexpected "s + mpc::quoted(std::move(x)));
} else {
return make_right(std::make_pair(std::move(x), std::move(xs)));
}
},
std::forward<decltype( pred )>( pred )));
})

述語を受け取り、パーサーを返す。このパーサーは、文字列の先頭が述語を満たす場合にそれを返す。

◆ sep_by

constexpr auto mpc::sep_by
inlineconstexpr
Initial value:
=
partial([](auto&& p, auto&& sep) {
using namespace operators::alternatives;
return sep_by1(std::forward<decltype( p )>( p ), std::forward<decltype( sep )>( sep ))
or pure<decltype(p)>(std::list<holding_t<decltype(p)>>{});
})
constexpr auto sep_by1
sepBy1 p sep = liftA2 (:) p (many (sep *> p))
Definition: parser.hpp:125

sepBy p sep = sepBy1 p sep <|> pure []

◆ sep_by1

constexpr auto mpc::sep_by1
inlineconstexpr
Initial value:
=
partial([](auto&& p, auto&& sep) {
auto p2 = p;
return liftA2(cons, std::forward<decltype( p )>( p ), many % discard1st(std::forward<decltype( sep )>( sep ), std::move(p2)));
})
constexpr partial< detail::liftA2_op > liftA2
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
Definition: applicative.hpp:102

sepBy1 p sep = liftA2 (:) p (many (sep *> p))

◆ string

constexpr auto mpc::string
inlineconstexpr
Initial value:
=
partial([](std::string_view sv) {
return sequence
% fmap(partial([](char c) { return char1 % std::move(c); }),
std::list(sv.begin(), sv.end()));
})
constexpr partial< detail::fmap_op > fmap
fmap :: (a -> b) -> f a -> f b
Definition: applicative.hpp:161
constexpr auto char1
文字を受け取り、パーサーを返す。このパーサーは、文字列の先頭が渡した文字に一致する場合にそれを返す。
Definition: parser.hpp:204

文字列を受け取り、パーサーを返す。このパーサーは、文字列の先頭が渡した文字列から始まる場合にその文字列を返す。

◆ try1

constexpr auto mpc::try1
inlineconstexpr
Initial value:
=
partial([](auto&& parser) {
return make_StateT<String>(partial(
[](auto&& parser2, similar_to<String> auto&& str) {
return run_StateT % std::forward<decltype( parser2 )>( parser2 ) % std::forward<decltype( str )>( str );
},
std::forward<decltype( parser )>( parser )));
})

パーサーを受け取り、パーサーを返す。このパーサーはパースに失敗しても直ちにエラーとならない。