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