
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