Progress towards REUSE compliance. Change-Id: Ia64efc4fbf4e8eb3800b75159f357ea009438ae1 Signed-off-by: Raito Bezarius <raito@lix.systems>
71 lines
2.3 KiB
C++
71 lines
2.3 KiB
C++
// SPDX-FileCopyrightText: 2024 Nix and Lix Authors
|
|
//
|
|
// SPDX-License-Identifier: LGPL-2.1-only
|
|
|
|
#pragma once
|
|
///@file
|
|
|
|
#include <tao/pegtl.hpp>
|
|
|
|
namespace nix::parser {
|
|
|
|
// modified copy of change_state, as the manual suggest for more involved
|
|
// state manipulation. we want to change only the first state parameter,
|
|
// and we care about the *initial* position of a rule application (not the
|
|
// past-the-end position as pegtl change_state provides)
|
|
template<typename NewState>
|
|
struct change_head : tao::pegtl::maybe_nothing
|
|
{
|
|
template<
|
|
typename Rule,
|
|
tao::pegtl::apply_mode A,
|
|
tao::pegtl::rewind_mode M,
|
|
template<typename...> class Action,
|
|
template<typename...> class Control,
|
|
typename ParseInput,
|
|
typename State,
|
|
typename... States
|
|
>
|
|
[[nodiscard]] static bool match(ParseInput & in, State && st, States &&... sts)
|
|
{
|
|
const auto begin = in.iterator();
|
|
|
|
if constexpr (std::is_constructible_v<NewState, State, States...>) {
|
|
NewState s(st, sts...);
|
|
if (tao::pegtl::match<Rule, A, M, Action, Control>(in, s, sts...)) {
|
|
if constexpr (A == tao::pegtl::apply_mode::action) {
|
|
_success<Action<Rule>>(0, begin, in, s, st, sts...);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
} else if constexpr (std::is_default_constructible_v<NewState>) {
|
|
NewState s;
|
|
if (tao::pegtl::match<Rule, A, M, Action, Control>(in, s, sts...)) {
|
|
if constexpr (A == tao::pegtl::apply_mode::action) {
|
|
_success<Action<Rule>>(0, begin, in, s, st, sts...);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
} else {
|
|
static_assert(decltype(sizeof(NewState))(), "unable to instantiate new state");
|
|
}
|
|
}
|
|
|
|
template<typename Target, typename ParseInput, typename... S>
|
|
static void _success(void *, auto & begin, ParseInput & in, S & ... sts)
|
|
{
|
|
const typename ParseInput::action_t at(begin, in);
|
|
Target::success(at, sts...);
|
|
}
|
|
|
|
template<typename Target, typename... S>
|
|
static void _success(decltype(Target::success0(std::declval<S &>()...), 0), auto &, auto &, S & ... sts)
|
|
{
|
|
Target::success0(sts...);
|
|
}
|
|
};
|
|
|
|
}
|