2.2 BNF基础
BNF是一种形式化符号,用于描述给定语言的语法,也是一种用于表示上下文无关文法的语言,在某种程度上说BNF可以定义其自身。
它的应用非常广泛,大到使用BNF定义编程语言的语法规则(编程语言,SQL语法等)、指令集,小到使用BNF编写伪代码,以便于他人也能够读懂其中的含义。而更为常见的可能是Linux命令里的帮助说明。如Linux或DOS下都存在的切换目录的cd命令,其使用方法是cd[目录名],使用者可以指定一个确定的目录作为参数,也可以不指定目录而用其他具有特殊含义的符号代替。也就是说,中括号[]中的内容是可选的。而这个中括号的含义,在BNF中是有明确定义的。
BNF最主要的核心元素是推导规则(产生式)和约定的符号和关键字(文本约定)。使用这些约定的符号和产生式就可以完成某种语义的描述。请看下面的产生式:
<symbol> ::= expression1 | expression2 ...
从左往右,依次是:
<symbol>,非终结符。所谓终结符是不能被代替的符号,是终了的符号,如双引号中有具体含义的字符、具体的内容,如数字1、2、3等,非终结符刚好相反。
expression,一系列的符号。
“::=”,表示左边的符号必须由右边的符号代替,有“被定义为”“赋值”的含义。产生式语句涉及的其他符号见表2-1。
表2-1 常见的产生式符号及含义
下面让我们看两个例子。
1)常见编程语言中IF-ELSE句法可定义为以下形式,它看起来是不是像伪代码呢?
<if_statement> ::= if <boolean_expression> then <statement_sequence> [ else <statement_sequence> ] end if ;
2)BNF定义自身的例子。
syntax ::= { rule } rule ::= identifier "::=" expression expression ::= term { "|" term } term ::= factor { factor } factor ::= identifier | quoted_symbol | "(" expression ")" | "[" expression "]" | "{" expression "}" identif?ier ::= letter { letter | digit } quoted_symbol ::= """ { any_character } """
该段代码的含义是:syntax由一个或多个rule组成(定义);rule则由identifier加上符号“::=”和expression表示;expression由一个或由符号“|”分隔的多个term组成;term由一个或多个factor组成;factor则由identifier或quoted_symbol或用3种括号(小括号、中括号、大括号)括起来的expression表示(expression已经递归的表示);identifier由字符或者字符数字组成;(其中letter、digit为具体的内容);quoted_symbol由双引号括起来的任何字符组成(3个双引号实际表示为外侧的两个双引号包含的中间的那个双引号)。
从前往后推导才能得出syntax具体的含义,也就是BNF的定义形式,它是否已经成功描述了自身呢?例子2)实际代表了本节的所有内容。
注意
ABNF(Augmented Backus–Naur Form,扩展的巴科斯范式)在基于BNF的基础上做了语法的扩展和延伸,感兴趣的读者可以参考相关的文献内容。