gpt4 book ai didi

c++ - boost::spirit 和语法

转载 作者:行者123 更新时间:2023-11-28 03:22:55 26 4
gpt4 key购买 nike

我试图用 Boost::Spirit 简单地解析这个 xml-minded 结构,

One{
Two{
Three{
}
}
}

代码组织如下:

结构定义以保持 spirit 的东西:

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{
}
}

(同一范围内的两个组,而不是其他组内的组)解析器失败。我不知道为什么。

最佳答案

为了将来引用,您的代码似乎是 mini_xml2.cpp 的简化版本来自 Boost 的教程(又名“无耻地偷来的”)。

要使您的示例工作,您必须更改行:

start_tag =  +(char_ -'{') >> '{';

start_tag = +(char_ -'{' - '}') >> '{';

现在很明显了:)每当解析器解析一个start_tag时,它就会开始寻找node(因为>> *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.

关于c++ - boost::spirit 和语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14966538/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com