Recursive parsers wip
This commit is contained in:
parent
a3d5a424dd
commit
5c582fb0cc
2 changed files with 66 additions and 0 deletions
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue