c++ - 使用带有 qi::grammar 的 boost::spirit::qi::phrase_parse() 时出错

标签 c++ boost c++11 boost-spirit boost-spirit-qi

我正在用 Boost.Spirit 做一个 IRC 消息解析器,但是当我尝试解析一个输入时我遇到了一个(很长的)错误。我遵循了“Roman Numerals”示例。此外,我将 g++4.7-std=c++11 一起使用。只有当我在 test.cpp 上调用 phrase_parse() 时才会发生错误,而不是在我创建 message_grammar 的实例时发生。

语法类是:

class message_grammar : qi::grammar<std::string::const_iterator, std::string()>
{
public:
    message_grammar() : base_type(m_message)
    {   
        using qi::_val;
        using qi::_1;
        using boost::spirit::ascii::char_;
        using qi::lit;

        qi::rule<std::string::const_iterator, std::string()> alpha, graph, number, special, user,
            nick, chn, channel;

        alpha  = qi::as_string[qi::alpha];
        graph  = qi::as_string[qi::graph];
        number = qi::as_string[char_('0', '9')];
        chn    = qi::as_string[(char_('#') | char_('$'))];

        special = qi::as_string[
                char_('-') | char_('[') | char_(']') | char_('\\') 
            |   char_('`') | char_('^') | char_('{') | char_('}')
        ];

        user = (
                graph   [_val = std::string("USER%% ") + _1] 
            >>  *graph[_val += _1]
        );

        nick = (
                alpha[_val = std::string("NICK%% ") + _1]
            >>  
            *(
                    alpha           
                |   number
                |   special
            )[_val += _1]
        );

        channel = (
                chn                         [_val = std::string("CHAN%% ") + _1]
            >>  +(alpha | number | special) [_val += _1]
        );

        m_message = (
                nick    [_val = _1]
            >>  alpha   [_val += std::string(" ") + _1]
            >>  channel [_val += std::string(" ") + _1]
            >>  user    [_val += std::string(" ") + _1]
        );
    }


    qi::rule<std::string::const_iterator, std::string()> m_message;
};

测试函数是:

int main()
{
    string str, parsed_str;
    getline(cin, str);

    irc::message_grammar grammar;

    auto it = str.begin();
    auto end = str.end();

    bool ok = qi::phrase_parse(it, end, 
        grammar
    , qi::space, parsed_str);

    if (ok && it == end) {
        cout << "OK" << endl;
        cout << parsed_str << endl;
    }
    else {
        cout << "NO " << ok << endl;
    }
}

错误信息:

murilo@mac:cleverbot$ g++-mp-4.7 -std=c++11 test.cpp -Wall
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp: In instantiation of 'struct boost::proto::domainns_::domain<>::as_expr<irc::message_grammar>':
/opt/local/include/boost/proto/traits.hpp:266:71:   required from 'struct boost::proto::result_of::as_expr<irc::message_grammar, boost::proto::domainns_::default_domain>'
/opt/local/include/boost/spirit/home/support/meta_compiler.hpp:221:16:   required from 'struct boost::spirit::traits::matches<boost::spirit::qi::domain, irc::message_grammar>'
/opt/local/include/boost/spirit/home/qi/parse.hpp:155:9:   required from 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = irc::message_grammar; Skipper = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>; Attr = std::basic_string<char>]'
/opt/local/include/boost/spirit/home/qi/parse.hpp:197:86:   required from 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = irc::message_grammar; Skipper = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>; Attr = std::basic_string<char>]'
test.cpp:20:25:   required from here
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef void boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_is_expr_' is inaccessible
In file included from /opt/local/include/boost/proto/traits.hpp:32:0,
                 from /opt/local/include/boost/proto/expr.hpp:27,
                 from /opt/local/include/boost/proto/core.hpp:17,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp:141:13: error: within this context
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef void boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_is_expr_' is inaccessible
In file included from /opt/local/include/boost/proto/traits.hpp:32:0,
                 from /opt/local/include/boost/proto/expr.hpp:27,
                 from /opt/local/include/boost/proto/core.hpp:17,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp:141:13: error: within this context
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef void boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_is_expr_' is inaccessible
In file included from /opt/local/include/boost/proto/traits.hpp:32:0,
                 from /opt/local/include/boost/proto/expr.hpp:27,
                 from /opt/local/include/boost/proto/core.hpp:17,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp:142:17: error: within this context
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef void boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_is_expr_' is inaccessible
In file included from /opt/local/include/boost/proto/traits.hpp:32:0,
                 from /opt/local/include/boost/proto/expr.hpp:27,
                 from /opt/local/include/boost/proto/core.hpp:17,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp:143:56: error: within this context
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef void boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_is_expr_' is inaccessible
In file included from /opt/local/include/boost/proto/traits.hpp:32:0,
                 from /opt/local/include/boost/proto/expr.hpp:27,
                 from /opt/local/include/boost/proto/core.hpp:17,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp:146:29: error: within this context
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef void boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_is_expr_' is inaccessible
In file included from /opt/local/include/boost/proto/traits.hpp:32:0,
                 from /opt/local/include/boost/proto/expr.hpp:27,
                 from /opt/local/include/boost/proto/core.hpp:17,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp:146:29: error: within this context
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef void boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_is_expr_' is inaccessible
In file included from /opt/local/include/boost/proto/traits.hpp:32:0,
                 from /opt/local/include/boost/proto/expr.hpp:27,
                 from /opt/local/include/boost/proto/core.hpp:17,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/domain.hpp:146:46: error: within this context
In file included from /opt/local/include/boost/proto/core.hpp:23:0,
                 from /opt/local/include/boost/proto/proto.hpp:12,
                 from /opt/local/include/boost/spirit/home/support/meta_compiler.hpp:19,
                 from /opt/local/include/boost/spirit/home/qi/meta_compiler.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi/action.hpp:14,
                 from /opt/local/include/boost/spirit/home/qi.hpp:14,
                 from /opt/local/include/boost/spirit/include/qi.hpp:16,
                 from ircparser.h:6,
                 from test.cpp:1:
/opt/local/include/boost/proto/matches.hpp: In instantiation of 'struct boost::proto::matches<irc::message_grammar, boost::spirit::meta_compiler<boost::spirit::qi::domain>::meta_grammar>':
/opt/local/include/boost/spirit/home/support/meta_compiler.hpp:221:16:   required from 'struct boost::spirit::traits::matches<boost::spirit::qi::domain, irc::message_grammar>'
/opt/local/include/boost/spirit/home/qi/parse.hpp:155:9:   required from 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, boost::spirit::qi::skip_flag, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = irc::message_grammar; Skipper = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>; Attr = std::basic_string<char>]'
/opt/local/include/boost/spirit/home/qi/parse.hpp:197:86:   required from 'bool boost::spirit::qi::phrase_parse(Iterator&, Iterator, const Expr&, const Skipper&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; Expr = irc::message_grammar; Skipper = boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0l>; Attr = std::basic_string<char>]'
test.cpp:20:25:   required from here
/opt/local/include/boost/proto/extends.hpp:551:13: error: 'typedef struct boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()> boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type> > >, 0l>, boost::spirit::qi::grammar<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>()>, boost::proto::domainns_::default_domain, 0l>::proto_derived_expr' is inaccessible

最佳答案

您应该将 message_grammar 声明为结构而不是类。 此外,您可以从 qi::grammar 公开派生您的类:

class message_grammar : public qi::grammar<std::string::const_iterator, std::string()>
{
}

您还可以找到这个 article有用。

关于c++ - 使用带有 qi::grammar 的 boost::spirit::qi::phrase_parse() 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11126930/

相关文章:

c++ - 在成员函数尾随返回类型中使用 this 和属性?

c++ - 如何以类型安全的方式分配 uint32_t::max 和 uint64_t 的最小值?

java - 编译器组件的良好源代码

sockets - 使用 boost asio 重用套接字

C++ boost::interprocess 简单应用

c++ - 如何设计我的类(class)?

c++ - SFML 2.0 循环 Sprite 显示不止一次

c++ - 实现可以转换为 Stream<U> 的 Stream<T>,其中 U 是 T 的基数

boost - 如何确定 CMake 的 Boost 库名称

c++ - 跨 DLL 边界访问虚拟方法是否安全/可能?