psemek/examples/parser.cpp

98 lines
2.2 KiB
C++

#include <psemek/parser/primitives.hpp>
#include <psemek/app/default_application_factory.hpp>
#include <iostream>
#include <fstream>
#include <iterator>
#include <psemek/util/clock.hpp>
#include <psemek/gfx/obj_parser.hpp>
template <typename Stream>
Stream & operator << (Stream & s, std::monostate)
{
return s << "()";
}
template <typename Stream>
Stream & operator << (Stream & s, psemek::parser::end_token)
{
return s << "(end)";
}
template <typename Stream>
Stream & operator << (Stream & s, psemek::parser::ws_token)
{
return s << "(ws)";
}
template <typename Stream>
Stream & operator << (Stream & s, psemek::parser::newline_token)
{
return s << "(newline)";
}
template <typename Stream, typename T>
Stream & operator << (Stream & s, std::optional<T> const & x)
{
if (x)
return s << *x;
return s << "(none)";
}
template <typename Stream, typename T>
Stream & operator << (Stream & s, std::vector<T> const & v)
{
s << '[';
for (std::size_t i = 0; i < v.size(); ++i)
{
if (i > 0) s << ", ";
s << v[i];
}
return s << ']';
}
template <typename Stream, typename T, std::size_t ... I>
void print_tuple (Stream & s, T const & t, std::index_sequence<I...>)
{
((s << (I == 0 ? "" : ", ") << std::get<I>(t)), ...);
}
template <typename Stream, typename ... Ts>
Stream & operator << (Stream & s, std::tuple<Ts...> const & t)
{
s << '(';
print_tuple(s, t, std::make_index_sequence<sizeof...(Ts)>{});
return s << ')';
}
template <typename Stream, typename T, typename ... Ts>
Stream & operator << (Stream & s, std::variant<T, Ts...> const & v)
{
auto visitor = [&s](auto const & x){ s << x; };
std::visit(visitor, v);
return s;
}
namespace psemek::app
{
std::unique_ptr<application::factory> make_application_factory()
{
return default_application_factory({.name = "Parser example"}, [](auto const & ...){
using namespace psemek::parser;
auto const p = map(concat(integer<int>, ws, one_of(ch('+'), ch('-')), ws, integer<int>), [](auto const & t){
auto id = [](auto x){ return x; };
return std::make_tuple(std::get<0>(t), std::visit(id, std::get<2>(t)), std::get<4>(t));
});
std::cout << p.parse("45 + 67") << std::endl;
return nullptr;
});
}
}