Mise à l'échelle dans boost :: spirit's assign_a
-
06-07-2019 - |
Question
Je plonge dans boost :: spirit afin d’analyser un protocole basé sur ASCII. J'ai réussi à extraire des valeurs de la ligne en utilisant des règles telles que:
rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_a(buffer.speed)];
J'ai également réussi à associer ces règles de manière significative. Ce qui manque pour un jour parfait est le suivant: Les valeurs de données sont des entiers qui doivent être transformés en valeurs à virgule flottante à l’aide d’un facteur de conversion fixe (généralement de 10).
Ce que je fais en ce moment, c’est simplement appliquer ces facteurs de mise à l’échelle après l’analyse. Cependant, j'apprécierais vraiment d'inclure le facteur d'échelle juste à l'intérieur de la définition de règle pour le champ. J'imagine quelque chose comme ça:
rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_a(buffer.speed,100)];
Des suggestions?
Merci d'avance Arne
La solution
Pour cela, utilisez Boost.Phoenix . Inclure ces en-têtes:
#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
puis utilisez quelque chose comme:
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
];
Bien que je trouve que Phoenix soit un peu difficile à utiliser et qu’il ne s’agisse généralement que de écrire ma propre action :
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;
}
};
Et utilisez-le comme ceci:
rule<> Speed = uint_parser<unsigned int,10,3,3>()[assign_scaled(buffer.speed, 100)];
Cela est peut-être plus détaillé, mais je le trouve plus facile à gérer.
Autres conseils
Avec Spirit.Qi, vous pouvez utiliser [ref (buffer.speed) = _1 * 100]