我的情况:我是Spirit的新手,我必须使用VC6,因此使用Spirit 1.6.4。
我有一行看起来像这样:
//The Description;DESCRIPTION;;
如果该行以DESCRIPTION
开头,我想将文字//The Description;
放在字符串中。
我有一些有效但看起来不那么优雅的东西:
vector<char> vDescription; // std::string doesn't work due to missing ::clear() in VC6's STL implementation
if(parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+~ch_p(';'))[assign(vDescription)]
),
// End grammar
space_p).hit)
{
const string desc(vDescription.begin(), vDescription.end());
}
我更希望将所有可打印的字符分配到下一个';'
,但以下内容无效,因为parse(...).hit == false
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+print_p)[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)
如何击中它?
答案 0 :(得分:3)
你没有受到打击,因为';'与print_p匹配。试试这个:
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+(print_p-';'))[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)
答案 1 :(得分:3)
您可以尝试使用confix_p
:
confix_p(as_lower_d["//the description;"],
(+print_p)[assign(vDescription)],
ch_p(';')
)
它应该等同于Fred's response。
您的代码失败的原因是因为print_p
贪婪。 +print_p
解析器将消耗字符,直到遇到输入的结尾或不可打印的字符。分号是可打印的,所以print_p
声称它。您的输入已耗尽,变量已分配,匹配失败 - 您的解析器的最后一个分号无法匹配。
Fred的答案构造了一个新的解析器(print_p - ';')
,它匹配print_p
所做的所有内容,但分号除外。 “匹配除 X 之外的所有内容,然后匹配 X ”是一种常见模式,因此提供confix_p
作为构造该类解析器的快捷方式。文档建议使用它来解析C或Pascal风格的注释,但这不是必需的。
为了使您的代码正常工作,Spirit需要认识到贪婪的print_p
匹配太多,然后回溯以允许匹配更少。但是,虽然Spirit会回溯,但它不会回溯到子解析器本来会贪婪匹配的“中间”。它将回溯到下一个“选择点”,但你的语法没有。请参阅Spirit文档中的Exhaustive backtracking and greedy RD。