c++ - 无法使用 lambda 参数编译 boost::spirit::x3 解析器
问题描述
根据此处的答案,我编写了以下解析器:
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <fstream>
#include <iostream>
#include <vector>
namespace x3 = boost::spirit::x3;
int main() {
std::ifstream input("input.txt");
boost::spirit::istream_iterator begin(input >> std::noskipws), end;
std::vector<float> data1, data2;
auto capture1 = [&](auto& ctx){ data1.emplace_back(_attr(ctx)); };
auto capture2 = [&](auto& ctx){ data2.emplace_back(_attr(ctx)); };
auto sequence1 = "v" >> x3::float_[capture1] >> x3::float_[capture1] >> x3::float_[capture1];
auto sequence2 = "vn" >> x3::float_[capture2] >> x3::float_[capture2] >> x3::float_[capture2];
auto skipper = x3::blank | '#' >> *(x3::char_ - x3::eol) >> (x3::eol|x3::eoi);
auto rule = x3::skip(skipper) [ *x3::eol >>
*( +(sequence1 >> (x3::eoi|+x3::eol) ) >>
*(sequence2 >> (x3::eoi|+x3::eol) ) )
];
if (x3::parse(begin, end, rule)) {
std::cout << "data1 size: " << data1.size() << "\n";
for(float& i:data1)
std::cout << i << ", ";
std::cout << '\n';
std::cout << "data2 size: " << data2.size() << "\n";
for(float& i:data2)
std::cout << i << ", ";
std::cout << '\n';
} else
std::cout << "failed to parse!\n";
if(begin!=end)
std::cerr<< "did not parsed completely!";
//---------------------------------
std::cout << "\ndone!\n";
return EXIT_SUCCESS;
}
我的输入文件看起来像这样:
# group 1
v -111.11 -0.017928 0.005579
v -0.014504 -0.017928 0.010577
v -0.010538 -0.017928 0.014543
v -0.005540 -0.017928 0.017090
vn -111.11 -0.017928 0.005579
vn -0.014504 -0.017928 0.010577
vn -0.010538 -0.017928 0.014543
# group 2
v 0.005540 -0.017928 0.017090
v 0.010538 -0.017928 0.014543
v 0.014504 -0.017928 0.010577
vn 0.014504 -0.017928 0.010577
vn 0.017050 -0.017928 0.005579
vn 0.017928 -0.017928 0.000039
vn -0.010538 -0.017928 0.014543
# group 3
# and so on..
使用以下设置正确编译和解析了相同的代码:
- 在带有boost-1.67.0和gcc的Windows 10上, MinGW-W64 7.3.0 “编译和解析很好!”
- 在带有boost-1.62.0和gcc 6.3.0的debian 9上“编译和解析很好!”
但是,我无法在ubuntu 18.04上使用boost-1.65.1和gcc(7.5.0、9.3.0和10.1.0)在(c++14、c++17或c++20)上编译它.
这是错误消息的一部分:
In file included from /usr/include/boost/spirit/home/x3/directive/expect.hpp:12,
from /usr/include/boost/spirit/home/x3/auxiliary/guard.hpp:11,
from /usr/include/boost/spirit/home/x3/auxiliary.hpp:13,
from /usr/include/boost/spirit/home/x3.hpp:14,
from parser.cpp:1:
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp: In instantiation of 'static bool boost::spirit::x3::detail::parse_into_container_impl<Parser, Context, RContext, typename boost::enable_if<boost::spirit::x3::traits::handles_container<Parser, Context> >::type>::call(const Parser&, Iterator&, const Iterator&, const Context&, RContext&, Attribute&, mpl_::true_) [with Iterator = boost::spirit::basic_istream_iterator<char>; Attribute = const boost::spirit::x3::unused_type; Parser = boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >; Context = boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >, boost::spirit::x3::unused_type>; RContext = const boost::spirit::x3::unused_type; mpl_::true_ = mpl_::bool_<true>]':
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:281:24: required from 'static bool boost::spirit::x3::detail::parse_into_container_impl<Parser, Context, RContext, typename boost::enable_if<boost::spirit::x3::traits::handles_container<Parser, Context> >::type>::call(const Parser&, Iterator&, const Iterator&, const Context&, RContext&, Attribute&) [with Iterator = boost::spirit::basic_istream_iterator<char>; Attribute = const boost::spirit::x3::unused_type; Parser = boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >; Context = boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >, boost::spirit::x3::unused_type>; RContext = const boost::spirit::x3::unused_type]'
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:293:74: required from 'bool boost::spirit::x3::detail::parse_into_container(const Parser&, Iterator&, const Iterator&, const Context&, RContext&, Attribute&) [with Parser = boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >; Iterator = boost::spirit::basic_istream_iterator<char>; Context = boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >, boost::spirit::x3::unused_type>; RContext = const boost::spirit::x3::unused_type; Attribute = const boost::spirit::x3::unused_type]'
/usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:378:33: required from 'bool boost::spirit::x3::detail::parse_sequence(const Parser&, Iterator&, const Iterator&, const Context&, RContext&, Attribute&, boost::spirit::x3::traits::container_attribute) [with Parser = boost::spirit::x3::sequence<boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > > >; Iterator = boost::spirit::basic_istream_iterator<char>; Context = boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >, boost::spirit::x3::unused_type>; RContext = const boost::spirit::x3::unused_type; Attribute = const boost::spirit::x3::unused_type]'
/usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:463:32: required from 'static bool boost::spirit::x3::detail::parse_into_container_impl<boost::spirit::x3::sequence<L, R>, Context, RContext>::call(const parser_type&, Iterator&, const Iterator&, const Context&, RContext&, Attribute&, mpl_::false_) [with Iterator = boost::spirit::basic_istream_iterator<char>; Attribute = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >; Right = boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >; Context = boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >, boost::spirit::x3::unused_type>; RContext = const boost::spirit::x3::unused_type; boost::spirit::x3::detail::parse_into_container_impl<boost::spirit::x3::sequence<L, R>, Context, RContext>::parser_type = boost::spirit::x3::sequence<boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > > >; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:496:24: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/spirit/home/x3/operator/kleene.hpp:32:48: required from 'bool boost::spirit::x3::kleene<Subject>::parse(Iterator&, const Iterator&, const Context&, RContext&, Attribute&) const [with Iterator = boost::spirit::basic_istream_iterator<char>; Context = boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >, boost::spirit::x3::unused_type>; RContext = const boost::spirit::x3::unused_type; Attribute = const boost::spirit::x3::unused_type; Subject = boost::spirit::x3::sequence<boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > > >]'
/usr/include/boost/spirit/home/x3/operator/sequence.hpp:32:37: required from 'bool boost::spirit::x3::sequence<Left, Right>::parse(Iterator&, const Iterator&, const Context&, RContext&, boost::spirit::x3::unused_type) const [with Iterator = boost::spirit::basic_istream_iterator<char>; Context = boost::spirit::x3::context<boost::spirit::x3::skipper_tag, const boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >, boost::spirit::x3::unused_type>; RContext = const boost::spirit::x3::unused_type; Left = boost::spirit::x3::kleene<boost::spirit::x3::eol_parser>; Right = boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > > > >]'
/usr/include/boost/spirit/home/x3/directive/skip.hpp:75:39: required from 'bool boost::spirit::x3::skip_directive<Subject, Skipper>::parse(Iterator&, const Iterator&, const Context&, RContext&, Attribute&) const [with Iterator = boost::spirit::basic_istream_iterator<char>; Context = boost::spirit::x3::unused_type; RContext = const boost::spirit::x3::unused_type; Attribute = const boost::spirit::x3::unused_type; Subject = boost::spirit::x3::sequence<boost::spirit::x3::kleene<boost::spirit::x3::eol_parser>, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > > > > >; Skipper = boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > >]'
/usr/include/boost/spirit/home/x3/core/parse.hpp:35:34: required from 'bool boost::spirit::x3::parse_main(Iterator&, Iterator, const Parser&, Attribute&) [with Iterator = boost::spirit::basic_istream_iterator<char>; Parser = boost::spirit::x3::skip_directive<boost::spirit::x3::sequence<boost::spirit::x3::kleene<boost::spirit::x3::eol_parser>, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > > > > >, boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > > >; Attribute = const boost::spirit::x3::unused_type]'
/usr/include/boost/spirit/home/x3/core/parse.hpp:71:26: required from 'bool boost::spirit::x3::parse(Iterator&, Iterator, const Parser&) [with Iterator = boost::spirit::basic_istream_iterator<char>; Parser = boost::spirit::x3::skip_directive<boost::spirit::x3::sequence<boost::spirit::x3::kleene<boost::spirit::x3::eol_parser>, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::plus<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:1&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > >, boost::spirit::x3::kleene<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_string<const char*, boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::action<boost::spirit::x3::real_parser<float>, main()::<lambda(auto:2&)> > >, boost::spirit::x3::alternative<boost::spirit::x3::eoi_parser, boost::spirit::x3::plus<boost::spirit::x3::eol_parser> > > > > > >, boost::spirit::x3::alternative<boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::blank_tag>, boost::spirit::x3::sequence<boost::spirit::x3::sequence<boost::spirit::x3::literal_char<boost::spirit::char_encoding::standard, boost::spirit::x3::unused_type>, boost::spirit::x3::kleene<boost::spirit::x3::difference<boost::spirit::x3::any_char<boost::spirit::char_encoding::standard>, boost::spirit::x3::eol_parser> > >, boost::spirit::x3::alternative<boost::spirit::x3::eol_parser, boost::spirit::x3::eoi_parser> > > >]'
parser.cpp:28:35: required from here
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:254:22: error: 'const struct boost::spirit::x3::unused_type' has no member named 'empty'
254 | if (attr.empty())
| ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:22: error: 'const struct boost::spirit::x3::unused_type' has no member named 'insert'
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:34: error: 'const struct boost::spirit::x3::unused_type' has no member named 'end'
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:46: error: 'const struct boost::spirit::x3::unused_type' has no member named 'begin'
259 | attr.insert(attr.end(), rest.begin(), rest.end());
| ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:60: error: 'const struct boost::spirit::x3::unused_type' has no member named 'end'
259 | attr.insert(attr.end(), rest.begin(), rest.end());
|
.
.
.
.
我也尝试了这个答案中的建议,但它仍然无法编译!
有人可以指出我做错了什么,或者至少是什么原因造成的?谢谢
解决方案
这是 1.65.0、1.65.1 和 1.66 中已知且已修复的错误
亲自查看:https ://wandbox.org/permlink/32WK3LoPb8yqmfsV (左侧切换升压版本)。
解决方法?
这是一个简化版本 - 解析器未更改但更具可读性(我正在查看代码),并且输入是为Compiler Explorer硬编码的:
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <fstream>
#include <fmt/ranges.h>
namespace x3 = boost::spirit::x3;
int main() {
std::string const& input = R"(# group 1
v -111.11 -0.017928 0.005579
vn -111.11 -0.017928 0.005579
# group 2
v 0.005540 -0.017928 0.017090
vn 0.014504 -0.017928 0.010577
# and so on..)";
auto triplet = [](auto id, auto& v) {
auto action = [&v](auto& ctx){ v.emplace_back(x3::_attr(ctx)); };
return id >> x3::repeat(3) [x3::double_ [action]];
};
auto NL = x3::eoi|+x3::eol;
auto skipper = x3::blank | '#' >> *(x3::char_ - x3::eol) >> NL;
std::vector<float> v, vn;
auto rule = x3::skip(skipper) [ -NL >>
*( +(triplet("v", v) >> NL) >>
*(triplet("vn", vn) >> NL) )
];
if (x3::parse(begin(input), end(input), rule >> x3::eoi)) {
fmt::print("v: {}\nvn: {}\n", v, vn);
}
}
印刷
v: {-111.11, -0.017928, 0.005579, 0.00554, -0.017928, 0.01709}
vn: {-111.11, -0.017928, 0.005579, 0.014504, -0.017928, 0.010577}
请注意,由于语义操作,这如何将来自不同组的数据序列混为一谈。对比下!
现在切换到 1.66.0 也失败了:https ://godbolt.org/z/bjvETE
然而,这里进一步简化但没有任何语义操作:
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <fstream>
#include <fmt/ranges.h>
namespace x3 = boost::spirit::x3;
int main() {
std::string const& input = R"(# group 1
v -111.11 -0.017928 0.005579
vn -111.11 -0.017928 0.005579
# group 2
v 0.005540 -0.017928 0.017090
vn 0.014504 -0.017928 0.010577
# and so on..)";
auto NL = x3::eoi|+x3::eol;
auto skipper = x3::blank | '#' >> *(x3::char_ - x3::eol) >> NL;
auto triplet = x3::repeat(3) [x3::double_];
using V = std::vector<float>;
using VN = std::vector<float>;
using Group = std::tuple<V, VN>;
auto group
= x3::rule<struct rule_id, Group> {"group"}
= +("v" >> triplet >> NL) >>
*("vn" >> triplet >> NL)
;
auto rule = x3::skip(skipper) [ -NL >> *group ];
std::vector<Group> groups;
if (x3::parse(begin(input), end(input), rule >> x3::eoi, groups)) {
fmt::print("{}\n", fmt::join(groups, "\n"));
}
}
最重要的是,它不再混淆组:
({-111.11, -0.017928, 0.005579}, {-111.11, -0.017928, 0.005579})
({0.00554, -0.017928, 0.01709}, {0.014504, -0.017928, 0.010577})
在没有 libfmt 的情况下打印数据(Live On Coliru)
for (auto& [v,vn] : groups) {
std::cout << "\nv"; for (auto&& f : v) std::cout << " " << f;
std::cout << "\nvn"; for (auto&& f : vn) std::cout << " " << f;
}
输出:
v -111.11 -0.017928 0.005579
vn -111.11 -0.017928 0.005579
v 0.00554 -0.017928 0.01709
vn 0.014504 -0.017928 0.010577
TL;博士
只需升级您的升压版本。Spirit 完全只有标头,因此如果需要,您可以将 1.67.0 标头从boost/spirit/x3
项目文件夹中放入。
题外话:语义动作有弊端:Boost Spirit:“语义动作是邪恶的”?.
推荐阅读
- excel - 自动启用库
- java - 当 Origin 被定义为 webapp 自己的主机名以外的任何内容时,Spring boot 2.2.4.RELEASE 为 GET 请求返回 403
- c# - 对 signInManager.PasswordSignInAsync 进行故障排除
- sql - 如何使用 SQL 将数字列表拆分为具有固定间隔的范围?
- ruby-on-rails - 带有 React Webpack 的 Ruby on Rails - 定义/访问环境变量?
- javascript - 使用单选按钮的嵌套问题切换
- xml - Powershell按字符串值选择节点
- apache-spark - 如何像运行 Python 作业一样运行 pyspark shell 代码
- css - 如何使用顺风使 CSS 网格项目具有自动高度?
- bigbluebutton - 有没有办法修改 bbb-install.sh 脚本以允许服务器在 2 个内核上运行(低于最低规格)