Pregunta

Me estoy sumergiendo en boost :: spirit para analizar un protocolo basado en ASCII. Me las arreglé para extraer valores de la línea usando reglas como esta:

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

También logro conectar estas reglas de manera significativa. Lo que falta para un día perfecto es lo siguiente: los valores de los datos son enteros que deben transformarse en valores de coma flotante utilizando un factor de conversión fijo (generalmente potencias de 10).

Lo que hago ahora es simplemente aplicar estos factores de escalado después del análisis. Sin embargo, realmente me gustaría incluir el factor de escala dentro de la definición de la regla para el campo. Me imagino algo como esto:

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

¿Alguna sugerencia?

Gracias de antemano Arne

¿Fue útil?

Solución

Una forma de hacerlo es usar Boost.Phoenix . Incluya estos encabezados:

#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

y luego usa algo como:

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
];

Aunque, creo que Phoenix es un poco difícil de usar y, en general, solo escribir mi propia acción :

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;
    }
};

Y úsalo así:

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

Esto puede ser más detallado, pero me resulta más fácil de mantener.

Otros consejos

Con Spirit.Qi puede usar [ref (buffer.speed) = _1 * 100]

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top