王朝百科
分享
 
 
 

BNF范式

王朝百科·作者佚名  2010-03-06  
宽屏版  字体: |||超大  

BNF范式(BNF: Backus-Naur Form 的缩写;也称为巴科斯-瑙尔范式、巴克斯-诺尔范式),是一种用于表示上下文无关文法的语言,上下文无关文法描述了一类形式语言。

是科学哲学家库恩提出的科学前进的模式,大意是一起工作的科学家们大体有一个共同的守则和目标,比如牛顿的经典力学,为此完成范式内的各项工作,科学的进步也就是一个范式取代另一个范式,比如后来的爱因斯坦的相对论在某种意义上的取代了宏观上的经典力学,还有量子力学在微观上完成了这个取代。

BNF范式的内容:

在双引号中的字("word")代表着这些字符本身。而double_quote用来代表双引号。

在双引号外的字(有可能有下划线)代表着语法部分。

< > : 内包含的为必选项。

[ ] : 内包含的为可选项。

{ } : 内包含的为可重复0至无数次的项。

| : 表示在其左右两边任选一项,相当于"OR"的意思。

::= : 是“被定义为”的意思

巴科斯范式的内容

在双引号中的字("word")代表着这些字符本身。而double_quote用来代表双引号。

在双引号外的字(有可能有下划线)代表着语法部分。

尖括号( < > )内包含的为必选项。

方括号( [ ] )内包含的为可选项。

大括号( { } )内包含的为可重复0至无数次的项。

竖线( | )表示在其左右两边任选一项,相当于"OR"的意思。

::= 是“被定义为”的意思。

巴科斯范式示例

这是用BNF来定义的Java语言中的For语句的实例:

FOR_STATEMENT ::=

"for" "(" ( variable_declaration |

( expression ";" ) | ";" )

[ expression ] ";"

[ expression ] ";"

")" statement

这是Oracle packages的BNF定义:

package_body ::= "package" package_name "is"

package_obj_body

[ "begin" seq_of_statements ]

"end" [ package_name ] ";"

package_obj_body ::= variable_declaration

| subtype_declaration

| cursor_declaration

| cursor_body

| exception_declaration

| record_declaration

| plsql_table_declaration

| procedure_body

| function_body

procedure_body ::= "procedure" procedure_name

[ "(" argument { "," argument } ")" ]

"return" return_type

"is"

[ "declare" declare_spec ";" { declare_spec ";" } ]

"begin"

seq_of_statements

[ "exception" exception_handler ]

"end" [ procedure_name ] ";"

statement ::= comment

| assignment_statement

| exit_statement

| goto_statement

| if_statement

| loop_statement

| null_statement

| raise_statement

| return_statement

| sql_statement

| plsql_block

这是用BNF来定义的BNF本身的例子:

syntax ::=

rule ::= identifier "::=" expression

expression ::= term { "|" term }

term ::= factor

factor ::= identifier |

quoted_symbol |

"(" expression ")" |

"[" expression "]" |

"{" expression "}"

identifier ::= letter { letter | digit }

quoted_symbol ::= """ """

扩展的巴科斯范式 Augmented BNF

RFC2234 定义了扩展的巴科斯范式(ABNF)。近年来在Internet的定义中ABNF被广泛使用。ABNF做了更多的改进,比如说,在ABNF中,尖括号不再需要。

什么是EBNF?

基本 (EBNF) 定义有关 EBNF 协定的详细情况,可以参看 Computing Dictionary.

这里是要点一览: "..." : 术语符号 [...] : 选项:最多出现一次 {...} : 重复项: 任意次数,包括 0 次 (...) : 分组 | : 并列选项,只能选一个斜体字: 参数,在其它地方有解释

http://estone.nease.net/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

", __[_]);

}

}

另外,还有一种EBNF就没有正宗的BNF这么爽了,也有很多人在用,前面的

那些递归的定义被写成了{}

有一段时间PASCAL爱好者们喜欢用一个叫语法图的东西,画出来很难看,但

功能和BNF差不多,现在好象已经没多少人用了

近几年流行另一种东西:

digit = one of

0 1 2 3 4 5 6 7 8 9

这里非终结符digit用斜体表示,one of是这种方法里定义的一个量词(常用斜黑体)

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如何用java替换看不见的字符比如零宽空格&#8203;十六进制U+200B
 干货   2023-09-10
网页字号不能单数吗,网页字体大小为什么一般都是偶数
 干货   2023-09-06
java.lang.ArrayIndexOutOfBoundsException: 4096
 干货   2023-09-06
Noto Sans CJK SC字体下载地址
 干货   2023-08-30
window.navigator和navigator的区别是什么?
 干货   2023-08-23
js获取referer、useragent、浏览器语言
 干货   2023-08-23
oscache遇到404时会不会缓存?
 干货   2023-08-23
linux下用rm -rf *删除大量文件太慢怎么解决?
 干货   2023-08-08
刀郎新歌破世界纪录!
 娱乐   2023-08-01
js实现放大缩小页面
 干货   2023-07-31
生成式人工智能服务管理暂行办法
 百态   2023-07-31
英语学习:过去完成时The Past Perfect Tense举例说明
 干货   2023-07-31
Mysql常用sql命令语句整理
 干货   2023-07-30
科学家复活了46000年前的虫子
 探索   2023-07-29
英语学习:过去进行时The Past Continuous Tense举例说明
 干货   2023-07-28
meta name="applicable-device"告知页面适合哪种终端设备:PC端、移动端还是自适应
 干货   2023-07-28
只用css如何实现打字机特效?
 百态   2023-07-15
css怎么实现上下滚动
 干货   2023-06-28
canvas怎么画一个三角形?
 干货   2023-06-28
canvas怎么画一个椭圆形?
 干货   2023-06-28
canvas怎么画一个圆形?
 干货   2023-06-28
canvas怎么画一个正方形?
 干货   2023-06-28
中国河南省郑州市金水区蜘蛛爬虫ip大全
 干货   2023-06-22
javascript简易动态时间代码
 干货   2023-06-20
感谢员工的付出和激励的话怎么说?
 干货   2023-06-18
 
>>返回首页<<
 
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有