Re: IPv6 address parsing
Michael Powell <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <CAMEoF_FkD5u_C0NejYJY6H7acQ4AXiao3Fuxasf70VapJwbSpA@mail.gmail.com> |
On Fri, Dec 15, 2017 at 11:31 AM, Michael Powell <[email protected]> wrote: > On Thu, Dec 7, 2017 at 1:21 PM, Michael Powell <[email protected]> wrote: >> Again, I am moving beyond IPv4 into IPv6. Do I need to re-post that >> grammar attempt? Maybe I do at this point. >> >> _dot = "."; >> _col = char_(':'); >> _col_x2 = _col >> _col; >> >> // _dec_octet = uint_parser<std::uint8_t, 10, 1, 3>(); >> >> qi::rule<Iterator> _dec_octet = ... ; // Approach TBD; probably >> running with the IPv4 proposal discussed in earlier thread(s). >> >> qi::rule<Iterator> _ipv4_addr = _dec_octet >> repeat(3)[_dot >> _dec_octet]; >> // or, qi::rule<Iterator> _ipv4_addr = raw[_dec_octet >> _dot >> >> _dec_octet >> _dot >> _dec_octet >> _dot >> _dec_octet]; >> >> qi::rule<Iterator> _h16 = raw[repeat(1, 4)[hex]]; >> // Or (?): _h16 = hex >> -(hex >> -(hex >> -hex)); >> qi::rule<Iterator> _h16_col = _h16 >> _col; >> qi::rule<Iterator> _ls32 = _h16_col >> _h16 | _ipv4_addr; >> >> qi::rule<Iterator, std::string()> _ipv6_addr >> = repeat(6)[_h16_col] >> _ls32 >> | _col_x2 >> repeat(5)[_h16_col] >> _ls32 >> | -(_h16) >> _col_x2 >> repeat(4)[_h16_col] >> _ls32 >> | -(_h16_col >> _h16) >> _col_x2 >> repeat(3)[_h16_col] >> _ls32 >> | -(repeat(1, 2)[_h16_col] >> _h16) >> _col_x2 >> >> repeat(2)[_h16_col] >> _ls32 >> | -(repeat(1, 3)[_h16_col] >> _h16) >> _col_x2 >> _h16_col >> _ls32 >> | -(repeat(1, 4)[_h16_col] >> _h16) >> _col_x2 >> _ls32 >> | -(repeat(1, 5)[_h16_col] >> _h16) >> _col_x2 >> _h16 >> | -(repeat(1, 6)[_h16_col] >> _h16) >> _col_x2 >> ; > > I am testing the grammar now, and it seems like to me that the > optional and/or repeat are not working correctly. > > For test case: prefix = pf_max_4|pf_count_1, suffix = pf_none, > appendix = bo_hex_2, which yields address: "6a80:9024::c7e3:4150". > > Should be matching the alternative, from the RFC grammar: > / [*4(h16 ":") h16] "::" ls32 > > Or from the Qi grammar: > | -(repeat(1, 4)[_h16_col] >> _h16) >> _col_x2 >> _ls32 > > But gets rejected. Did not parse, or rejected the entire string. > > Perhaps repeat does not work quite as advertised? > > Thoughts? Suggestions? qi::rule<Iterator, std::string()> _ipv6_addr = repeat(6)[_h16_col] >> _ls32 | _col_x2 >> repeat(5)[_h16_col] >> _ls32 | -(-_h16) >> _col_x2 >> repeat(4)[_h16_col] >> _ls32 | -(-_h16_col >> _h16) >> _col_x2 >> repeat(3)[_h16_col] >> _ls32 | -(-repeat(1, 2)[_h16_col] >> _h16) >> _col_x2 >> repeat(2)[_h16_col] >> _ls32 | -(-repeat(1, 3)[_h16_col] >> _h16) >> _col_x2 >> _h16_col >> _ls32 | -(-repeat(1, 4)[_h16_col] >> _h16) >> _col_x2 >> _ls32 | -(-repeat(1, 5)[_h16_col] >> _h16) >> _col_x2 >> _h16 | -(-repeat(1, 6)[_h16_col] >> _h16) >> _col_x2 ; I did identify that possibly the prefix phrase needs to be built from optional elements within itself. However, still not parsing. I am concerned that either Qi optional, repeat, etc, perhaps even alternatives, are not working quite right in this instance. Do I need to separate the alternatives here into "micro" grammars within themselves for this to possibly work? > Thank you! > >> qi::rule<Iterator> _start = _ipv6_addr >> eoi; >> >> Q: Notwithstanding concern over raw IPv4, does the overall Qi-based >> IPv6 grammar look reasonable? If not, why not? >> >> I'd like to land in a Fusion data structure something like (string >> >> uint16_t >> eoi), but if I can land here, that's acceptable, too: >> (string >> -(uint8_t >> uint8_t >> >> uint8_t >> uint8_t) >> uint16_t >> eoi). >> >> From what I can determine, then, raw[...] is the difference between >> parsed types like uint8_t and string? >> >> ref: http://www.ietf.org/rfc/rfc5954.txt, section 4.1 Resolution for >> Extra Colon in IPv4-Mapped IPv6 Address >> >> Constructive feedback appreciated. >> >> Untested ATM, to be fair. >> >> On Thu, Dec 7, 2017 at 1:09 PM, Seth <[email protected]> wrote: >>> On 07-12-17 18:21, Michael Powell wrote: >>>> Well, you remembered incorrectly. >>> >>> I was asking. >>> >>>> If there's a doable intermediate step of parsed individual octets, so >>>> be it; no problem. >>> >>> Please per-use all the parts of my answer. >>> >>> On 07-12-17 17:13, Seth wrote: >>>> Maybe you'll be more convinced when it's demonstrated (I think I did >>>> this before): >>>> >>>> https://wandbox.org/permlink/M12U5PEYcB8vnxIs >>>> >>>> It's really just ~3 lines of code changed: >>>> >>>> using ipv4_address = std::string; // much less useful representation >>>> // .... >>>> addr_ = raw[ octet_ >> '.' >> octet_ >> '.' >> octet_ >> '.' >> >>>> octet_ ]; >>>> >>>> Note now that test fails: >>> >>> It's all there. >>> ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot