使用Boost :: Spirit(V2.4)解析到容器中 [英] Parsing with Boost::Spirit (V2.4) into container
问题描述
我刚刚开始研究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屋!