[英]ABNF rule `zero = [“0”] “0”` matches `00` but not `0`
我有以下ABNF语法:
zero = ["0"] "0"
我希望它能匹配字符串0
和00
,但似乎只匹配00
? 为什么?
repl-it演示: https : //repl.it/@DanStevens/abnf-rule-zero-0-0-matches-00-but-not-0
好问题。
ABNF(“增强Backus Naur格式” 9由RFC 5234定义, RFC 5234是文档的当前版本,旨在阐明许多RFC使用(带有变体)的表示法。
不幸的是,尽管RFC 5234详尽地描述了ABNF的语法 ,但它并没有以清晰的语义声明的方式提供太多帮助。 特别是,它没有指定ABNF替换是无序的(如BNF的正式语言定义中)还是有序的(如“ PEG”中的-解析表达式语法 -表示法)。 请注意,选择性/重复仅仅是交替的类型,因此,如果您选择一种约定进行交替,则很可能也会为选择性和重复选择它。
在这种情况下,差异非常重要。 如果命令了交替,那么解析器将不会备份以在某些替代方法成功后尝试其他替代方法。 在可选性方面,这意味着如果流中存在可选元素,则即使某些后续元素无法匹配 ,解析器也不会重新考虑接受可选元素的决定。 如果您采用这种观点,那么交替不会在串联中分布。 ["0"]"0"
恰好是("0"/"")"0"
,与"00"/"0"
。 后一个表达式将匹配单个0
因为第二个替代项将在第一个替代项失败后尝试。 您使用的前一个表达式不会。
我不认为RFC 5234的作者会采用这种观点,尽管如果他们在文档中做出明确的决定会更有帮助。 我唯一支持我的信念的真实证据是,如果认为重复是有序的,则RFC 5234中包含的用于描述ABNF本身的ABNF将会失败。 特别是重复的规则:
repetition = [repeat] element
repeat = 1*DIGIT / (*DIGIT "*" *DIGIT)
所无法比拟的7*"0"
,由于7
将通过的第一替代匹配repeat
,这将被接受为满足可选[repeat]
在repetition
,和element
将随后会失败。
实际上,此示例(或与之类似的示例) 在RFC 5234中已作为错误报告给IETF,并且该错误被认为是不必要的,因为验证者认为应该进行正确的解析,从而为官方提供了证据。有观点认为ABNF不是PEG的变体。 显然,APG解析器生成器的作者(也不似乎也没有记录其解释)的作者并不认同这种观点。建议的勘误选择了与您想到的大致相同的解决方案:
repeat = *DIGIT ["*" *DIGIT]
尽管严格说来并不一样; 原始repeat
不能匹配空字符串,但是替换可以。 (由于语法中repeat
的唯一使用是可选的,因此这没有任何实际区别。)
(请注意:我不是PEG的拥护者。因此上述答案可能并非毫无偏见。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.