Boost logo

Boost Users :

Subject: [Boost-users] boost-spirit: need help with simple parser
From: Allan Nielsen (a_at_[hidden])
Date: 2012-07-03 06:04:31


Hi

I would like to use boost::spirit for parsing ipv4 addresses. Here is
what I have tried to do:

struct Ipv4 {
    Ipv4() { raw.as_int = 0; }
    Ipv4( const Ipv4& i ) { raw.as_int = i.raw.as_int; }
    Ipv4& operator=(const Ipv4& i ) { raw.as_int = i.raw.as_int; return *this; }

    Ipv4(const boost::tuple<uint8_t, uint8_t, uint8_t, uint8_t>& v) {
        raw.as_char[3] = v.get<0>();
        raw.as_char[2] = v.get<1>();
        raw.as_char[1] = v.get<2>();
        raw.as_char[0] = v.get<3>();
    }

    union {
        uint32_t as_int;
        uint16_t as_short[2];
        uint8_t as_char[4];
    } raw;
};

struct DecOctet : qi::grammar<const char *, uint8_t()>
{
    DecOctet() : DecOctet::base_type(start)
    {
        start %= qi::uint_parser<uint8_t, 10, 1, 3>();
    }

    qi::rule<const char *, uint8_t()> start;
} dec_octet;

struct Ipv4Address : qi::grammar<const char *, Ipv4()>
{
    Ipv4Address() : Ipv4Address::base_type(start)
    {
        start %= dec_octet >> qi::lit('.') >>
                 dec_octet >> qi::lit('.') >>
                 dec_octet >> qi::lit('.') >>
                 dec_octet
        ;
    }

    qi::rule<const char *, Ipv4()> start;
} ipv4_address;

bool parse(const const_string& s, Ipv4& i)
{
    Ipv4 _i;
    const char * iter = s.begin();
    bool r = qi::parse(iter, s.end(), ipv4_address, _i);

    if( !r || iter != s.end() )
        return false;

    i = _i;
    return true;
}

But unfortunately if I parse an address such as "1.2.3.4", I end up
with the address "1.0.0.0" in my Ipv4 struct. The IPv4 struct is
legacy code, and the union member can therefor not be changed. I can
add other constructors, but I prefer non-intrusive changes.

So here are my questions:
- What have I done wrong?
- How should this has been done if I did not have a constructor
accepting the tuple?
- How would you have done?

Best regards
Allan W. Nielsen


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net