我有一个用Boost :: Spirit编写的简单语法,定义如下:
template <typename Iterator_T>
struct my_grammar :
qi::grammar<Iterator_T, vector<basic_value_t>(), qi::locals<size_t> >
{
my_grammar();
qi::rule<Iterator_T, vector<basic_value_t>(), qi::locals<size_t> > start;
qi::rule<Iterator_T, basic_value_t(), qi::locals<size_t> > ptuple;
};
template <typename Iterator_T>
my_grammar<Iterator_T>::
my_grammar() : my_grammar<Iterator_T>::base_type(start), start(), ptuple() {
start = (*ptuple);
ptuple
= (qi::byte_ >>
qi::omit[qi::byte_[qi::_a = qi::_1]] >>
qi::repeat(qi::_a)[qi::byte_])
;
}
basic_value_t定义为:
struct basic_value_t {
uint8_t type;
vector<uint8_t> val;
};
包含在BOOST_FUSION_ADAPT_STRUCT中:
BOOST_FUSION_ADAPT_STRUCT
(
basic_value_t,
(std::uint8_t, type)
(std::vector<std::uint8_t>, val)
)
然后使用以下语句初始化语法:
my_grammar<vector<uint8_t>::const_iterator> grammar;
在使用boost 1.54编译代码时,我遇到错误。但是,如果我使用boost 1.49编译相同的代码,我不会收到错误。我可以想象,我有一个微妙的错误,当我移动到更新版本的Boost时,它只会显示出来。
以下是非常长的错误消息序列的最后一部分的错误。
/home/making/Dev/filename.cpp:498:51: required from here
/usr/include/boost/fusion/view/transform_view/detail/value_of_impl.hpp:36:79: error: no type named ‘type’ in ‘struct boost::mpl::apply<boost::fusion::detail::apply_transform_result<boost::spirit::traits::build_attribute_sequence<boost::fusion::cons<boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::fusion::cons<boost::spirit::qi::omit_directive<boost::spirit::qi::action<boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::local_variable<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > > > >, boost::fusion::cons<boost::spirit::qi::lazy_directive<boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<boost::spirit::terminal<boost::spirit::tag::repeat> >, boost::spirit::local_variable<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >, boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::spirit::unused_type>, boost::fusion::nil> > >, boost::spirit::context<boost::fusion::cons<ccss_protocols::iec61850::basic_value_t&, boost::fusion::nil>, boost::fusion::vector1<long unsigned int> >, boost::spirit::traits::sequence_attribute_transform, __gnu_cxx::__normal_iterator<const unsigned char*, std::vector<unsigned char> >, boost::spirit::qi::domain>::element_attribute>, boost::spirit::qi::lazy_directive<boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<boost::spirit::terminal<boost::spirit::tag::repeat> >, boost::spirit::local_variable<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >, boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::spirit::unused_type>, mpl_::na, mpl_::na, mpl_::na, mpl_::na>’
typedef typename mpl::apply<transform_type, value_type>::type type;
^
make[2]: *** [CMakeFiles/ccss-protocols-iec61850.dir/src/goose/application-layer.cpp.o] Error 1
提前感谢您考虑此错误。
答案 0 :(得分:4)
定义
#define BOOST_SPIRIT_USE_PHOENIX_V3
修复它,如链接样本中所示(感谢@cv_and_he)
在现有答案中记录了原因:
以下是完整工作样本以供将来参考:生活在 Coliru
#include <iostream>
#include <string>
#include <vector>
//#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
struct basic_value_t {
uint8_t type;
std::vector<uint8_t> val;
};
BOOST_FUSION_ADAPT_STRUCT
(
basic_value_t,
(std::uint8_t, type)
(std::vector<std::uint8_t>, val)
)
template <typename Iterator_T>
struct my_grammar :
qi::grammar<Iterator_T, std::vector<basic_value_t>() >
{
my_grammar();
qi::rule<Iterator_T, std::vector<basic_value_t>() > start;
qi::rule<Iterator_T, basic_value_t(), qi::locals<size_t> > ptuple;
};
template <typename Iterator_T>
my_grammar<Iterator_T>::
my_grammar() : my_grammar<Iterator_T>::base_type(start), start(), ptuple() {
start = (*ptuple);
ptuple
%= (qi::byte_ >>
qi::omit[qi::byte_[qi::_a = qi::_1]] >>
qi::repeat(qi::_a)[qi::byte_])
;
}
int main()
{
std::vector<std::uint8_t> test = {1,3,1,2,3};
my_grammar<std::vector<std::uint8_t>::const_iterator> grammar;
std::vector<std::uint8_t>::const_iterator iter = test.begin(), end = test.end();
std::vector<basic_value_t> parsed_value_vector;
bool result = qi::parse(iter,end,grammar,parsed_value_vector);
if(result && iter==end)
{
std::cout << "Success: Type=" << static_cast<int>(parsed_value_vector[0].type) << "; Vals= ";
for(int num : parsed_value_vector[0].val)
std::cout << num << ".";
std::cout << std::endl;
}
else
{
std::cout << "Failure." << std::endl;
}
}