diff --git a/peglib.h b/peglib.h index d2ad3b5..a2f2de9 100644 --- a/peglib.h +++ b/peglib.h @@ -2735,6 +2735,12 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &vs, c.error_info.message = msg; } } + } else { + if (c.log && !outer_->error_message.empty() && + c.error_info.message_pos < s) { + c.error_info.message_pos = s; + c.error_info.message = outer_->error_message; + } } }); @@ -3382,9 +3388,8 @@ private: opt(seq(g["InstructionItem"], zom(seq(g["InstructionItemSeparator"], g["InstructionItem"])))), g["EndBlacket"]); - g["InstructionItem"] <= cho(g["PrecedenceClimbing"], g["ErrorMessage"], - g["NoAstOpt"] - ); + g["InstructionItem"] <= + cho(g["PrecedenceClimbing"], g["ErrorMessage"], g["NoAstOpt"]); ~g["InstructionItemSeparator"] <= seq(chr(';'), g["Spacing"]); ~g["SpacesZom"] <= zom(g["Space"]); diff --git a/test/test2.cc b/test/test2.cc index 7cd764d..0aedd32 100644 --- a/test/test2.cc +++ b/test/test2.cc @@ -2051,3 +2051,39 @@ SkipToRCUR ← (!RCUR (LCUR SkipToRCUR / .))* RCUR )", ast_to_s(ast)); } + +TEST(ErrorTest, Error_message_with_rule_instruction) { + parser pg(R"( +START <- (LINE (ln LINE)*)? ln? + +LINE <- STR '=' CODE + +CODE <- HEX / DEC { message 'code format error...' } +HEX <- < [a-f0-9]+ 'h' > +DEC <- < [0-9]+ > + +STR <- < [a-z0-9]+ > + +~ln <- [\r\n]+ +%whitespace <- [ \t]* + )"); + + EXPECT_TRUE(!!pg); + + std::vector errors{ + R"(2:5: code format error...)", + }; + + size_t i = 0; + pg.log = [&](size_t ln, size_t col, const std::string &msg) { + std::stringstream ss; + ss << ln << ":" << col << ": " << msg; + EXPECT_EQ(errors[i++], ss.str()); + }; + + EXPECT_FALSE(pg.parse(R"(1 = ah +2 = b +3 = ch + )")); + EXPECT_EQ(i, errors.size()); +}