![](/img/trans.png)
[英]Spirit karma grammar issue when one rule uses BOOST_FUSION_ADAPT_STRUCT
[英]boost::spirit compile issue with BOOST_FUSION_ADAPT_STRUCT
我是新来提升:: spirit / fusion的人。 有人可以向我解释为什么不编译以下内容吗? 如果将m_name
和m_settings
变量直接放在config结构中,则可以正常编译,但将它们分成两个不同的结构时编译失败。 我想念什么?
顺便说一句,使编译器喷出大量的boost::spirit errors is: cfg = section >> node;
的代码行boost::spirit errors is: cfg = section >> node;
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace qi = boost::spirit::qi;
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace ascii = boost::spirit::ascii;
struct config_section
{
std::string m_name;
std::string m_settings;
};
struct config
{
config_section m_sections;
};
BOOST_FUSION_ADAPT_STRUCT(
config_section,
(std::string, m_name)
(std::string, m_settings)
)
BOOST_FUSION_ADAPT_STRUCT(
config,
(config_section, m_sections)
)
template <typename Iterator>
struct config_grammar : qi::grammar<Iterator, config(), ascii::space_type>
{
config_grammar() : config_grammar::base_type(cfg)
{
using qi::lexeme;
using qi::lit;
using ascii::string;
using ascii::char_;
using namespace qi::labels;
section %= '[' >> lexeme[+(char_ - ']')] >> ']';
node %= !lit('[') >> lexeme[+(char_ - '\n')];
cfg %= section >> node;
}
qi::rule<Iterator, config(), ascii::space_type> cfg;
qi::rule<Iterator, std::string(), ascii::space_type> node;
qi::rule<Iterator, std::string(), ascii::space_type> section;
};
template <typename Iterator>
bool parse_config(Iterator first, Iterator last)
{
using qi::double_;
using qi::phrase_parse;
using ascii::space;
using boost::phoenix::ref;
config result;
config_grammar<Iterator> config_parser;
bool r = phrase_parse(first, last, config_parser, space, result);
if (first != last) // fail if we did not get a full match
return false;
return r;
}
int main()
{
std::string input = "[section]\nstuff";
bool b = parse_config(input.begin(), input.end());
if (b)
std::cout << "Success" << std::endl;
else
std::cout << "Failure" << std::endl;
return 0;
}
谢谢!
问题似乎是您没有指定如何从config_section转换为config。 您告诉过精神,config_section由2个字符串组成,但是尝试在没有规则的情况下解析配置,以链接配置和config_section之间的转换。 这似乎可以编译。
template <typename Iterator>
struct config_grammar : qi::grammar<Iterator, config(), ascii::space_type>
{
config_grammar() : config_grammar::base_type(cfg)
{
using qi::lexeme;
using qi::lit;
using ascii::string;
using ascii::char_;
using namespace qi::labels;
section %= '[' >> lexeme[+(char_ - ']')] >> ']';
node %= !lit('[') >> lexeme[+(char_ - '\n')];
//create a rule to specify conversion of a config_section to a config
cfg %= cfg_sec;
//this a now a cfg_sec (which is what you declared to be composed of 2
// strings)
cfg_sec %= section >> node;
}
qi::rule<Iterator, config(), ascii::space_type> cfg;
//add new declaration here for cfg_sec
qi::rule<Iterator, config_section(), ascii::space_type> cfg_sec;
qi::rule<Iterator, std::string(), ascii::space_type> node;
qi::rule<Iterator, std::string(), ascii::space_type> section;
};
问题在于,您的cfg
规则和config_grammar
语法的属性不是config
,而是(据我所知-因为它是两个随后的字符串) config_section
。 更换之后:
struct config_grammar : qi::grammar<Iterator, config_section(), ascii::space_type>
....
qi::rule<Iterator, config_section(), ascii::space_type> cfg;
它编译。
我建议您更多地了解规则的属性以及它们如何工作-否则您会一直迷路。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.