Boost Spirit X3解析字符转义时无法消费最后令牌问题求助
问题原因
你代码的核心问题是规则定义存在冗余和歧义,导致解析器回溯异常,最终无法匹配末尾的闭合双引号,所以返回false,但已匹配到的内容已经正确赋值到了result属性中。
具体问题如下:
- 存在冗余规则:你重复定义了
\\n的转义规则,还额外写了一条完全多余的转义双引号规则"\\\"" >> x3::char_('"'),这条规则和前面的"\\" >> x3::char_("\"\\")功能完全重叠,反而会导致解析器出现不必要的回溯。 - 可选优化:如果需要确保解析器消费完全部输入,需要在规则末尾加上
x3::eoi,否则只要前半部分匹配成功就会返回true,忽略末尾未消费的字符。
修改后完整代码
#include <boost/spirit/home/x3.hpp> #include <string> #include <iostream> namespace x3 = boost::spirit::x3; using namespace std::string_literals; auto const qstring = x3::lexeme['"' >> *( "\\n" >> x3::attr('\n') | "\\b" >> x3::attr('\b') | "\\f" >> x3::attr('\f') | "\\t" >> x3::attr('\t') | "\\v" >> x3::attr('\v') | "\\0" >> x3::attr('\0') | "\\r" >> x3::attr('\r') | "\\" >> x3::char_("\"\\") | ~x3::char_('"') ) >> '"']; int main(int, char**){ auto const quoted = "\"Hel\\\"lo Wor\\\"ld\""s; auto const expected = "Hel\"lo Wor\"ld"s; std::string result; auto first = quoted.begin(); auto const last = quoted.end(); // 加x3::eoi确保消费完全部输入 bool ok = x3::phrase_parse(first, last, qstring >> x3::eoi, x3::ascii::space, result); std::cout << "parse returned " << std::boolalpha << ok << '\n'; std::cout << result << " == " << expected << " is " << std::boolalpha << (result == expected) << '\n'; std::cout << "first == last = " << (first == last) << '\n'; if (first != last) { std::cout << "first = " << *first << '\n'; } return 0; }
运行结果
parse returned true Hel"lo Wor"ld == Hel"lo Wor"ld is true first == last = true
内容的提问来源于stack exchange,提问作者Jellybaby
相关产品推荐
相关产品推荐

