BFN記法とは:構文定義の基本と再帰的定義、EBNFとの違いを徹底解説

基本情報技術者試験, FE 基本情報技術者試験
基本情報技術者試験
スポンサーリンク

はじめに: BFN記法とは

BFN記法(Backus-Naur Form、バッカス・ナウア記法)は、形式言語プログラミング言語の文法を定義するために用いられる表記法です。

特に、コンパイラやインタプリタを作成する際に、構文の規則を明確に示すために利用されます。

BFN記法は、与えられた言語の構文を生成規則として表現し、それに従って文法的に正しい文や式を構築できるようにします。

この記法はシンプルでありながら強力で、複雑な文法の定義にも対応できます。

主な用途

  • プログラミング言語の構文定義
  • データフォーマット(JSONやXMLなど)の文法規則の記述
  • コンパイラの設計における構文解析の基盤

基本的な概念

BFN記法では、以下のような規則を用いて文法を定義します。

  • 非終端記号: 他の記号や規則を参照するシンボル(例: <expression>
  • 終端記号: 実際の文字や記号を表すシンボル(例: +, *, 0, 1
  • 生成規則: 文法のルールを定義し、::=を用いて左辺と右辺を関連付けます

これにより、プログラミング言語の文法やシンタックス(構文)を形式的かつ明確に表現することが可能になります。


BFN記法の歴史と背景

BFN記法は、1950年代後半にジョン・バックス(John Backus)とピーター・ナウア(Peter Naur)によって開発されました。

最初にこの記法が使われたのは、初期の高級プログラミング言語であるALGOLの文法を定義するためでした。

発展の経緯

  • ジョン・バックスは、FORTRANの設計者としても知られ、プログラミング言語の設計における形式的なアプローチを提唱していました。
  • ピーター・ナウアはALGOL 60の仕様策定に大きく関わり、Backusのアイデアを拡張・洗練させ、後にBFN記法として完成させました。

これにより、プログラミング言語の文法が形式的に定義されることが標準化され、BFN記法はコンピュータサイエンスの分野における基盤的なツールとなりました。


BFN記法の基本構文

BFN記法の基本構文は、規則(production rule)を使用して文法を定義します。

この規則は、文法的に有効な文や表現を記述するための一連のルールを表します。

基本的な記号

  • ::= : 定義(左辺が右辺で定義されることを示す)
  • | : 選択肢を表す(「または」の意味)
  • <> : 非終端記号を囲む(例: <expression>

構文の例

たとえば、基本的な算術式をBFN記法で定義すると次のようになります。

<expression> ::= <term> | <expression> "+" <term>
<term> ::= <factor> | <term> "*" <factor>
<factor> ::= "(" <expression> ")" | <digit>
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

この例では、<expression>(式)が定義されており、式は<term>(項)であるか、<expression> "+" <term>の形を持つことが示されています。


再帰的定義とその重要性

BFN記法の強力な特徴の一つが再帰的定義です。

再帰的定義とは、ある規則の右辺にその規則自身を含む定義を指します。

これにより、入れ子構造繰り返しを含む複雑な文法を表現することが可能です。

再帰的定義の例

先ほどの算術式の例を見てみましょう。<expression>の定義に再帰が含まれています。

<expression> ::= <term> | <expression> "+" <term>

この定義では、<expression>が再び右辺に現れています。

これにより、例えば以下のような複雑な式も表現可能です。

1 + 2 + 3 * 4

再帰的定義は、プログラミング言語の構文で特に重要です。

多くの言語では、構造の再利用ネストされた式が頻繁に出現するため、再帰によってそれらを自然に表現することができます。


BNFと拡張形式 (EBNF) の違い

BFNには拡張形式が存在し、これは拡張バックス・ナウア記法EBNF: Extended Backus-Naur Form)と呼ばれます。

EBNFでは、より複雑な文法を簡潔に記述できるように、いくつかの追加のシンボルが導入されています。

BNFとEBNFの違い

  • 繰り返し: BNFでは繰り返しを再帰的に定義する必要がありますが、EBNFでは{}を使って簡潔に表現できます。
  • オプション: EBNFでは、[]を使ってオプション(省略可能な部分)を表現します。
  • グルーピング: EBNFでは、()を使って部分式をグループ化できます。

EBNFの例

先ほどのBNF記法をEBNFで書き直すと、次のようにシンプルになります。

expression = term , { "+" , term } ;
term = factor , { "*" , factor } ;
factor = "(" , expression , ")" | digit ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;

このように、EBNFでは繰り返しやオプションが簡潔に記述できるため、文法の定義がより読みやすくなります。


実際の使用例: BNFでの構文定義

BFN記法は、さまざまなプログラミング言語やデータフォーマットの文法定義に使用されます。

ここでは、JSONの文法をBFN記法で定義する例を示します。

JSONの文法(BNF記法)

<json> ::= <object> | <array>
<object> ::= "{" <members> "}" | "{}"
<members> ::= <pair> | <pair> "," <members>
<pair> ::= <string> ":" <value>
<array> ::= "[" <elements> "]" | "[]"
<elements> ::= <value> | <value> "," <elements>
<value> ::= <string> | <number> | <object> | <array> | "true" | "false" | "null"
<string> ::= "\"" <characters> "\""
<number> ::= <integer> | <integer> "." <digits>
<integer> ::= <digit> | <digit> <digits>
<digits> ::= <digit> | <digit> <digits>
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

上記の例では、JSONの構造をBFN記法で定義しています。

オブジェクトや配列、キーと値のペアといったJSONの基本構造がすべてこの定義で表現されています。


まとめ

BFN記法は、プログラミング言語やデータフォーマットの文法をシンプルかつ明確に定義するための強力なツールです。

再帰的定義を用いることで、複雑な文法や構造を効率的に表現でき、またEBNFのような拡張形式を使うことで、より直感的かつ簡潔に文法を記述することも可能です。

BFN記法の利点

  • 形式的で明確な文法定義が可能
  • 再帰的な構造を自然に表現できる
  • 拡張形式(EBNF)を使うことで、より簡潔に記述できる

活用シーン

  • プログラミング言語の設計・解析
  • データフォーマットの仕様書作成
  • コンパイラやインタプリタの構文解析

BFN記法は、形式言語の扱いにおいて学びやすく、また非常に実用的なツールです。

プログラミングやコンパイラの設計に関心がある人にとって、必須の知識と言えるでしょう。

コメント