C++ Boost Spirit X3:如何恢复规则的匹配和不匹配结果
考虑以下示例文本行: “你好:世界2020:tag1:tag2:tag3” 我想设计一个spirit X3解析器,它可以提取:C++ Boost Spirit X3:如何恢复规则的匹配和不匹配结果,c++,c++14,boost-spirit-x3,C++,C++14,Boost Spirit X3,考虑以下示例文本行: “你好:世界2020:tag1:tag2:tag3” 我想设计一个spirit X3解析器,它可以提取: 内容:=“你好:世界2020” 标记:={tag1,tag2,tag3} 问题:内容在匹配标记后被定义为剩余字符序列(不包括eol),我不知道如何编写一个规则来合成两个属性:一个表示提取的标记,另一个表示剩余字符(内容) 到目前为止,我已经编写了提取标记的规则: 。。。 名称空间ast{ 结构样本{ std::u32string内容; std::向量标签; }; //推
。。。
名称空间ast{
结构样本{
std::u32string内容;
std::向量标签;
};
//推进核聚变。。。。。
}
名称空间语法{
使用x3=boost::spirit::x3;
使用x3::unicode::lit;
使用x3::unicode::char\ux;
使用x3::unicode::alnum;
自动常数标签
=x3::规则{“标记”}
%=
照明(U):
>>
+(alnum|lit(U“)| lit(U@”)| lit(U“#”)lit(U“%”)
;
自动常量标记
=x3::规则>照明(U):”;
}
但被困在这里:
自动常量示例\u规则=
=x3::规则{“样本”}
= ?? // 类似于(+char|-(eol|tags);
我确信有一个非常优雅的解决方案。与此同时,一个混乱的解决方案:
#prgama一次
#包括
名称空间ast{
结构样本{
std::u32string内容;
std::向量标签;
};
}
样本h
\pgrama一次
#包括
#包括
#包括
#包括“样本水电站”
//标记属性被故意忽略。
//它将被合成
//手动使用语义操作
BOOST\u FUSION\u ADAPT\u STRUCT(ast::示例,内容)
名称空间语法{
名称空间详细信息{
使用x3=boost::spirit::x3;
使用x3::unicode::char\ux;
使用x3::eol;
使用x3::eoi;
使用x3::词素;
自动常数采样线
=x3::规则{“采样线”}
=词素[+(字符-(eol | eoi));
自动筛选标签=/*..为清晰起见,定义移到下一页*/
自动常量样本
=x3::规则{“样本”}
=%过滤器标签[采样线];
}}
名称空间语法{
使用语法::细节::示例;
}
筛选标签定义
从右到左迭代匹配的数据
冒号分隔标记,直到找到无效的标记字符
遇到或已耗尽所有字符。
pos_saved
用于跟踪开始
标记列表的一部分,用于丢弃标记
从内容中收集后放入ast
auto-filter_-tags=[](自动和上下文)
{
auto&attr=_attr(上下文);//内容字符串
auto&val=_val(上下文);//ast::sample
std::stack mem;
auto pos=attr.rbegin();
auto&const pos_end=attr.rend();
auto pos_saved=atrr.end();
做{
//标记开始或结束
如果(*pos==U':'){
if(mem.empty()){//tag start
记忆推送(U’:’);
}
else{//标记结束
//标记关闭状态:
//当前标记的所有字符
//准备转入
//ast。
std::u32string标签;
而(mem.top()!=':'){
//因为我们正在反向迭代数据
//标签不会倒着
tag.push_back(mem.top());
mem.pop();
}
val.tags.向后推(tag);
//更新的起始偏移量
//那个标签
pos_saved=pos.base();
}
}else{//是否标记字符
使用u=spirit::char\u编码::unicode;
如果(!mem.empty()){
if(u::isalnum(*pos))mem.push(*pos);//找到标记字符
else break;//找到无效的标记字符
}
否则{
//标记列表后但内容结束前的空格
如果(u::isspace(*pos)pos_saved=pos.base();
}
}
}而(++pos!=pos_end);
如果(pos_saved!=attr.end())attr.erase(pos_saved,attr.end());
if(attr.empty())\u pass(context)=false;
};
我确信有一个非常优雅的解决方案。与此同时,一个混乱的解决方案:
#prgama一次
#包括
名称空间ast{
结构样本{
std::u32string内容;
std::向量标签;
};
}
样本h
\pgrama一次
#包括
#包括
#包括
#包括“样本水电站”
//标记属性被故意忽略。
//它将被合成
//手动使用语义操作
BOOST\u FUSION\u ADAPT\u STRUCT(ast::示例,内容)
名称空间语法{
名称空间详细信息{
使用x3=boost::spirit::x3;
使用x3::unicode::char\ux;
使用x3::eol;
使用x3::eoi;
使用x3::词素;
自动常数采样线
=x3::规则{“采样线”}
=词素[+(字符-(eol | eoi));
自动筛选标签=/*..为清晰起见,定义移到下一页*/
自动常量样本
=x3::规则{“samp”