C++ 解析std::vector<;标准::向量<;双倍>;作为具有精神的结构属性
我有以下文字:C++ 解析std::vector<;标准::向量<;双倍>;作为具有精神的结构属性,c++,parsing,vector,boost,boost-spirit,C++,Parsing,Vector,Boost,Boost Spirit,我有以下文字: [70000000:45] 4, 5, 6, 7 [60000000:60] 1, 2, 3, 4 [80000:90] 4, 5, 6, 7, 8, 9 方括号中的行包含频率和角度,其形式为[freq:angle],而后面的行是与这些参数相关的数字向量。我可以有不同的频率和角度,每个频率和角度都定义了一个向量 我有以下结构: struct Data { std::vector<int> frequencies; std::vector<int&g
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
方括号中的行包含频率和角度,其形式为[freq:angle]
,而后面的行是与这些参数相关的数字向量。我可以有不同的频率和角度,每个频率和角度都定义了一个向量
我有以下结构:
struct Data {
std::vector<int> frequencies;
std::vector<int> elevations;
std::vector<std::vector<double>> gains;
};
qi::rule<It, Data(), Skipper> start;
qi::rule<It, Ast::Data(), Skipper> section;
我需要解析文件以填充结构。我能够解析频率
和高程
,并将它们存储在向量中,但我无法存储增益数据。我需要从这些数据中创建一个向量
你可以在下面找到代码;解析后,parsed
填充了频率和高程,我需要增益。我能做些什么来解析它们
#include <boost/optional/optional_io.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
const std::string file1 = R"xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx";
struct Data {
std::vector<int> frequencies;
std::vector<int> elevations;
std::vector<std::vector<double>> gains;
};
BOOST_FUSION_ADAPT_STRUCT(
Data,
(std::vector<int>, frequencies)
(std::vector<int>, elevations)
(std::vector<std::vector<double>>, gains)
)
template <typename It, typename Skipper = qi::space_type>
struct grammar : qi::grammar<It, Data(), Skipper> {
grammar() : grammar::base_type(start) {
auto frequencyParser = qi::int_[px::push_back(px::at_c<0>(qi::_val), qi::_1)];
auto elevationParser = qi::int_[px::push_back(px::at_c<1>(qi::_val), qi::_1)];
auto frequencyElevationParser = qi::lit('[') >> frequencyParser >> qi::lit(':') >> elevationParser >> qi::lit(']');
auto gainsParser = qi::double_ % qi::lit(','); // Problem here where I want to parse vector rows
start = *(frequencyElevationParser >> gainsParser);
}
private:
qi::rule<It, Data(), Skipper> start;
};
int main() {
using It = std::string::const_iterator;
Data parsed;
bool ok = qi::phrase_parse(file1.begin(), file1.end(), grammar<It>(), qi::space, parsed);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
名称空间px=boost::phoenix;
常量std::字符串文件1=R“xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx”;
结构数据{
向量频率;
std::矢量高程;
矢量增益;
};
增强融合适应结构(
数据,
(标准:矢量,频率)
(标准::矢量,高程)
(标准::矢量,增益)
)
模板
结构语法:qi::grammar{
语法():语法::基本类型(开始){
自动频率PARSER=qi::int_u2;[px::推回(px::at_c(qi::val),qi:1)];
自动提升解析器=qi::int_ux::push_back(px::at_c(qi::_val),qi:_1)];
auto-frequencyElevationParser=qi::lit('[')>>frequencyParser>>qi::lit(':')>>elevationParser>>qi::lit(']');
auto-gainsParser=qi::double_%qi::lit(',');//这里的问题是我要在哪里解析向量行
开始=*(frequencyElevationParser>>GainParser);
}
私人:
qi::规则开始;
};
int main(){
使用它=std::string::const_迭代器;
解析数据;
bool ok=qi::phrase_parse(file1.begin()、file1.end()、grammar()、qi::space,已解析);
返回0;
}
我自己找到了解决办法
我在语法中为std::vector
添加了qi::rule
,然后我用它解析向量,将结果像其他字段一样附加到结构中。下面是更正后的代码:
#include <boost/optional/optional_io.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
const std::string file1 = R"xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx";
struct Data {
std::vector<int> frequencies;
std::vector<int> elevations;
std::vector<std::vector<double>> gains;
};
BOOST_FUSION_ADAPT_STRUCT(
Data,
(std::vector<int>, frequencies)
(std::vector<int>, elevations)
(std::vector<std::vector<double>>, gains)
)
template <typename It, typename Skipper = qi::space_type>
struct grammar : qi::grammar<It, Data(), Skipper> {
grammar() : grammar::base_type(start) {
auto frequencyParser = qi::int_[px::push_back(px::at_c<0>(qi::_val), qi::_1)];
auto elevationParser = qi::int_[px::push_back(px::at_c<1>(qi::_val), qi::_1)];
auto frequencyElevationParser = qi::lit('[') >> frequencyParser >> qi::lit(':') >> elevationParser >> qi::lit(']');
vectorParser = qi::double_ % qi::lit(',');
auto gainsParser = vectorParser[px::push_back(px::at_c<2>(qi::_val), qi::_1)];
start = *(frequencyElevationParser >> gainsParser);
}
private:
qi::rule<It, Data(), Skipper> start;
qi::rule<It, std::vector<double>(), Skipper> vectorParser;
};
int main() {
using It = std::string::const_iterator;
Data parsed;
bool ok = qi::phrase_parse(file1.begin(), file1.end(), grammar<It>(), qi::space, parsed);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
名称空间px=boost::phoenix;
常量std::字符串文件1=R“xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx”;
结构数据{
向量频率;
std::矢量高程;
矢量增益;
};
增强融合适应结构(
数据,
(标准:矢量,频率)
(标准::矢量,高程)
(标准::矢量,增益)
)
模板
结构语法:qi::grammar{
语法():语法::基本类型(开始){
自动频率PARSER=qi::int_u2;[px::推回(px::at_c(qi::val),qi:1)];
自动提升解析器=qi::int_ux::push_back(px::at_c(qi::_val),qi:_1)];
auto-frequencyElevationParser=qi::lit('[')>>frequencyParser>>qi::lit(':')>>elevationParser>>qi::lit(']');
vectorParser=qi::double_%qi::lit(',');
auto-gainsParser=vectorParser[px::push_back(px::at_c(qi::_val),qi::_1)];
开始=*(frequencyElevationParser>>GainParser);
}
私人:
qi::规则开始;
qi::规则向量解析器;
};
int main(){
使用它=std::string::const_迭代器;
解析数据;
bool ok=qi::phrase_parse(file1.begin()、file1.end()、grammar()、qi::space,已解析);
返回0;
}
本着我经常重复的咒语的精神,我会使用一个特征,并将每个部分解析为Ast结构:
struct Data {
std::vector<int> frequencies;
std::vector<int> elevations;
std::vector<std::vector<double>> gains;
};
qi::rule<It, Data(), Skipper> start;
qi::rule<It, Ast::Data(), Skipper> section;
魔法:
让我们创建一个Ast结构,并仅对其进行调整,而不是使用给定的不切实际的数据类型:
namespace Ast {
struct Data {
int frequency;
int elevation;
std::vector<double> gains;
};
}
BOOST_FUSION_ADAPT_STRUCT(Ast::Data, frequency, elevation, gains)
这要简单得多
演示
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
const std::string file1 = R"xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx";
namespace MyLib {
struct Data {
std::vector<int> frequencies;
std::vector<int> elevations;
std::vector<std::vector<double> > gains;
};
}
namespace Ast {
struct Data {
int frequency;
int elevation;
std::vector<double> gains;
};
}
namespace boost { namespace spirit { namespace traits {
template <> struct container_value<MyLib::Data> { using type = Ast::Data; };
template<> struct push_back_container<MyLib::Data, Ast::Data> {
static bool call(MyLib::Data& c, Ast::Data const& val) {
c.frequencies.push_back(val.frequency);
c.elevations.push_back(val.elevation);
c.gains.push_back(val.gains);
return true;
}
};
} } }
BOOST_FUSION_ADAPT_STRUCT(Ast::Data, frequency, elevation, gains)
namespace MyLib {
template <typename It, typename Skipper = qi::space_type>
struct grammar : qi::grammar<It, Data(), Skipper> {
grammar() : grammar::base_type(start) {
using namespace qi;
section = '[' >> int_ >> ':' >> int_ >> ']' >> double_ % ',';
start = *section;
}
private:
qi::rule<It, Data(), Skipper> start;
qi::rule<It, Ast::Data(), Skipper> section;
};
}
int main() {
using It = std::string::const_iterator;
MyLib::Data parsed;
bool ok = qi::phrase_parse(file1.begin(), file1.end(), MyLib::grammar<It>(), qi::space, parsed);
}
#包括
#包括
名称空间qi=boost::spirit::qi;
常量std::字符串文件1=R“xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx”;
名称空间MyLib{
结构数据{
向量频率;
std::矢量高程;
矢量增益;
};
}
名称空间Ast{
结构数据{
整数频率;
内立面图;
矢量增益;
};
}
名称空间提升{名称空间精神{名称空间特征{
模板结构容器_值{using type=Ast::Data;};
模板结构推回容器{
静态bool调用(MyLib::Data&c,Ast::Data const&val){
c、 频率。推回(值频率);
c、 标高。推回(val.标高);
c、 增益。推回(值增益);
返回true;
}
};
} } }
增强融合自适应结构(Ast::数据、频率、高程、增益)
名称空间MyLib{
模板
结构语法:qi::grammar{
语法():语法::基本类型(开始){
使用名称空间qi;
section='['>>int\>':'>>int\>']'>>double\%',';
开始=*节;
}
私人:
qi::规则开始;
qi::规则部分;
};
}
int main(){
使用它=std::string::const_迭代器;
MyLib::解析的数据;
bool ok=qi::phrase_parse(file1.begin()、file1.end()、MyLib::grammar()、qi::space,已解析);
}
使用X3,这将变得更加简单:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
const std::string file1 = R"xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx";
struct Data {
std::vector<int> frequencies;
std::vector<int> elevations;
std::vector<std::vector<double>> gains;
};
int main() {
Data parsed;
auto appender = [](auto& ctx)
{
Data& data = x3::_val(ctx);
auto& entry = x3::_attr(ctx);
data.frequencies.push_back(boost::fusion::at_c<0>(entry));
data.elevations.push_back(boost::fusion::at_c<1>(entry));
data.gains.emplace_back(std::move(boost::fusion::at_c<2>(entry)));
};
auto block = x3::rule<struct r_block, Data>{} =
(('[' >> x3::int_ >> ':' >> x3::int_ >> ']') >> (x3::double_ % ','))[appender];
auto it = file1.begin();
while (x3::phrase_parse(it, file1.end(), block, x3::space, parsed))
;
if (it != file1.end()) {
std::cout << "Not all input parsed" << std::endl;
}
assert(parsed.elevations.size() == parsed.frequencies.size()
&& parsed.frequencies.size() == parsed.gains.size());
for (int i = 0; i < parsed.frequencies.size(); ++i) {
std::cout << "frequency: " << parsed.frequencies[i] << std::endl;
std::cout << "elevations: " << parsed.elevations[i] << std::endl;
std::cout << "gains: ";
std::copy(parsed.gains[i].begin(), parsed.gains[i].end(), std::ostream_iterator<double>(std::cout, ","));
std::cout << std::endl;
}
return 0;
}
#包括
#包括
名称空间x3=boost::spirit::x3;
常量std::字符串文件1=R“xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx”;
结构数据{
向量频率;
std::矢量高程;
矢量增益;
};
int main(){
解析数据;
自动追加器=[](自动和ctx)
{
数据和数据=x3::_val(ctx);
自动输入(&entry=x3::_attr(ctx);
数据。频率。推回(boost::fusion::at_c(条目));
数据。高程。推回(boost::fusion::at_c(条目));
数据.gains.emplace_back(std::move(boost::fusion::at_c(entry));
};
自动块=x3::规则{}=
((“[”>>x3::int\u>>”:“>>x3::int\u>>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
const std::string file1 = R"xx(
[70000000:45]
4, 5, 6, 7
[60000000:60]
1, 2, 3, 4
[80000:90]
4, 5, 6, 7, 8, 9
)xx";
struct Data {
std::vector<int> frequencies;
std::vector<int> elevations;
std::vector<std::vector<double>> gains;
};
int main() {
Data parsed;
auto appender = [](auto& ctx)
{
Data& data = x3::_val(ctx);
auto& entry = x3::_attr(ctx);
data.frequencies.push_back(boost::fusion::at_c<0>(entry));
data.elevations.push_back(boost::fusion::at_c<1>(entry));
data.gains.emplace_back(std::move(boost::fusion::at_c<2>(entry)));
};
auto block = x3::rule<struct r_block, Data>{} =
(('[' >> x3::int_ >> ':' >> x3::int_ >> ']') >> (x3::double_ % ','))[appender];
auto it = file1.begin();
while (x3::phrase_parse(it, file1.end(), block, x3::space, parsed))
;
if (it != file1.end()) {
std::cout << "Not all input parsed" << std::endl;
}
assert(parsed.elevations.size() == parsed.frequencies.size()
&& parsed.frequencies.size() == parsed.gains.size());
for (int i = 0; i < parsed.frequencies.size(); ++i) {
std::cout << "frequency: " << parsed.frequencies[i] << std::endl;
std::cout << "elevations: " << parsed.elevations[i] << std::endl;
std::cout << "gains: ";
std::copy(parsed.gains[i].begin(), parsed.gains[i].end(), std::ostream_iterator<double>(std::cout, ","));
std::cout << std::endl;
}
return 0;
}