从Spirit X3开始
Starting with Spirit X3
我刚开始使用 Spirit X3,我有一个与第一次测试相关的小问题。你知道为什么这个函数返回 "false" 吗?
bool parse()
{
std::string rc = "a 6 literal 8";
auto iter_begin = rc.begin();
auto iter_end = rc.end();
bool bOK= phrase_parse( iter_begin, iter_end,
// ----- start parser -----
alpha >> *alnum >> "literal" >> *alnum
// ----- end parser -----
, space);
return bOK && iter_begin == iter_end;
}
我发现问题与我如何编写语法有关。如果我用这个替换它,它 returns "true"
alpha >> -alnum >> "literal" >> *alnum
我正在使用 Boost 1.61.0 中包含的 Spirit 版本。
提前致谢,
森
您的问题是操作员 *
的贪婪和船长的使用的结合。你需要记住 alnum
是一个 PrimitiveParser
这意味着在每次尝试这个解析器之前,Spirit 都会预先跳过,所以你的解析器的行为是:
alpha
解析 a
.
- kleene 运算符启动。
alnum
跳过 space 然后解析 6
.
alnum
跳过 space 然后解析 l
.
alnum
解析 i
.
- ...
alnum
解析 l
.
alnum
跳过 space 然后解析 8
.
alnum
尝试并未能解析更多。这完成了 kleene 运算符,其解析属性为 6literal8
.
"literal"
尝试解析但失败。
- 序列运算符失败,调用
phrase_parse
returns false
.
您可以使用 lexeme
指令轻松避免此问题(barebones x3 docs, qi docs). Something like this 应该有效:
alpha >> lexeme[*alnum] >> "literal" >> lexeme[*alnum];
我刚开始使用 Spirit X3,我有一个与第一次测试相关的小问题。你知道为什么这个函数返回 "false" 吗?
bool parse()
{
std::string rc = "a 6 literal 8";
auto iter_begin = rc.begin();
auto iter_end = rc.end();
bool bOK= phrase_parse( iter_begin, iter_end,
// ----- start parser -----
alpha >> *alnum >> "literal" >> *alnum
// ----- end parser -----
, space);
return bOK && iter_begin == iter_end;
}
我发现问题与我如何编写语法有关。如果我用这个替换它,它 returns "true"
alpha >> -alnum >> "literal" >> *alnum
我正在使用 Boost 1.61.0 中包含的 Spirit 版本。
提前致谢,
森
您的问题是操作员 *
的贪婪和船长的使用的结合。你需要记住 alnum
是一个 PrimitiveParser
这意味着在每次尝试这个解析器之前,Spirit 都会预先跳过,所以你的解析器的行为是:
alpha
解析a
.- kleene 运算符启动。
alnum
跳过 space 然后解析6
.alnum
跳过 space 然后解析l
.alnum
解析i
.- ...
alnum
解析l
.alnum
跳过 space 然后解析8
.alnum
尝试并未能解析更多。这完成了 kleene 运算符,其解析属性为6literal8
."literal"
尝试解析但失败。- 序列运算符失败,调用
phrase_parse
returnsfalse
.
您可以使用 lexeme
指令轻松避免此问题(barebones x3 docs, qi docs). Something like this 应该有效:
alpha >> lexeme[*alnum] >> "literal" >> lexeme[*alnum];