Improved error message

This commit is contained in:
yhirose 2021-01-10 16:02:15 -05:00
parent 50aaba73a3
commit befdd27075

View File

@ -604,7 +604,7 @@ public:
std::vector<size_t> source_line_index; std::vector<size_t> source_line_index;
const char *error_pos = nullptr; const char *error_pos = nullptr;
std::vector<const char *> expected_tokens; std::vector<std::pair<const char *, bool>> expected_tokens;
const char *message_pos = nullptr; const char *message_pos = nullptr;
std::string message; // TODO: should be `int`. std::string message; // TODO: should be `int`.
@ -1961,7 +1961,7 @@ public:
bool ret; bool ret;
size_t len; size_t len;
const char *error_pos; const char *error_pos;
const std::vector<const char *> expected_tokens; const std::vector<std::pair<const char *, bool>> expected_tokens;
const char *message_pos; const char *message_pos;
const std::string message; const std::string message;
}; };
@ -2186,13 +2186,15 @@ inline void Context::set_error_pos(const char *a_s, const char *literal) {
expected_tokens.clear(); expected_tokens.clear();
} }
if (literal) { if (literal) {
expected_tokens.push_back(literal); expected_tokens.push_back(std::make_pair(literal, true));
} else if (!rule_stack.empty()) { } else if (!rule_stack.empty()) {
auto rule = rule_stack.back(); auto rule = rule_stack.back();
auto ope = rule->get_core_operator(); auto ope = rule->get_core_operator();
if (auto token = FindLiteralToken::token(*ope); if (auto token = FindLiteralToken::token(*ope);
token && token[0] != '\0') { token && token[0] != '\0') {
expected_tokens.push_back(token); expected_tokens.push_back(std::make_pair(token, true));
} else {
expected_tokens.push_back(std::make_pair(rule->name.c_str(), false));
} }
} }
} }
@ -3826,9 +3828,23 @@ private:
size_t i = 0; size_t i = 0;
while (i < r.expected_tokens.size()) { while (i < r.expected_tokens.size()) {
message += (i == 0 ? ", expecting '" : ", '"); auto [token, is_literal] =
message += r.expected_tokens[r.expected_tokens.size() - i - 1]; r.expected_tokens[r.expected_tokens.size() - i - 1];
// Skip rules start with '_'
if (!is_literal && token[0] != '_') {
message += (i == 0 ? ", expecting " : ", ");
if (is_literal) {
message += "'"; message += "'";
message += token;
message += "'";
} else {
message += "<";
message += token;
message += ">";
}
}
i++; i++;
} }
message += "."; message += ".";