以下语法(来自RFC 2396):
domainlabel = 'a' / ('a' ('a' / '-')* 'a')
无法解析:
aa
为什么?
答案 0 :(得分:1)
因为PEG不是BNF。使用 / 而不是通常的BNF交替运算符 | (如RFC 2396中所见)是故意避免混淆的尝试(尽管它对旧标准没有帮助)例如RFC 822也使用 / )。
在PEG中, / 是"ordered-choice" operator。与BNF交替运算符不同, / 不对称。如果第一个替代方案成功,则接受。只有当第一种选择失败时,PEG才会回溯并尝试第二种选择。
因此当'a' / ('a' ('a' / '-')* 'a')
应用于aa
时,第一个替代方案会成功吸收第一个 a ,并且永远不会尝试第二个替代方案。解析随后无法匹配整个字符串的事实并不重要; / 只有在匹配第一个备选本身失败时才会回溯,而不是在解析的某些后续部分失败时。
简而言之,如果您使用PEG,则需要小心以正确的顺序编写替换。