什么是BNF范式,什么又是EBNF范式?巴科斯范式及其扩展 在双引号中的字("word")代表着这些字符本身。而double_quote用来代表双引号。 这是用BNF来定义的Java语言中的For语句的实例:
这是Oracle packages的BNF定义:
这是用BNF来定义的BNF本身的例子:
什么是EBNF?
基本 (EBNF) 定义有关 EBNF 协定的详细情况,可以参看 Computing Dictionary.
这里是要点一览:
http://estone./sgf/sgf4.html#2 里会给出一个EBNF在棋牌类的应用.
--------------------------------------------------------------------------------------------
<BNF>::= <非终结符>::=<或项列表>
<或项列表>::= <项> | <或项列表>|<项> <项>::= <非终结符> | <终结符> | <项><非终结符> | <项><终结符> <非终结符>::= <非终结符名> ( 但愿能有人看得懂:-) ) BNF就是巴科特·瑙尔式的缩写, 在计算机的史前时代(1950s),曾有一位大师,他奠定了现代计算机的基础 在他老人家的诸多成就之中,包括了对形式语言的研究,和发明了高级语言: FORTRAN。 为了纪念他老人家,我们把他提出的一套描述语言的方法叫做BNF 其实BNF很简单::=表示定义 |表示或 尖括号(<>)括起来的是非终结符 所谓非终结符就是语言中某些抽象的概念,终结符就是可以直接出现在 语言中的符号 比如:C语言的声明语句可以用BNF这样描述: <声明语句> ::= <类型><标识符>; | <类型><标识符>[<数字>]; 这一句中<声明语句>这个非终结符被定义成了两种形式(上面用|隔开的两部分) 在这里引入了三个终结符: 分号; 左右方括号[ ] <类型> ::= <简单类型> | <指针类型> | <自定义类型> <指针类型> ::= <简单类型> * | <自定义类型> * <简单类型> ::= 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语言只用一二百句就可以描述清楚) 而且相当的精确,不会有自然语言中那种模棱两可的表达 如果你对BNF比较敏感的话,会发现C里面的标识符不能由数字开头 而且在C里面下划线是被当做字母看待的(也就是说能用字母的地方 都可以用下划线)比如:(最好用老一点的编译器比如PDP11上的cc) #define ____ main #define ___ for typedef char* _____; int (*______)(char *, ...) = printf; //如果这一句不灵,就用下面这句 //#define ______ printf //如果你用的是C++可以试一下下面这个 //int (*______)(const char *, ...) = printf; ____(_,char* __[]) //要是你编译器不吃,可以改成int ____(int _,char*__[]) { ___( ; _ ; _ --) { ______("%s\n", __[_]); } } 另外,还有一种EBNF就没有正宗的BNF这么爽了,也有很多人在用,前面的 那些递归的定义被写成了{} 有一段时间PASCAL爱好者们喜欢用一个叫语法图的东西,画出来很难看,但 功能和BNF差不多,现在好象已经没多少人用了 近几年流行另一种东西: digit = one of 0 1 2 3 4 5 6 7 8 9 这里非终结符digit用斜体表示,one of是这种方法里定义的一个量词(常用斜黑体) 我不喜欢这个,因为我眼神不好,常常分不清那个是斜体,那个是正体 |
|