【问题标题】:Sequential Or parser a || b顺序或解析器 a || b
【发布时间】:2014-09-26 18:50:33
【问题描述】:

我无法正确输出 boost 文档中提供的示例的修改版本

这是关于顺序 OR 解析器的文档: http://www.boost.org/doc/libs/1_56_0/libs/spirit/doc/html/spirit/qi/reference/operator/sequential_or.html

test_parser("123.456", int_ || ('.' >> int_));  // full

我希望这个表达式用 2 个条目填充 vector<int>

[0] = 123
[1] = 456

为什么这不起作用?

string input("123.456");
vector<int> output;

string::iterator i = input.begin();

parse(i, input.end(), int_ || ('.' >> int_), output);

我已验证解析返回 truei == input.end()。我还尝试了不同的输出数据结构,包括带有选项的元组和选项向量。而且它们都生成一个仅包含 123 个,而不是 456 个的条目。

【问题讨论】:

  • @Yakk “而且它们都产生一个只包含 123 的条目,而不是 456。”对我来说似乎很清楚。
  • 如果我正确阅读了文档,parse 不会输出到向量,而是输出到各个可变参数。由于您只有一个输出参数,因此您只能得到一个结果。
  • Mark Ransom 是对的。提供两个整数确实会输出 123 和 456。一个 std::pair 整数也可以。然而,一个元组、optional> 和一个可选向量只能产生 123。不过我还是想知道为什么。
  • @Jimbobot 这是因为属性兼容性规则/启发式的限制。这就是Spirit可以变得非常神奇的地方。不过,随着时间的推移,您会对此有所了解。

标签: c++ boost boost-spirit boost-spirit-qi


【解决方案1】:

||解析器将解析为tuple&lt;optional&lt;A&gt;, optional&lt;B&gt; &gt;(对于乐观场景)。这永远不会与您的容器属性兼容。

不过,看起来你可以使用

parse(i, input.end(), -int_ >> -('.' >> int_), output);

也就是说……如果我是偷偷摸摸的 Clippy,我可能会说“看起来你正在尝试解析实数。

考虑float_double_ 或基础real_parser,可能还有自定义策略。另见:

【讨论】:

  • ||是一个顺序或解析器。去阅读我提供的链接中的文档。
  • 糟糕。我想我应该知道文档。但是,您有一点我掩盖了您使用 || 而不是 | 的事实。
  • 更新了我的答案。我还添加了一个答案的链接,其中我谈到了根据您的需要解析混合整数/双精度数。
  • 啊。那样。 A. 你混淆了 Fusion tuples 和 Boost Tuple 吗?在那种情况下,#include &lt;boost/fusion/adapted/boost_tuple.hpp&gt; 可以解决您的问题。 B. 要了解它的实际工作原理,您最好阅读源代码,因为文档没有雄心详细解释属性转换和兼容性规则的各种权衡和干扰。
  • @Jimbobot 我有时间来演示我对使用 tuple&lt;int,int 和 Fusion 适配的含义:Live On Coliru
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 2022-01-08
  • 1970-01-01
  • 2019-11-25
相关资源
最近更新 更多