【问题标题】:Parsing with Boost::Spirit (V2.4) into container使用 Boost::Spirit (V2.4) 解析到容器中
【发布时间】:2010-10-12 08:11:41
【问题描述】:

我刚刚开始深入研究 Boost::Spirit,目前的最新版本——V2.4。 我的问题的本质如下:

我想解析像“1a2”“3b4”这样的字符串。 所以我使用的规则是:

  (double_ >> lit('b') >> double_)
| (double_ >> lit('a') >> double_);

规则的属性必须是“vector ”。我正在将它读入容器中。

完整代码:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>

int main(int argc, char * argv[])
{
    using namespace std;
    using namespace boost::spirit;
    using namespace boost::spirit::qi;
    using boost::phoenix::arg_names::arg1;

    char const * first = "1a2";
    char const * last  = first + std::strlen(first);
    vector<double> h;

    rule<char const *, vector<double>()> or_test;
    or_test %=    (double_ >> lit('b') >> double_) 
            | (double_ >> lit('a') >> double_);

    if (parse(first, last, or_test,h)) {
           cout << "parse success: "; 
           for_each(h.begin(), h.end(), (cout << arg1 << " "));
           cout << "end\n";
    } else cout << "parse error\n" << endl;
    return 0;
 }

我正在用 g++ 4.4.3 编译它。它返回“1 1 2”。虽然我期待“1 ​​2”。

据我了解,这是因为解析器:

  • 转到第一个备选方案
  • 读取一个 double_ 并将其存储在容器中
  • 然后在“a”处停止,同时期待 lit(“b”)
  • 进入第二个备选方案
  • 再读两个双打

我的问题是——这是一个正确的行为吗?如果是——为什么?

【问题讨论】:

    标签: stl boost-spirit


    【解决方案1】:

    这是预期的行为。在回溯期间,Spirit 不会“取消”对属性的更改。因此,您应该使用hold[] 指令显式强制解析器保留属性的副本(允许回滚任何属性更改):

    or_test =    
            hold[double_ >> lit('b') >> double_)]
        |   (double_ >> lit('a') >> double_)
        ; 
    

    该指令需要应用于所有修改属性的替代方案,除了最后一个。

    【讨论】:

    • 感谢您的回答。对不起,愚蠢的问题 - 但我真的仔细阅读了文档,并没有发现任何关于这样的事情。我可以要求跟进 - 有没有更好的方法来做同样/类似的事情?
    • 这是您能做的最好的事情,我认为没有理由采取不同的做法。由于hold[] 是显式的,因此您可以完全控制引发的开销,从而将其最小化。
    猜你喜欢
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 2012-01-17
    • 2015-01-25
    • 1970-01-01
    相关资源
    最近更新 更多