Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion include/iris/x4/core/action.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
#include <iris/x4/core/context.hpp>
#include <iris/x4/core/action_context.hpp>

#include <ranges>
#include <ranges> // subrange
#include <iterator>
#include <concepts>
#include <type_traits>
#include <utility>
#include <format>

namespace iris::x4 {

Expand Down Expand Up @@ -109,6 +110,11 @@ struct action : proxy_parser<Subject, action<Subject, ActionF>>

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<Subject>{}(this->subject));
}

private:
// Semantic action with no parameter: `p[([] { /* ... */ })]`
template<class Context, X4Attribute Attr>
Expand Down
19 changes: 19 additions & 0 deletions include/iris/x4/core/skip_over.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ enum struct builtin_skipper_kind : char
space,
};

namespace detail {

template<builtin_skipper_kind Kind>
struct builtin_skipper_traits;

template<>
struct builtin_skipper_traits<builtin_skipper_kind::blank>
{
static constexpr char const* name = "blank";
};

template<>
struct builtin_skipper_traits<builtin_skipper_kind::space>
{
static constexpr char const* name = "space";
};

} // detail

template<std::forward_iterator It, std::sentinel_for<It> Se, class Context>
requires X4Subject<get_context_plain_t<contexts::skipper, Context>>
constexpr void skip_over(It& first, Se const& last, Context const& ctx)
Expand Down
6 changes: 6 additions & 0 deletions include/iris/x4/directive/lexeme.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <iris/x4/core/skip_over.hpp>
#include <iris/x4/core/parser.hpp>

#include <format>
#include <iterator>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -43,6 +44,11 @@ struct lexeme_directive : proxy_parser<Subject, lexeme_directive<Subject>>
attr
);
}

[[nodiscard]] constexpr std::string get_x4_info() const
{
return std::format("lexeme[{}]", get_info<Subject>{}(this->subject));
}
};

namespace detail {
Expand Down
19 changes: 19 additions & 0 deletions include/iris/x4/directive/skip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <iris/x4/char/char_class_tags.hpp>

#include <format>
#include <concepts>
#include <iterator>
#include <type_traits>
Expand Down Expand Up @@ -49,6 +50,15 @@ struct skip_directive : proxy_parser<Subject, skip_directive<Subject, Skipper>>
return this->subject.parse(first, last, x4::replace_first_context<contexts::skipper>(ctx, skipper_), attr);
}

[[nodiscard]] constexpr std::string get_x4_info() const
{
return std::format(
"skip({})[{}]",
get_info<Skipper>{}(this->skipper_),
get_info<Subject>{}(this->subject)
);
}

private:
template<class Context>
using context_t = std::remove_cvref_t<decltype(
Expand Down Expand Up @@ -98,6 +108,15 @@ struct builtin_skip_directive : proxy_parser<Subject, builtin_skip_directive<Kin
/* constexpr */ builtin_skipper_kind skipper_kind = Kind;
return this->subject.parse(first, last, x4::replace_first_context<contexts::skipper>(ctx, skipper_kind), attr);
}

[[nodiscard]] constexpr std::string get_x4_info() const
{
return std::format(
"skip({})[{}]",
detail::builtin_skipper_traits<Kind>::name,
get_info<Subject>{}(this->subject)
);
}
};


Expand Down
10 changes: 10 additions & 0 deletions include/iris/x4/operator/alternative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <iris/rvariant/rvariant.hpp>

#include <format>
#include <concepts>
#include <iterator>
#include <type_traits>
Expand Down Expand Up @@ -192,6 +193,15 @@ struct alternative : binary_parser<Left, Right, alternative<Left, Right>>
}
return false; // `attr` is untouched
}

[[nodiscard]] constexpr std::string get_x4_info() const
{
return std::format(
"{} | {}",
get_info<Left>{}(this->left),
get_info<Right>{}(this->right)
);
}
};

template<X4Subject Left, X4Subject Right>
Expand Down
10 changes: 10 additions & 0 deletions include/iris/x4/operator/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <iris/x4/traits/container_traits.hpp>

#include <format>
#include <iterator>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -63,6 +64,15 @@ struct list : binary_parser<Left, Right, list<Left, Right>>
return true;
}
}

[[nodiscard]] constexpr std::string get_x4_info() const
{
return std::format(
"({} % {})",
get_info<Left>{}(this->left),
get_info<Right>{}(this->right)
);
}
};

template<X4Subject Left, X4Subject Right>
Expand Down
22 changes: 22 additions & 0 deletions include/iris/x4/operator/sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@
#include <iris/x4/directive/expect.hpp>

#include <iris/alloy/tuple.hpp>
#include <iris/type_traits.hpp>

#include <format>
#include <concepts>
#include <iterator>
#include <type_traits>
#include <utility>

namespace iris::x4 {

template<class Subject>
struct expect_directive;

template<class Left, class Right>
struct sequence : binary_parser<Left, Right, sequence<Left, Right>>
{
Expand Down Expand Up @@ -73,6 +78,23 @@ struct sequence : binary_parser<Left, Right, sequence<Left, Right>>
{
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<Right, expect_directive>) {
return std::format(
"{} > {}",
get_info<Left>{}(this->left),
get_info<typename Right::subject_type>{}(this->right.subject)
);
} else {
return std::format(
"{} >> {}",
get_info<Left>{}(this->left),
get_info<Right>{}(this->right)
);
}
}
};

template<X4Subject Left, X4Subject Right>
Expand Down
19 changes: 0 additions & 19 deletions test/x4/expect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -418,23 +416,6 @@ TEST_CASE("expect")
});
}

//
// ********* Developers note **********
//
// As of now (see `git blame`), get_info<T> 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
{
Expand Down
Loading