harbour-sextant/external/test.cc

153 lines
3.3 KiB
C++

#include <string>
#include <cassert>
#include <iostream>
#include <fstream>
#include <vector>
#include "lexy/callback.hpp"
#include "lexy/dsl.hpp"
#include "lexy/input/string_input.hpp"
#include "lexy/action/parse.hpp"
#include "lexy_ext/report_error.hpp"
struct raw_text
{
std::string text;
std::string eol;
raw_text* next;
raw_text* prev;
};
struct document
{
raw_text* first_child;
};
raw_text* make_raw_text(const std::string& str, const std::string& eol)
{
raw_text* line = new raw_text;
line->text = str;
line->eol = eol;
line->next = nullptr;
line->prev = nullptr;
return line;
}
struct _node_sink
{
raw_text* _head = nullptr;
raw_text* _tail = nullptr;
using return_type = raw_text*;
raw_text* operator()(raw_text* obj)
{
if (obj != NULL)
{
if (_head == nullptr)
_head = _tail = obj;
else
{
_tail->next = obj;
obj->prev = _tail;
_tail = obj;
}
}
return _head;
}
raw_text* operator()(std::vector<char>&& str)
{
assert(false);
return make_raw_text("", "");
}
raw_text* operator()(std::string&& str)
{
return make_raw_text(str, "");
}
raw_text* finish() &&
{
return LEXY_MOV(_head);
}
};
struct _append_node
{
using return_type = raw_text*;
constexpr raw_text* operator()(raw_text* obj) const
{
return LEXY_MOV(obj);
}
raw_text* operator()(lexy::nullopt&&) const
{
return nullptr;
}
template <typename... Args>
constexpr raw_text* operator()(Args&&... args) const
{
assert(false);
return nullptr;
}
auto sink() const
{
return _node_sink{};
}
};
constexpr auto append_node = _append_node {};
namespace grammar
{
namespace dsl = lexy::dsl;
struct eol
{
static constexpr auto rule = dsl::capture(dsl::newline);
static constexpr auto value = lexy::as_string<std::string>;
};
struct raw_line
{
// static constexpr auto rule = dsl::terminator(dsl::eol).opt_list(dsl::capture(dsl::code_point));
static constexpr auto rule = dsl::terminator(dsl::p<eol>).opt_list(dsl::capture(dsl::code_point));
static constexpr auto value = lexy::as_string<std::string> >>
lexy::callback<raw_text*>([](lexy::nullopt&& opt, std::string&& _eol) {
return make_raw_text("", _eol);
},
[](std::string&& str, std::string&& _eol) {
return make_raw_text(str, _eol);
});
};
struct document
{
static constexpr auto rule = dsl::terminator(dsl::eof).list(dsl::p<raw_line>);
static constexpr auto value = append_node;
};
} // namespace grammar
int main (int argc, char** argv)
{
if (argc > 1)
{
std::ifstream ifs(argv[1]);
std::string content((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
auto input = lexy::string_input<lexy::utf8_encoding>(content);
auto result = lexy::parse<grammar::document>(input, lexy_ext::report_error);
if (!result)
return 2;
if (result.has_value())
return 0;
}
return 1;
}