BNF范式
巴科斯范式(英语:Backus Normal Form,缩写为 BNF),又称为巴科斯-诺尔范式(英语:Backus-Naur Form,缩写同样为 BNF,也译为巴科斯-瑙尔范式、巴克斯-诺尔范式),是一种用于表示上下文无关文法的语言,上下文无关文法描述了一类形式语言。它是由约翰·巴科斯(John Backus)和彼得·诺尔(Peter Naur)首先引入的用来描述计算机语言语法的符号集。
尽管巴科斯范式也能表示一部分自然语言的语法,它还是更广泛地使用于程序设计语言、指令集、通信协议的语法表示中。大多数程序设计语言或者形式语义方面的教科书都采用巴科斯范式。在各种文献中还存在巴科斯范式的一些变体,如扩展巴科斯范式 EBNF 或扩充巴科斯范式 ABNF
示例
1 | <non-terminal> ::= <replacement> |
non-terminal意为非终止符,就是说我们还没有定义完的东西,还可以继续由右边的replacement,也就是代替物来进一步解释、定义。
终止符永远不会出现在左边。一旦我们看到了终止符,这个描述过程就结束了。
定义加减乘除运算
1 | <表达式> ::= <项> | <表达式> "+" <项> | <表达式> "-" <项> |
这个BNF定义的是一个四则运算表达式的语法结构,包括:
-
数字(整数)
-
加法(+)、减法(-)
-
乘法(*)、除法(/)
-
括号运算
-
运算优先级规则(乘除 > 加减)
分解说明
1 | <表达式> ::= <项> | <表达式> "+" <项> | <表达式> "-" <项> |
-
<表达式>是最外层结构,表示一个完整的数学表达式。
-
可以是一个<项>,也可以是两个表达式通过 + 或 - 相连接。
-
说明:加减运算在最外层处理,优先级最低。
例子
-
5
-
3 + 4
-
1 - 2 + 3(会解析为 ((1 - 2) + 3))
1 | <项> ::= <因子> | <项> "*" <因子> | <项> "/" <因子> |
-
<项>表示一个次级结构,处理乘法和除法。
-
可以是一个<因子>,也可以是两个<项>通过 * 或 / 相连接。
-
说明:乘除运算在这一层处理,优先级高于加减。
例子:
-
2
-
2 * 3
-
4 / 2 * 5
1 | <因子> ::= <数字> | "(" <表达式> ")" |
-
<因子>是最小的可运算单位。
-
它可以是一个数字,也可以是一个括号括起来的表达式。
-
说明:括号改变默认的运算优先级,比如 (2 + 3) * 4。
1 | <数字> ::= <数字> <数字> | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" |
-
<数字>可以是一个单个数字字符(0–9),也可以是多个数字拼接。
-
这是一种递归定义,允许生成任意位数的整数。
例子:
-
“1”
-
“42”:先是 “4”,再是 “2”,递归构成 “42”
BNF结构自然体现了运算优先级:
-
加减运算(在 <表达式>)在最外层,优先级最低。
-
乘除运算(在 <项>)在中间层,优先级更高。
-
括号表达式(在 <因子>)可以强制改变默认优先级。
JavaScript语法的 BNF 示例
变量声明
1 | <声明> ::= "var" <标识符> "=" <表达式> ";" |
-
<声明>表示一个变量声明,可以是 var、let 或 const。
-
<标识符>是变量的名字。
-
<表达式>是要赋给变量的值,可以是任何合法的 JavaScript 表达式。
表达式
- 表达式可以包括数字、变量、函数调用、算术运算、逻辑运算等。我们可以通过 BNF 定义表达式的结构。
1 | <表达式> ::= <数字> |
控制结构
- JavaScript 中的常见控制结构如 if、for、while 等,可以通过 BNF 规则定义。
1 | <语句> ::= "if" "(" <表达式> ")" <语句> |
函数声明
函数声明的 BNF 规则也可以这样定义:
1 | <函数声明> ::= "function" <标识符> "(" <参数列表> ")" <语句> |
总结
通过这些规则,你可以看到如何逐步从最简单的元素(数字、标识符)构建出更复杂的表达式、语句,最终形成一个完整的程序。每种结构都有对应的产生式,定义了如何组合不同的语法元素。