13 #pragma GCC diagnostic push 14 #pragma GCC diagnostic ignored "-Wshadow" 25 virtual bool skip(std::string_view& sv) noexcept = 0;
28 class SkipWhitespace :
public Skipper
32 bool skip(std::string_view& sv) noexcept {
35 bool remove_char =
false;
36 while (!sv.empty() && 0 != std::isspace(sv.front())) {
44 class NoSkip :
public Skipper
49 bool skip(std::string_view& sv) noexcept {
54 static SkipWhitespace skws;
60 template <
typename Base>
62 constexpr
auto operator*() const noexcept;
63 constexpr auto operator+() const noexcept;
64 constexpr auto operator[](std::string_view& output) const noexcept;
65 constexpr auto operator[](std::function<
void(const std::string_view&)> callback) const noexcept;
76 constexpr
explicit char_(
const char ch) noexcept
86 struct not_ final : impl::parser_base<not_> {
87 constexpr
explicit not_(
const char ch) noexcept
91 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
92 if (!sv.empty() && sv.front() != ch) {
106 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
107 if (!sv.empty() && sv.front() == ch) {
127 struct charset_ final :
public impl::parser_base<charset_> {
130 constexpr
explicit charset_(
char const*
set) noexcept
140 struct not_ final : impl::parser_base<not_> {
141 constexpr
explicit not_(
char const*
set) noexcept
145 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
147 for (
char const* s =
set; *s; ++s) {
148 if (*s == sv.front()) {
165 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
167 for (
char const* s =
set; *s; ++s) {
168 if (*s == sv.front()) {
188 struct char_if_ final :
public impl::parser_base<char_if_> {
192 constexpr
explicit char_if_(
bool(*pred)(
char)) noexcept
196 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
197 if (!sv.empty() && pred(sv.front())) {
212 [[maybe_unused ]]
static inline auto alnum_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isalnum(ch); });
216 [[maybe_unused ]]
static inline auto alpha_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isalpha(ch); });
220 [[maybe_unused ]]
static inline auto lower_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::islower(ch); });
224 [[maybe_unused ]]
static inline auto upper_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isupper(ch); });
228 [[maybe_unused ]]
static inline auto digit_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isdigit(ch); });
232 [[maybe_unused ]]
static inline auto xdigit_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isxdigit(ch); });
236 [[maybe_unused ]]
static inline auto cntrl_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::iscntrl(ch); });
240 [[maybe_unused ]]
static inline auto graph_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isgraph(ch); });
244 [[maybe_unused ]]
static inline auto space_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isspace(ch); });
248 [[maybe_unused ]]
static inline auto blank_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isblank(ch); });
252 [[maybe_unused ]]
static inline auto print_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::isprint(ch); });
256 [[maybe_unused ]]
static inline auto punct_ =
char_if_([](
char const ch) noexcept ->
bool {
return 0 != std::ispunct(ch); });
263 struct lit_ final :
public impl::parser_base<lit_> {
266 constexpr
lit_(std::string_view str) noexcept
270 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
271 if (sv.substr(0, str.size()) == str) {
272 sv.remove_prefix(str.size());
279 std::string_view str;
289 template <
typename Func>
290 struct action_ final :
public impl::parser_base<action_<Func>> {
311 constexpr
explicit action_(Func&& func) noexcept
312 : func(std::forward<Func>(func))
315 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
328 template <
typename Base>
329 struct opt_ final :
public impl::parser_base<opt_<Base>> {
330 constexpr
explicit opt_(Base base) noexcept
331 : base(std::forward<Base>(base))
334 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
336 base.visit(sv, skipper);
347 template <
typename Base>
348 struct lexeme_ final :
public impl::parser_base<lexeme_<Base>> {
349 constexpr
explicit lexeme_(Base base) noexcept
350 : base(std::forward<Base>(base))
353 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
356 return base.visit(sv, nosk);
364 template <
typename Left,
typename Right>
365 struct seq_ final :
public impl::parser_base<seq_<Left, Right>> {
366 constexpr
explicit seq_(Left&& left, Right&& right) noexcept
367 : left(std::forward<Left>(left))
368 , right(std::forward<Right>(right))
371 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
373 bool left_result = left.visit(sv, skipper);
377 return right.visit(sv, skipper);
388 template <
typename Left,
typename Right>
389 struct alt_ final :
public impl::parser_base<alt_<Left, Right>> {
390 constexpr
explicit alt_(Left&& left, Right&& right) noexcept
391 : left(std::forward<Left>(left))
392 , right(std::forward<Right>(right))
395 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
397 const std::string_view save = sv;
398 return left.visit(sv, skipper) || right.visit(sv = save, skipper);
406 template <
typename Base>
407 struct kleene_ final :
public impl::parser_base<kleene_<Base>> {
408 constexpr
explicit kleene_(Base base) noexcept
409 : base(std::move(base))
412 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
414 std::string_view save = sv;
418 while (base.visit(sv, skipper) && !sv.empty() && save != sv)
427 template <
typename Base>
428 struct plus_ final :
public impl::parser_base<plus_<Base>> {
429 constexpr
explicit plus_(Base base) noexcept
430 : base(std::move(base))
433 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
435 if (!base.visit(sv, skipper)) {
438 std::string_view save = sv;
442 while (base.visit(sv, skipper) && !sv.empty() && save != sv)
451 template <
typename Base>
452 struct match_ final :
public impl::parser_base<match_<Base>> {
453 constexpr
explicit match_(Base base, std::string_view& sv) noexcept
454 : base(std::move(base))
458 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
460 std::string_view save = sv;
461 if (base.visit(sv, skipper)) {
462 out = save.substr(0, save.size() - sv.size());
470 std::string_view& out;
473 template <
typename Base>
474 struct match_call_ final :
public impl::parser_base<match_call_<Base>> {
475 constexpr
explicit match_call_(Base base, std::function<
void(
const std::string_view&)> callback) noexcept
476 : base(std::move(base))
477 , callback(std::move(callback))
480 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
482 std::string_view save = sv;
483 if (base.visit(sv, skipper)) {
484 callback(save.substr(0, save.size() - sv.size()));
492 std::function<void(const std::string_view&)> callback;
495 struct endtype_ final :
public impl::parser_base<endtype_> {
496 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
501 struct emptytype_ final :
public impl::parser_base<emptytype_> {
502 constexpr
inline bool visit(std::string_view& sv, Skipper& skipper)
const& noexcept {
516 [[maybe_unused]] constexpr
static inline auto end_ = impl::endtype_();
526 [[maybe_unused]] constexpr
static inline auto empty_ = impl::emptytype_();
541 template <
typename Left,
typename Right>
542 constexpr
inline auto operator>>(Left&& left, Right&& right) noexcept {
543 return impl::seq_<Left, Right>(
544 std::forward<Left>(left),
545 std::forward<Right>(right)
564 template <
typename Left,
typename Right>
565 constexpr
inline auto operator|(Left&& left, Right&& right) noexcept {
566 return impl::alt_<Left, Right>(
567 std::forward<Left>(left),
568 std::forward<Right>(right)
578 template <
typename Base>
579 constexpr
inline auto impl::parser_base<Base>::operator*()
const noexcept {
580 return impl::kleene_<Base>(*
static_cast<Base const*
>(
this));
589 template <
typename Base>
590 constexpr
inline auto impl::parser_base<Base>::operator+()
const noexcept {
591 return impl::plus_<Base>(*
static_cast<Base const*
>(
this));
607 template <
typename Base>
608 constexpr
inline auto impl::parser_base<Base>::operator[](std::string_view& ouput)
const noexcept {
609 return impl::match_<Base>(*
static_cast<Base const*
>(
this), ouput);
628 template <
typename Base>
629 constexpr
inline auto impl::parser_base<Base>::operator[](std::function<
void(
const std::string_view&)> callback)
const noexcept {
630 return impl:: match_call_<Base>(*
static_cast<Base const*
>(
this), std::move(callback));
649 template <
typename Parser>
650 constexpr
bool parse(std::string_view input, Parser
const& parser, Skipper& skipper = skws) noexcept {
651 return parser.visit(input, skipper);
663 template <
typename Parser>
664 constexpr
bool parse_ref(std::string_view& input, Parser
const& parser, Skipper& skipper = skws) noexcept {
665 return parser.visit(input, skipper);
670 #pragma GCC diagnostic pop constexpr charset_(char const *set) noexcept
Construct a charset_ parser.
Definition: limn.h:130
static auto blank_
Single character parser based on std::blank.
Definition: limn.h:248
Single character parser for any of several characters.
Definition: limn.h:127
constexpr bool parse_ref(std::string_view &input, Parser const &parser, Skipper &skipper=skws) noexcept
The parse function that takes input by reference.
Definition: limn.h:664
static auto alnum_
Single character parser based on std::isalnum.
Definition: limn.h:212
constexpr auto operator!() const &noexcept
Opposite parser.
Definition: limn.h:139
constexpr char_if_(bool(*pred)(char)) noexcept
Construct a char_if_ parser.
Definition: limn.h:192
static constexpr auto end_
End of input parser.
Definition: limn.h:516
constexpr lit_(std::string_view str) noexcept
Construct a lit_ parser.
Definition: limn.h:266
static auto cntrl_
Single character parser based on std::cntrl.
Definition: limn.h:236
constexpr action_(Func &&func) noexcept
Construct an action_ parser.
Definition: limn.h:311
constexpr auto operator>>(Left &&left, Right &&right) noexcept
The sequence parser combinator.
Definition: limn.h:542
constexpr bool parse(std::string_view input, Parser const &parser, Skipper &skipper=skws) noexcept
The parse function.
Definition: limn.h:650
constexpr char_(const char ch) noexcept
Construct a char_ parser.
Definition: limn.h:76
Customizable parser.
Definition: limn.h:290
Single character parser based on a char.
Definition: limn.h:73
Single character parser based on a function.
Definition: limn.h:188
Zero or one of the match parser, in another word it is an optional item.
Definition: limn.h:329
constexpr auto operator!() const &noexcept
Opposite parser.
Definition: limn.h:85
The namesapce for all Limn types, functions, and variables.
String literal parser.
Definition: limn.h:263
constexpr auto operator|(Left &&left, Right &&right) noexcept
The alternate parser combinator.
Definition: limn.h:565
static auto print_
Single character parser based on std::print.
Definition: limn.h:252
static auto digit_
Single character parser based on std::isdigit.
Definition: limn.h:228
static auto lower_
Single character parser based on std::islower.
Definition: limn.h:220
static auto space_
Single character parser based on std::space.
Definition: limn.h:244
static constexpr auto empty_
Empty parser.
Definition: limn.h:526
static auto alpha_
Single character parser based on std::isalpha.
Definition: limn.h:216
static auto xdigit_
Single character parser based on std::xdigit.
Definition: limn.h:232
static auto punct_
Single character parser based on std::punct.
Definition: limn.h:256
static auto graph_
Single character parser based on std::graph.
Definition: limn.h:240
static auto upper_
Single character parser based on std::isupper.
Definition: limn.h:224