[英]Boost Spirit optional parser and backtracking
为什么即使没有匹配选项,此解析器也会在属性中保留'b'
呢?
using namespace boost::spirit::qi;
std::string str = "abc";
auto a = char_("a");
auto b = char_("b");
qi::rule<std::string::iterator, std::string()> expr;
expr = +a >> -(b >> +a);
std::string res;
bool r = qi::parse(
str.begin(),
str.end(),
expr >> lit("bc"),
res
);
它解析成功,但是res是"ab"
。
如果"abac"
expr解析"abac"
,则选项匹配并且属性为"aba"
。
与"aac"
相同,选项未开始匹配并且属性为"aa"
。
但是使用"ab"
,即使b被回溯,并且例如与下一个解析器匹配,属性还是"ab"
。
UPD
使用expr.name("expr");
和debug(expr);
我有
<expr>
<try>abc</try>
<success>bc</success>
<attributes>[[a, b]]</attributes>
</expr>
首先,使用auto
变量保留表达式模板是UB ,因为它们保存对临时变量"a"
和"b"
引用[1] 。
改写
expr = +qi::char_("a") >> -(qi::char_("b") >> +qi::char_("a"));
或者,如果您坚持:
auto a = boost::proto::deep_copy(qi::char_("a"));
auto b = boost::proto::deep_copy(qi::char_("b"));
expr = +a >> -(b >> +a);
现在注意到在parse
调用中隐藏了>> lit("bc")
部分,建议您可能希望在解析失败发生时回溯到成功匹配的令牌。
那没有发生:Spirit生成PEG语法,并且总是从左到右贪婪地匹配。
在给定的样本上,即使确实发生了回溯, ab
结果也不会消失,如果没有qi::hold
则不会回滚对属性的影响: Live On Coliru
容器属性由ref传递,并且以前的(成功的)表达式的效果不会回滚,除非您也告诉Spirit。 这样,您可以“为所用内容付费”(因为一直复制临时文件会很昂贵)。
见例如
<a>
<try>abc</try>
<success>bc</success>
<attributes>[a]</attributes>
</a>
<a>
<try>bc</try>
<fail/>
</a>
<b>
<try>bc</try>
<success>c</success>
<attributes>[b]</attributes>
</b>
<a>
<try>c</try>
<fail/>
</a>
<bc>
<try>bc</try>
<success></success>
<attributes>[]</attributes>
</bc>
Success: 'ab'
[1]看到这里:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.