什么是巴科斯范式?
巴科斯范式(BNF: Backus-Naur Form 的缩写)是由 John Backus 和 Peter Naur 首先引入的用来描述计算机语言语法的符号集。现在,几乎每一位新编程语言书籍的作者都使用巴科斯范式来定义编程语言的语法规则。
扩展的巴科斯范式(Augmented BNF):
RFC2234 定义了扩展的巴科斯范式(ABNF)。近年来在Internet的定义中ABNF被广泛使用。ABNF做了更多的改进,比如说,在ABNF中,尖括号不再需要。
在双引号外的字(有可能有下划线)代表着语法部分。
尖括号( < > )内包含的为必选项。
方括号( [ ] )内包含的为可选项。
大括号( { } )内包含的为可重复0至无数次的项。
竖线( | )表示在其左右两边任选一项,相当于"OR"的意思。
::= 是“被定义为”的意思。
终结符就是可以直接出现在语言中的符号,非终结符就是语言中某些抽象的概念。
用BNF定义BNF( 有意思吧 :)):
<BNF>::= <非终结符>::=<或项列表>
<或项列表>::= <项> | <或项列表>|<项>
<项>::= <非终结符> | <终结符> | <项><非终结符> | <项><终结符>
<非终结符>::= <非终结符名>
比如可以用BFN这样描述C语言的声明语句:
<声明语句> ::= <类型><标识符>; | <类型><标识符>[<数字>];
这一句中 <声明语句> 这个非终结符被定义成了两种形式(上面用 | 隔开的两部分),在这里引入了三个终结符: 分号(;)、左方括号( [ )、右方括号( ] )。
<类型> ::= <简单类型> | <指针类型> | <自定义类型>
<指针类型> ::= <简单类型> * | <自定义类型> *
<简单类型> ::= int|char|double|float|long|short|void
<自定义类型> ::= enum<标识符>|struct<标识符>|union<标识符>|<标识符>
到这里就基本上把<类型>定义清楚了。
<数字> ::= 0X<十六进制数字串> | 0<八进制数字串> | <十进制数字串>
<十六进制数字串> ::= <十六进制数字> | <十六进制数字串><十六进制数字>
<八进制数字串> ::= <八进制数字> | <八进制数字串><八进制数字>
<十进制数字串> ::= <十进制数字> | <十进制数字串><十进制数字>
<十六进制数字> ::= <十进制数字> | A | B | C | D | E | F
<十进制数字> ::= <八进制数字> | 8 | 9
<八进制数字> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
到这里就把<数字>定义清楚了
<标识符> ::= <字母> | <标识符> <字母数字串>
<字母数字串> ::= <字母>|<十进制数字>|<字母数字串><字母>|<字母数字串><十进制数字>
<字母> ::= _ | <大写字母> | <小写字母>
<小写字母> ::= a|b|c|d|e|f|g|h|i|j …… (偷个懒)
<大写字母> ::= A|B|C|D|E|F|G|H|I|J ……
到此为止整个声明语句就定义完了(就是说已经没有非终结符了)。
虽然看起来很繁,但前面定义的各种非终结符都可以很容易的在别的地方重用比如,函数声明可以定义成下面的样子:
<函数声明语句> ::= <类型><标识符>(<形参表>);
<形参表> ::= <类型><标识符> | <形参表>,<形参表>
只用两句就描述完了,所以BNF实际上比用自然语言要简练得多,整个C语言只用一二百句就可以描述清楚,而且相当的精确,不会有自然语言中那种模棱两可的表达。