'parse': 不是 boost::spirit::x3::unused_type 的成员
'parse': is not a member of boost::spirit::x3::unused_type
我正在尝试使用 Boost Spirit 实现 HTTP header 解析器,但是我陷入了一个基本的子任务:从第一行提取 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
是一个标记 class,用于指示规则不填充属性.但是,我不明白该示例中该标记的来源。
如果我使用没有规则 <> 定义的内联规则修改代码,并将 std::pair<int, int>
作为属性传入,则代码会编译并且 运行 没问题。
这是怎么回事,这个简单的例子哪里出了问题?
这只是 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 不是障碍:
在您的代码中有 BOOST_SPIRIT_DEFINE(rtsp_request_line)
,但规则的实际名称是 version_number
。修复此拼写错误后,您的代码可以使用 Boost 1.65.1 和 VC++ 2017 Update 3(编译器 v19.11.25508)为我干净地编译。
我正在尝试使用 Boost Spirit 实现 HTTP header 解析器,但是我陷入了一个基本的子任务:从第一行提取 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
是一个标记 class,用于指示规则不填充属性.但是,我不明白该示例中该标记的来源。
如果我使用没有规则 <> 定义的内联规则修改代码,并将 std::pair<int, int>
作为属性传入,则代码会编译并且 运行 没问题。
这是怎么回事,这个简单的例子哪里出了问题?
这只是 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 不是障碍:
在您的代码中有 BOOST_SPIRIT_DEFINE(rtsp_request_line)
,但规则的实际名称是 version_number
。修复此拼写错误后,您的代码可以使用 Boost 1.65.1 和 VC++ 2017 Update 3(编译器 v19.11.25508)为我干净地编译。