Boost Spirit X3 phrase_parse中std::string存入variant退化为char的问题
问题:Boost Spirit X3中解析结果存入Variant时std::string退化为char的原因及资料查询
1. 定义的literal_string规则
我定义了返回类型为std::string的literal_string规则:
namespace parsesss { namespace x3 = boost::spirit::x3; auto const literal_string = x3::rule<class literal_string,std::string>{"literal_string"}; auto const literal_string_def = x3::lexeme['"' >> +(x3::char_ - '"') >> '"']; BOOST_SPIRIT_DEFINE(literal_string); }
2. 存入std::vector<std::string>时解析正常
测试将解析结果存入std::vector<std::string>时,结果符合预期:
std::string test = "\"asdfjalsdjflajsdlfjalsdf\" \"xxxxxxxxxxasdfjalsdjflajsdlfjalsdf\""; std::vector<std::string> out; bool r = parse::x3::phrase_parse(test.begin(), test.end(), *(parsesss::literal_string), parse::x3::ascii::space, out); if(r && (parse::g_iter == parse::g_end)){ std::cout << "parse success!" << std::endl; }else{ std::cerr << "parse fail!" << std::endl; }
3. 使用Variant存储时出现std::string退化为char的问题
但当使用如下variant数据结构存储解析结果时,std::string却退化为char:
struct constant : x3::variant<long,char,double,float,int>{ using base_type::base_type; using base_type::operator=; }; struct last : x3::variant<std::string,char,constant>{ using base_type::base_type; using base_type::operator=; }; // 测试代码 std::string test = "\"asdfjalsdjflajsdlfjalsdf\" \"xxxxxxxxxxasdfjalsdjflajsdlfjalsdf\""; std::vector<last> out; bool r = parse::x3::phrase_parse(test.begin(), test.end(), *(parsesss::literal_string), parse::x3::ascii::space, out); if(r && (parse::g_iter == parse::g_end)){ std::cout << "parse success!" << std::endl; }else{ std::cerr << "parse fail!" << std::endl; }
原因分析
问题出在Boost Spirit X3的属性转换机制:当解析得到的std::string要赋值给包含char类型的variant时,存在类型匹配歧义。std::string作为字符序列,Spirit会尝试将其分解为单个字符,匹配variant中的char类型,而非将整个字符串匹配到std::string类型,最终导致解析出的完整字符串被截断为单个char存入variant。
解决方法
- 明确指定属性类型:在解析规则中强制将结果转换为
std::string,确保variant匹配正确的类型,修改解析表达式为:*(x3::as<std::string>(parsesss::literal_string)) - 调整Variant类型定义:如果业务允许,移除
variant中的char类型;或把char包装到独立结构体中,避免与std::string的转换歧义。
官方资料查询位置
在Boost Spirit X3官方文档中,可以重点查看以下内容:
- **Attribute Handling(属性处理)**章节:了解规则与目标类型之间的属性传递逻辑,尤其是Variant类型的属性适配
- **Transformations and Adaptations(转换与适配)**章节:学习如何自定义属性转换,避免类型匹配歧义
- Variant相关文档:详细了解Variant作为解析结果容器时的行为规范
内容的提问来源于stack exchange,提问作者luohe
相关产品推荐
相关产品推荐

