[英]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.