# 擴展巴科斯範式

## 基本

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 } ] );
```