使用std :: array作为boost :: spirit :: x3的Attribute

时间:2015-10-12 13:29:05

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

我尝试使用boost :: spirit的最新版本x3(包含在boost 1.54中)将数字列表解析为固定大小的std::array容器。 由于std::array具有必要的功能,因此它被检测为容器,但缺少插入功能,这使得它不兼容。 以下是我想要完成的一个简短示例:

#include <boost/spirit/home/x3.hpp>

#include <array>
#include <iostream>
#include <string>

namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;

typedef std::array<double, 3> Vertex;

int main(int, char**) {
  using x3::double_;
  using ascii::blank;

  std::string input = "3.1415 42 23.5";
  auto iter = input.begin();

  auto vertex = x3::rule<class vertex, Vertex>{} =
    double_ >> double_ >> double_;

  Vertex v;

  bool const res = x3::phrase_parse(iter, input.end(), vertex, blank, v);
  if (!res || iter != input.end()) return EXIT_FAILURE;

  std::cout << "Match:" << std::endl;
  for (auto vi : v) std::cout << vi << std::endl;
  return EXIT_SUCCESS;
}

由于std::array没有insert功能,因此不会编译。 作为一种解决方法,我使用了语义操作:

auto vertex() {
  using namespace x3;
  return rule<class vertex_id, Vertex>{} =
    double_[([](auto &c) { _val(c)[0] = _attr(c); })] >>
    double_[([](auto &c) { _val(c)[1] = _attr(c); })] >>
    double_[([](auto &c) { _val(c)[2] = _attr(c); })];
}

然后致电

x3::phrase_parse(iter, input.end(), vertex(), blank, v);

代替。这是有效的(使用clang 3.6.0和-std = c ++ 14),但我认为这个解决方案非常不优雅且难以阅读。

所以我尝试使用BOOST_FUSION_ADAPT_ADT将std :: array作为融合序列进行调整,如下所示:

BOOST_FUSION_ADAPT_ADT(
  Vertex,
  (double, double, obj[0], obj[0] = val)
  (double, double, obj[1], obj[1] = val)
  (double, double, obj[2], obj[2] = val))

然后为Vertex专门设置x3::traits::is_container告诉x3不要将std :: array视为容器:

namespace boost { namespace spirit { namespace x3 { namespace traits {
  template<> struct is_container<Vertex> : public mpl::false_ {};
}}}}

但是这不会与x3一起编译。这是一个错误还是我使用它错了? 呼叫例如fusion::front(v)没有所有x3代码编译和工作,所以我猜我的代码并不完全错误。

但是,我确信有一个更清晰的解决方案,x3不涉及任何融合适配器或语义操作来解决这个简单的问题。

1 个答案:

答案 0 :(得分:0)

您发布的代码充满了草率错误。没有理由期望在那里编译任何东西,真的。

无论如何,我把它清理干净了。当然你应该包括

#include <boost/fusion/adapted/array.hpp>

可悲的是,它根本行不通。我得出的结论基本上与(在你阅读之前尝试过相同的事情之后:))。

这是Spirit X3的可用性问题 - 它仍处于试验阶段。您可以在[spirit-general]邮件列表中报告。回应通常非常迅速。

¹如果您想查看我使用http://paste.ubuntu.com/12764268/的内容;我还使用x3::repeat(3)[x3::double_]进行比较。