Re: Domain name parser not working
Michael Powell <[email protected]>
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <CAMEoF_EtP6F_mj=8sKYELNVW+spq-qz8kO2T3cy9mGbcBorHmw@mail.gmail.com> |
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