Re: Domain name parser not working
JF <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <CACYgye+bL5auLbiMFZBm+KFjamAO6zGd_y=N01sJzE8NfE3tGQ@mail.gmail.com> |
In your https://wandbox.org/permlink/nDoBOQGXzUhZ07Al: 1. Comment line 58. 2. Change line 59 to "pass = l.size() < 63;" 3. Change line 76 to "_label %= repeat(1, 63)[_let_dig_hyp][label_validation()];" Result: Start Running with Boost version: '106501' Parsing 'E-PHUMZ8G8j1KEZG26C' -> E-PHUMZ8G8j1KEZG26C (PASS) 0 Finish 2018-01-03 3:28 GMT+01:00 Michael Powell <[email protected]>: > On Tue, Jan 2, 2018 at 9:10 PM, Michael Powell <[email protected]> > wrote: > > On Tue, Jan 2, 2018 at 7:15 PM, JF <[email protected]> wrote: > >> Hi Michael, > >> If I understand RFC correctly, is this what you want? > > > > Have you tried to compile this? I have tried this and received the > > following errors: > > With oversimplified grammar, without the semantic action, the parser > passes. With the semantic action, the parser fails. > > https://wandbox.org/permlink/hCcMbPzJnRYWLEnU > > Incidentally, I can leverage repeat(1, 63)[_let_dig_hyp] in this > instance to vet the length aspects of a valid label. However, again, > as soon as I inject the semantic action, boom, failure to parse. > > https://wandbox.org/permlink/nDoBOQGXzUhZ07Al > > I've followed the docs, as well as the proposed approach, to no avail. > > > https://wandbox.org/permlink/ATvd59XXSLbqB07s > > > > prog.cc: In instantiation of 'void > > client::label_validation::operator()(Attrib&, Context&, bool&) const > > [with Attrib = boost::iterator_range<__gnu_cxx::__normal_iterator<const > > char*, std::__cxx11::basic_string<char> > >; Context = > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >]': > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/support/action_dispatch.hpp:95:25: > > required from 'decltype (f(a, b, c)) > > boost::spirit::traits::action_dispatch<Component>::fwd_ > attrib_context_pass::operator()(F&&, > > A&&, B&&, C&&, Rest&& ...) [with F = const client::label_validation&; > > A = boost::iterator_range<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> > >&; B = > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >&; C = bool&; Rest = > > {}; Component = > > boost::spirit::qi::raw_directive<boost::spirit::qi:: > plus<boost::spirit::qi::reference<const > > boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type> > > >; decltype (f(a, b, c)) = void]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/support/action_dispatch.hpp:143:17: > > required from 'static void > > boost::spirit::traits::action_dispatch<Component>::caller(F&&, A&& > > ...) [with F = const client::label_validation&; A = > > {boost::iterator_range<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char, std::char_traits<char>, > > std::allocator<char> > > >&, > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char, > > std::char_traits<char>, std::allocator<char> >&, boost::fusion::nil_>, > > boost::fusion::vector<> >&, bool&}; Component = > > boost::spirit::qi::raw_directive<boost::spirit::qi:: > plus<boost::spirit::qi::reference<const > > boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type> > > >]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/support/action_dispatch.hpp:153:19: > > required from 'bool > > boost::spirit::traits::action_dispatch<Component>::operator()(const > > F&, Attribute&, Context&) [with F = client::label_validation; > > Attribute = boost::iterator_range<__gnu_cxx::__normal_iterator<const > > char*, std::__cxx11::basic_string<char> > >; Context = > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >; Component = > > boost::spirit::qi::raw_directive<boost::spirit::qi:: > plus<boost::spirit::qi::reference<const > > boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type> > > >]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/qi/action/action.hpp:69:55: > > required from 'bool boost::spirit::qi::action<Subject, > > Action>::parse(Iterator&, const Iterator&, Context&, const Skipper&, > > Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<const > > char*, std::__cxx11::basic_string<char> >; Context = > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = > > boost::spirit::unused_type; Attribute = const > > boost::spirit::unused_type; Subject = > > boost::spirit::qi::raw_directive<boost::spirit::qi:: > plus<boost::spirit::qi::reference<const > > boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type> > > >; Action = client::label_validation]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/qi/nonterminal/detail/parser_binder.hpp:33:65: > > required from 'bool boost::spirit::qi::detail::parser_binder<Parser, > > Auto>::call(Iterator&, const Iterator&, Context&, const Skipper&, > > mpl_::true_) const [with Iterator = __gnu_cxx::__normal_iterator<const > > char*, std::__cxx11::basic_string<char> >; Skipper = > > boost::spirit::unused_type; Context = > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >; Parser = > > boost::spirit::qi::action<boost::spirit::qi::raw_ > directive<boost::spirit::qi::plus<boost::spirit::qi::reference<const > > boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type> > > >, client::label_validation>; Auto = > > mpl_::bool_<false>; mpl_::true_ = mpl_::bool_<true>]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/qi/nonterminal/detail/parser_binder.hpp:53:67: > > [ skipping 4 instantiation contexts, use > > -ftemplate-backtrace-limit=0 to disable ] > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/function/ > function_template.hpp:1061:16: > > required from 'boost::function<R(T0, T1, T2, T3)>::function(Functor, > > typename boost::enable_if_c<(! boost::is_integral<Functor>::value), > > int>::type) [with Functor = > > boost::spirit::qi::detail::parser_binder<boost::spirit:: > qi::action<boost::spirit::qi::raw_directive<boost::spirit:: > qi::plus<boost::spirit::qi::reference<const > > boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type> > > >, client::label_validation>, > > mpl_::bool_<false> >; R = bool; T0 = > > __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >&; T1 = const > > __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >&; T2 = > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const > > boost::spirit::unused_type&; typename boost::enable_if_c<(! > > boost::is_integral<Functor>::value), int>::type = int]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/function/ > function_template.hpp:1114:5: > > required from 'typename boost::enable_if_c<(! > > boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, > > T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) > > [with Functor = > > boost::spirit::qi::detail::parser_binder<boost::spirit:: > qi::action<boost::spirit::qi::raw_directive<boost::spirit:: > qi::plus<boost::spirit::qi::reference<const > > boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type> > > >, client::label_validation>, > > mpl_::bool_<false> >; R = bool; T0 = > > __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >&; T1 = const > > __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >&; T2 = > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const > > boost::spirit::unused_type&; typename boost::enable_if_c<(! > > boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, > > T3)>&>::type = boost::function<bool(__gnu_cxx::__normal_iterator<const > > char*, std::__cxx11::basic_string<char> >&, const > > __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >&, > > boost::spirit::context<boost::fusion::cons<std::__cxx11:: > basic_string<char>&, > > boost::fusion::nil_>, boost::fusion::vector<> >&, const > > boost::spirit::unused_type&)>&]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/qi/nonterminal/rule.hpp:183:19: > > required from 'static void boost::spirit::qi::rule<Iterator, T1, T2, > > T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, > > const Expr&, mpl_::true_) [with Auto = mpl_::bool_<false>; Expr = > > boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, > > boost::proto::argsns_::list2<const > > 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::raw>, 0>&, const > > boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus, > > boost::proto::argsns_::list1<boost::spirit::qi::rule<__gnu_ > cxx::__normal_iterator<const > > char*, std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type>&>, 1>&>, 2>&, > > boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, > > boost::proto::argsns_::term<const client::label_validation&>, 0> >, > > 2>; Iterator = __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >; T1 = > > std::__cxx11::basic_string<char>(); T2 = boost::spirit::unused_type; > > T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; > > mpl_::true_ = mpl_::bool_<true>]' > > /opt/wandbox/boost-1.65.1/gcc-head/include/boost/spirit/ > home/qi/nonterminal/rule.hpp:221:32: > > required from 'boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>& > > boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const > > Expr&) [with Expr = > > boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, > > boost::proto::argsns_::list2<const > > 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::raw>, 0>&, const > > boost::proto::exprns_::expr<boost::proto::tagns_::tag::unary_plus, > > boost::proto::argsns_::list1<boost::spirit::qi::rule<__gnu_ > cxx::__normal_iterator<const > > char*, std::__cxx11::basic_string<char> >, char(), > > boost::spirit::unused_type, boost::spirit::unused_type, > > boost::spirit::unused_type>&>, 1>&>, 2>&, > > boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, > > boost::proto::argsns_::term<const client::label_validation&>, 0> >, > > 2>; Iterator = __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >; T1 = > > std::__cxx11::basic_string<char>(); T2 = boost::spirit::unused_type; > > T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]' > > prog.cc:79:20: required from > > 'client::my_grammar<Iterator>::my_grammar() [with Iterator = > > __gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> >]' > > prog.cc:129:20: required from here > > prog.cc:58:20: error: 'class > > boost::iterator_range<__gnu_cxx::__normal_iterator<const char*, > > std::__cxx11::basic_string<char> > >' has no member named 'length' > > pass = l.length() < 63; > > ~~^~~~~~ > > > > > > > >> #include <boost/spirit/include/qi.hpp> > >> > >> namespace qi = boost::spirit::qi; > >> namespace ascii = qi::ascii; > >> > >> template > >> < > >> typename Iterator > >>> > >> struct grammar : qi::grammar<Iterator, std::vector<std::string>()> > >> { > >> qi::rule<Iterator, std::vector<std::string>()> domain; > >> qi::rule<Iterator, std::string()> label; > >> > >> grammar() > >> : grammar::base_type(domain) > >> { > >> domain = label >> *('.' >> label); > >> label %= qi::raw[ascii::alpha >> *(ascii::alnum | '-')][check_label()]; > >> } > >> > >> struct check_label > >> { > >> template > >> < > >> typename Attrib, typename Context > >>> > >> void operator()(Attrib &attr, Context &context, bool &pass) const > >> { > >> auto label_length = attr.size(); > >> auto last_char = attr[label_length - 1]; > >> if(label_length < 64 && std::isalnum(last_char)) > >> { > >> pass = true; > >> } > >> else > >> { > >> pass = false; > >> } > >> } > >> }; > >> }; > >> > >> int main() > >> { > >> std::string input = "E-PHUMZ8G8j1KEZG26C.xx1.-"; > >> > >> std::vector<std::string> domain; > >> > >> auto b = input.cbegin(); > >> auto e = input.cend(); > >> > >> if(qi::parse(b, e, grammar<std::string::const_iterator>(), domain)) > >> { > >> std::string d; > >> > >> for(const auto &label : domain) > >> { > >> if(!d.empty()) > >> { > >> d += '.'; > >> } > >> > >> d += label; > >> } > >> > >> std::cout << "matched " << d << '\n'; > >> if(b != e) > >> { > >> std::cout << "unmatched " << std::string(b, e) << '\n'; > >> } > >> } > >> else > >> { > >> std::cout << "nothing matched\n"; > >> } > >> } > >> > >> ? > >> > >> (There may be errors... It's 1AM here.) > >> > >> J > >> > >> 2018-01-03 0:54 GMT+01:00 Joel de Guzman <[email protected]>: > >>> > >>> On 03/01/2018 6:59 AM, Michael Powell wrote: > >>>> > >>>> On Tue, Jan 2, 2018 at 3:24 PM, Joel de Guzman<[email protected]> > wrote: > >>>>> > >>>>> On 02/01/2018 11:42 PM, Michael Powell wrote: > >>>>>> > >>>>>> Now after providing additional follow up, live examples, etc, any > >>>>>> feedback on this at all? > >>>>>> > >>>>>> This cannot be that difficult, however any of the documentation, > etc, > >>>>>> I am scanning does not seem to work or are incomplete at best, which > >>>>>> isn't helping the case. > >>>>> > >>>>> > >>>>> Not sure. I know you presented some code, but is it minimal enough? > >>>>> To me, minimal code would look like something like the code here: > >>>>> http://boost-spirit.com/home/feedback-and-support/ > >>>> > >>>> There is nothing I consider extraneous in the examples I presented. > >>>> There is a test scaffold, the grammar, and the AST. It's all pretty > >>>> clearly outlined in the examples. Anything more or other than that I > >>>> would consider NOT minimal. > >>> > >>> > >>> Give it some more effort. For example, focus on one exact problem. The > >>> very subject of this thread does not even convey any usable information > >>> other than "not working". Most often than not, I could distill > problematic > >>> code to only a few lines --one or two rules is ideal. You do not even > >>> have to have grammars. Also, get rid of the scaffolding, etc. > >>> > >>> Again, you'll have better luck if the essence of your question can > >>> be fully comprehended in one or two minutes. Do I need to study RFC > >>> 1034 to understand your problem? If not, then that information is > >>> extraneous. If yes, then your issue requires too much investment in > >>> time (at least for me). > >>> > >>> 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 > >> _______________________________________________ > >> 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 > _______________________________________________ > 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 _______________________________________________ Spirit-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/spirit-general