语法格式描述规范BNF、EBNF、ABNF

由于经常研究东西,所以经常涉及语法的定义;以前我都是按照我自己定义的一套语法格式描述规则来进行严谨地描述语法格式,但是我自己设计的这套语法格式描述规则并不通用,所以决定改为通用的语法格式描述规则--EBNF(扩展的巴科斯范式) 或 ABNF(增强型巴科斯范式),本文就详细讲讲 BNF、EBNF、ABNF 这三者之间的关系与区别;

1. 简介

  • BNF 是最原始,最简单的方法,主要用于理论背景的学术论文中,以与人类进行交流。(与在编译器/解析器中使用相反)。BNF 没有确切的规范。
  • EBNFExtended BNF (扩展的BNF)的缩写。没有一个标准的 EBNF,因为每个作者或程序都定义了自己的稍有不同的 EBNF 变体。
  • ABNFaugmented BNF(增强型BNF)的缩写,ABNF 的语法 与 BNF 完全不同,但是更加标准化,利于解析器的翻译,但不利于阅读;

BNFEBNFABNF 这三者的表达能力是等效的;它们只是语法上的差异。

  • 举例1:在传统的 BNF 中,左式 和 右式 的 分隔符(即:定义符)通常是::=,而在书籍中通常是 ,在 EBNF 和 ABNF 中是 =
  • 举例2:在传统的 BNF 中,非终结符用尖括号括起来,例如,<EXPR>终结符不用加任何额外的符号,用普通字符表示即可。而在 ABNF 中,非终结符用普通字符表示,终结符需要用双引号括起来,例如"+" ;
  • 举例3:在 BNF 和 EBNF 中,替代符号(选项符号)是 |,在 ABNF 中,替代符号是 /
  • 举例4:EBNF 和 ABNF 还具有快捷语法语法,比如指定 0个 或 多个 重复项。要将其用 BNF 表示,则需要引入更多规则。

通常,BNF 更适合教学、解释和理论讨论。EBNF 和 ABNF 经常用于语法定义 和 解析器解析,其中 ABNF 更加利于解析器解析;

2. 巴科斯范式BNF

巴科斯范式的英文缩写为BNF,它是以美国人巴科斯(Backus)和丹麦人诺尔(Naur)的名字命名的一种形式化的语法表示方法,用来描述语法的一种形式体系,是一种典型的元语言。又称巴科斯-诺尔形式(Backus-Naur form)。它不仅能严格地表示语法规则,而且所描述的语法是与上下文无关的。它具有语法简单,表示明确,便于语法分析和编译的特点。

BNF表示语法规则的方式为:

  • 非终结符用尖括号括起。
  • 每条规则的左部是一个非终结符,右部是由非终结符和终结符组成的一个符号串,中间一般以::=分开。
  • 具有相同左部的规则可以共用一个左部,各右部之间以直竖“|”隔开。

BNF中常用的元字符及其表示的意义如下:

  • ::= :是“被定义为”的意思;示例:字符串 ::= 用引号包围的字符序列,表示 字符串 就是 用引号包围的字符序列
  • "...":终结符,即引号中的字符序列本身,并非指代其它字。而终结符双引号 "double_quote 用来表示;示例:函数调用 ::= 名字 "()" 表示 函数的调用 是 由 名字 加上左右括号字符 () 组成;
  • double_quote :代表终结符 双引号 "; 示例:字符串 ::= double_quote ... double_quote,表示 字符串 是由被字符 " 包围的字符序列组成;
  • 在双引号外的字代表着语法部分;示例:基本类型 ::= 字符串 | 数字 | 布尔,表示 字符串数字布尔 都是 基本类型,但 字符串数字布尔 具体是什么,由其它 规则定义;
  • <...>:必选项;示例:名字 ::= [姓] <名> 表示 名字 中的 是必须要有的,但 是可有可无的,即:姓 名名字 也是 名字
  • [...]:可选,可有可无;示例:名字 ::= [姓] <名> 表示 名字 中的 是必须要有的,但 是可有可无的,即:姓 名名字 也是 名字
  • {...}:重复,0 或 任意次重复;示例:AB ::= "a" {"b"},表示 AB 是由 一个 a 后面跟上任意数量(包括0个)个 b 组成,如 aa ba bba bbb
  • (...):分组,用来控制表达式的优先级;示例:AX ::= "a" ("m"|"n"),表示 AX 是由 一个 a 后面跟上 mn 组成;
  • |:替换,即 的意思;示例:布尔 ::= "true" | "false",表示 truefalse 都是 布尔
  • ...:表示各种列举或省略的代码片断;示例:a...z 表示 从 az 的字符,"..." 表示 由 双引号 " 包围起来的任意字符;
  • 斜体字: 参数,在其它地方有解释;

3. 扩展的巴科斯范式EBNF

EBNF,EBNFExtended BNF 的缩写,意思是扩展的巴科斯范式。用来描述计算机语言语法的符号集。现在,几乎每一位新编程语言书籍的作者都使用巴科斯范式来定义编程语言的语法规则。

扩展巴科斯-瑙尔范式(EBNF)是表达作为描述计算机编程语言和形式语言的正规方式的上下文无关文法的元语法符号表示法。它是基本巴科斯范式(BNF)元语法符号表示法的一种扩展。

它最初由尼古拉斯·沃斯开发,最常用的 EBNF 变体由标准,特别是 ISO-14977 所定义。

3.1. EBNF符号表

下面是 推荐标准ISO/IEC 14977 所定义的符号及其含义

  • =:定义;示例:字符串 = 用引号包围的字符序列,表示 字符串 就是 用引号包围的字符序列
  • ,:串接;示例:郭斌勇 = 'guo' , 'binyong' 表示 郭斌勇 是 由 guobinyong 串接而成的 guobinyong 而不是 guo binyong;
  • ;:终止,表示一个定义语句结束了,在没有歧义的情况下可省略;示例:变量名字 = 标识符 ; 类型名字 = 标识符
  • |:替换,即 的意思;示例:布尔 = 'true' | 'false',表示 truefalse 都是 布尔
  • [...]:可选,可有可无;示例:名字 = [姓] 名 表示 名字 中的 是可有可无的,即:姓 名名字 也是 名字
  • {...}:重复,0 或 任意次重复;示例:AB = 'a' {'b'},表示 AB 是由 一个 a 后面跟上任意数量(包括0个)个 b 组成,如 aa ba bba bbb
  • (...):分组,用来控制表达式的优先级;示例:AX = 'a' ('m'|'n'),表示 AX 是由 一个 a 后面跟上 mn 组成;
  • '...':终结符,即引号中的字符序列本身,并非指代其它字;示例:函数调用 = 名字 '()' 表示 函数的调用 是 由 名字 加上左右括号字符 () 组成;
  • "...":终结符,同 '...'
  • (*...*):注释,说明性文本,不表示任何语法;
  • ?...?:特殊序列
  • -:排除,除去;

3.2. EBNF语法的定义

用 EBNF范式 来描述 EBNF 的语法

生成式 = 生成式名 '=' [ 表达式 ] [';'] ;
表达式 = 选择项 { '|' 选择项 } ;
选择项 = 条目 { 条目 } ;
条目   = 生成式名 | 标记 [ '…' 标记 ] | 分组 | 可选项 | 重复项 ;
分组   = '(' 表达式 ')' ;
可选项 = '[' 表达式 ']' ;
重复项 = '{' 表达式 '}' ;

生成式由表达式构造,表达式通过术语及以下操作符构造,自上而下优先级递增(低=>高):

|   选择
()  分组
[]  可选(0 或 1 次)
{}  重复(0 到 n 次)

小写生成式名用于标识词法标记。非终结符使用驼峰记法。 位于引号 '...' 内的即为终结符。

形式 a … b 表示把从 ab 的字符集作为选择项。 横向省略号 也在本文档中非正式地表示各种列举或简略的代码片断。

4. 增强型巴科斯范式ABNF

RFC2234 定义了增加型巴科斯范式(ABNF)。近年来在Internet的定义中 ABNF 被广泛使用。ABNF 做了更多的改进。增强型巴科斯-瑙尔范式(ABNF)基于了巴科斯-瑙尔范式(BNF),但由它自己的语法和推导规则构成。这种元语言的发起原则是描述作为通信协议(双向规范)的语言的形式系统。它建档于 RFC 4234 中通常充当 IETF 通信协议的定义语言。

4.1. 推导规则

ABNF 规定是一组推导规则,写为:

规则 = 定义 ; 注释 CR LF

说明:

  • 这里的规则是大小写敏感的非终结符,定义是由定义这个规则的符号序列、一个文档注释组成,并结束于回车换行。
  • 规则名字是大小写不敏感的: <rulename>, <Rulename>, <RULENAME> 和 <rUlENamE> 都提及同一个规则。规则名字由开始于一个字母的字母、数字和连字符组成。不要求用尖括号(“<”, “>”) (如 BNF 那样)包围规则名字。但是它们可以用来界定规则名字,比如在冗文中识别出规则名字的时候。ABNF 使用 7-位 ASCII 编码,在 8-位域中把高位置零。
  • 终结符由一个或多个数值字符指定。数值字符可以指定为跟随着基数(b = 二进制, d = 十进制, x = 十六进制)的一个百分号“%”,随后是这个数值,或数值的串联(用“.” 来指示)。例如回车可以指定为十进制的 %d13 或十六进制的 %x0D。回车换行可以指定为 %d13.10。
  • 文字正文通过使用包围在引号(")中字符串来指定。这些字符串是大小写不敏感的,使用的字符集是 US-ASCII。所以字符串“abc”将匹配“abc”, “Abc”, “aBc”, “abC”, “ABc”, “AbC”, “aBC” 和 “ABC”。对于大小写敏感匹配,必须定义明确的字符: 要匹配 “aBc” 定义将是 %d97 %d66 %d99。

4.2. 操作符

空白被用来分隔定义的各个元素: 要使空格被识别为分割符则必须明确的包含它。

4.3. 串联

规则1 规则2

规则可以通过列出一序列的规则名字来定义。

示例:
要匹配字符串“aba”可以使用下列规则:

fu = %x61; a
bar = %x62; b
mumble = fu bar fu

4.4. 选择

规则1 / 规则2

规则可以通过用反斜杠(“/”)分隔的多选一规则来定义。

示例:
要接受规则 <fu> 或规则 <bar> 可构造如下规则:

fubar = fu / bar

4.5. 递增选择

规则1 =/ 规则2

可以通过使用在规则名字和定义之间的“=/”来向一个规则增加补充选择。

示例:
规则

ruleset = alt1 / alt2 / alt3 / alt4 / alt5

等价于

ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt5

4.6. 值范围

%c##-##

数值范围可以通过使用连字符(“-”)来指定。

示例:
规则

OCTAL = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7"

等价于

OCTAL = %x30-37

4.7. 序列分组

(规则1 规则2)

元素可以放置在圆括号中来组合定义中的规则。

示例:
要匹配“elem fubar snafu”或“elem tarfu snafu”可以构造下列规则:

group = elem (fubar / tarfu) snafu

要匹配“elem fubar”或“tarfu snafu”可以构造下列规则:

group = elem fubar / tarfu snafu
group = (elem fubar) / (tarfu snafu)

4.8. 可变重复

n*m规则

要指示一个元素的重复可以使用形式 <a>*<b>元素。可选的 <a> 给出要包括的元素的最小数目,缺省为 0。可选的 <b> 给出要包括的元素的最大数目,缺省为无穷。
对零或多个元素使用 *元素,对一或多个元素使用 1*元素,对二或三个元素使用 2*3元素

4.9. 特定重复

n规则

要指示明确数目的元素可使用形式 <a>元素,它等价于 <a>*<a>元素
使用 2DIGIT 得到两个数字,使用 3DIGIT 得到三个数字。(DIGIT 在下面的核心规则中定义)。

4.10. 可选序列

[规则]

示例:
要指示可选元素下列构造是等价的:

[fubar snafu]
*1(fubar snafu)
0*1(fubar snafu)

4.11. 注释

; 注释

分号(“;”)开始一个注释并持续到此行的结束。

4.12. 操作符优先级

上述操作符有从最紧绑定(binding)到最松绑定的给定优先级:

  1. 字符串,名字形成(formation)
  2. 注释
  3. 值范围
  4. 重复
  5. 分组,可选
  6. 串联
  7. 选择

与串联一起使用选择操作符可以造成混淆,建议使用分组来做明确串联分组。

4.13. 核心规则

核心规则定义于 ABNF 标准中;


核心规则.png

5. 郭斌勇版巴科斯范式EBNF-GBY

对于会正则表达工式的人来说,可能不喜欢喜欢EBNF的重复规则,而更喜欢正则表达工的重复规则(正如我的喜好一样),为了实现类正则的巴科斯范式,我便定义了郭斌勇版巴科斯范式EBNF-GBY;

郭斌勇版巴科斯范式EBNF-GBY是基本ABNF修改和扩展的,相对于EBNF,有如下区别:

5.1. 修改

弃用 ABNF中的重复规则 和 EBNF中的可重复项表示{ },改用如下正则表达式的重复规则,如下:

规则{min,max}

表示规则重复次数大于或等于min次,小于或等于max次;

min表示最小的重复次数,默认值为0
max表示最大的重复次数,默认值为无穷大
min或者max被省略时,min或者max取相应默认值;

规则{n}

等价于:

规则{n,n}

表示规则重复n次;

5.2. 增加

相对ABNF,增加以下元字符:

? : 表示前面的规则重复零次或一次;等价于`{0,1}`;
+ : 表示前面的规则重复一次或多次(大于等于1次);等价于`{1,}`;
* : 表示前面的规则重复任意次;等价于`{0,}`;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,602评论 18 399
  • 紫煊: 我亲爱的宝贝! 最近,小姨因她家的矛盾很是烦心。我俩虽然不能帮她解决问题,但是一直陪伴和鼓励...
    窚煊阅读 122评论 0 2
  • 因为你在乎她 因为你们本来关系就不好 妈蛋真生气好想删好友哦
    千绪萦心阅读 476评论 0 0
  • 蔡英文,你能不能好好干点经济发展的事,让台湾老百姓感觉实实在在的利益,自然就会什么都听你的。没事老往军队瞎转悠什么...
    幸福打开快乐阅读 145评论 0 1