我试图简单地解析它,并将xml的结构与Boost::Spirit结合起来,
One{
Two{
Three{
}
}
}代码的组织方式如下:
结构定义,以保持精神的东西:
struct config;
typedef boost::variant< boost::recursive_wrapper<config> , std::string > config_node;
struct config
{
std::string name;
std::vector<config_node> children;
};
BOOST_FUSION_ADAPT_STRUCT(
config,
(std::string, name)
(std::vector<config_node>, children)
)(不知羞耻地从xml简介中窃取)
规则声明(在解析器类上)
qi::rule<Iterator, config(), qi::locals<std::string>, ascii::space_type> cfg;
qi::rule<Iterator, config_node(), ascii::space_type> node;
qi::rule<Iterator, std::string(), ascii::space_type> start_tag;
qi::rule<Iterator, void(std::string), ascii::space_type> end_tag;解析器“parse”方法中的规则定义。
node = cfg;
start_tag = +(char_ -'{') >> '{';
end_tag = char_('}');
cfg %= start_tag[_a = _1]
>> *node
>> end_tag(_a);_a和_1是boost::phoenix变量。
此规则适用于上面粘贴的小片段,但如果我将其更改为:
One{
Two{
}
Three{
}
}(同一作用域中的两个组,而不是另一个组中的组)解析器失败。我也不知道为什么。
发布于 2013-02-20 06:38:02
为了便于将来参考,您的代码看起来像是Boost教程中的mini_xml2.cpp的简化版本(也称为“无耻被盗的代码”)。
要使您的示例工作,您必须更改行:
start_tag = +(char_ -'{') >> '{';至
start_tag = +(char_ -'{' - '}') >> '{';
现在已经不言自明了:)每当解析器解析start_tag时,它都会开始查找nodes (因为>> *node部分)。因为}是一个合法的start_tag,所以它可能被认为是合法的,而不应该被识别。
顺便说一句,你可以考虑修复代码中的一些冗余。例如:
在最初的mini_xml2.cpp示例中,end_tag用作一个函数,用于检查您关闭的标记是否与打开的标记相同(因此称为签名void(std::string))。你最好带上
cfg %= start_tag[_a = _1]
>> *node
>> "}";mini_xml2.cpp示例中的节点是多态的,所以boost::variant与访问者一起使用。在您的示例中,这也是多余的。老实说,这让我想知道这条线
node = cfg因为node有一个boost::variant类型,所以在编译过程中没有引起任何问题。仅供参考,在原始示例中,该行为:
node %= xml | text;而且%=操作符正确地“猜测”了RHS的类型,因为|操作符将结果读取为boost::variant。
https://stackoverflow.com/questions/14966538
复制相似问题