首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ABNF规则` `zero = ["0"] "0"`匹配`00`,但不匹配`0`

ABNF规则` `zero = ["0"] "0"`匹配`00`,但不匹配`0`
EN

Stack Overflow用户
提问于 2019-06-22 00:04:24
回答 1查看 139关注 0票数 0

我有以下ABNF语法:

代码语言:javascript
复制
zero = ["0"] "0"

我希望它与字符串000匹配,但它似乎只与00匹配?为什么?

repl-it演示:https://repl.it/@DanStevens/abnf-rule-zero-0-0-matches-00-but-not-0

EN

回答 1

Stack Overflow用户

发布于 2019-06-22 04:41:05

问得好。

ABNF ("Augmented Form"9 )是由RFC 5234定义的,它是一个文档的当前版本,旨在澄清许多RFC使用的符号(带有变体)。

不幸的是,虽然RFC5234详尽地描述了ABNF的语法,但它并没有提供多少清晰的语义陈述。特别是,它没有指定ABNF交替是无序的(就像在BNF的形式语言定义中一样)还是有序的(就像在"PEG" -- Parsing Expression Grammar --表示法中一样)。请注意,可选性/重复只是交替的类型,所以如果您选择一种约定进行交替,那么您很可能也会选择它作为可选性和重复。

在这样的情况下,区别很重要。如果交替是有序的,那么解析器将不会在某些替代成功后备份以尝试不同的替代。就可选性而言,这意味着如果流中存在可选元素,解析器将永远不会重新考虑接受可选元素的决定,即使后续元素无法匹配也是如此。如果您采用该视图,那么alternation不会分布在连接上。["0"]"0"就是("0"/"")"0",它不同于"00"/"0"。后一个表达式将匹配单个0,因为第二个替换将在第一个替换失败后尝试。您使用的前一个表达式将不会。

我不相信RFC5234的作者接受了这种观点,尽管如果他们在文档中明确地做出这个决定,那会更有帮助。我唯一支持我的信念的真实证据是,如果重复被认为是有序的,则RFC5234中包含的描述ABNF本身的ABNF将失败。特别是,重复的规则:

代码语言:javascript
复制
repetition     =  [repeat] element
repeat         =  1*DIGIT / (*DIGIT "*" *DIGIT)

无法匹配7*"0",因为7将由repeat的第一个替代项匹配,该替代项将被接受为满足repetition中的可选[repeat],并且element随后将失败。

事实上,这个例子(或类似的例子)是作为一个erratum in RFC 5234报告给IETF的,这个勘误表被认为是不必要的,因为验证者认为应该产生正确的解析,从而提供了官方观点是ABNF不是PEG的变体的证据。显然,APG解析器生成器的作者并不认同这种观点(他似乎也没有记录他们的解释)。建议的勘误表选择了与您提出的大致相同的解决方案:

代码语言:javascript
复制
repeat         =  *DIGIT ["*" *DIGIT]

虽然从严格意义上讲这不是相同的;原始repeat不能匹配空字符串,但替换的can可以。(因为repeat在语法中的唯一用法是可选的,所以这没有任何实际的区别。)

(披露说明:我不是PEG的粉丝。因此,上面的答案可能并不是没有偏见。)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56706950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档