如何处理 BNF 中的大字母表?

How to deal with large alphabets in BNF?

给定一种语言定义为:

Any pair of matching symbols is a valid string.

E.g. 00, 55, qq, YY

还有一大堆非终结符符号(比方说 4,294,967,296 个)...

您将如何定义 BNF 文法来表达语言? (上下文相关或其他。)


我特别想知道是否有一种方法可以在不编写 4,294,967,296 规则的情况下做到这一点:即一个如此庞大的语法,它失去了用 BNF 定义的所有好处,因为它已经成为一组“强力”有效文字。


BNF 的大部分用途是描述 context-free 语法。

对于非context-free 文法,您当然可以使用 BNF 表示法;您需要做的就是在 left-hand 一侧放置多个终端。然而,这在实践中通常不是很有用,因为非 context-free 语法不提供对所解析语言结构的直观描述,也不会导致解析语言的算法。人们会期望任何实用的语法形式主义要么给人类 readers 一个很好的描述,要么允许自动生成解析器,或者两者兼而有之。 (这不会使非 context-free 语法在语言的形式分析中变得无用;在数学理论中,没有必要取悦 reader 或解析器生成器。)

但是如果我们限制自己使用context-free文法,我们马上就会遇到障碍,因为context-free文法不能表达重复,例如{ωω| ω∈Σ*}。根据定义,重复几乎不是 context-free,因为 context-free 意味着 non-terminal 的扩展不能依赖于 non-terminal 出现的上下文。因此,表示重复的规则“this non-terminal must have the same expansion as that non-terminal”,不能是 context-free.

当然,语言{ ωω | ω∈Σ},这就是你要描述的,context-free,但那只是因为可以枚举所有的可能性(必须是有限数,因为我们坚持认为字母表 Σ 是一个有限集)。

那你会怎样呢?

基本上,您可以自由发明适合您目的的任何形式,只要您明确定义其对 reader 的含义即可。这种形式主义可能会也可能不会导致自动解析器生成的可能性,但如果这不是您的目标,那么这个事实是无关紧要的。大多数 EBNF 方言 - 其中有很多,实际上 none 实际上可以在没有帮助的情况下生成解析器 - 允许以某种方式嵌入用自然语言编写的描述,用于难以或无法描述的语法context-free 语法。如果您查看 EBNF 示例,您可能会发现一大堆不同的说法“是字符集的任何元素”,而没有真正详尽地列出整个字符集,考虑到 Unicode 的存在,这将是一项荒谬的任务。 (虽然Unicode只有17*216个codepoints,比232少了很多。但还是超过一百万。)