Сцепление семантических действий - PullRequest
0 голосов
/ 06 декабря 2018

У меня проблемы с цепочкой семантических действий.

Я хочу проанализировать процент (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, как предполагалось).Особенно взрыв rule s делает это смешным.

Если я пытаюсь применить семантическое действие ensure_normalized непосредственно к первому правилу, например,

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

Я получаю мусорценитьТакже кажется, что задание в ensure_normalized является чем-то вроде хака.Я просто не вижу, как еще сказать X3, что делать.

Код на coliru .

...