使用Boost :: Spirit(V2.4)解析到容器中 [英] Parsing with Boost::Spirit (V2.4) into container

查看:86
本文介绍了使用Boost :: Spirit(V2.4)解析到容器中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始研究Boost :: Spirit,目前是最新版本-V2.4. 我的问题的实质是:

I just started to dig into Boost::Spirit, latest version by now -- V2.4. The essense of my problem is following:

我想解析"1a2" "3b4"之类的字符串. 因此,我使用的规则是:

I would like to parse strings like "1a2" or "3b4". So the rule I use is:

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

规则的属性必须为"vector< double>".我正在将其读取到容器中.

The attribute of the rule must be "vector <double>". And I'm reading it into the container.

完整代码:

#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".

I'm compiling it with g++ 4.4.3. And it returns "1 1 2". While I expect "1 2".

据我了解,发生这种情况是因为解析器:

As far as I understand this happens because parser:

  • 转到第一个替代方案
  • 读取double_并将其存储在容器中
  • 然后停在"a",而期待lit("b")
  • 转到第二种选择
  • 再读两个双打

我的问题是-这是正确的行为吗?如果是,为什么?

My question is -- Is this a correct behavior, and if yes -- why?

推荐答案

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

That's expected behavior. During backtracking Spirit does not 'unmake' changes to attributes. Therefore, you should use the hold[] directive explicitly forcing the parser to hold on to a copy of the attribute (allowing to roll back any attribute change):

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

此指令需要应用于所有修改属性的替代方法,最后一个除外.

This directive needs to be applied to all alternatives modifying the attribute, except the last one.

这篇关于使用Boost :: Spirit(V2.4)解析到容器中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆