Domanda

Mi sto tuffando in boost :: spirit per analizzare un protocollo basato su ASCII. Ho organizzato per estrarre valori dalla riga usando regole come questa:

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

Riesco anche a collegare queste regole in modo significativo. Ciò che manca per un giorno perfetto è il seguente: I valori dei dati sono numeri interi che devono essere trasformati in valori in virgola mobile utilizzando un fattore di conversione fisso (generalmente potenze di 10).

Quello che faccio adesso è semplicemente applicare questi fattori di ridimensionamento dopo l'analisi. Tuttavia, mi piacerebbe davvero includere il fattore di ridimensionamento proprio all'interno della definizione della regola per il campo. Immagino qualcosa del genere:

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

Qualche suggerimento?

Grazie in anticipo Arne

È stato utile?

Soluzione

Un modo per farlo è utilizzare Boost.Phoenix . Includi queste intestazioni:

#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

e quindi usa qualcosa come:

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

Anche se trovo che Phoenix sia un po 'difficile da usare e generalmente solo scrivi la mia azione :

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

E usalo in questo modo:

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

Potrebbe essere più dettagliato, ma trovo che sia più facile da mantenere.

Altri suggerimenti

Con Spirit.Qi puoi usare [ref (buffer.speed) = _1 * 100]

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top