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