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
79
peglib.h
79
peglib.h
@ -189,6 +189,13 @@ struct SemanticValues : protected std::vector<SemanticValue>
|
|||||||
|
|
||||||
SemanticValues() : s(nullptr), n(0), choice(0) {}
|
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;
|
typedef SemanticValue T;
|
||||||
using std::vector<T>::iterator;
|
using std::vector<T>::iterator;
|
||||||
using std::vector<T>::const_iterator;
|
using std::vector<T>::const_iterator;
|
||||||
@ -442,8 +449,9 @@ struct Context
|
|||||||
const char* s;
|
const char* s;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
const char* error_ptr;
|
const char* error_pos;
|
||||||
const char* msg; // TODO: should be `int`.
|
const char* message_pos;
|
||||||
|
std::string message; // TODO: should be `int`.
|
||||||
|
|
||||||
size_t def_count;
|
size_t def_count;
|
||||||
std::vector<bool> cache_register;
|
std::vector<bool> cache_register;
|
||||||
@ -457,6 +465,8 @@ struct Context
|
|||||||
Context(const char* _s, size_t _l, size_t _def_count, bool enablePackratParsing)
|
Context(const char* _s, size_t _l, size_t _def_count, bool enablePackratParsing)
|
||||||
: s(_s)
|
: s(_s)
|
||||||
, l(_l)
|
, l(_l)
|
||||||
|
, error_pos(nullptr)
|
||||||
|
, message_pos(nullptr)
|
||||||
, def_count(_def_count)
|
, def_count(_def_count)
|
||||||
, cache_register(enablePackratParsing ? def_count * (l + 1) : 0)
|
, cache_register(enablePackratParsing ? def_count * (l + 1) : 0)
|
||||||
, cache_success(enablePackratParsing ? def_count * (l + 1) : 0)
|
, cache_success(enablePackratParsing ? def_count * (l + 1) : 0)
|
||||||
@ -512,6 +522,10 @@ struct Context
|
|||||||
void pop() {
|
void pop() {
|
||||||
stack_size--;
|
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;
|
const auto& rule = *ope;
|
||||||
auto len = rule.parse(s + i, n - i, sv, c, dt);
|
auto len = rule.parse(s + i, n - i, sv, c, dt);
|
||||||
if (fail(len)) {
|
if (fail(len)) {
|
||||||
if (!c.msg) {
|
|
||||||
c.msg = "missing an element in the 'sequence'";
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
i += len;
|
i += len;
|
||||||
@ -614,8 +625,6 @@ public:
|
|||||||
id++;
|
id++;
|
||||||
c.pop();
|
c.pop();
|
||||||
}
|
}
|
||||||
c.error_ptr = s;
|
|
||||||
c.msg = "nothing was matched in the 'prioritized choice'";
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,9 +669,6 @@ public:
|
|||||||
const auto& rule = *ope_;
|
const auto& rule = *ope_;
|
||||||
auto len = rule.parse(s, n, sv, c, dt);
|
auto len = rule.parse(s, n, sv, c, dt);
|
||||||
if (fail(len)) {
|
if (fail(len)) {
|
||||||
if (!c.msg) {
|
|
||||||
c.msg = "nothing occurred in the 'one-or-more'";
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
auto i = len;
|
auto i = len;
|
||||||
@ -728,11 +734,13 @@ public:
|
|||||||
|
|
||||||
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||||
const auto& rule = *ope_;
|
const auto& rule = *ope_;
|
||||||
|
auto error_pos = c.error_pos;
|
||||||
auto len = rule.parse(s, n, sv, c, dt);
|
auto len = rule.parse(s, n, sv, c, dt);
|
||||||
if (success(len)) {
|
if (success(len)) {
|
||||||
c.error_ptr = s;
|
c.set_error_pos(s);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
c.error_pos = error_pos;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -752,7 +760,7 @@ public:
|
|||||||
auto i = 0u;
|
auto i = 0u;
|
||||||
for (; i < lit_.size(); i++) {
|
for (; i < lit_.size(); i++) {
|
||||||
if (i >= n || s[i] != lit_[i]) {
|
if (i >= n || s[i] != lit_[i]) {
|
||||||
c.error_ptr = s;
|
c.set_error_pos(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -773,7 +781,7 @@ public:
|
|||||||
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||||
// TODO: UTF8 support
|
// TODO: UTF8 support
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
c.error_ptr = s;
|
c.set_error_pos(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
auto ch = s[0];
|
auto ch = s[0];
|
||||||
@ -791,7 +799,7 @@ public:
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.error_ptr = s;
|
c.set_error_pos(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,7 +817,7 @@ public:
|
|||||||
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||||
// TODO: UTF8 support
|
// TODO: UTF8 support
|
||||||
if (n < 1 || s[0] != ch_) {
|
if (n < 1 || s[0] != ch_) {
|
||||||
c.error_ptr = s;
|
c.set_error_pos(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
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 {
|
int parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||||
// TODO: UTF8 support
|
// TODO: UTF8 support
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
c.error_ptr = s;
|
c.set_error_pos(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -1046,10 +1054,11 @@ class Definition
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct Result {
|
struct Result {
|
||||||
bool ret;
|
bool ret;
|
||||||
int len;
|
int len;
|
||||||
const char* error_ptr;
|
const char* error_pos;
|
||||||
const char* msg;
|
const char* message_pos;
|
||||||
|
const std::string message;
|
||||||
};
|
};
|
||||||
|
|
||||||
Definition()
|
Definition()
|
||||||
@ -1176,11 +1185,12 @@ public:
|
|||||||
holder_->accept(v);
|
holder_->accept(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
size_t id;
|
size_t id;
|
||||||
std::vector<Action> actions;
|
std::vector<Action> actions;
|
||||||
bool ignoreSemanticValue;
|
std::function<std::string ()> error_message;
|
||||||
bool enablePackratParsing;
|
bool ignoreSemanticValue;
|
||||||
|
bool enablePackratParsing;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class DefinitionReference;
|
friend class DefinitionReference;
|
||||||
@ -1194,7 +1204,7 @@ private:
|
|||||||
|
|
||||||
Context c(s, n, defIds.ids.size(), enablePackratParsing);
|
Context c(s, n, defIds.ids.size(), enablePackratParsing);
|
||||||
auto len = holder_->parse(s, n, sv, c, dt);
|
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_;
|
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);
|
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;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1379,8 +1394,8 @@ inline std::shared_ptr<Ope> ref(const std::unordered_map<std::string, Definition
|
|||||||
* PEG parser generator
|
* PEG parser generator
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
inline std::pair<size_t, size_t> line_info(const char* beg, const char* cur) {
|
inline std::pair<size_t, size_t> line_info(const char* start, const char* cur) {
|
||||||
auto p = beg;
|
auto p = start;
|
||||||
auto col_ptr = p;
|
auto col_ptr = p;
|
||||||
auto no = 1;
|
auto no = 1;
|
||||||
|
|
||||||
@ -1659,8 +1674,8 @@ private:
|
|||||||
|
|
||||||
if (!r.ret) {
|
if (!r.ret) {
|
||||||
if (log) {
|
if (log) {
|
||||||
auto line = line_info(s, r.error_ptr);
|
auto line = line_info(s, r.error_pos);
|
||||||
log(line.first, line.second, r.msg ? "syntax error" : r.msg);
|
log(line.first, line.second, r.message.empty() ? "syntax error" : r.message);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -1951,8 +1966,8 @@ private:
|
|||||||
void output_log(const char* s, size_t n, Log log, const Definition::Result& r) const {
|
void output_log(const char* s, size_t n, Log log, const Definition::Result& r) const {
|
||||||
if (log) {
|
if (log) {
|
||||||
if (!r.ret) {
|
if (!r.ret) {
|
||||||
auto line = line_info(s, r.error_ptr);
|
auto line = line_info(s, r.error_pos);
|
||||||
log(line.first, line.second, r.msg ? "syntax error" : r.msg);
|
log(line.first, line.second, r.message.empty() ? "syntax error" : r.message);
|
||||||
} else if (r.len != n) {
|
} else if (r.len != n) {
|
||||||
auto line = line_info(s, s + r.len);
|
auto line = line_info(s, s + r.len);
|
||||||
log(line.first, line.second, "syntax error");
|
log(line.first, line.second, "syntax error");
|
||||||
|
Loading…
Reference in New Issue
Block a user