我正在阅读polux的精彩parsers的来源,并发现有一个我无法理解的特殊isCommitted
属性:
class ParseResult<A> {
final bool isSuccess;
final bool isCommitted;
/// [:null:] if [:!isSuccess:]
final A value;
final String text;
final Position position;
final Expectations expectations;
// ...
}
您可以看到已经有isSuccess
表示解析结果是否成功,为什么我们需要isCommitted
?我试图阅读相关代码,但仍然不了解。
如果您想查看来源,可以找到它{。{3}}。
答案 0 :(得分:1)
简短的回答是:不要担心isCommited
,它只是出于内部目的。
答案很长:你可以在paser上拨打commited
,这意味着一旦成功,你肯定知道回溯是没有意义的(非常像Prolog&#39; s切)。例如,考虑这样的语法:
expr() => str('(') + rec(expr) str(')') ^ ...
| num()
假设我们解析字符串"(..."
。一旦我们识别出括号,我们就确定如果...
结果而不是成为一个expr,则无需回退到字符串的开头并尝试解析一个num,因为num永远不会以括号开头。我们可以早点失败。这是通过将(
标记为&#34;提交点&#34;:
expr() => str('(').commited + rec(expr) str(')') ^ ...
| num()
这是一个应该非常谨慎使用的优化,因为它打破了|
解析器的模块性。到目前为止,我个人从未使用它。
每当您在解析器上调用commited
时,它都会返回一个isCommited
属性为true的新解析器。然后|
使用它来决定是否回溯。这是isCommited
的用途。作为最终用户,您永远不必关心。我应该把它变成私人的。
此功能的灵感来自Polyparse's commit。