我的情况:我刚接触“精神”,我必须使用VC6,因此我使用“精神”1.6.4。
我有一行代码,如下所示:
//The Description;DESCRIPTION;;如果行以//The Description;开头,我希望将文本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)我怎么才能让它成功呢?
发布于 2009-01-21 22:43:25
您可以尝试使用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风格的注释,但这并不是必需的。
为了让你的代码工作,精神将需要认识到贪婪的print_p匹配太多,然后回溯到允许更少的匹配。但是,尽管Spirit会回溯,但它不会回溯到子解析器贪婪匹配的“中间”。它将回溯到下一个“选择点”,但您的语法没有任何选择点。请参见精神文档中的。
发布于 2009-01-21 22:30:05
你得不到匹配,因为print_p匹配了';‘。请尝试以下操作:
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+(print_p-';'))[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)https://stackoverflow.com/questions/466802
复制相似问题