From c06e78f87275aee9eab05358a00136e9e50ac567 Mon Sep 17 00:00:00 2001 From: Nana Sakisaka <1901813+saki7@users.noreply.github.com> Date: Sat, 14 Feb 2026 20:41:19 +0900 Subject: [PATCH 1/6] Improve error diagnostics --- include/iris/x4/core/action.hpp | 8 +++++++- include/iris/x4/core/skip_over.hpp | 19 +++++++++++++++++++ include/iris/x4/directive/skip.hpp | 19 +++++++++++++++++++ include/iris/x4/operator/alternative.hpp | 10 ++++++++++ include/iris/x4/operator/list.hpp | 10 ++++++++++ include/iris/x4/operator/sequence.hpp | 22 ++++++++++++++++++++++ 6 files changed, 87 insertions(+), 1 deletion(-) diff --git a/include/iris/x4/core/action.hpp b/include/iris/x4/core/action.hpp index fba6c57ab..da408cb64 100644 --- a/include/iris/x4/core/action.hpp +++ b/include/iris/x4/core/action.hpp @@ -17,11 +17,12 @@ #include #include -#include +#include // subrange #include #include #include #include +#include namespace iris::x4 { @@ -109,6 +110,11 @@ struct action : proxy_parser> constexpr void operator[](auto const&) const = delete; // You can't add semantic action for semantic action + [[nodiscard]] constexpr std::string get_x4_info() const + { + return std::format("{}[f]", get_info{}(this->subject)); + } + private: // Semantic action with no parameter: `p[([] { /* ... */ })]` template diff --git a/include/iris/x4/core/skip_over.hpp b/include/iris/x4/core/skip_over.hpp index 51a9f6eeb..83910a2d0 100644 --- a/include/iris/x4/core/skip_over.hpp +++ b/include/iris/x4/core/skip_over.hpp @@ -42,6 +42,25 @@ enum struct builtin_skipper_kind : char space, }; +namespace detail { + +template +struct builtin_skipper_traits; + +template<> +struct builtin_skipper_traits +{ + static constexpr char const* name = "blank"; +}; + +template<> +struct builtin_skipper_traits +{ + static constexpr char const* name = "space"; +}; + +} // detail + template Se, class Context> requires X4Subject> constexpr void skip_over(It& first, Se const& last, Context const& ctx) diff --git a/include/iris/x4/directive/skip.hpp b/include/iris/x4/directive/skip.hpp index 2b788f5c6..83e10bf90 100644 --- a/include/iris/x4/directive/skip.hpp +++ b/include/iris/x4/directive/skip.hpp @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -49,6 +50,15 @@ struct skip_directive : proxy_parser> return this->subject.parse(first, last, x4::replace_first_context(ctx, skipper_), attr); } + [[nodiscard]] constexpr std::string get_x4_info() const + { + return std::format( + "skip({})[{}]", + get_info{}(this->skipper_), + get_info{}(this->subject) + ); + } + private: template using context_t = std::remove_cvref_tsubject.parse(first, last, x4::replace_first_context(ctx, skipper_kind), attr); } + + [[nodiscard]] constexpr std::string get_x4_info() const + { + return std::format( + "skip({})[{}]", + detail::builtin_skipper_traits::name, + get_info{}(this->subject) + ); + } }; diff --git a/include/iris/x4/operator/alternative.hpp b/include/iris/x4/operator/alternative.hpp index 2746a15e5..ca187c5c7 100644 --- a/include/iris/x4/operator/alternative.hpp +++ b/include/iris/x4/operator/alternative.hpp @@ -22,6 +22,7 @@ #include +#include #include #include #include @@ -211,6 +212,15 @@ struct alternative : binary_parser> } return false; // `attr` is untouched } + + [[nodiscard]] constexpr std::string get_x4_info() const + { + return std::format( + "{} | {}", + get_info{}(this->left), + get_info{}(this->right) + ); + } }; template diff --git a/include/iris/x4/operator/list.hpp b/include/iris/x4/operator/list.hpp index c6d9039b9..87646a504 100644 --- a/include/iris/x4/operator/list.hpp +++ b/include/iris/x4/operator/list.hpp @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -63,6 +64,15 @@ struct list : binary_parser> return true; } } + + [[nodiscard]] constexpr std::string get_x4_info() const + { + return std::format( + "({} % {})", + get_info{}(this->left), + get_info{}(this->right) + ); + } }; template diff --git a/include/iris/x4/operator/sequence.hpp b/include/iris/x4/operator/sequence.hpp index 67109b1a9..9d31d2550 100644 --- a/include/iris/x4/operator/sequence.hpp +++ b/include/iris/x4/operator/sequence.hpp @@ -20,7 +20,9 @@ #include #include +#include +#include #include #include #include @@ -28,6 +30,9 @@ namespace iris::x4 { +template +struct expect_directive; + template struct sequence : binary_parser> { @@ -73,6 +78,23 @@ struct sequence : binary_parser> { return detail::parse_sequence(*this, first, last, ctx, attr); } + + [[nodiscard]] constexpr std::string get_x4_info() const + { + if constexpr (iris::is_ttp_specialization_of_v) { + return std::format( + "{} > {}", + get_info{}(this->left), + get_info{}(this->right.subject) + ); + } else { + return std::format( + "{} >> {}", + get_info{}(this->left), + get_info{}(this->right) + ); + } + } }; template From ea37c441fc1fff4a9c236df548595e6fb093375e Mon Sep 17 00:00:00 2001 From: Nana Sakisaka <1901813+saki7@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:44:29 +0900 Subject: [PATCH 2/6] Don't test fragile debug output --- test/x4/expect.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/test/x4/expect.cpp b/test/x4/expect.cpp index 86fe5b483..7421940de 100644 --- a/test/x4/expect.cpp +++ b/test/x4/expect.cpp @@ -339,13 +339,11 @@ TEST_CASE("expect") #ifndef IRIS_X4_NO_RTTI X4_TEST_FAILURE("ay:a", char_ > char_('x') >> ':' > 'a', { - CHECK(x.which().find("sequence") != std::string::npos); CHECK(where == "y:a"sv); }); #else X4_TEST_FAILURE("ay:a", char_ > char_('x') >> ':' > 'a', { - CHECK(which == "undefined"sv); CHECK(where == "y:a"sv); }); #endif @@ -418,23 +416,6 @@ TEST_CASE("expect") }); } - // - // ********* Developers note ********** - // - // As of now (see `git blame`), get_info is still not - // specialized for many of the X4 parsers so that the - // value of `expectation_failure<...>::which()` will be - // implementation-defined demangled string. - // Therefore, it's essentially impossible to test them - // right now; further work must be done. - // - // Some specific situations are already been reported - // (e.g. https://github.com/boostorg/spirit/issues/777) - // but we really need to implement all specializations for - // X4's predefined parsers, not just the one reported above. - // - - // sanity check: test expectation_failure propagation // on custom skippers { From 31ad2065ec0211302d49d0f8f6d1c3d47c047401 Mon Sep 17 00:00:00 2001 From: Nana Sakisaka <1901813+saki7@users.noreply.github.com> Date: Fri, 20 Feb 2026 12:27:26 +0900 Subject: [PATCH 3/6] Improve error diagnostics --- include/iris/x4/directive/lexeme.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/iris/x4/directive/lexeme.hpp b/include/iris/x4/directive/lexeme.hpp index f14118091..d12dfc20f 100644 --- a/include/iris/x4/directive/lexeme.hpp +++ b/include/iris/x4/directive/lexeme.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,11 @@ struct lexeme_directive : proxy_parser> attr ); } + + [[nodiscard]] constexpr std::string get_x4_info() const + { + return std::format("lexeme[{}]", get_info{}(this->subject)); + } }; namespace detail { From 60f56e25e3778f33b845cf8d24e79b780bffafdc Mon Sep 17 00:00:00 2001 From: Nana Sakisaka <1901813+saki7@users.noreply.github.com> Date: Wed, 4 Mar 2026 23:07:29 +0900 Subject: [PATCH 4/6] Remove utf8 handling --- include/iris/x4/string/literal_string.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/iris/x4/string/literal_string.hpp b/include/iris/x4/string/literal_string.hpp index 848e5ed7a..54def7122 100644 --- a/include/iris/x4/string/literal_string.hpp +++ b/include/iris/x4/string/literal_string.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -75,7 +76,7 @@ struct get_info> using result_type = std::string; [[nodiscard]] constexpr std::string operator()(literal_string const& p) const { - return '"' + x4::to_utf8(p.str) + '"'; + return std::format("\"{}\"", p.str); } }; From 1bd7bad0b844ba97263a8996ac60a49d0eefcce3 Mon Sep 17 00:00:00 2001 From: Nana Sakisaka <1901813+saki7@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:01:23 +0900 Subject: [PATCH 5/6] Print string directly --- include/iris/x4/debug/print_attribute.hpp | 26 ++++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/include/iris/x4/debug/print_attribute.hpp b/include/iris/x4/debug/print_attribute.hpp index 650641993..97859dfd7 100644 --- a/include/iris/x4/debug/print_attribute.hpp +++ b/include/iris/x4/debug/print_attribute.hpp @@ -18,6 +18,7 @@ #include #include +#include #ifdef IRIS_X4_UNICODE # include @@ -133,18 +134,23 @@ struct print_attribute_debug requires (!std::is_same_v) static void call(std::ostream& out, T_ const& val) { - out << '['; - bool is_first = true; - auto last = traits::end(val); - for (auto it = traits::begin(val); it != last; ++it) { - if (is_first) { - is_first = false; - } else { - out << ", "; + if constexpr (iris::StringLike) { + out << std::basic_string_view{val}; + + } else { + out << '['; + bool is_first = true; + auto last = traits::end(val); + for (auto it = traits::begin(val); it != last; ++it) { + if (is_first) { + is_first = false; + } else { + out << ", "; + } + traits::print_attribute(out, *it); } - traits::print_attribute(out, *it); + out << ']'; } - out << ']'; } // for variant types From 45bbba5f2cf61347d5c673419cdaa1d0c018fd5e Mon Sep 17 00:00:00 2001 From: Nana Sakisaka <1901813+saki7@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:46:10 +0900 Subject: [PATCH 6/6] Update iris --- modules/iris | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/iris b/modules/iris index cec583eed..fe9e3a14d 160000 --- a/modules/iris +++ b/modules/iris @@ -1 +1 @@ -Subproject commit cec583eed7ab2fb70e7ef6aa52ab840bc03e92ca +Subproject commit fe9e3a14dd412910b5a6dd6f14590bb6ced68ddc