Масштабирование в boost :: spirit's assign_a - PullRequest
2 голосов
/ 18 июня 2009

Я углубляюсь в boost :: spirit, чтобы разобрать протокол на основе ASCII. Мне удалось извлечь значения из строки, используя такие правила:

rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_a(buffer.speed)];

Мне также удалось соединить эти правила осмысленно. Чего не хватает для идеального дня, так это следующего: значения данных являются целыми числами, которые необходимо преобразовать в значения с плавающей запятой, используя фиксированный коэффициент преобразования (обычно степени 10).

То, что я делаю прямо сейчас, это просто применение этих коэффициентов масштабирования после анализа Однако я бы с радостью включил масштабный коэффициент прямо в определение правила для поля. Я представляю что-то вроде этого:

rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_a(buffer.speed,100)];

Есть предложения?

Заранее спасибо Arne

Ответы [ 2 ]

1 голос
/ 22 июня 2009

Один из способов сделать это - использовать Boost.Phoenix . Включить эти заголовки:

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp> // For static_cast_
#include <boost/spirit/include/phoenix_operator.hpp> // For multiplication

, а затем используйте что-то вроде:

using namespace boost::phoenix;
using namespace boost::phoenix::arg_names;

rule<> Speed = uint_parser<unsigned int,10,3,3>()[
    ref(buffer.speed) = static_cast_<double>(arg1) * 100
];

Хотя я нахожу Феникса немного хитрым в использовании и обычно просто пишу свое собственное действие :

struct assign_scaled
{
    double& result;
    double scale;

    assign_with_scale(double& r, double scale) : result(r), scale(scale) {}

    void operator()(unsigned int x) const
    {
        result = static_cast<double>(x) * scale;
    }
};

И используйте это так:

    rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_scaled(buffer.speed, 100)];

Это может быть более многословно, но мне легче поддерживать.

0 голосов
/ 08 января 2010

С Spirit.Qi вы можете использовать [ref(buffer.speed) = _1 * 100]

...