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::any &dt)>
|
||||
leave;
|
||||
std::function<std::string()> error_message;
|
||||
bool ignoreSemanticValue = false;
|
||||
std::shared_ptr<Ope> whitespaceOpe;
|
||||
std::shared_ptr<Ope> wordOpe;
|
||||
@ -2262,6 +2261,8 @@ public:
|
||||
TracerLeave tracer_leave;
|
||||
bool disable_action = false;
|
||||
|
||||
std::string error_message;
|
||||
|
||||
private:
|
||||
friend class Reference;
|
||||
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.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;
|
||||
@ -2688,7 +2682,16 @@ inline size_t Recovery::parse_core(const char *s, size_t n, SemanticValues &vs,
|
||||
|
||||
if (success(len)) {
|
||||
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();
|
||||
|
||||
@ -3024,7 +3027,12 @@ private:
|
||||
|
||||
// Instruction grammars
|
||||
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["SpacesOom"] <= oom(g["Space"]);
|
||||
@ -3033,7 +3041,7 @@ private:
|
||||
|
||||
// PrecedenceClimbing instruction
|
||||
g["PrecedenceClimbing"] <=
|
||||
seq(lit("precedence"), g["SpacesZom"], g["PrecedenceInfo"],
|
||||
seq(lit("precedence"), g["SpacesOom"], g["PrecedenceInfo"],
|
||||
zom(seq(g["SpacesOom"], g["PrecedenceInfo"])), g["SpacesZom"]);
|
||||
g["PrecedenceInfo"] <=
|
||||
seq(g["PrecedenceAssoc"],
|
||||
@ -3043,6 +3051,11 @@ private:
|
||||
seq(npd(cho(g["PrecedenceAssoc"], g["Space"], chr('}'))), dot())));
|
||||
g["PrecedenceAssoc"] <= cls("LR");
|
||||
|
||||
// Error message instruction
|
||||
g["ErrorMessage"] <= seq(lit("message"), g["SpacesOom"],
|
||||
g["LiteralD"],
|
||||
g["SpacesZom"]);
|
||||
|
||||
// Set definition names
|
||||
for (auto &x : g) {
|
||||
x.second.name = x.first;
|
||||
@ -3340,6 +3353,14 @@ private:
|
||||
};
|
||||
g["PrecedenceOpe"] = [](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,
|
||||
@ -3554,6 +3575,8 @@ private:
|
||||
if (!apply_precedence_instruction(rule, info, s, log)) {
|
||||
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