我有以下ABNF语法:
zero = ["0"] "0"我希望它与字符串0和00匹配,但它似乎只与00匹配?为什么?
repl-it演示:https://repl.it/@DanStevens/abnf-rule-zero-0-0-matches-00-but-not-0
发布于 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将失败。特别是,重复的规则:
repetition = [repeat] element
repeat = 1*DIGIT / (*DIGIT "*" *DIGIT)无法匹配7*"0",因为7将由repeat的第一个替代项匹配,该替代项将被接受为满足repetition中的可选[repeat],并且element随后将失败。
事实上,这个例子(或类似的例子)是作为一个erratum in RFC 5234报告给IETF的,这个勘误表被认为是不必要的,因为验证者认为应该产生正确的解析,从而提供了官方观点是ABNF不是PEG的变体的证据。显然,APG解析器生成器的作者并不认同这种观点(他似乎也没有记录他们的解释)。建议的勘误表选择了与您提出的大致相同的解决方案:
repeat = *DIGIT ["*" *DIGIT]虽然从严格意义上讲这不是相同的;原始repeat不能匹配空字符串,但替换的can可以。(因为repeat在语法中的唯一用法是可选的,所以这没有任何实际的区别。)
(披露说明:我不是PEG的粉丝。因此,上面的答案可能并不是没有偏见。)
https://stackoverflow.com/questions/56706950
复制相似问题