Boost Spirit X3回溯属性异常:输入"lal<char>"返回defaultchar求助
关于Boost Spirit X3语法匹配异常的困惑
我最近在用Boost Spirit X3写语法时遇到了一个摸不着头脑的问题,下面这段代码是从一个更大的语法里抽出来的简化示例。我原本想实现的逻辑类似(lal)?(<char>)?:当第二组(也就是<char>部分)不存在时,默认值设为default。但实际运行时,输入"lal<char>"得到的结果却是defaultchar,完全不符合预期。
先贴出我的代码:
#include <iostream> #include <boost/config/warning_disable.hpp> #include <boost/spirit/home/x3.hpp> #include <boost/fusion/adapted/std_pair.hpp> int main() { namespace x3 = boost::spirit::x3; namespace ascii = boost::spirit::x3::ascii; using ascii::alnum; using ascii::char_; using ascii::space; using x3::attr; using x3::eoi; using x3::lexeme; using x3::lit; using x3::string; const auto letter = lit("<") >> string("char") >> lit('>') | attr(std::string{"default"}) ; const auto letterset = letter >> eoi | lit("lal") >> letter >> eoi ; for (std::string i: {"", "<char>", "lal", "lal<char>"}) { auto res = std::string{}; auto first = i.cbegin(); auto last = i.cend(); auto r = x3::phrase_parse(first, last, letterset, space, res); if (r && first == last) std::cout << i << ": " << res << '\n'; else std::cout << i << ": failed\n"; } }
运行这段代码后得到的结果是:
: default <char>: char lal: defaultdefault lal<char>: defaultchar
我自己观察后发现,如果把letterset里的分支顺序调换一下(改成lit("lal") >> letter >> eoi | letter >> eoi),就能得到预期的结果。我猜测这应该和回溯有关——原来的逻辑里,第一次尝试匹配第一个分支letter >> eoi时,写入了default,之后回溯去匹配第二个分支lit("lal") >> letter >> eoi,成功匹配后又写入了char,最后这两个值就被拼接成了defaultchar。我有点怀疑这是不是个bug,但我刚接触X3,用的是Boost 1.65版本,希望能有人帮我解释清楚这个问题。
内容的提问来源于stack exchange,提问作者akim
相关产品推荐
相关产品推荐

