boost::spirit::qi Parser Problem(e)
-
Möp,
Ich dachte mir, die IRC Nachrichten meines Bots mit Spirit.Qi zu parsen, da im RFC 1459 bereits eine BNF angegeben wird und ich so die möglichkeit habe, das Protokoll komplett richtig zu parsen.
Zum Fehler meines Parsers fällt mir selbst recht wenig ein. Ich denke es liegt entweder an den %= oder aber an den von mir definierten structs, da ich beides noch nicht ganz so verstanden habe. Naja, hier der Code.
Grammatik:
template <typename Iterator> class grammar : boost::spirit::qi::grammar<Iterator, message()> { boost::spirit::qi::rule<Iterator, message()> msg; boost::spirit::qi::rule<Iterator, prefix_type()> prefix; boost::spirit::qi::rule<Iterator, std::string()> command; boost::spirit::qi::rule<Iterator, void()> space; boost::spirit::qi::rule<Iterator, std::vector<std::string>()> params; boost::spirit::qi::rule<Iterator, std::string()> middle; boost::spirit::qi::rule<Iterator, std::string()> trailing; boost::spirit::qi::rule<Iterator, std::vector<std::string>()> target; boost::spirit::qi::rule<Iterator, std::string()> to; boost::spirit::qi::rule<Iterator, std::string()> channel; boost::spirit::qi::rule<Iterator, std::string()> host; boost::spirit::qi::rule<Iterator, std::string()> nick; boost::spirit::qi::rule<Iterator, std::string()> mask; boost::spirit::qi::rule<Iterator, std::string()> chstring; boost::spirit::qi::rule<Iterator, std::string()> user; boost::spirit::qi::rule<Iterator, char()> letter; boost::spirit::qi::rule<Iterator, char()> number; boost::spirit::qi::rule<Iterator, char()> special; boost::spirit::qi::rule<Iterator, char()> nonwhite; public: grammar() : grammar::base_type(msg) { using boost::spirit::qi::char_; msg %= -(':' >> prefix >> space) >> command >> params; prefix %= (host | nick) >> -('!' >> user) >> -('@' >> host); command %= +letter | (number >> number >> number); space = +char_(' '); params %= space >> -(middle % space) >> -(':' >> trailing); middle %= !char_(':') >> +nonwhite; trailing %= *(char_ - '\0' - '\r' - '\n'); target %= to % ','; to %= channel | (user >> '@' >> host) | nick | mask; channel %= ('#' | '&') >> chstring; host %= letter | number >> *('.' >> letter | number); nick %= letter >> -(*letter | *number | *special); mask %= (char_('#') | '$') >> chstring; chstring %= +(char_ - ' ' - '\a' - '\0' - '\r' - '\n' - ','); user %= +nonwhite; letter %= char_('a', 'z') | char_('A', 'Z'); number %= char_('0', '9'); special %= char_('-') | '[' | ']' | '\\' | '‘' | '^' | '{' | '}'; nonwhite %= char_ - ' ' - '\0' - '\r' - '\n'; }Meine structs:
namespace paprikachu { namespace irc { struct user { std::string nick; std::string user; std::string host; }; typedef boost::variant<std::string, user> prefix_type; struct message { prefix_type prefix; std::string command; std::vector<std::string> params; }; } } BOOST_FUSION_ADAPT_STRUCT ( paprikachu::irc::user, (std::string, nick) (std::string, user) (std::string, host) ) BOOST_FUSION_ADAPT_STRUCT ( paprikachu::irc::message, (paprikachu::irc::prefix_type, prefix) (std::string, command) (std::vector<std::string>, params) )Benutzung:
bool r = boost::spirit::qi::parse(begin, end, paprikachu::irc::grammar<decltype(end)>(), msg);Ich weiß nicht, wie ich den Quellcode noch weiter kürzen kann, sorry. Hier die Fehlermeldung: http://ideone.com/ZK7wt
Grüße,
PI
-
Musst du vielleicht public von boost...grammar erben?
-
Wow, das hab ich doch glatt übersehen. Danke

Die Fehlermeldung ist nun viel kürzer, ich denke, ich kann sie hier direkt reinpasten.
In file included from /opt/local/include/boost/spirit/home/qi/nonterminal.hpp:14:0,
from /opt/local/include/boost/spirit/home/qi.hpp:20,
from /opt/local/include/boost/spirit/include/qi.hpp:16,
from ../grammar.hpp:4,
from ../main.cpp:6:
/opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp: In static member function 'static void boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<true>, Expr = boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const int&>, 0l>, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>, Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, T1 = std::basic_string<char>(), T2 = boost::spirit::unused_type, T3 = boost::spirit::unused_type, T4 = boost::spirit::unused_type, boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> = boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>, mpl_::false_ = mpl_::bool_<false>]':
/opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:230:13: instantiated from 'boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>& boost::spirit::qi::operator%=(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const int&>, 0l>, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>, Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, T1 = std::basic_string<char>(), T2 = boost::spirit::unused_type, T3 = boost::spirit::unused_type, T4 = boost::spirit::unused_type, boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> = boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>]'
../grammar.hpp:54:5: instantiated from 'paprikachu::irc::grammar<Iterator>::grammar() [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >]'
../main.cpp:20:89: instantiated from here
/opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:176:13: error: no matching function for call to 'assertion_failed(mpl_::failed************ (boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<true>, Expr = boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const int&>, 0l>, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>, Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, T1 = std::basic_string<char>(), T2 = boost::spirit::unused_type, T3 = boost::spirit::unused_type, T4 = boost::spirit::unused_type, boost::spirit::qi::rule<Iterator, T1, T2, T3, T4> = boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>, mpl_::false_ = mpl_::bool_<false>]::error_invalid_expression::***********)(boost::proto::exprns_::expr<boost::proto::tag::shift_right, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const int&>, 0l>, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>))'
/opt/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:176:13: note: candidate is:
/opt/local/include/boost/mpl/assert.hpp:79:48: note: template<bool C> int mpl_::assertion_failed(typename mpl_::assert<C>::type)
-
Fehler gefunden

Es muss natürlichchar_('#') | '&'statt
'#' | '&'heißen.
Kompiliert nun. Wenns noch Probleme gibt, melde ich mich. Vielen Dank
