ppc-lang/include/treeifier/parsers/helper.hh

125 lines
3.3 KiB
C++
Raw Normal View History

2023-02-10 14:10:34 +00:00
#pragma once
2022-10-04 13:00:18 +00:00
2023-02-10 14:10:34 +00:00
#include "treeifier/constr.hh"
2022-10-09 11:18:38 +00:00
2023-02-10 14:10:34 +00:00
namespace ppc::tree::parse {
2023-01-26 08:06:39 +00:00
struct helper_t {
2022-10-04 13:00:18 +00:00
private:
2023-02-10 14:10:34 +00:00
parse_ctx_t &ctx;
2022-10-04 13:00:18 +00:00
size_t &res_i;
2022-10-14 17:27:45 +00:00
public:
size_t i;
void throw_ended() {
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end.", loc());
}
2022-10-04 20:45:08 +00:00
void throw_ended(const std::string &reason) {
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end: " + reason, loc());
}
2022-10-11 10:13:10 +00:00
location_t loc(size_t n) {
location_t res = prev_loc();
res.start += res.length;
res.code_start += res.length;
res.length = n;
return res;
}
location_t prev_loc() {
auto prev_i = i;
if (i > 0) i--;
auto res = loc();
i = prev_i;
return res;
}
2022-10-04 13:00:18 +00:00
location_t next_loc(size_t n = 1) {
location_t res = loc();
res.start += res.length;
res.code_start += res.length;
res.length = n;
return res;
}
location_t loc() {
if (ended()) {
if (i == 0) return location_t::NONE;
location_t loc = ctx.tokens[i - 1].location;
loc.start += loc.length;
loc.code_start += loc.length;
loc.length = 1;
return loc;
}
else return curr().location;
}
location_t res_loc() {
if (res_i >= ctx.tokens.size()) return loc();
else return ctx.tokens[res_i].location.intersect(loc());
}
2022-10-14 17:27:45 +00:00
bool err(std::string message) {
2022-10-09 11:18:38 +00:00
throw message_t::error(message, loc());
}
2022-10-14 17:27:45 +00:00
bool err(std::string message, size_t n) {
2022-10-11 10:13:10 +00:00
throw message_t::error(message, loc(n));
}
2022-10-09 11:18:38 +00:00
bool submit(bool inc_i = true) {
res_i = (i += inc_i);
return true;
2022-10-04 13:00:18 +00:00
}
2022-10-09 11:18:38 +00:00
bool ended() {
return i == ctx.tokens.size();
}
2022-10-14 17:27:45 +00:00
token_t &curr(const std::string &reason) {
throw_ended(reason);
return ctx.tokens[i];
}
2022-10-09 11:18:38 +00:00
token_t &curr() {
throw_ended();
return ctx.tokens[i];
2022-10-04 13:00:18 +00:00
}
bool try_advance() {
if (ended()) return false;
i++;
return !ended();
}
void advance() {
throw_ended();
2022-10-04 13:00:18 +00:00
i++;
throw_ended();
2022-10-04 13:00:18 +00:00
}
2022-10-04 20:45:08 +00:00
void advance(const std::string &reason) {
throw_ended(reason);
i++;
throw_ended(reason);
}
2022-10-04 13:00:18 +00:00
2023-01-26 08:06:39 +00:00
template <class ParserT, class ...ArgsT>
bool parse(const ParserT &parser, ArgsT &...args) {
return parser(ctx, i, args...);
2022-10-09 11:18:38 +00:00
}
2023-01-26 08:06:39 +00:00
template <class ParserT, class ...ArgsT>
void force_parse(const ParserT &parser, std::string message, ArgsT &...args) {
2022-10-14 17:27:45 +00:00
throw_ended(message);
2022-10-09 11:18:38 +00:00
try {
2023-01-26 08:06:39 +00:00
if (!parser(ctx, i, args...)) err(message);
2022-10-09 11:18:38 +00:00
}
catch (const message_t &msg) {
ctx.messages.push(msg);
2023-01-26 08:06:39 +00:00
err(message);
2022-10-09 11:18:38 +00:00
}
}
2023-02-10 14:10:34 +00:00
helper_t(parse_ctx_t &ctx, size_t &i): ctx(ctx), res_i(i) {
2022-10-04 13:00:18 +00:00
this->i = i;
}
};
}