3

我的情况:我是 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)

我如何让它击中?

4

2 回答 2

3

你没有受到打击,因为';' 由 print_p 匹配。试试这个:

parse(chars,
    // Begin grammar
    (
       as_lower_d["//the description;"]
    >> (+(print_p-';'))[assign(vDescription)]
    >> ';'
    ),
    // End grammar
    space_p).hit)
于 2009-01-21T22:30:05.320 回答
3

您可以尝试使用confix_p

confix_p(as_lower_d["//the description;"],
         (+print_p)[assign(vDescription)],
         ch_p(';')
        )

它应该等同于Fred 的响应

您的代码失败的原因是print_p因为greedy。解析器将+print_p使用字符,直到遇到输入的结尾或不可打印的字符。分号是可打印的,所以print_p声称它。您的输入已用尽,变量已分配,匹配失败 - 解析器的最后一个分号无法匹配。

Fred 的回答构造了一个新的解析器 ,(print_p - ';')它匹配print_p除了分号之外的所有内容。“匹配除X之外的所有内容,然后匹配X ”是一种常见模式,因此confix_p被提供为构建这种解析器的快捷方式。文档建议使用它来解析 C 或 Pascal 样式的注释,但这不是必需的。

为了使您的代码正常工作,Spirit 需要识别贪婪print_p匹配太多,然后回溯以允许匹配更少。但是尽管 Spirit 会回溯,但它不会回溯到子解析器贪婪匹配的“中间”。它会回溯到下一个“选择点”,但你的语法没有。请参阅Spirit 文档中的详尽回溯和贪婪 RD

于 2009-01-21T22:43:25.310 回答