mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Error message support
This commit is contained in:
parent
1442e3e21f
commit
d4aa6e7df5
45
peglib.h
45
peglib.h
@ -2251,7 +2251,6 @@ public:
|
|||||||
std::function<void(const char *s, size_t n, size_t matchlen, std::any &value,
|
std::function<void(const char *s, size_t n, size_t matchlen, std::any &value,
|
||||||
std::any &dt)>
|
std::any &dt)>
|
||||||
leave;
|
leave;
|
||||||
std::function<std::string()> error_message;
|
|
||||||
bool ignoreSemanticValue = false;
|
bool ignoreSemanticValue = false;
|
||||||
std::shared_ptr<Ope> whitespaceOpe;
|
std::shared_ptr<Ope> whitespaceOpe;
|
||||||
std::shared_ptr<Ope> wordOpe;
|
std::shared_ptr<Ope> wordOpe;
|
||||||
@ -2262,6 +2261,8 @@ public:
|
|||||||
TracerLeave tracer_leave;
|
TracerLeave tracer_leave;
|
||||||
bool disable_action = false;
|
bool disable_action = false;
|
||||||
|
|
||||||
|
std::string error_message;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Reference;
|
friend class Reference;
|
||||||
friend class ParserGenerator;
|
friend class ParserGenerator;
|
||||||
@ -2505,13 +2506,6 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &vs,
|
|||||||
vs.emplace_back(std::move(val));
|
vs.emplace_back(std::move(val));
|
||||||
vs.tags.emplace_back(str2tag(outer_->name));
|
vs.tags.emplace_back(str2tag(outer_->name));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (outer_->error_message) {
|
|
||||||
if (c.error_info.message_pos < s) {
|
|
||||||
c.error_info.message_pos = s;
|
|
||||||
c.error_info.message = outer_->error_message();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
@ -2688,7 +2682,16 @@ inline size_t Recovery::parse_core(const char *s, size_t n, SemanticValues &vs,
|
|||||||
|
|
||||||
if (success(len)) {
|
if (success(len)) {
|
||||||
c.recovered = true;
|
c.recovered = true;
|
||||||
if (c.log) { c.error_info.output_log(c.log, c.s, c.l); }
|
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 = c.error_info.error_pos;
|
||||||
|
c.error_info.message = label->rule_->error_message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.error_info.output_log(c.log, c.s, c.l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.error_info.clear();
|
c.error_info.clear();
|
||||||
|
|
||||||
@ -3024,7 +3027,12 @@ private:
|
|||||||
|
|
||||||
// Instruction grammars
|
// Instruction grammars
|
||||||
g["Instruction"] <=
|
g["Instruction"] <=
|
||||||
seq(g["BeginBlacket"], cho(g["PrecedenceClimbing"]), g["EndBlacket"]);
|
seq(g["BeginBlacket"],
|
||||||
|
cho(
|
||||||
|
cho(g["PrecedenceClimbing"]),
|
||||||
|
cho(g["ErrorMessage"])
|
||||||
|
),
|
||||||
|
g["EndBlacket"]);
|
||||||
|
|
||||||
~g["SpacesZom"] <= zom(g["Space"]);
|
~g["SpacesZom"] <= zom(g["Space"]);
|
||||||
~g["SpacesOom"] <= oom(g["Space"]);
|
~g["SpacesOom"] <= oom(g["Space"]);
|
||||||
@ -3033,7 +3041,7 @@ private:
|
|||||||
|
|
||||||
// PrecedenceClimbing instruction
|
// PrecedenceClimbing instruction
|
||||||
g["PrecedenceClimbing"] <=
|
g["PrecedenceClimbing"] <=
|
||||||
seq(lit("precedence"), g["SpacesZom"], g["PrecedenceInfo"],
|
seq(lit("precedence"), g["SpacesOom"], g["PrecedenceInfo"],
|
||||||
zom(seq(g["SpacesOom"], g["PrecedenceInfo"])), g["SpacesZom"]);
|
zom(seq(g["SpacesOom"], g["PrecedenceInfo"])), g["SpacesZom"]);
|
||||||
g["PrecedenceInfo"] <=
|
g["PrecedenceInfo"] <=
|
||||||
seq(g["PrecedenceAssoc"],
|
seq(g["PrecedenceAssoc"],
|
||||||
@ -3043,6 +3051,11 @@ private:
|
|||||||
seq(npd(cho(g["PrecedenceAssoc"], g["Space"], chr('}'))), dot())));
|
seq(npd(cho(g["PrecedenceAssoc"], g["Space"], chr('}'))), dot())));
|
||||||
g["PrecedenceAssoc"] <= cls("LR");
|
g["PrecedenceAssoc"] <= cls("LR");
|
||||||
|
|
||||||
|
// Error message instruction
|
||||||
|
g["ErrorMessage"] <= seq(lit("message"), g["SpacesOom"],
|
||||||
|
g["LiteralD"],
|
||||||
|
g["SpacesZom"]);
|
||||||
|
|
||||||
// Set definition names
|
// Set definition names
|
||||||
for (auto &x : g) {
|
for (auto &x : g) {
|
||||||
x.second.name = x.first;
|
x.second.name = x.first;
|
||||||
@ -3340,6 +3353,14 @@ private:
|
|||||||
};
|
};
|
||||||
g["PrecedenceOpe"] = [](const SemanticValues &vs) { return vs.token(); };
|
g["PrecedenceOpe"] = [](const SemanticValues &vs) { return vs.token(); };
|
||||||
g["PrecedenceAssoc"] = [](const SemanticValues &vs) { return vs.token(); };
|
g["PrecedenceAssoc"] = [](const SemanticValues &vs) { return vs.token(); };
|
||||||
|
|
||||||
|
|
||||||
|
g["ErrorMessage"] = [](const SemanticValues &vs) {
|
||||||
|
Instruction instruction;
|
||||||
|
instruction.type = "message";
|
||||||
|
instruction.data = std::any_cast<std::string>(vs[0]);
|
||||||
|
return instruction;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool apply_precedence_instruction(Definition &rule,
|
bool apply_precedence_instruction(Definition &rule,
|
||||||
@ -3554,6 +3575,8 @@ private:
|
|||||||
if (!apply_precedence_instruction(rule, info, s, log)) {
|
if (!apply_precedence_instruction(rule, info, s, log)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
} else if (instruction.type == "message") {
|
||||||
|
rule.error_message = std::any_cast<std::string>(instruction.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user