X3:如何创建解析器以进行集中读取
X3: How to create parser to read in sets?
如何创建一个读取3组整数的规则。即…
1 2 3 OK, 1 set of 3 ints
1 2 3 4 5 6 OK, 2 sets of 3 ints
1 2 3 4 5 ERROR, 1 set of 3 ints, 1 short for 2nd
1 2 3 4 5 6 7 8 9 OK, 3 sets of 3 ints
1 2 3 4 5 6 7 8 9 10 ERROR, 3 sets of 3 ints, 1 short for 4th
我对fusion adapt结构有问题(如何使args的数量可变(。。。
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, n1, n2, n3, n4, n5, n6)
不知道为什么这个规则不起作用。
... = *(int_ >> int_ >> int_);
这是我的尝试。。。http://coliru.stacked-crooked.com/a/cb10e8096c95fc55
//#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
namespace client {
namespace ast {
struct number {
int n1, n2, n3, n4, n5, n6;
};
struct comment {
std::string text;
bool dummy;
};
struct input {
std::vector<comment> comments;
std::vector<number> numbers;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, n1, n2, n3) // , n4, n5, n6) error
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers)
namespace client {
namespace parser {
namespace x3 = boost::spirit::x3;
using namespace x3;
typedef std::string::const_iterator It;
using namespace x3;
auto const comment = rule<struct _c, ast::comment> {"comment"} = lexeme[*(char_ - eol)] >> attr(false);
auto const number = rule<struct _n, ast::number> {"number"} = int_ >> int_ >> int_;
// auto const number = rule<struct _n, ast::number> {"number"} = *(int_ >> int_ >> int_); error
auto lines = [](auto p) { return *(p >> eol); };
auto const input =
repeat(1)[comment] >> eol >>
lines(number);
}
}
int main() {
namespace x3 = boost::spirit::x3;
std::string const iss("any char string heren1 2 3n1 2 3 4 5 6");
auto iter = iss.begin(), eof = iss.end();
client::ast::input types;
bool ok = phrase_parse(iter, eof, client::parser::input, x3::blank, types);
if (iter != eof) {
std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'n";
}
std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter) / iss.size()) << "%n";
std::cout << "ok = " << ok << std::endl;
for (auto& item : types.comments) { std::cout << "comment: " << boost::fusion::as_deque(item) << "n"; }
for (auto& item : types.numbers) { std::cout << "number: " << boost::fusion::as_deque(item) << "n"; }
}
打印
Parsed: 71.0526%
ok = 1
comment: (any char string here 0)
number: (1 2 3)
算子Kleene-star合成为容器属性(文档显示:vector<T>
(
结构体number
不是容器属性。所以。
此外,我完全不清楚你想要实现什么。你的结构应该是6int,但你想解析3的组吗?组的是什么意思?我可能会这么做:
struct number {
struct group { int n1, n2, n3; };
std::vector<group> groups;
};
BOOST_FUSION_ADAPT_STRUCT(client::ast::number::group, n1, n2, n3)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, groups)
这与语法分析器表达式兼容
*(int_ >> int_ >> int_)
现场演示
两个注意事项:
- 再次需要伪attibute(考虑
using number = std::vector<number_group>;
( - 输入结束时缺少
n
(考虑eol | eoi
(
Coliru
//#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
namespace client {
namespace ast {
struct number {
struct group { int n1, n2, n3; };
std::vector<group> groups;
bool dummy;
};
struct comment {
std::string text;
bool dummy;
};
struct input {
std::vector<comment> comments;
std::vector<number> numbers;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number::group, n1, n2, n3)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, groups, dummy)
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers)
namespace client {
namespace parser {
namespace x3 = boost::spirit::x3;
using namespace x3;
typedef std::string::const_iterator It;
using namespace x3;
auto const comment = rule<struct _c, ast::comment> {"comment"} = lexeme[*(char_ - eol)] >> attr(false);
auto const number = rule<struct _n, ast::number> {"number"} = *(int_ >> int_ >> int_) >> attr(false);
auto lines = [](auto p) { return *(p >> eol); };
auto const input =
repeat(1)[comment] >> eol >>
lines(number);
}
}
int main() {
namespace x3 = boost::spirit::x3;
std::string const iss("any char string heren1 2 3n1 2 3 4 5 6n");
auto iter = iss.begin(), eof = iss.end();
client::ast::input types;
bool ok = phrase_parse(iter, eof, client::parser::input, x3::blank, types);
if (iter != eof) {
std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'n";
}
std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter) / iss.size()) << "%n";
std::cout << "ok = " << ok << std::endl;
for (auto &item : types.comments) {
std::cout << "comment: " << boost::fusion::as_deque(item) << "n";
}
for (auto& item : types.numbers) {
std::cout << "number: ";
for (auto& g : item.groups)
std::cout << boost::fusion::as_deque(g) << " ";
std::cout << "n";
}
}
打印
Parsed: 100%
ok = 1
comment: (any char string here 0)
number: (1 2 3)
number: (1 2 3) (4 5 6)
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 无法找到/读取配置文件.conf-FileIOException
- 如何使用Luacneneneba API正确读取字符串和表参数
- C++将文本文件中的数据读取到结构数组中
- 正在将csv文件读取为双精度矢量
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 为什么在读取文件大小时文件IO速度会发生变化
- 正在读取二进制文件(is_open)
- 如何在c++中从文本文件中逐行读取整数
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- 独立读取-修改-写入顺序
- X3:如何创建解析器以进行集中读取
- 将任意大小的大量 Base-10 数字读取到位集中
- 这是我的程序,C++使用 OpenCv 库从数据集中读取图像序列,但它没有运行
- 如何从数据集中读取特定的字符列