mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Fix #226
This commit is contained in:
parent
1958bad23e
commit
afd3acbeaf
@ -45,7 +45,11 @@ function generateErrorListHTML(errors) {
|
|||||||
let html = '<ul>';
|
let html = '<ul>';
|
||||||
|
|
||||||
html += $.map(errors, function (x) {
|
html += $.map(errors, function (x) {
|
||||||
return '<li data-ln="' + x.ln + '" data-col="' + x.col + '"><span>' + x.ln + ':' + x.col + '</span> <span>' + escapeHtml(x.msg) + '</span></li>';
|
if (x.gln && x.gcol) {
|
||||||
|
return `<li data-ln="${x.ln}" data-col="${x.col}" data-gln="${x.gln}" data-gcol="${x.gcol}"><span>${x.ln}:${x.col}</span> <span>${escapeHtml(x.msg)}</span></li>`;
|
||||||
|
} else {
|
||||||
|
return `<li data-ln="${x.ln}" data-col="${x.col}"><span>${x.ln}:${x.col}</span> <span>${escapeHtml(x.msg)}</span></li>`;
|
||||||
|
}
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
html += '<ul>';
|
html += '<ul>';
|
||||||
@ -149,6 +153,11 @@ function makeOnClickInInfo(editor) {
|
|||||||
editor.navigateTo(el.data('ln') - 1, el.data('col') - 1);
|
editor.navigateTo(el.data('ln') - 1, el.data('col') - 1);
|
||||||
editor.scrollToLine(el.data('ln') - 1, true, false, null);
|
editor.scrollToLine(el.data('ln') - 1, true, false, null);
|
||||||
editor.focus();
|
editor.focus();
|
||||||
|
|
||||||
|
if(el.data('gln') && el.data('gcol')) {
|
||||||
|
grammar.navigateTo(el.data('gln') - 1, el.data('gcol') - 1);
|
||||||
|
grammar.scrollToLine(el.data('gln') - 1, true, false, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$('#grammar-info').on('click', 'li', makeOnClickInInfo(grammar));
|
$('#grammar-info').on('click', 'li', makeOnClickInInfo(grammar));
|
||||||
|
@ -18,15 +18,24 @@ std::string escape_json(const std::string &s) {
|
|||||||
return o.str();
|
return o.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void(size_t, size_t, const std::string &)>
|
std::function<void(size_t, size_t, const std::string &, const std::string &)>
|
||||||
makeJSONFormatter(std::string &json, bool &init) {
|
makeJSONFormatter(peg::parser &peg, std::string &json, bool &init) {
|
||||||
init = true;
|
init = true;
|
||||||
return [&](size_t ln, size_t col, const std::string &msg) mutable {
|
return [&](size_t ln, size_t col, const std::string &msg, const std::string &rule) mutable {
|
||||||
if (!init) { json += ","; }
|
if (!init) { json += ","; }
|
||||||
json += "{";
|
json += "{";
|
||||||
json += R"("ln":)" + std::to_string(ln) + ",";
|
json += R"("ln":)" + std::to_string(ln) + ",";
|
||||||
json += R"("col":)" + std::to_string(col) + ",";
|
json += R"("col":)" + std::to_string(col) + ",";
|
||||||
json += R"("msg":")" + escape_json(msg) + R"(")";
|
json += R"("msg":")" + escape_json(msg) + R"(")";
|
||||||
|
if (!rule.empty()) {
|
||||||
|
auto it = peg.get_grammar().find(rule);
|
||||||
|
if (it != peg.get_grammar().end()) {
|
||||||
|
auto [gln, gcol] = it->second.line_;
|
||||||
|
json += ",";
|
||||||
|
json += R"("gln":)" + std::to_string(gln) + ",";
|
||||||
|
json += R"("gcol":)" + std::to_string(gcol);
|
||||||
|
}
|
||||||
|
}
|
||||||
json += "}";
|
json += "}";
|
||||||
|
|
||||||
init = false;
|
init = false;
|
||||||
@ -36,7 +45,7 @@ makeJSONFormatter(std::string &json, bool &init) {
|
|||||||
bool parse_grammar(const std::string &text, peg::parser &peg,
|
bool parse_grammar(const std::string &text, peg::parser &peg,
|
||||||
std::string &json) {
|
std::string &json) {
|
||||||
bool init;
|
bool init;
|
||||||
peg.set_logger(makeJSONFormatter(json, init));
|
peg.set_logger(makeJSONFormatter(peg, json, init));
|
||||||
json += "[";
|
json += "[";
|
||||||
auto ret = peg.load_grammar(text.data(), text.size());
|
auto ret = peg.load_grammar(text.data(), text.size());
|
||||||
json += "]";
|
json += "]";
|
||||||
@ -47,7 +56,7 @@ bool parse_code(const std::string &text, peg::parser &peg, std::string &json,
|
|||||||
std::shared_ptr<peg::Ast> &ast) {
|
std::shared_ptr<peg::Ast> &ast) {
|
||||||
peg.enable_ast();
|
peg.enable_ast();
|
||||||
bool init;
|
bool init;
|
||||||
peg.set_logger(makeJSONFormatter(json, init));
|
peg.set_logger(makeJSONFormatter(peg, json, init));
|
||||||
json += "[";
|
json += "[";
|
||||||
auto ret = peg.parse_n(text.data(), text.size(), ast);
|
auto ret = peg.parse_n(text.data(), text.size(), ast);
|
||||||
json += "]";
|
json += "]";
|
||||||
|
BIN
docs/native.wasm
BIN
docs/native.wasm
Binary file not shown.
21
peglib.h
21
peglib.h
@ -2328,6 +2328,7 @@ public:
|
|||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
const char *s_ = nullptr;
|
const char *s_ = nullptr;
|
||||||
|
std::pair<size_t, size_t> line_ = {1, 1};
|
||||||
|
|
||||||
std::function<bool(const SemanticValues &vs, const std::any &dt,
|
std::function<bool(const SemanticValues &vs, const std::any &dt,
|
||||||
std::string &msg)>
|
std::string &msg)>
|
||||||
@ -2557,6 +2558,9 @@ inline void ErrorInfo::output_log(const Log &log, const char *s, size_t n) {
|
|||||||
msg += "'";
|
msg += "'";
|
||||||
} else {
|
} else {
|
||||||
msg += "<" + error_rule->name + ">";
|
msg += "<" + error_rule->name + ">";
|
||||||
|
if (label.empty()) {
|
||||||
|
label = error_rule->name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
first_item = false;
|
first_item = false;
|
||||||
}
|
}
|
||||||
@ -2937,14 +2941,12 @@ inline size_t Recovery::parse_core(const char *s, size_t n,
|
|||||||
// Custom error message
|
// Custom error message
|
||||||
if (c.log) {
|
if (c.log) {
|
||||||
auto label = dynamic_cast<Reference *>(rule.args_[0].get());
|
auto label = dynamic_cast<Reference *>(rule.args_[0].get());
|
||||||
if (label) {
|
if (label && !label->rule_->error_message.empty()) {
|
||||||
if (!label->rule_->error_message.empty()) {
|
|
||||||
c.error_info.message_pos = s;
|
c.error_info.message_pos = s;
|
||||||
c.error_info.message = label->rule_->error_message;
|
c.error_info.message = label->rule_->error_message;
|
||||||
c.error_info.label = label->rule_->name;
|
c.error_info.label = label->rule_->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Recovery
|
// Recovery
|
||||||
auto len = static_cast<size_t>(-1);
|
auto len = static_cast<size_t>(-1);
|
||||||
@ -3481,13 +3483,14 @@ private:
|
|||||||
rule <= ope;
|
rule <= ope;
|
||||||
rule.name = name;
|
rule.name = name;
|
||||||
rule.s_ = vs.sv().data();
|
rule.s_ = vs.sv().data();
|
||||||
|
rule.line_ = line_info(vs.ss, rule.s_);
|
||||||
rule.ignoreSemanticValue = ignore;
|
rule.ignoreSemanticValue = ignore;
|
||||||
rule.is_macro = is_macro;
|
rule.is_macro = is_macro;
|
||||||
rule.params = params;
|
rule.params = params;
|
||||||
|
|
||||||
if (data.start.empty()) {
|
if (data.start.empty()) {
|
||||||
data.start = name;
|
data.start = rule.name;
|
||||||
data.start_pos = vs.sv().data();
|
data.start_pos = rule.s_;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data.duplicates_of_definition.emplace_back(name, vs.sv().data());
|
data.duplicates_of_definition.emplace_back(name, vs.sv().data());
|
||||||
@ -4549,13 +4552,7 @@ public:
|
|||||||
|
|
||||||
const Definition &operator[](const char *s) const { return (*grammar_)[s]; }
|
const Definition &operator[](const char *s) const { return (*grammar_)[s]; }
|
||||||
|
|
||||||
std::vector<std::string> get_rule_names() const {
|
const Grammar &get_grammar() const { return *grammar_; }
|
||||||
std::vector<std::string> rules;
|
|
||||||
for (auto &[name, _] : *grammar_) {
|
|
||||||
rules.push_back(name);
|
|
||||||
}
|
|
||||||
return rules;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_eoi_check() {
|
void disable_eoi_check() {
|
||||||
if (grammar_ != nullptr) {
|
if (grammar_ != nullptr) {
|
||||||
|
@ -901,7 +901,8 @@ TEST(GeneralTest, Semantic_values_test) {
|
|||||||
x <- 'x'
|
x <- 'x'
|
||||||
)");
|
)");
|
||||||
|
|
||||||
for (const auto &rule : parser.get_rule_names()) {
|
for (const auto &item : parser.get_grammar()) {
|
||||||
|
const auto &rule = item.first;
|
||||||
parser[rule.data()] = [rule](const SemanticValues &vs, std::any &) {
|
parser[rule.data()] = [rule](const SemanticValues &vs, std::any &) {
|
||||||
if (rule == "term") {
|
if (rule == "term") {
|
||||||
EXPECT_EQ("a at 0", std::any_cast<std::string>(vs[0]));
|
EXPECT_EQ("a at 0", std::any_cast<std::string>(vs[0]));
|
||||||
|
Loading…
Reference in New Issue
Block a user