我应该如何修改语法以允许不回溯的可选表达式
How should I modify the grammar to allow optional expression without backtracking
这是一个简单的语法:
filling = fill? align
fill = .
align = [<>=^]
它应该匹配以下内容:
<
0<
<<
然而,PEG.js不允许回溯,fill
只是消耗了<
字符:
< (does not work)
0< (works)
<< (works)
我应该如何修改语法以使其工作?
PEG.js doesn't allow backtracking
这不完全正确。以下代码可以按您的意愿工作:
filling = fill align / align
这个有效而带有 ?
的版本无效的原因是回溯仅在单个规则中的备选方案上执行。也就是说,如果一个备选方案失败,解析器将回溯并尝试下一个备选方案,直到备选方案匹配或所有备选方案都用尽。解析器没有做的是在已经成功的子规则中尝试其他替代方案。所以在fill? align
中,如果fill?
通过匹配<
成功,当align
之后不匹配时,它不会尝试匹配空字符串的替代方案。但在 fail align / align
中,如果 fail align
因 align
失败而失败,它会尝试下一个替代方案,然后成功。
此行为意味着您通常可以通过内联子规则或在本例中使用 "inlining" 运算符(如 ?
.
)来实现回溯
这是一个简单的语法:
filling = fill? align
fill = .
align = [<>=^]
它应该匹配以下内容:
<
0<
<<
然而,PEG.js不允许回溯,fill
只是消耗了<
字符:
< (does not work)
0< (works)
<< (works)
我应该如何修改语法以使其工作?
PEG.js doesn't allow backtracking
这不完全正确。以下代码可以按您的意愿工作:
filling = fill align / align
这个有效而带有 ?
的版本无效的原因是回溯仅在单个规则中的备选方案上执行。也就是说,如果一个备选方案失败,解析器将回溯并尝试下一个备选方案,直到备选方案匹配或所有备选方案都用尽。解析器没有做的是在已经成功的子规则中尝试其他替代方案。所以在fill? align
中,如果fill?
通过匹配<
成功,当align
之后不匹配时,它不会尝试匹配空字符串的替代方案。但在 fail align / align
中,如果 fail align
因 align
失败而失败,它会尝试下一个替代方案,然后成功。
此行为意味着您通常可以通过内联子规则或在本例中使用 "inlining" 运算符(如 ?
.