扩展巴科斯范式

基本

EBNF 定义了把各符号序列分别指派到非终结符产生规则:

```digit excluding zero = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
digit                = "0" | digit excluding zero ;
```

```twelve                          = "1" , "2" ;
two hundred one                 = "2" , "0" , "1" ;
three hundred twelve            = "3" , twelve ;
twelve thousand two hundred one = twelve , two hundred one ;
```

```natural number = digit excluding zero , { digit } ;
```

```integer = "0" | [ "-" ] , natural number ;
```

EBNF 还包括描述指定次数的重复，和排除产生式的某部分或向 EBNF 文法插入注释的语法。

约定

1. 使用了如下约定:

• 扩展 BNF 每个元标识符都被写为用连字号连接起来的一个或多个字；
• 结束于“-symbol” 的元标识符是扩展 BNF 的终结符的名字。

2. 表示扩展 BNF 的每个操作符的正常字符和它所蕴涵的优先级(顶部为最高优先级)为:

```* repetition-symbol
- except-symbol
, concatenate-symbol
| definition-separator-symbol
= defining-symbol
; terminator-symbol
```

3. 下列括号对超越正常优先级:

```´  first-quote-symbol            first-quote-symbol  ´
"  second-quote-symbol          second-quote-symbol  "
(* start-comment-symbol          end-comment-symbol *)
(  start-group-symbol              end-group-symbol  )
[  start-option-symbol            end-option-symbol  ]
{  start-repeat-symbol            end-repeat-symbol  }
?  special-sequence-symbol   special-sequence-symbol ?
```

```aa = "A";
bb = 3 * aa, "B";
cc = 3 * [aa], "C";
dd = {aa}, "D";
ee = aa, {aa}, "E";
ff = 3 * aa, 3 * [aa], "F";
gg = {3 * aa}, "D";
```

```aa: A
bb: AAAB
cc: C AC AAC AAAC
ee: AE AAE AAAE AAAAE AAAAAE etc.
ff: AAAF AAAAF AAAAAF AAAAAAF
```

示例

``` (* a simple program in EBNF − Wikipedia *)
program = 'PROGRAM' , white space , identifier , white space ,
'BEGIN' , white space ,
{ assignment , ";" , white space } ,
'END.' ;
identifier = alphabetic character , [ { alphabetic character | digit } ] ;
number = [ "-" ] , digit , [ { digit } ] ;
string = '"' , { all characters − '"' } , '"' ;
assignment = identifier , ":=" , ( number | identifier | string ) ;
alphabetic character = "A" | "B" | "C" | "D" | "E" | "F" | "G"
| "H" | "I" | "J" | "K" | "L" | "M" | "N"
| "O" | "P" | "Q" | "R" | "S" | "T" | "U"
| "V" | "W" | "X" | "Y" | "Z" ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
white space = ? white space characters ? ;
all characters = ? all visible characters ? ;
```

``` PROGRAM DEMO1
BEGIN
A0:=3;
B:=45;
H:=-100023;
C:=A;
D123:=B34A;
BABOON:=GIRAFFE;
TEXT:="Hello world!";
END.
```

比较 EBNF 和 BNF

BNF 有着可选项和重复不能直接表达的问题。作为替代，它们需要利用中介规则或两选一规则，对于可选项，定义要么是空的要么是可选的产生式的规则，对于重复，递归的定义要么是被重复的产生式要么是自身的规则。同样的构造仍可用在 EBNF 中。

```signed number = [ sign , ] number ;
```

```signed number = sign , number | number ;
```

```signed number = optional sign , number ;
optional sign , = ε | sign , ; (* 使用 ε 来更清晰的指示空产生式 *)
```

```number = { digit } digit ;
```

```number = digit | number digit;
```

EBNF 较 BNF 的优点

EBNF 排除了 BNF 的一些缺陷:

• BNF 为自身使用了符号 (<, >, |, ::=)。当它们出现在要定义的语言中的时候，BNF 不得不加以修改或解释的使用。
• BNF-语法在一行中只表示一个规则。

EBNF 解决了这些问题:

• 终结符被严格的包围在引号 ("..." 或 '...') 中。给非终结符的尖括号 ("<...>")可以省略。
• 通常使用终止字符分号结束一个规则。

EBNF 已经被ISO用代码 ISO/IEC 14977:1996(E) 标准化了。

扩展

```space = ? US-ASCII character 32 ?;
```

```something = foo ( bar );
```

```function application = list( symbol , [ { expression } ] );
```