我有一大堆Spirit编码,它通过使用std::vector<std::string>
作为主要属性,将std::string input = "RED.MAGIC(1, 2, 3)[9].GREEN"
正确解析为一个简单的std::vector<std::string>
。如何将std :: vector <std::string>转换为boost :: spirit中的结构体的成员?
我想给std::vector<std::string>
更换成含有std::vector<std::string>
一个结构my_rec
,而是继续使用自动生成,如果可能的话。
当我用-DUSE_MY_REC
进行编译时,我遇到了难以逾越的编译错误。
样品编译和运行
/tmp$ g++ -g -std=c++11 sandbox.cpp -o sandbox && ./sandbox
Finished.
MATCHED
/tmp$ g++ -DUSE_MY_REC -g -std=c++11 sandbox.cpp -o sandbox && ./sandbox
WALL OF COMPILE ERRORS --------------------------------------------
sandbox.cpp
// #define BOOST_SPIRIT_DEBUG
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <string>
#include <iostream>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
#ifdef USE_MY_REC
struct my_rec
{
std::vector<std::string> m_pieces;
};
BOOST_FUSION_ADAPT_STRUCT(
my_rec,
(std::vector<std::string>, m_pieces)
)
typedef struct my_rec MY_TYPE;
#else
typedef std::vector<std::string> MY_TYPE;
#endif
template <typename ITERATOR>
struct my_parser :
qi::grammar<ITERATOR, MY_TYPE(), ascii::space_type>
{
my_parser() :
my_parser::base_type(start)
{
start %= (color | fun_call) % '.'
;
color %=
qi::string("RED")
| qi::string("GREEN")
| qi::string("BLUE")
;
fun_call %=
qi::string("MAGIC")
>> '('
>> +qi::char_("0-9") % ','
>> ')'
>> '['
>> +qi::char_("0-9")
>> ']'
;
}
qi::rule<ITERATOR, MY_TYPE(), ascii::space_type> start, fun_call;
qi::rule<ITERATOR, std::string(), ascii::space_type> color;
};
int
main(int argc, char* argv[])
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
MY_TYPE v;
std::string str = "RED.MAGIC(1, 2, 3)[9].GREEN";
std::vector<std::string> exp = {{ "RED", "MAGIC", "1", "2", "3", "9", "GREEN" }};
auto it = str.begin(), end = str.end();
my_parser<decltype(it)> g;
if(qi::phrase_parse(it, end, g, ascii::space, v) && it==end)
{
std::cout << "Finished." << std::endl;
#ifndef USE_MY_REC
if (!std::equal(v.begin(), v.end(), exp.begin()))
{
std::cout << "MISMATCH" << std::endl;
for(const auto& x : v)
std::cout << x << std::endl;
} else {
std::cout << "MATCHED" << std::endl;
}
#endif
} else
std::cout << "Error." << std::endl;
return 0;
}
[精神不能分配属性到单个元件结构](http://stackoverflow.com/questions/7770791/spirit-unable-to-assign-attribute-to-single-element-struct-or-融合序列)。 – 2012-11-30 22:01:26
+1对于一个有趣的发现,但不知道如果可行,因为在我的真实代码中,开始深深嵌入在我真正的分析规则中(不像在这个玩具的例子中的开始) - 不知道eps是否还没有好(doesn )... – kfmfe04