首页 > 解决方案 > 链接语义动作

问题描述

我在链接语义操作时遇到问题。

我想解析一个百分比(X%带有X实数)并将其值作为 0 到 1 之间的浮点数返回。如果百分比高于 100%,我也想失败。

我目前拥有的是两个几乎微不足道的简单规则和一些简单的语义操作:

const auto ensure_normalized = [](auto& context)
{
  const auto& value = _attr(context);

  _pass(context) = value >= 0 && value <= 1;
  _val(context) = _attr(context);
};

template<typename T, typename ContextType>
void multiply_by(T multiplier, ContextType& context)
{
  using value_type = std::remove_reference_t<decltype(_val(context))>;
  using attribute_type = std::remove_reference_t<decltype(_attr(context))>;

  _val(context) = value_type(_attr(context) * attribute_type(multiplier));
}
constexpr auto divide_by_100 = [](auto& context) { multiply_by(.01f, context); };
const auto percentage = rule<struct percentage, float>{"percentage"}
                        = (float_ >> '%')[divide_by_100];
const auto normalized_percentage = rule<struct normalized_percentage, float>{"normalized_percentage"}
                                   = percentage[ensure_normalized];

这适用于我所期望的一切。问题是,我觉得我没有这样做The Right Way(即我认为我没有按预期使用 Boost.Spirit.X3)。尤其是 s 的爆发,rule让这看起来很可笑。

如果我尝试将ensure_normalized语义操作直接应用于第一条规则,例如

const auto normalized_percentage = rule<struct normalized_percentage, float>{"normalized_percentage"}
                                   =  ((float_ >> '%')[divide_by_100])[ensure_normalized];

我得到一个垃圾值。看起来这个任务ensure_normalized也有点像黑客。我只是不明白还有什么方法可以告诉 X3 该做什么。

代码在coliru上。

标签: c++parsingc++17boost-spirit-x3

解决方案


推荐阅读