Recursive parsers wip

This commit is contained in:
Nikita Lisitsa 2022-05-17 12:43:53 +03:00
parent a3d5a424dd
commit 5c582fb0cc
2 changed files with 66 additions and 0 deletions

View file

@ -84,6 +84,49 @@ namespace psemek::parser
return res; return res;
} }
template <typename R, typename Gen>
struct recursive_helper
{
using P = decltype(std::declval<Gen>()(std::declval<parser_ref<recursive_helper>>()));
P p;
recursive_helper(Gen && gen)
: p(std::forward<Gen>(gen)(parser_ref<recursive_helper>{this}))
{}
template <typename Buffer>
result<R> apply(Buffer & buf) const
{
return p.apply(buf);
}
R parse(std::string_view text) const
{
return p.parse(text);
}
};
template <typename R, typename Gen>
struct recursive_impl
{
std::unique_ptr<recursive_helper<R, Gen>> p;
recursive_impl(Gen && gen)
: p(std::make_unique<recursive_helper<R, Gen>>(std::forward<Gen>(gen)))
{}
template <typename Buffer>
result<R> apply(Buffer & buf) const
{
return p->apply(buf);
}
R parse(std::string_view text) const
{
return p->parse(text);
}
};
} }
template <typename P, typename F> template <typename P, typename F>
@ -261,4 +304,10 @@ namespace psemek::parser
return fold(std::forward<P>(p), [](auto const &, auto const &){ return skip_token{}; }, skip_token{}); return fold(std::forward<P>(p), [](auto const &, auto const &){ return skip_token{}; }, skip_token{});
} }
template <typename R, typename Gen>
auto recursive(Gen && gen)
{
return detail::recursive_impl<R, Gen>(std::forward<Gen>(gen));
}
} }

View file

@ -105,6 +105,23 @@ namespace psemek::parser
} }
}; };
template <typename P>
struct parser_ref
{
P * p;
template <typename Buffer>
auto apply(Buffer & buf) const
{
return p->apply(buf);
}
auto parse(std::string_view text) const
{
return p->parse(text);
}
};
} }
struct error struct error