mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2025-01-22 21:35:29 +00:00
Improved location info of error report.
This commit is contained in:
parent
26060c0f00
commit
1f48b4ca82
65
peglib.h
65
peglib.h
@ -189,6 +189,13 @@ struct SemanticValues : protected std::vector<SemanticValue>
|
||||
|
||||
SemanticValues() : s(nullptr), n(0), choice(0) {}
|
||||
|
||||
std::string str(size_t i = 0) const {
|
||||
if (i > 0) {
|
||||
return (*this)[i].str();
|
||||
}
|
||||
return std::string(s, n);
|
||||
}
|
||||
|
||||
typedef SemanticValue T;
|
||||
using std::vector<T>::iterator;
|
||||
using std::vector<T>::const_iterator;
|
||||
@ -442,8 +449,9 @@ struct Context
|
||||
const char* s;
|
||||
size_t l;
|
||||
|
||||
const char* error_ptr;
|
||||
const char* msg; // TODO: should be `int`.
|
||||
const char* error_pos;
|
||||
const char* message_pos;
|
||||
std::string message; // TODO: should be `int`.
|
||||
|
||||
size_t def_count;
|
||||
std::vector<bool> cache_register;
|
||||
@ -457,6 +465,8 @@ struct Context
|
||||
Context(const char* _s, size_t _l, size_t _def_count, bool enablePackratParsing)
|
||||
: s(_s)
|
||||
, l(_l)
|
||||
, error_pos(nullptr)
|
||||
, message_pos(nullptr)
|
||||
, def_count(_def_count)
|
||||
, cache_register(enablePackratParsing ? def_count * (l + 1) : 0)
|
||||
, cache_success(enablePackratParsing ? def_count * (l + 1) : 0)
|
||||
@ -512,6 +522,10 @@ struct Context
|
||||
void pop() {
|
||||
stack_size--;
|
||||
}
|
||||
|
||||
void set_error_pos(const char* s) {
|
||||
if (error_pos < s) error_pos = s;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -557,9 +571,6 @@ public:
|
||||
const auto& rule = *ope;
|
||||
auto len = rule.parse(s + i, n - i, sv, c, dt);
|
||||
if (fail(len)) {
|
||||
if (!c.msg) {
|
||||
c.msg = "missing an element in the 'sequence'";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
i += len;
|
||||
@ -614,8 +625,6 @@ public:
|
||||
id++;
|
||||
c.pop();
|
||||
}
|
||||
c.error_ptr = s;
|
||||
c.msg = "nothing was matched in the 'prioritized choice'";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -660,9 +669,6 @@ public:
|
||||
const auto& rule = *ope_;
|
||||
auto len = rule.parse(s, n, sv, c, dt);
|
||||
if (fail(len)) {
|
||||
if (!c.msg) {
|
||||
c.msg = "nothing occurred in the 'one-or-more'";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
auto i = len;
|
||||
@ -728,11 +734,13 @@ public:
|
||||
|
||||
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||
const auto& rule = *ope_;
|
||||
auto error_pos = c.error_pos;
|
||||
auto len = rule.parse(s, n, sv, c, dt);
|
||||
if (success(len)) {
|
||||
c.error_ptr = s;
|
||||
c.set_error_pos(s);
|
||||
return -1;
|
||||
} else {
|
||||
c.error_pos = error_pos;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -752,7 +760,7 @@ public:
|
||||
auto i = 0u;
|
||||
for (; i < lit_.size(); i++) {
|
||||
if (i >= n || s[i] != lit_[i]) {
|
||||
c.error_ptr = s;
|
||||
c.set_error_pos(s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -773,7 +781,7 @@ public:
|
||||
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||
// TODO: UTF8 support
|
||||
if (n < 1) {
|
||||
c.error_ptr = s;
|
||||
c.set_error_pos(s);
|
||||
return -1;
|
||||
}
|
||||
auto ch = s[0];
|
||||
@ -791,7 +799,7 @@ public:
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
c.error_ptr = s;
|
||||
c.set_error_pos(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -809,7 +817,7 @@ public:
|
||||
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||
// TODO: UTF8 support
|
||||
if (n < 1 || s[0] != ch_) {
|
||||
c.error_ptr = s;
|
||||
c.set_error_pos(s);
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
@ -827,7 +835,7 @@ public:
|
||||
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||
// TODO: UTF8 support
|
||||
if (n < 1) {
|
||||
c.error_ptr = s;
|
||||
c.set_error_pos(s);
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
@ -1048,8 +1056,9 @@ public:
|
||||
struct Result {
|
||||
bool ret;
|
||||
int len;
|
||||
const char* error_ptr;
|
||||
const char* msg;
|
||||
const char* error_pos;
|
||||
const char* message_pos;
|
||||
const std::string message;
|
||||
};
|
||||
|
||||
Definition()
|
||||
@ -1179,6 +1188,7 @@ public:
|
||||
std::string name;
|
||||
size_t id;
|
||||
std::vector<Action> actions;
|
||||
std::function<std::string ()> error_message;
|
||||
bool ignoreSemanticValue;
|
||||
bool enablePackratParsing;
|
||||
|
||||
@ -1194,7 +1204,7 @@ private:
|
||||
|
||||
Context c(s, n, defIds.ids.size(), enablePackratParsing);
|
||||
auto len = holder_->parse(s, n, sv, c, dt);
|
||||
return Result { success(len), len, c.error_ptr, c.msg };
|
||||
return Result{ success(len), len, c.error_pos, c.message_pos, c.message };
|
||||
}
|
||||
|
||||
std::shared_ptr<Holder> holder_;
|
||||
@ -1248,6 +1258,11 @@ inline int Holder::parse(const char* s, size_t n, SemanticValues& sv, Context& c
|
||||
sv.emplace_back(val, outer_->name.c_str(), ancs, ancn);
|
||||
}
|
||||
|
||||
if (fail(len) && outer_->error_message && !c.message_pos) {
|
||||
c.message_pos = s;
|
||||
c.message = outer_->error_message();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1379,8 +1394,8 @@ inline std::shared_ptr<Ope> ref(const std::unordered_map<std::string, Definition
|
||||
* PEG parser generator
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
inline std::pair<size_t, size_t> line_info(const char* beg, const char* cur) {
|
||||
auto p = beg;
|
||||
inline std::pair<size_t, size_t> line_info(const char* start, const char* cur) {
|
||||
auto p = start;
|
||||
auto col_ptr = p;
|
||||
auto no = 1;
|
||||
|
||||
@ -1659,8 +1674,8 @@ private:
|
||||
|
||||
if (!r.ret) {
|
||||
if (log) {
|
||||
auto line = line_info(s, r.error_ptr);
|
||||
log(line.first, line.second, r.msg ? "syntax error" : r.msg);
|
||||
auto line = line_info(s, r.error_pos);
|
||||
log(line.first, line.second, r.message.empty() ? "syntax error" : r.message);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -1951,8 +1966,8 @@ private:
|
||||
void output_log(const char* s, size_t n, Log log, const Definition::Result& r) const {
|
||||
if (log) {
|
||||
if (!r.ret) {
|
||||
auto line = line_info(s, r.error_ptr);
|
||||
log(line.first, line.second, r.msg ? "syntax error" : r.msg);
|
||||
auto line = line_info(s, r.error_pos);
|
||||
log(line.first, line.second, r.message.empty() ? "syntax error" : r.message);
|
||||
} else if (r.len != n) {
|
||||
auto line = line_info(s, s + r.len);
|
||||
log(line.first, line.second, "syntax error");
|
||||
|
Loading…
Reference in New Issue
Block a user