boost :: spiritのassign_aのスケーリング
-
06-07-2019 - |
質問
ASCIIベースのプロトコルを解析するためにboost :: spiritに飛び込みます。次のようなルールを使用して、行から値を抽出しました。
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)];
提案はありますか
事前に感謝 アルネ
解決
これを行う1つの方法は、 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)];
これはより冗長かもしれませんが、保守が簡単だと思います。
他のヒント
Spirit.Qiでは、 [ref(buffer.speed)= _1 * 100]
所属していません StackOverflow