我将literal_string的输出定义为std::字符串:
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);
}
然后我用下面的代码进行了测试,结果也符合预期:
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;
}
但是当我使用变量数据结构来存储输出时,std::字符串退化为字符,这是为什么?
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;
}
谁能告诉我为什么
或者在官方网站上哪里可以找到关于这方面的更详细的问题。
1条答案
按热度按时间voj3qocg1#
变量属性可以从
char
构造,这是首选。如果从变量元素类型列表中删除
char
,它将工作:Live On Coliru
指纹
尝试次数
我试着用traits来暗示属性系统:
但是,不出所料,这并没有奏效。
工作环境
你可以做的是破坏“char”的兼容性:
这已经工作了(live)。你可以在这里做得更短:(live)
然而,我注意到,当您确实想解析字符字面量时,这些只会给您给予其他麻烦.
解决方案
所以,我把飞行向前,并制定了一些规则来匹配所有的AST节点。
根据经验,明确属性一致性是有帮助的。例如,
constant
的“naive”表达式将不起作用:原因有两个:
double_
将急切地消耗整数。我们通过替换strict_real_policies
来避免这个问题。x3::int_
与double
或intmax_t
兼容。现在,将有一个x3
numeric parser,如x3::long_long
,它恰好与intmax_t
匹配,但最好是精确的Live On Coliru
印刷