好的,假设我们得到了以下using 和别名命名空间指令:
using namespace boost::spirit::qi;
namespace phx = boost::phoenix;
并给出字符串:
std::string strLinesRecur = "%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)";
我们想将括号内的“代码”提取成res:
std::string res;
一种方法是使用boost::phoenix::ref 作为语义操作。
所以给定一个代码语法为:
using boost::spirit::ascii::alnum;
auto code = copy(+(alnum | char_('-')));
(这与正则表达式中的 [a-zA-Z\-] 类似)
我们可以为整个字符串创建自己的语法:
using boost::spirit::ascii::alpha;
auto grammar = copy(
(char_('%') >> char_('%') >> +alpha >> char_(':'))
>> +alpha >> char_('(') >> as_string[lexeme[code]][phx::ref(res) = _1] >> char_(')'));
它会解析以两个% 开头的任何内容,后跟一些字母字符和一个:,然后是括号内的一些“代码”。
这一点的重点是as_string[lexeme[code]][phx::ref(res) = _1]。如果我们将其分解:lexeme[code] 只是说将解析的code 视为一个原子单元,as_string“返回”结果为std::string(而不是std::vector<char>)和[phx::ref(res) = _1] 使用语义动作将解析后的字符串存储到res(_1 是该语法中第一个匹配的占位符)。
在这种情况下,以下调用会跳过空格:
using boost::spirit::ascii::blank;
phrase_parse(begin(strLinesRecur), end(strLinesRecur), grammar, blank);
Live demo
这当然只是适合字符串的语法示例。
注意:copy 指的是qi::copy,这是一种能够像在对象code 和grammar 中存储语法片段的方法。否则,auto 的使用将失败(可能存在分段错误)。