gpt4 book ai didi

c++ - spirit x3 如何将 vector 添加到 AST

转载 作者:行者123 更新时间:2023-11-30 05:11:33 24 4
gpt4 key购买 nike

我正在尝试解析文件并将数据复制到类对象内的 vector 中。我以员工为例并将其修改为我正在尝试做的事情。被解析的文件看起来像这样(但更多行)...

1 0.2 0.3 0.4

我已经添加了一个 vector 来构造 employee 并且在 phrase_parse 行上遇到断言失败。

static assertion failed: Attribute does not have the expected size.
static_assert(
^

我有点认为预期大小与 vector 有关。想我哪里出错了?

namespace client {
namespace ast {

struct employee
{
int id;
std::vector<double> coords;
};

using boost::fusion::operator<<;
}}

BOOST_FUSION_ADAPT_STRUCT(
client::ast::employee,
(int, id)
(std::vector<double>, coords)
)

namespace client
{
namespace parser
{
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;

using x3::int_;
using x3::double_;

x3::rule<class employee, ast::employee> const employee = "employee";
auto const employee_def =
int_ >> double_ >> double_ >> double_;
BOOST_SPIRIT_DEFINE(employee)
}
}

int main()
{
using boost::spirit::x3::ascii::space;
using client::parser::employee;

string fil("test-file.in");

mapped_file_source map(fil);
istringstream iss(map.data());
map.close();

client::ast::employee emp;

boost::spirit::istream_iterator iter(iss >> noskipws), eof;

phrase_parse(iter, eof, employee, space, emp);
// failure on above line
}

最佳答案

根据文档,double_ >> double_ >> double_合成 double、double、double 的融合 序列(所以 fusion::tuple<double, double, double>fusion::list<double, double, double> 等)。

你想要一个 vector ,所以你需要一个重复的解析器(运算符)

  • repeat 指令将执行 repeat(3) [double_]
  • Kleene 星号 ( operator * ) 或加号 ( operator + ) 很有趣(但没有限制)
  • 列表运算符 ( operator % ) 也是无界的,但接受分隔符(例如 double_ % ','

在这种情况下,我会采用另一种方式:对语法使用适当的 AST:

Live On Coliru

struct coord {
double x,y,z;
};

struct employee
{
int id;
coord coords;
};

调整它们比您使用的老式方法更简单:

BOOST_FUSION_ADAPT_STRUCT(client::ast::coord, x, y, z)
BOOST_FUSION_ADAPT_STRUCT(client::ast::employee, id, coords)

解析器是干净的

auto const coord_def = double_ >> double_ >> double_;
auto const employee_def = int_ >> coord;

完整演示:

Live On Coliru

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <iostream>

namespace client {
namespace ast {

struct coord {
double x,y,z;
};

struct employee
{
int id;
coord coords;
};

using boost::fusion::operator<<;
}}

BOOST_FUSION_ADAPT_STRUCT(client::ast::coord, x, y, z)
BOOST_FUSION_ADAPT_STRUCT(client::ast::employee, id, coords)

namespace client
{
namespace parser
{
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;

using x3::int_;
using x3::double_;

x3::rule<class employee, ast::coord> const coord = "coord";
x3::rule<class employee, ast::employee> const employee = "employee";

auto const coord_def = double_ >> double_ >> double_;
auto const employee_def = int_ >> coord;

BOOST_SPIRIT_DEFINE(employee, coord);
}
}

int main()
{
using boost::spirit::x3::ascii::space;
using client::parser::employee;

std::istringstream iss("1 0.2 0.3 0.4");

client::ast::employee emp;

boost::spirit::istream_iterator iter(iss >> std::noskipws), eof;

bool ok = phrase_parse(iter, eof, employee, space, emp);
if (ok)
std::cout << "parsed: "
<< emp.id << " "
<< emp.coords.x << " "
<< emp.coords.y << " "
<< emp.coords.z << "\n";
}

关于c++ - spirit x3 如何将 vector 添加到 AST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44992473/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com