Re: Trying to sort out AST vs grammar mapped attributes

Michael Powell <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <CAMEoF_GOsDviacYpm5wRaH3EwW2pFde8ozAEdNE5HE4_vjEoXQ@mail.gmail.com>
On Wed, Dec 20, 2017 at 7:39 PM, Michael Powell <[email protected]> wrote:
> On Wed, Dec 20, 2017 at 6:15 PM, Joel de Guzman <[email protected]> wrote:
>> On 21/12/2017 6:33 AM, Michael Powell wrote:
>>
>>>>>>
>>>>>> I've got a parser/AST composed something like this:
>>>>>>
>>>>>> https://wandbox.org/permlink/P4227jXxu9DvQThF
>>>>>
>>>>>
>>>>> I sorted it out. It seems to be a matter of having the appropriate
>>>>> intermediate structs/attributed-rules to capture the octets,
>>>>> addresses, etc.
>>>>>
>>>>> https://wandbox.org/permlink/HEz4qn3XQLmpWUAx
>>>>>
>>>>> Now just a matter of rinsing and repeating for additional IPv4 mapped
>>>>> alternatives.
>>>>
>>>>
>>>> The parser is failing. The IPv4 mapped address bytes appear to be
>>>> parsed correctly, but the IPv6 base address does not.
>>>>
>>>> https://wandbox.org/permlink/Mpi0dhIqe1kW6N34
>>>>
>>>> Thoughts?
>>>
>>>
>>> Ah, I'm starting to see. Love attributes!
>>>
>>
>> Interesting to see you solve and answer your own questions ;-)
>
> Indeed, it is interesting, especially when I apply that to my current code base.
>
> BTW, I am finding more "dynamics" whereby optionals are not meshing
> well with alternatives (or vice versa) in a similar context. Not sure
> exactly why that is, but hopefully I can find some workarounds for it.
>
> _ls32 for instance wants a std::string(), all told. Which for "pure"
> natural IPv6, has no problem.
>
> But when I introduce the possibility of extending that into IPv4
> mapped via an "Appendix" typename, I get errors like below, for the
> rule:
>
> // RFC alternative phrase: / [*2(h16 ":") h16] "::" 2(h16 ":") ls32
> _ipv6_addr_base = lexeme[
>     -(_h16_col >> _h16_col >> _h16
>         | _h16_col >> _h16
>         | _h16) >> _col_x2 >> _h16_col >> _h16_col >> _ls32
> ];
>
> Which seems  to be the difference between (compiles):
>
> // RFC alternative phrase: / [*1(h16 ":") h16] "::" 3(h16 ":") ls32
> _ipv6_addr_base = lexeme[(
>     _h16_col >> _h16 >> _col_x2
>     | _h16 >> _col_x2
>     ) >> _h16_col >> _h16_col >> _h16_col >> _ls32
> ];
>
> And (does not compile):
>
> _ipv6_addr_base = lexeme[(
>     -(_h16_col >> _h16
>         | _h16) >> _col_x2
>     ) >> _h16_col >> _h16_col >> _h16_col >> _ls32
> ];
>
> Eventually, when I get into IPv4 mapped, I want for that to reflect
> IPv4::Address(), not std::string().
>
> 1) I want to know why that is? I am "programming" the grammar such as
> it is, but Qi doesn't like it. 2) What is the general recommendation?
> Apart from the difference in approach, avoiding alternatives,
> optionals, etc.
>
> To my knowledge, I've applied the same Attribute propagation
> principles there that I did in my online example.
>
> Or perhaps some other insights I may be missing.

As further evidenced by the difference between:

// RFC alternative phrase: / [*2(h16 ":") h16] "::" 2(h16 ":") ls32
_ipv6_addr_base = lexeme[
    (_h16_col >> _h16_col >> _h16 >> _col_x2
        | _h16_col >> /*  */ _h16 >> _col_x2
        | /*              */ _h16 >> _col_x2
        | /*                      */ _col_x2) >> _h16_col >> _h16_col >> _ls32
];

And, does not compile:

_ipv6_addr_base = lexeme[
    -(_h16_col >> _h16_col >> _h16
        | _h16_col >> /*   */ _h16
        | /*               */ _h16) >> _col_x2 >> _h16_col >> _h16_col >> _ls32
];

The only difference that I can fathom, besides the better propagation
of attributes, is the embedded optional element. The version that
works is a bit more involved given I need to repeat _col_x2, I would
really like to leverage the optional, but that's okay.

The embedded comments help to "align" the bits of the phrase a bit better.

Thoughts?

> Thanks!
>
> 3>  G:\Source\Kingdom
> Software\Kingdom.Messaging\Working\src\transports/boost/spirit/ipv6/addr.hpp(183):
> note: see reference to function template instantiation
> 'boost::spirit::qi::rule<Iterator,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &boost::spirit::qi::rule<Iterator,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>::operator
> =<boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<T>,0>
> &,const boost::proto::exprns_::expr<Tag,Args,2> &>,2>>(const Expr &)'
> being compiled
> 3>          with
> 3>          [
> 3>              Iterator=It,
> 3>              T=boost::spirit::tag::lexeme,
> 3>              Tag=boost::proto::tagns_::tag::shift_right,
> 3>              Args=boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::negate,boost::proto::argsns_::list1<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,1> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,
> 3>
> Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::lexeme>,0>
> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::negate,boost::proto::argsns_::list1<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,1> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,2>
> 3>          ]
> 3>  G:\Source\Kingdom
> Software\Kingdom.Messaging\Working\src\transports/boost/spirit/ipv6/addr.hpp(179):
> note: see reference to function template instantiation
> 'boost::spirit::qi::rule<Iterator,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &boost::spirit::qi::rule<Iterator,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>::operator
> =<boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<T>,0>
> &,const boost::proto::exprns_::expr<Tag,Args,2> &>,2>>(const Expr &)'
> being compiled
> 3>          with
> 3>          [
> 3>              Iterator=It,
> 3>              T=boost::spirit::tag::lexeme,
> 3>              Tag=boost::proto::tagns_::tag::shift_right,
> 3>              Args=boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::negate,boost::proto::argsns_::list1<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,1> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,
> 3>
> Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::lexeme>,0>
> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::negate,boost::proto::argsns_::list1<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const
> boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,1> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &,boost::spirit::qi::rule<It,std::string
> (void),boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type>
> &>,2> &>,2>
> 3>          ]
> 3>  G:\Source\Kingdom
> Software\Kingdom.Messaging\Working\src\transports/boost/spirit/ipv6/addr.hpp(169):
> note: while compiling class template member function
> 'Kmsg::IPv6::NaturalAddrParser4<It>::NaturalAddrParser4(void)'
> 3>  G:\Source\Kingdom
> Software\Kingdom.Messaging\Working\tests\rfc\Rfc3986_Uri_BoostSpiritParsing.cpp(153):
> note: see reference to function template instantiation
> 'Kmsg::IPv6::NaturalAddrParser4<It>::NaturalAddrParser4(void)' being
> compiled
> 3>  G:\Source\Kingdom
> Software\Kingdom.Messaging\Working\tests\rfc\Rfc3986_Uri_BoostSpiritParsing.cpp(153):
> note: see reference to class template instantiation
> 'Kmsg::IPv6::NaturalAddrParser4<It>' being compiled
>
>
>> Regards,
>> --
>> Joel de Guzman
>> http://www.ciere.com
>> http://boost-spirit.com
>> http://www.cycfi.com/
>>
>> ------------------------------------------------------------------------------
>> Check out the vibrant tech community on one of the world's most
>> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>> _______________________________________________
>> Spirit-general mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/spirit-general

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.