'parse':不是boost :: spirit :: x3 :: unused_type的成员

时间:2017-09-16 22:14:06

标签: c++ boost boost-spirit boost-spirit-x3

我正在尝试使用Boost Spirit实现HTTP头解析器,但是我已经陷入了一个基本的子任务:从第一行提取HTTP版本号。

简化代码:

#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted.hpp>
#include <boost/fusion/sequence.hpp>
#include <iostream>
#include <string>

namespace parser
{
    namespace ast
    {
        struct version_number
        {
            int major = 0;
            int minor = 0;
        };
    }

    using boost::fusion::operator<<;
}
BOOST_FUSION_ADAPT_STRUCT(
    parser::ast::version_number,
    (int, major)
    (int, minor)
)

namespace parser
{
    using namespace boost::spirit::x3;

    class version_number_id;
    rule<version_number_id, ast::version_number> version_number = "version_number";
    auto const version_number_def = eps
        >> int_
        >> "."
        >> int_
        ;
    BOOST_SPIRIT_DEFINE(rtsp_request_line)
}

int main()
{
    using namespace std;
    string input = "4.332";


    parser::ast::version_number vn;
    auto res = boost::spirit::x3::parse(begin(input), end(input), parser::version_number, vn);
    if (res)
    {
        cout << "Success" << endl;
    }
    else
    {
        cout << "Failure" << endl;
    }
}

然而即使使用这个简单的例子,我也会使用Boost v1.64和MSVC ++ 14.1遇到编译错误。编译器输出如下:

1>------ Build started: Project: spirit_test, Configuration: Debug Win32 ------
1>main2.cpp
1>c:\devlib\boost_1_64_0\include\boost\spirit\home\x3\nonterminal\rule.hpp(36): error C2338: BOOST_SPIRIT_DEFINE undefined for this rule.
1>c:\devlib\boost_1_64_0\include\boost\spirit\home\x3\nonterminal\rule.hpp(116): note: see reference to function template instantiation 'boost::spirit::x3::detail::default_parse_rule_result boost::spirit::x3::parse_rule<parser::version_number_id,parser::ast::version_number,Iterator,Context,Attribute_>(boost::spirit::x3::rule<parser::version_number_id,parser::ast::version_number,false>,Iterator &,const Iterator &,const Context &,ActualAttribute &)' being compiled
1>        with
1>        [
1>            Iterator=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>            Context=boost::spirit::x3::unused_type,
1>            Attribute_=parser::ast::version_number,
1>            ActualAttribute=parser::ast::version_number
1>        ]
1>c:\devlib\boost_1_64_0\include\boost\spirit\home\x3\core\parse.hpp(35): note: see reference to function template instantiation 'bool boost::spirit::x3::rule<parser::version_number_id,parser::ast::version_number,false>::parse<Iterator,boost::spirit::x3::unused_type,Attribute>(Iterator &,const Iterator &,const Context &,boost::spirit::x3::unused_type,Attribute_ &) const' being compiled
1>        with
1>        [
1>            Iterator=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>            Attribute=parser::ast::version_number,
1>            Context=boost::spirit::x3::unused_type,
1>            Attribute_=parser::ast::version_number
1>        ]
1>c:\devlib\boost_1_64_0\include\boost\spirit\home\x3\core\parse.hpp(35): note: see reference to function template instantiation 'bool boost::spirit::x3::rule<parser::version_number_id,parser::ast::version_number,false>::parse<Iterator,boost::spirit::x3::unused_type,Attribute>(Iterator &,const Iterator &,const Context &,boost::spirit::x3::unused_type,Attribute_ &) const' being compiled
1>        with
1>        [
1>            Iterator=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>            Attribute=parser::ast::version_number,
1>            Context=boost::spirit::x3::unused_type,
1>            Attribute_=parser::ast::version_number
1>        ]
1>c:\devlib\boost_1_64_0\include\boost\spirit\home\x3\core\parse.hpp(60): note: see reference to function template instantiation 'bool boost::spirit::x3::parse_main<Iterator,Parser,Attribute>(Iterator &,Iterator,const Parser &,Attribute &)' being compiled
1>        with
1>        [
1>            Iterator=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>            Parser=boost::spirit::x3::rule<parser::version_number_id,parser::ast::version_number,false>,
1>            Attribute=parser::ast::version_number
1>        ]
1>d:\documents\visual studio 2017\projects\spirit_test\spirit_test\main2.cpp(49): note: see reference to function template instantiation 'bool boost::spirit::x3::parse<std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,boost::spirit::x3::rule<parser::version_number_id,parser::ast::version_number,false>,parser::ast::version_number>(const Iterator &,Iterator,const Parser &,Attribute &)' being compiled
1>        with
1>        [
1>            Iterator=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>,
1>            Parser=boost::spirit::x3::rule<parser::version_number_id,parser::ast::version_number,false>,
1>            Attribute=parser::ast::version_number
1>        ]
1>c:\devlib\boost_1_64_0\include\boost\spirit\home\x3\nonterminal\rule.hpp(37): error C2039: 'parse': is not a member of 'boost::spirit::x3::unused_type'
1>c:\devlib\boost_1_64_0\include\boost\spirit\home\x3\support\traits\attribute_category.hpp(22): note: see declaration of 'boost::spirit::x3::unused_type'
1>Done building project "spirit_test.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped =========

我注意到在调试消息中出现了Context=boost::spirit::x3::unused_type行,并且我知道unused_type是一个标记类,用于指示规则不会填充属性。但是,我不明白该示例中的标记来自何处。

如果我使用没有规则的内联规则修改代码&lt;&gt;定义,并作为属性传递std::pair<int, int>,代码编译并运行正常。

这里发生了什么,我在这个简单的例子中出了什么问题?

2 个答案:

答案 0 :(得分:2)

在您的代码中,您有BOOST_SPIRIT_DEFINE(rtsp_request_line),但该规则的实际名称为version_number。一旦修复了这个拼写错误,你的代码就可以通过Boost 1.65.1和VC ++ 2017 Update 3(编译器v19.11.25508)为我编译。

答案 1 :(得分:0)

这只是MSVC的一个问题。目前不支持MSVC编译器。

其他编译器不是问题:http://coliru.stacked-crooked.com/a/aba5282f5cb7bb02

支持的编译器上的来源:http://boost-spirit.com/home/2015/05/16/spirit-3-0-0/

有趣的是,我所知道的唯一在线MSVC编译器确实强调了诊断:MSVC不受支持(http://rextester.com/ZSEF55595),虽然它会产生不同的错误 - 可能是由于Boost 1.60.0那里。

关于GCC / Clang Boost 1.60.0不是一个障碍:

相关问题