深入理解Net-Snmp
上QQ阅读APP看书,第一时间看更新

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的基础上做了语法的扩展和延伸,感兴趣的读者可以参考相关的文献内容。