BNF記法とは(全体像)
BNF記法は、ことばや記号の「正しい組み立て方」をきちんと書き表すためのルールのこと。プログラミング言語の仕様書などで、「この言語ではこういう書き方が正しい」と定義するのに使われる。
イメージは、レゴの組み立て説明書。「整数とは、数字を1つ以上ならべたもの」のように、部品(数字)と組み立て方(ならべる)を記号で表す。人間の感覚ではなく、機械が迷わず読めるように形式的に書くのがねらいだ。
使う記号はごくわずか。
- `< >` … 部品の名前(非終端記号。さらに細かく定義されるもの)
- `::=` … 「左を右のように定義する」という意味
- `|` … 「または」(候補を並べる)
詳しく:この読み方だけ覚えれば戦える
ここが記事の心臓部。まずはBNFの基本の読み方を、例で見るのが一番早い。
BNFの基本記号
| 記号 | 読み方・意味 | |
|---|---|---|
| `< >` | 部品の名前(あとで定義される側) | |
| `::=` | 「左は、右のように定義される」 | |
| `\ | ` | 「または」(候補を並べる) |
| 生の文字 | そのままの文字・記号(終端記号) |
たとえば「数字」と「整数」を定義するとこうなる。
``` <数字> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <整数> ::= <数字> | <数字><整数> ```
上は「数字とは0〜9のどれか」。下は「整数とは、数字1個、または数字のうしろにまた整数が続くもの」と読む。この自分自身(整数)を使って定義するやり方を再帰といい、これで「1」も「12345」もすべて表せる。再帰が使えるのがBNFの大事な性質だ。
次に、BNFを書きやすく拡張したのがEBNF。よく出るパターン(繰り返し・省略)を専用の記号で短く書ける。
EBNFの拡張記号
| 記号 | 意味 |
|---|---|
| `{ }` | 中身を0回以上くりかえす |
| `[ ]` | 中身はあってもなくてもよい(省略可) |
| `( )` | グループにまとめる |
たとえばさっきの整数は、EBNFなら `<整数> ::= <数字>{<数字>}`(数字1個+うしろに数字の繰り返し)と短く書ける。つまり、BNFとEBNFは別物ではなく、EBNFはBNFを便利にした拡張版だ。
わかりやすく言い換えると
要するに、BNFは「ことばの組み立てルールを記号で書いた設計図」だ。
①`::=` は「〜とは、こう作る」のイコール
②`|` は「または」(選べる候補)
③`< >` は「まだ細かく決める部品」
再帰のイメージは「入れ子のロシア人形(マトリョーシカ)」。整数の中にまた整数が入る、という形で、いくらでも長い整数を表せる。つまり、短いルールで無限のパターンを書けるのが強みだ。
試験のツボ
🔴 一番出る:基本記号の読み方
①`::=` = 「左を右のように定義する」
②`|` = 「または」(候補を並べる)
③`< >` = 部品の名前(非終端記号)
🔴 次に出る:再帰定義の意味
①自分自身を使って定義できる
②短いルールで長い文字列を表せる
🟡 押さえると安定:EBNFはBNFの拡張
①`{}`=0回以上の繰り返し
②`[]`=省略可(0か1回)
よくある間違い
①「BNFとEBNFは同じもの」→ ✗ EBNFはBNFを拡張した版。繰り返し`{}`や省略`[]`の記号が増えている。
②「BNFでは自分自身を使った定義(再帰)はできない」→ ✗ 再帰定義はできる。これで無限のパターンを表せる。
③「`|`は『かつ(and)』を表す」→ ✗ `|`は「または(or)」。候補を並べる記号。
試験での出題パターン
実際の問題でたしかめてみよう。
オリジナル問題1(基本記号)
BNF記法の記号に関する次の記述のうち、正しいものはどれか。
- 記号`::=`は左辺と右辺がつねに等しい数値かどうかを調べる比較演算子だ
- 記号`|`は「かつ(and)」を表し、両方の条件を同時に満たす必要を示している
- 記号`::=`は「左辺を右辺のように定義する」、記号`|`は「または」を表す
- 記号`< >`で囲まれた部分は、これ以上分解できない生の文字そのものを表す
解答は 3 だぜ。
`::=`は「左辺を右辺のように定義する」、`|`は「または」だ。この2つが読めればBNFは怖くない。
選択肢1は`::=`を数値の比較とする誤り(定義の記号だ)。選択肢2は`|`を「かつ」としているが正しくは「または」。選択肢4は`< >`を生の文字としているが、これはあとで定義される部品(非終端記号)だぜ。
| 選択肢 | 判定 | 理由 | |
|---|---|---|---|
| 1 | ✗ | `::=`は定義の記号で比較ではない | |
| 2 | ✗ | `\ | `は「または」 |
| 3 | ✓ | `::=`は定義、`\ | `はまたはで正しい |
| 4 | ✗ | `< >`は部品の名前(非終端記号) |
オリジナル問題2(再帰定義)
BNFの`<整数> ::= <数字> | <数字><整数>`という定義に関する次の記述のうち、正しいものはどれか。
- 整数は数字1個、または数字のうしろにさらに整数が続くもので、長い整数も表せる
- この定義は誤りで、BNFでは自分自身を使った再帰的な定義は認められていない
- この定義では1けたの数字しか表せず、12や345のような複数けたは表現できない
- 整数とは数字をかならず3個ならべたもので、それ以外の長さは整数と認めない
解答は 1 だぜ。
この定義は「整数とは、数字1個、または数字のうしろに整数が続くもの」と読む。自分自身(整数)を使う再帰だから、1も12345も全部表せるんだ。
選択肢2は「再帰は認められない」が誤りで、BNFは再帰定義ができる。選択肢3は「1けたしか表せない」が誤り。選択肢4の「かならず3個」も誤りだぜ。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✓ | 再帰で長い整数も表せる |
| 2 | ✗ | BNFは再帰定義ができる |
| 3 | ✗ | 複数けたも表現できる |
| 4 | ✗ | けた数を3個に固定していない |
オリジナル問題3(EBNF)
EBNFに関する次の記述のうち、正しいものはどれか。
- EBNFはBNFとまったく同じ記法で、新しく追加された記号は一つもない方式だ
- EBNFはBNFの拡張で、`{}`は0回以上の繰り返し、`[]`は省略可能を表す
- EBNFはBNFより機能が少なく、繰り返しや省略は表現できなくなった方式である
- EBNFの`[]`は中身を必ず1回以上くりかえすことを表す、繰り返し専用の記号だ
解答は 2 だぜ。
EBNFはBNFの拡張版。`{}`は「0回以上の繰り返し」、`[]`は「省略可能(0か1回)」を表す。よく出るパターンを短く書けるようにしたものだ。
選択肢1は「追加記号がない」が誤り。選択肢3は「機能が少ない」が逆で、拡張して増えている。選択肢4は`[]`を繰り返しとしているが、`[]`は省略可で、繰り返しは`{}`だぜ。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✗ | `{}`や`[]`が追加されている |
| 2 | ✓ | `{}`繰り返し・`[]`省略可で正しい |
| 3 | ✗ | 拡張して機能は増えている |
| 4 | ✗ | `[]`は省略可、繰り返しは`{}` |
まとめ
押さえどころ
- 🔴 基本記号 = `::=`は定義、`|`は「または」、`< >`は部品の名前(非終端記号)。
- 🔴 再帰定義 = 自分自身を使って定義でき、短いルールで長い文字列を表せる。
- 🟡 EBNF = BNFの拡張版。`{}`=0回以上の繰り返し、`[]`=省略可。
次に学ぶ
- コンパイラの仕組み ── BNFで書いた文法をもとに、プログラムを機械語へ翻訳する流れ。BNFが何のためにあるかが見えてくる。
- 逆ポーランド記法 ── 式の書き方のルール。文法を形式的に扱うという点でBNFと地続きの話題。
執筆: SikakuQuest編集部