翻訳: ISO/IEC 14977:1996 Information technology — Syntactic metalanguage — Extended BNF
導入
構文メタ言語 (syntactic metalanguage) はコンピュータサイエンスの重要なツールである。その概念はよく知られているが、微妙に異なる多くの表記法が使われている。そのため構文メタ言語はまだ広く使われておらず、厳密な表記の利点が理解されていないのが現状である。
Extended BNF は構文の形式的な定義に秩序をもたらし、プログラミング言語だけではなく、他の多くの形式的な定義にも有用である。
プログラミング言語 Algol 60 (Naur, 1960) が定義されて以来、プログラミング言語の構文を形式的に定義する慣習がある。Algol 60 は現在 BNF または Backus-Naur Form として知られる記法で定義された。この表記法はその後の言語の基礎として適切であることが証明されているが、頻繁に拡張されたり、わずかに変更されている。異なる表記が多く存在することは混乱を招き、曖昧さのない正式な定義の利点が広く理解されることを妨げてきた。この規格では Backus-Naur Form をベースに最も広く採用されている拡張機能を加えた Extended BNF を採用している。
Table of Contents
- 導入
- 1 スコープ
- 2 基準となる文献
- 3 定義
- 4 Extended BNF の各構文要素の形式
- 4.1 一般
- 4.2 構文 (syntax)
- 4.3 構文規則 (syntax-rule)
- 4.4 定義リスト (definitions-list)
- 4.5 単一定義 (single-definition)
- 4.6 構文述語 (syntactic-term)
- 4.7 構文例外 (syntactic-exception)
- 4.8 構文要素 (syntactic-factor)
- 4.9 整数 (integer)
- 4.10 構文プライマリー (syntactic-primary)
- 4.11 オプションシーケンス (optional-sequence)
- 4.12 繰り返しシーケンス (repeated-sequence)
- 4.13 グループ化シーケンス (grouped-sequence)
- 4.14 メタ識別子 (meta-identifier)
- 4.15 メタ識別子文字 (meta-identifier-character)
- 4.16 終端文字列 (termina-string)
- 4.17 第一終端文字 (first-terminal-character)
- 4.18 第二終端文字 (second-terminal-character)
- 4.19 特殊シーケンス (special-sequence)
- 4.20 特殊シーケンス文字 (special-sequence-symbol)
- 4.21 空シーケンス (empty-sequence)
- 4.22 応用例
- 5 各構文要素が表す記号
- 5.1 一般
- 5.2 終端文字列 (terminal-string)
- 5.3 メタ識別子 (meta-identifier)
- 5.4 グループ化シーケンス (grouped-sequence)
- 5.5 オプションシーケンス (optional-sequence)
- 5.6 繰り返しシーケンス (repeated-sequence)
- 5.7 構文要素 (syntactic-factor)
- 5.8 構文述語 (syntactic-term)
- 5.9 単一定義 (single-definition)
- 5.10 定義リスト (definitions-list)
- 5.11 特殊シーケンス (special-sequence)
- 5.12 空シーケンス (empty-sequence)
- 6 レイアウトとコメント
- 7 Extended BNF における各終端文字の表現
- 8 例
- Annex A (informative) Two-level grammars
- Annex B (informative) Bibliography
- 翻訳抄
構文メタ言語
構文メタ言語とは、いくつかの規則を用いて言語の構文を定義するための記法である。各規則は、言語の一部 (言語の非終端記号 (non-terminal symbol) と呼ばれる) に名前をつけ、その取り得る形式を定義する。言語の終端記号 (terminal symbol) とは、それ以上の小さな構成要素に分割できないアトムのことである。構文メタ言語はジャーナルに投稿する論文の参考文献のフォーマットや、複雑なタスクを実行するための指示など、明確な形式的記述や定義が必要な場合に役立つ。
形式的な構文定義には 3 つの異なる用途がある。
- 言語の様々な構文部分 (非終端記号) に名前をつける。
- どのような記号の並びが言語の有効な分であるかを示す。
- その言語の任意の文の構文構造を示す。
構文メタ言語標準の必要性
構文メタ言語標準がなければ、すべてのプログラミング言語の定義はその構文を定義するために使用するメタ言語を規定することから始まる。これは様々な問題を引き起こす。
- 多くの異なる記法
- 2 つの異なるプログラミング言語が同じメタ言語を使用するのはあまりないことである。そのため、人間の解読者は新しい言語を勉強する前に新しいメタ言語を学ばなければならないというハンディを追うことになる。
- 概念が広く理解されていない
- 標準的な表記法がないため、厳密で曖昧さのない定義を用いることができない。
- 不完全な表記
- すべてのプログラミング言語に対してメタ言語を定義する必要があるため、ほぼ必然的にメタ言語には欠陥が含まれている。例えば RTL/2 (BS5904) や CORAL 66 (BS5905) のドラフトではメタ言語の片付けが容易ではなかったためエラーが発生している。
- 特別な目的のための表記
- 特定のプログラミング言語のために定義されたメタ言語は、定義される言語の特別な機能を利用して簡素化されることが多い。しかしこれは保管プログラミング言語には適さない。
- 一般的な構文処理器が少ない
- 構文メタ言語の多様性により、構文を解析し処理するコンピュータプログラム、つまり、構文を正しくリストし、構文で使用される記号のインデックスを作成し、その言語で記述されたプログラムの構文チェッカーを作成するプログラムの可用性が限られている。
実際には、経験豊富な解読者が新しい表記法を覚えることはそれほど難しいことではないが、それでもその違いは相互理解を妨げ、コミュニケーションの妨げとなる。標準的なメタ言語があれば、より多くの人が漠然としたアイディアを明確な定義に昇華させることができる。また、形式的な定義を必要とする他の人々が同じような概念を再発明する必要がなくなるという点でも有用である。
満たすべき目的
構文メタ言語は次のようであることが望まれる:
- 簡潔である。言語を簡潔に定義することで理解がより簡単になる。
- 正確である。規則が曖昧にならない。
- 形式的である。必要に応じてコンピュータがルールを解析したり処理できる。
- 自然である。言語設計者ではない人でも比較的簡単に憶えて理解できる表記法と書式であること; (記号の意味が意外なものであってはならない。また構文の意味を表すのに役立つような方法で言語の構文を定義できなければならない)
- 一般的である。様座な言語の記述を含む多くの目的に適している。
- 文字セットがシンプルで、標準的なキーボード (タイプライターとコンピュータ端末の両方) で一般に使用できない文字を可能な限り避けた表記方法で、ルールをタイプしたり、コンピュータプログラムで処理できる。
- 自己記述性がある。表記が自分自身を記述できる。
- 線形である。構文が 1 つの文字の流れとして表現できる。(これにより構文の印刷が簡単になる。またコンピュータでの処理も簡単になる。)
いくつかの一般的な構文メタ言語
残念ながら、既存の構文メタ言語の中には標準として採用できるものが存在しなかった。
- COBOL (ISO 1989:1985) では選択肢を縦に並べ何行にも渡って括弧を使っている。これはコンピュータ処理には不向きでタイプライターでは作成できない。
- Backus-Naur Form (ALGOL 60 で使用) では、メタシンボル < > | ::= は定義される言語で発生する。一般的な構文 (コメントなど) は自然に表現できず、他の構文 (繰り返しなど) は長文となる。
- 廃止された FORTRAN77 (ISO 1539:1980) には "railroad tracks" があった。これらは理解するのは簡単だが準備するのは難しく、コンピュータやタイプライターで処理するのは難しい。現在のバージョンである FORTRAN 90 (ISO/IEC 1539:1991) ではこの表記は使われなくなった。
他の殆どの言語はこれらのメタ言語のいずれかの変種を使用している。これらの変種のほとんどは、定義されている言語にはない文字をメタ言語のメタ記号として使用しているため標準化の候補にはならない。これはメタ言語を単純化するが一般的な使用を阻害する。
POSIX (ISO/IEC 9945-2:1993) には、ISO/IEC 646:1991 文字セットを前提とした 2 つの保管的な機能がある。LEX は正規表現の定義と字句解析を行うことができるが、任意の文脈自由分布を記述するには不十分であり、YACC (Yet Another Compiler Compiler) は LALR(1) 文法のパーサジェネレータである。
メタ言語標準 Extended BNF
この国際規格で定義されているメタ言語 Extended BNF は、Niklaus Wirth (Wirth, 1977) が提案したもので、Backus-Naur Form をベースにした最も一般的な拡張機能、すなはち:
- 言語の末端記号は引用符で囲まれているため、Extended BNF で使用されている文字を含め、定義されている言語の終端記号として任意の文字を定義できる。
- [ と ] はオプションの記号を示す。
- { と } は繰り返しを示す。
- 各ルールには終了文字が明示されているため、ルールの終わりが曖昧になることがない。
- 括弧は項目をまとめている。( と ) を通常の数学的な意味で使用することは明らかな便宜上のことである。
Extended BNF の主な違いは、これまでの経験から正式な定義を行う際に必要とされる機能が追加されていることである:
- 項目の数を明示的に定義すること。Fortran にはラベルフィールドが正確に 5 文字であるという規則が含まれている。PL/1 や COBOL の識別子は最大 32 文字である。このような規則は Backus Naur Form では困難な表現しかできない。実際にはこのような定義は不完全なままで、規則は英語で非公式に表現されることが多い。
- 少数の例外的なケースを指定して何かを定義すること。Algol の end-コメントは最初の end, else またはセミコロンで終了する。このようなルールは Backus-Naur Form では簡潔かつ明確に表現できず、英語でも通常は非公式に述べられる。
- コメントを含むこと。複雑な構文を持つプログラミング言語などの構造は、それを定義するために多くのルールが必要である。説明と相互参照を提供できれば構文はより明確となる。そこで Extended BNF にはコメント機能があり、構文の形式的な意味に影響を与えることなく、人間の解読者のために通常のテキストを構文に追加することができる。
- メタ識別子。メタ識別子 (言語内の非終端記号の名前) は、明示的な連結記号があるため、一語である必要も括弧で囲む必要もない。これにより、構文のレイアウト (終端記号を除く) が定義されている言語に影響を与えないことをも保証される。
- 拡張。ユーザは Extended BNF を拡張することができる。この目的のために特別なシーケンスが提供されており、その形式と意味は拡張の開始と終了を常に簡単に認識できるようにすることを除いて、標準では定義されていない。以下のパラグラフでは様々な拡張機能の概要を説明する。
制限と拡張
Extended BNF の主な制限は、定義される言語が線形であることである。つまり、その言語の文中のシンボルが順序どおりに配置されている必要がある。例えば編み物のパターンや料理のレシピは線形言語だが、電気回路図は線形言語ではない。
さらに、Extended BNF は、より複雑な形式の分布を定義するには不十分という制限がある。このような機能が提供されなかったのは、より単純で一般的な要件に十分な表記法を定義することが主なニーズであると考えたからである。
その代わりに Extended BNF は様々な拡張が自然な形でできるように定義されている。標準メタ言語を拡張するには 2 つの簡単な方法がある。第一に、特殊シーケンスの概念はあらゆる拡張のための基本的な枠組みを提供し、特殊シーケンス文字間のフォーマットはほぼ完全に任意である。この方法は、アクション文法、つまり文が解析されるときに行われるアクションを指定する文法に適している。第二に、メタ識別子の直後に標準メタ言語の左括弧をつけることはできない。したがって、メタ言語を拡張する別の方法は、メタ識別子の構文と意味を定義し、その後に括弧で囲んだ一連のパラメータを定義することである。これは、ルールが定義されている言語の文の異なる部分の間の一貫性を保証する属性文法では合理的だろう。
より複雑な拡張も可能である。Annex A では Extended BNF を拡張して 2 レベルの文法を定義する方法を提案している。
Information technology - Syntactic metalanguage - Extended BNF
1 スコープ
この国際規格は記号の線形シーケンスの構文を表すための表記 Extended BNF を定義する。この規格では表記の論理構造とそのグラフィカルな表現の両方を定義している。
Extended BNF はプログラミング言語やその他の言語定義以外にも、オペレーティングシステムのコマンドや、データや結果の正確なフォーマットなど、他の形式的な定義にも応用されている。
Extended BNF の例を 8 節で紹介する。
注意 ─ 他の多くの記法と同様に Extended BNF も誤用される可能性がある。したがって、誰かが解析不能な言語や曖昧な言語を定義しようとすることを防ぐことはできない。
2 基準となる文献
以下の規格には、本文中の参照により本国際規格の規定を構成する条項が含まれている。発行時点では示された半が有効であった。すべての企画は改定される可能性があり、この国際規格に基づく協定の当事者は、下記の規格の最新版を提供する可能性を検討することが望ましい。IEC および ISO メンバーは現在、有効な国際規格の登録を行っている。
- IS0 2382-15:1985, Data processing - Vocabulary - Part 15: Programming languages.
- ISO/IEC 646:1991, Information technology - IS0 7-bit coded character set for information interchange.
- ISO/IEC 6429:1992, Information technology - Control functions for coded character sets.
- BS 6154:1981, Method of defining - Syntactic metalanguage.
3 定義
本国際規格では ISO 2382-15 に記載されている定義と、以下の定義が適用される。
3.1 シーケンス (sequence)
0 個以上の項目からなる順序付きリスト。
3.2 サブシーケンス (subsequence)
あるシーケンスに含まれるシーケンス。
3.3 非終端記号 (non-terminal symbol)
定義されている言語の構文上の部分。
3.4 メタ識別子 (meta-identifier)
非終端記号の名前。
3.5 開始記号 (start symbol)
1 つ以上の構文規則で定義されているが、他の構文規則には存在しない非終端記号。
3.6 文 (sentence)
開始記号を表す記号のシーケンス。
3.7 終端記号 (terminal symbol)
言語の不可分な要素を形成する 1 つ以上の文字の並び。
注意 ─ この国際規格では Extended BNF の終端記号を terminal-character と呼び、構文で定義される言語の終端記号を terminal-string と表す。
4 Extended BNF の各構文要素の形式
- 以下の規約を使用する:
- Extended BNF の各メタ識別子はハイフンで繋がれた 1 つ以上の単語として記述される。
- "-symbol" で終わるメタ識別子は Extended BNF の終端記号の名前である。
- Extended BNF の各演算子を表す通常の文字とその暗黙の優先順位は (最優先が最上位):
* repetition-symbol - except-symbol , concatenate-symbol | definition-separator-symbol = defining-symbol ; terminator-symbol - 通常の優先順位は以下の括弧ペアによって上書きされる:
' 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 ?
4.1 一般
Extended BNF の論理構造は 4.2 から 4.21 で定義されている。
4.2 構文 (syntax)
言語の syntax は 1 つ以上の syntax-ruleで構成されている。
4.3 構文規則 (syntax-rule)
syntax-rule は、meta-identifier (定義される非終端記号の名前)、defining-symbol、definitions-list、terminator-symbol の順で構成される。
4.4 定義リスト (definitions-list)
定義リストは、definition-separator-symbol で互いに区切られた 1 つ以上の single-definition の順序付きリストで構成される。
4.5 単一定義 (single-definition)
single-definition は concatenate-symbol で区切られた 1 つ以上の syntactic-term の順序付きリストで構成される。
4.6 構文述語 (syntactic-term)
syntactic-term は以下のいずれかで構成される。
- syntactic-factor または
- syntactic-factor, except-symbol, syntactic-exception
4.7 構文例外 (syntactic-exception)
syntactic-exception は、syntactic-exception によって表される記号のシーケンスが meta-identifier を含まない syntactic-factor によって等しく表されるという制限を受けた syntactic-factor から成る。
注意 ─ syntactic-exception が任意の syntactic-factor であることを認めれば、Extended BNF は context-free 文法よりも広いクラスの言語を定義することができる。例えば Russell のようなパラドックスにつながる以下の試行も含む。
xx = "A" - xx;
"A" は xx の例だろうか? このようなライセンスは望ましくないため、syntactic-exception の形式は安全であることが証明できる場合に限定される。このように、syntactic-factor は一般にある context-free 文法と等価であるのに対し、syntactic-exception は常にある正規の文法と等価である。context-free 文法と通常の文法の間の違いは、常に別の context-free 文法であることが示されるかも知れない。したがって、syntactic-term (とこの標準にしたがって定義されるあらゆる文法) はある context-free 文法と等価である。
4.8 構文要素 (syntactic-factor)
syntactic-factor は以下のいずれかで構成される:
- 整数の後に repetition-symbol が続き、さらにsyntactic-primary が続く、または
- syntactic-primary
4.9 整数 (integer)
integer は 1 つ以上の 10 進法の桁を並べたもの。
4.10 構文プライマリー (syntactic-primary)
syntactic-primary は以下のいずれかで構成される:
- optional-sequence
- repeated-sequence
- grouped-sequence
- meta-identifier
- terminal-string
- special-sequence
- empty-sequence
4.11 オプションシーケンス (optional-sequence)
optional-sequence は、start-option-symbol, definitions-list, end-option-symbol の順で構成される。
4.12 繰り返しシーケンス (repeated-sequence)
repeated-sequence は、start-repeat-symbol, definitions-list, end-repeat-symbol の順で構成される。
4.13 グループ化シーケンス (grouped-sequence)
grouped-sequence は、start-group-symbol, definitions-list, end-group-symbol の順で構成される。
4.14 メタ識別子 (meta-identifier)
meta-identifier は、最初の meta-identifier-character が文字であることを条件に、1 つ以上の meta-identifier-character の順序付きリストで構成される。
4.15 メタ識別子文字 (meta-identifier-character)
meta-identifier-character は letter または decimal digit である。
4.16 終端文字列 (termina-string)
terminal-string は以下のいずれかで構成される:
- first-quote-symbol の後に 1 つ以上の first-terminal-character が続き、その後に first-quote-symbol が続く、または
- second-quote-symbol の後に 1 つ以上の second-terminal-character が続き、その後に second-quote-symbol が続く
4.17 第一終端文字 (first-terminal-character)
first-terminal-character は first-quote-symbol を除く任意の terminal-character である。
4.18 第二終端文字 (second-terminal-character)
second-terminal-character は second-quote-symbol を除く任意の terminal-character である。
4.19 特殊シーケンス (special-sequence)
special-sequence は、special-sequence-symbol, (空の場合もある) special-sequence-character のシーケンス, special-sequence-symbol で構成される。
4.20 特殊シーケンス文字 (special-sequence-symbol)
special-sequence-character は special-sequence-symbol を除く任意の terminal-character である。
4.21 空シーケンス (empty-sequence)
empty-sequence は terminal-character の空のシーケンスで構成される。
4.22 応用例
以下の例は、Fortran 77 の継続行は 5 つの空白で始まり、6 番目の文字は空白やゼロであってはならず、全体で72 (=5+1+66) 文字を超えてはならないという構文ルールである。
Fortran 77 continuation line = 5 * " ", (character - (" " | "0")), 66 * [character} ;
Fortran 66 での継続行の定義はより複雑である。次の例は、継続行は文字 C で始まってはならず、少なくとも 6 文字でなければならず、6 文字目は空白やゼロであってはならず、全体で 72 (=1+4+1+66) 文字を超えてはならないという構文ルールである。
Fortran 66 continuation line = character - "C", 4 * character, character - (" " | "0"), 66 * [character] ;
5 各構文要素が表す記号
5.1 一般
各 syntax-rule は終端記号と非終端記号のシーケンス (空の場合もある) を定義する構文ルールである。これらの記号のシーケンスは syntax-rule の先頭にある meta-identifier で指定された非終端記号で表される。5.2 から 5.12 では、任意の definitions-list で表現される記号のシーケンスを定義する。
- 完全な言語の構文が定義されると、次が存在する:
- 開始記号
- syntactic-primary として使用される各 meta-identifier で始まる、少なくとも 1 つの syntax-rule
- meta-identifier を定義する syntax-rule がいくつかあり、それぞれの定義が非終端記号を部分的にしか定義していないことをが示されていないと、言語を理解するのが難しくなる。
5.2 終端文字列 (terminal-string)
terminal-string は次のいずれかを表す:
- その first-quote-symbol 間の first-terminal-character のシーケンス、または
- その second-quoted-symbol 間の second-terminal-character のシーケンス。
5.3 メタ識別子 (meta-identifier)
syntactic-primary として使用される meta-identifier は、その meta-identifier で始まる syntax-rule の definitions-list で定義される記号の任意のシーケンスを表す。
5.4 グループ化シーケンス (grouped-sequence)
grouped-sequence は、start-group-symbol と end-group-symbol で囲まれた definitions-list によって定義される記号の任意のシーケンスを表す。
5.5 オプションシーケンス (optional-sequence)
optional-sequence は次のいずれかを表す:
- 記号の空シーケンス、または
- start-option-symbol と end-option-symbol で囲まれた definitions-list によって定義された記号の任意のシーケンス。
5.6 繰り返しシーケンス (repeated-sequence)
repeated-sequence はサブシーケンスのシーケンス (空の場合もある) を表し、各サブシーケンスは start-repeat-symbol と end-repeat-symbol で囲まれた definitions-list によって定義された記号の任意のシーケンスである。
5.7 構文要素 (syntactic-factor)
syntactic-factor は明示的な数のサブシーケンスを表し、各サブシーケンスはその syntactic-factor の一部である syntactic-primary によって記号のシーケンスである。必要なサブシーケンスの数は integer が与えられていない場合は 1 となり、それ以外の場合は integer の値となる。
例として、次の syntax-rule は繰り返しを表現するための機能を示している。
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";
このルールで定義された terminal-string は以下の通り:
aa: A
bb: AAAB
cc: C AC AAC AAAC
dd: D AD AAD AAAD AAAAD etc.
ee: AE AAE AAAE AAAAE AAAAAE etc.
ff: AAAF AAAAF AAAAAF AAAAAAF
注意 ─ gg の定義は構文的には有効だが意味がない。gg で表される記号のシーケンスは dd で与えられたものと同じだが曖昧さなく解析することはできない。
5.8 構文述語 (syntactic-term)
syntactic-term が単一の syntactic-factor である場合、それはその syntactic-factor によって表される記号の任意のシーケンスを表す。
syntactic-term が、syntactic-factor の後に except-symbol, syntactic-exception が続く場合、それは両方の条件を満たす任意のシーケンスを表す:
- syntactic-factor によって表される記号のシーケンスである。
- syntactic-exception によって表される記号のシーケンスではない。
例として、以下の syntax-rule は except-symbol が提供する機能を示している。
letter = "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";
vowel = "A" | "E" | "I" | "O" | "U";
consonant = letter - vowel;
ee = {"A"}-, "E";
このルールで定義された terminal-string は以下の通り:
letter: A B C D E F G H I J etc.
vowel : A E I O U
consonant: B C D F G H J K L M etc.
ee: AE AAE AAAE AAAAE AAAAAE etc.
注意 ─ {"A"}- は空の syntactic-exception を持つ syntactic-term であるため、1 つ以上の A のシーケンスを表す。
5.9 単一定義 (single-definition)
single-definition は 1 つ以上のサブシーケンスのシーケンスを表し、各サブシーケンスはその single-definition の対応する syntactic-term で表される記号のシーケンスである。
5.10 定義リスト (definitions-list)
definitions-list は、それを形成する single-definition のいずれか 1 つで表現される記号のシーケンスを表す。
5.11 特殊シーケンス (special-sequence)
special-sequence で表される記号のシーケンスは、この国際規格の範囲外である。この国際規格では special-sequence のフォーマットのみが定義されている。special-sequence はユーザが必要とする拡張機能のための記法を提供する。
5.12 空シーケンス (empty-sequence)
empty-sequence は記号の空シーケンスを表す。
6 レイアウトとコメント
6.1 一般
ページ上の構文のレイアウトはほぼ完全に任意である。6.2 から 6.4 では、スペースや改行などの非印刷文字が terminal-string や単一の terminal-character を形成する文字のペアの外にある場合は、構文に正式な影響を及ぼさないと定義している。6.5 から 6.7 では、任意のテキストをコメントとして構文に挿入できる場所を定義している。
- 各 syntax-rule が新しい行で始まり、様々なメタ言語記号が適切な間隔で配置されていると、人間が構文を読んで理解するのが遥かに容易となる。
- Extended BNF で定義された言語は Extended BNF 自体とは全く異なる字句規則を持つことができる。
- コメントは、構文に説明テキストを追加することで、人間が構文を理解するのに役立つ。例えば syntax-rule に番号をつけ、各 meta-identifier の後にそれを定義する syntax-rule の位置を示すコメントをつけることができる。syntax-rule に関するコメントは、ルールの terminator-symbol の前に置くことが推奨される。
- コメントは、構文で定義された言語に正式な影響を与えない。
6.2 終端文字 (terminal-character)
Extended BNF の終端文字は以下のいずれかである:
- a letter
- a decimal-digit
- a concatenate-symbol
- a defining-symbol
- a definition-separator-symbol
- an end-comment-symbol
- an end-group-symbol
- an end-option-symbol
- an end-repeat-symbol
- an except-symbol
- a first-quote-symbol
- a repetition-symbol
- a second-quote-symbol
- a special-sequence-symbol
- a start-comment-symbol
- a start-group-symbol
- a start-option-symbol
- a start-repeat-symbol
- a terminator-symbol
- an other-character
6.3 ギャップフリー記号 (gap-free-symbol)
gap-free-symbol は次のいずれかである:
- first-quote-symbol でも second-quote-symbol でもない terminal-character、または
- terminal-string
6.4 ギャップ分割子 (gap-separator)
gap-separator は空白、水平タブ、改行、垂直タブ、フォームフィードのいずれかの非印刷文字である。
1 つ以上の gap-separator は構文が定義する言語に影響与えることなく次の場所に配置することができる:
- syntax の前
- syntax の任意の 2 つの gap-free-symbol の間
- syntax の後
6.5 コメントレス記号 (commentless-symbol)
commentless-symbol は以下のいずれか:
- letter や decimal-digit、first-quoted-symbol、second-quoted-symbol、start-comment-symbol、end-comment-symbol、special-sequence-symbol、other-character ではない terminal-character
- a meta-identifier
- an integer
- a terminal-string
- a special-sequence
6.6 コメント記号 (comment-symbol)
comment-symbol は以下のいずれか:
- a bracketed-textual-comment
- a commentless-symbol
- an other-character
6.7 ブランケット付きテキストコメント (bracketed-textual-comment)
bracketed-textual-comment は、start-comment-symbol, comment-symbol の (空の場合もある) シーケンス, end-comment-symbol の順である。
1 つ以上の bracketed-textual-comment は、構文が定義する言語に影響を与えることなく以下の場所に置くことができる:
- syntax の前
- syntax の任意の 2 つの commentless-symbol の間
- syntax の後
注意 ─ 6.5 から 6.7 は bracketed-textual-comment が以下のいずれでも現れないことを意味している:
- a meta-identifier
- an integer
- a special-sequence
- a terminal-string
7 Extended BNF における各終端文字の表現
7.1 一般
Extended BNF における 7-bit 文字セット (ISO/IEC 646:1991 International Reference Version) を用いた各終端文字およびギャップ分割子の表現は 7.2 から 7.8 に定義されている。
7.2 文字と数字
letter とdecimal-digit のそれぞれは対応する文字で表される。
7.3 その他の終端文字
Table 1 は letter でもなく decimal-digit でも other-character でもない各 terminal-character の文字表現を定義している。
メタ言語記号 | 通常の表現 |
---|---|
concatenate-symbol | , コンマ |
defining-symbol | = 等号 |
definition-separator-symbol | | 縦線 |
end-comment-symbol | *) アスタリスク, 右括弧 |
end-group-symbol | ) 右括弧 |
end-option-symbol | ] 右角括弧 |
end-repeat-symbol | } 右波括弧 |
except-symbol | - ハイフン-マイナス |
first-quote-symbol | ' アポストロフィ |
repetition-symbol | * アスタリスク |
second-quote-symbol | " 引用記号 |
special-sequence-symbol | ? 疑問符 |
start-comment-symbol | (* 左括弧, アスタリスク |
start-group-symbol | ( 左括弧 |
start-option-symbol | [ 左角括弧 |
start-repeat-symbol | { 左波括弧 |
terminator-symbol | ; セミコロン |
7.4 代替表現
Table 2 はいくつかの terminal-character の代替表現を定義している。
メタ言語記号 | 代替表現 |
---|---|
definition-separator-symbol | / 分割斜線 |
definition-separator-symbol | ! 感嘆符 |
end-option-symbol | /) 分割斜線, 右括弧 |
end-repeat-symbol | :) コロン, 右括弧 |
start-option-symbol | (/ 左括弧, 分割斜線 |
start-repeat-symbol | (: 左括弧, コロン |
terminator-symbol | . 終止符 |
- 代替表現を規定する主な理由は、すべてのコンピュータやタイプライターが Table 1 に記載されている文字を持っているわけではないからである。
- 混乱を避けるために 1 つの文書における terminator-symbol の表現は一貫するべきである。
- 7.2 から 7.4 は Extended BNF に必要な文字が以下であることを意味してる:
letter digits = , - * ( ) ?
| or / or !
/ or [ ] の両方
: or { } の両方
' or " (定義されている言語でどちらかが終端記号である場合は両方の文字が必要)
7.5 その他の文字 (other-character)
other-character は ISO/IEC 646:1991 文字セットの中で以下のいずれでもないその他の文字である:
- 制御文字、または
- 他の terminal-character を表すために必要
注意 ─ 終端文字が Table 1 のように表現されている場合、other-characters は次のようになる:
空白
. 終止符
: コロン
! 感嘆符
+ プラス
_ 下線
% パーセント記号
@ 商用アット
& アンパーサンド
# ナンバー
$ ドル記号
< 小なり記号
> 大なり記号
/ 分割斜線
\ 逆分割斜線
^ サーカムフレックスアクセント
` グレイブアクセント
~ チルダ
7.6 ギャップ分割子 (gap-separator)
gap-separator は次のように表される:
- space は空白文字で表される
- horizontal-tabulation は水平タブ文字で表される
- new-line は、キャリッジリターン文字とラインフィード文字の (空の場合もある) シーケンス、キャリッジリターン文字の (空の場合もある) シーケンスで表される
- vertical-tabulation は垂直タブ文字で表される
- form-feed はフォームフィード文字で表される
7.7 ペアで表現される終端文字
Table 3 の文字ペアは、terminal-string や special-sequence の中を除き、syntax-rule の中で常に 1 つの terminal-character を表す。
注意 ─ この制限は、これらの文字列が曖昧であるために必要である。例えば /) は definition-separator-symbol の後に end-group-symbol や end-option-symbol が続いているのかもしれない。
(* |
*) |
(: |
:) |
(/ |
/) |
7.8 無効な文字シーケンス
Table 4 の各行は terminal-string や special-sequence 以外の syntax-rule では出現しない文字列を指定している。
(*) |
(:) |
(/) |
注意 ─ この制限が必要なのは、これらの文字列が曖昧だからである。例えば (*) は start-comment-symbol, end-group-symbol でも start-group-symbol, end-comment-symbol でも解釈できる。
gap-separator を挿入するとどちらの意味でも可能となる。例えば (* ) は start-comment-symbol, end-group-symbol であり、( *) は start-group-symbol, end-comment-symbol である。
8 例
8.1 Extended BNF の構文
(*
Extended BNF 構文はそれ自体を使って定義することができる。
この例には4 つの部分があり、最初の部分は文字の名前、2 番目は
不要な非印字文字の除去、3 番目はテキストコメントの除去を定義し、
最後の部分は Extended BNF の構造そのものを定義している。
この例の各構文規則は、規格の対応する条項を示すコメントで開始
している。
special-sequence の意味は規格では定義されていない。この例
(7.6 参照) では、ISO/IEC 6429:1992 で定義された制御関数を
表している。別の special-sequence は syntactic-exception
を定義する (4.7 参照)。
*)
(*
字句構文の最初の部分では Extended BNF の各 terminal-character
と gap-separator を表す 7-bit 文字セット (ISO/IEC
646:1991) の文字を定義している。
*)
(* see 7.2 *) letter
= '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'
| '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';
(* see 7.2 *) decimal digit
= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7'
| '8' | '9';
(*
以下の terminal-character の表現は 7.3, 7.4 節および
Table 1, 2 で定義されている。
*)
concatenate symbol = ',';
defining symbol = '=';
definition separator symbol = '|' | '/' | '!';
end comment symbol = '*)';
end group symbol = ')';
end option symbol = ']' | '/)';
end repeat symbol = '}' | ':)';
except symbol = '-';
first quote symbol = "'";
repetition symbol = '*';'
second quote symbol = '"';
special sequence symbol = '?';
start comment symbol = '(*';
start group symbol = '(';
start option symbol = '[' | '(/';
start repeat symbol = '{' | '(:';
terminator symbol = ';' | '.';
(* see 7.5 *) other character
= ' ' | ':' | '+' | '_' | '%' | '@'
| '&' | '#' | '$' | '<' | '>' | '\'
| '^' | '`' | '~';
(* see 7.6 *) space character = ' ';
horizontal tabulation character
= ? IS0 6429 character Horizontal Tabulation ?;
new line
= { ? IS0 6429 character Carriage Return ? },
? IS0 6429 character Line Feed ?,
{ ? IS0 6429 character Carriage Return ? };
vertical tabulation character
= ? IS0 6429 character Vertical Tabulation ?;
form feed
= ? IS0 6429 character Form Feed ?;
(*
構文の 2 番目の部分は、構文から不要な非印刷文字を除去する
ことを定義している。
*)
(* see 6.2 *) terminal character
= letter
| decimal digit
| concatenate symbol
| defining symbol
| definition separator symbol
| end comment symbol
| end group symbol
| end option symbol
| end repeat symbol
| except symbol
| first quote symbol
| repetition symbol
| second quote symbol
| special sequence symbol
| start comment symbol
| start group symbol
| start option symbol
| start repeat symbol
| terminator symbol
| other character;
(* see 6.3 *) gap free symbol
= terminal character
- (first quote symbol | second quote symbol)
| terminal string;
(* see 4.16 *) terminal string
= first quote symbol, first terminal character,
{first terminal character},
first quote symbol
| second quote symbol, second terminal character,
{second terminal character},
second quote symbol;
(* see 4.17 *) first terminal character
= terminal character - first quote symbol;
(* see 4.18 *) second terminal character
= terminal character - second quote symbol;
(* see 6.4 *) gap separator
= space character
| horizontal tabulation character
| new line
| vertical tabulation character
| form feed;
(* see 6.5 *) syntax
= {gap separator},
gap free symbol, {gap separator},
{gap free symbol, {gap separator}};
(*
構文の 3 番目の部分は、構文を形成する gap-free-symbol
から bracketed-textual-comment を削除する定義を
行う。
*)
(* see 6.6 *) commentless symbol
= terminal character
- (letter
| decimal digit
| first quote symbol
| second quote symbol
| start comment symbol
| end comment symbol
| special sequence symbol
| other character)
| meta identifier
| integer
| terminal string
| special sequence;
(* see 4.9 *) integer
= decimal digit, {decimal digit};
(* see 4.14 *) meta identifier
= letter, {meta identifier character};
(* see 4.15 *) meta identifier character
= letter
| decimal digit;
(* see 4.19 *) special sequence
= special sequence symbol,
{special sequence character},
special sequence symbol;
t* see 4.20 *) special sequence character
= terminal character - special sequence symbol;
(* see 6.7 *) comment symbol
= bracketed textual comment
| other character
| commentless symbol;
(* see 6.8 *) bracketed textual comment
= start comment symbol, {comment symbol},
end comment symbol;
(* see 6.9 *) syntax
= {bracketed textual comment},
commentless symbol,
{bracketed textual comment},
{commentless symbol,
{bracketed textual comment}};
(*
構文の最後の部分では Extended BNF の抽象構文、つまり
commentless-symbol を定義する。
*)
(* see 4.2 *) syntax
= syntax rule, {syntax rule};
(* see 4.3 *) syntax rule
= meta identifier, defining symbol,
definitions list, terminator symbol;
(* see 4.4 *) definitions list
= single definition,
{definition separator symbol,
single definition};
(* see 4.5 *) single definition
= syntactic term,
{concatenate symbol, syntactic term};
(* see 4.6 *) syntactic term
= syntactic factor,
[except symbol, syntactic exception];
(* see 4.7 *) syntactic exception
= ? a syntactic-factor that could be replaced
by a syntactic-factor containing no
meta-identifiers
? ;
(* see La *) syntactic factor
= [integer, repetition symbol],
syntactic primary;
(* see 4.10 *) syntactic primary
= optional sequence
| repeated sequence
| grouped sequence
| meta identifier
| terminal string
| special sequence
| empty sequence;
(* see 4.11 *) optional sequence
= start option symbol, definitions list,
end option symbol;
(* see 4.12 *) repeated sequence
= start repeat symbol, definitions list,
end repeat symbol;
(* see 4.13 *) grouped sequence
= start group symbol, definitions list,
end group symbol;
(* see 4.21 *) empty sequence
= ;
8.2 自身を非公式に定義する Extended BNF
(*
この例では Extended BNF を非公式に定義している。多くの
構文規則にはその意味を説明するコメントを含めている。コメントの
中では類似した英単語との混同を避けるためにメタ識別子を角括弧
< および > で囲んでいる。非終端記号である <letter>,
<decimal digit> および <character> は定義されていない。
<comments> の位置はコメントで述べられているが正式には
定義されていない。
*)
syntax = syntax rule, {syntax rule};
syntax rule
= meta identifier, '=' , definitions list, ';'
(* <syntax rule> は <meta identifier> で表される記号の
シーケンスを定義する *);
definitions list
= single definition, {'|', single definition}
(* | separates alternative
<single definitions> *);
single definition = term, {',', term}
(* | separates successive <terms> *);
term = factor, ['-', exception]
(* A <term> represents any sequence of symbols
that is defined by the <factor> but
not defined by the <exception> *);
exception = factor
(* A <factor> may be used as an <exception>
if it could be replaced by a <factor>
containing no <meta identifiers> *);
factor = [integer, '*'], primary
(* The <integer> specifies the number of
repetitions of the <primary> *);
primary
= optional sequence | repeated sequence
| special sequence | grouped sequence
| meta identifier | terminal string | empty;
empty = ;
optional sequence = '[', definitions list, ']'
(* The brackets [ and ] enclose symbols
which are optional *);
repeated sequence = '{', definitions list, '}'
(* The brackets { and > enclose symbols
which may be repeated any number of times *);
grouped sequence = '(', definitions list, ')',
(* The brackets ( and ) allow any
<definitions list> to be a <primary> *);
terminal string
= "'", character - "'", {character - "'"}, "'"
| '"', character - '"', {character - '"'}, '"'
(* A <terminal string> represents the
<characters> between the quote symbols
'_' or "_" *);
meta identifier = letter, {letter | decimal digit}
(* A <meta identifier> is the name of a
syntactic element of the language being
defined *);
integer = decimal digit, {decimal digit};
special sequence = '?', {character - '?'}, '?'
(* The meaning of a <special sequence>' is not
defined in the standard metalanguage. *);
comment = '(*', {comment symbol}, '*)'
(* A comment is allowed anywhere outside a
<terminal string>, <meta identifier>,
<integer> or <special sequence> *);
comment symbol
= comment | terminal string | special sequence
| character;
8.3 非公式に定義された Extended BNF
(*
この例は Table 2 で定義されている表現を使用している。
*)
SYNTAX = SYNTAX RULE, (: SYNTAX RULE :).
SYNTAX RULE
= META IDENTIFIER, '=', DEFINITIONS LIST, '.'.
DEFINITIONS LIST
= SINGLE DEFINITION,
(: '/', SINGLE DEFINITION :).
SINGLE DEFINITION = TERM, (: ',', TERM :).
TERM = FACTOR, (/ '-', EXCEPTION /).
EXCEPTION = FACTOR.
FACTOR = (/ INTEGER, '*' /), PRIMARY.
PRIMARY
= OPTIONAL SEQUENCE / REPEATED SEQUENCE
/ SPECIAL SEQUENCE / GROUPED SEQUENCE
/ META IDENTIFIER / TERMINAL / EMPTY.
EMPTY = .
OPTIONAL SEQUENCE = '(/', DEFINITIONS LIST, '/)'.
REPEATED SEQUENCE = '(:', DEFINITIONS LIST, ':)'.
GROUPED SEQUENCE = '(', DEFINITIONS LIST, ')'.
TERMINAL
= "'", CHARACTER - "'",
(: CHARACTER - "'" :), "'"
/ '"', CHARACTER - '"',
(: CHARACTER - '"' :), '"'.
META IDENTIFIER = LETTER, (: LETTER / DIGIT :).
INTEGER = DIGIT, (: DIGIT :).
SPECIAL SEQUENCE = '?', (: CHARACTER - '?' :), '?'.
COMMENT = '(*', (: COMMENT SYMBOL :), '*)'.
COMMENT SYMBOL
= COMMENT / TERMINAL / SPECIAL SEQUENCE
/ CHARACTER.
Annex A (informative) Two-level grammars
A.1
ほとんどのユーザにはこの国際規格に記載されている機能で十分だろう。しかし、より強力な拡張を望むユーザもいるかもしれない。この付録では Extended BNF を拡張して 2 レベルの文法を定義する方法を提案することでその可能性を示している。この種の文法は、例えば Algol 68 (van Wijngaarden, 1975) で使用されており、言語を定義するためのより正確だが直接的ではない方法を提供している。この (van Wijngaarden 文法、または W-文法で知られる) 表記法はより強力であるが、より複雑である。Algol 68 の作者が言うように "慣れていない読者には難しいかも知れない"。
2 レベル文法には 2 種類のルールが有る。ハイパールールと呼ばれるものは Extended BNF の構文ルールと似ているが、メタノーション (metanotion) と呼ばれる特殊な単語を含むことができる。他のルールはメタプロダクション (metaproduction) ルールと呼ばれ、それぞれのメタノーションに対する記号のシーケンスを定義する。言語の構文規則は各メタノーションをハイパールールで適切に置き換えることに寄って生成される。あるメタノーションがハイパールールの中で複数回出現する場合は、同一のメタノーションに置き換えて構文規則を生成する。終端文字列やコメントに含まれるメタノーションも体系的に置き換えられる。
A.2
Extended BNF を 2 レベルの文法に拡張するために必要は記法はほとんどない。
- metaproduction-defining-symbol、つまり == を導入することで、メタプロダクションルールをハイパールールと区別できるようにする。
- metanotion には大文字、hypernotion と meta-identifier には小文字を使うことで、メタノーションと他のハイパーノーションを区別する。
例えば、2 レベル文法によって定義される言語:
metaproduction rule:
INTREAL == integer | real;
hyper-rules:
program = {statement}, 'end';
statement = INTREAL statement;
INTREAL statement
= 'print INTREAL', INTREAL expression;
INTREAL expression = INTREAL value,
{('+' | '-' | '*' | '/'), INTREAL value};
integer value = digit, {digit};
real value
= digit, '.', digit, {digit}, '@', digit;
は (Extended BNF を使って定義した) 次の言語と等しい:
program = {statement}, 'end';
statement = integer statement;
statement = real statement;
integer statement
= 'print integer', integer expression;
real statement = 'print real', real expression;
integer expression = integer value,
{('+' | '-' | '*' | '/'), integer value};
real expression = real value,
{('+' | '-' | '*' | '/'), real value};
integer value = digit, {digit};
real value
= digit, '.', digit, {digit}, ,@', digit;
A.3
Extended BNF の構文は次のように変更する必要があるだろう:
- 以下のルールを挿入する:
metaproduction rule = metanotion, metaproduction defining symbol, hypernotion, {definition separator symbol, hypernotion}, terminator symbol; metanotion = upper case letter, {upper case letter); metaproduction defining symbol = "=="; hypernotion = letter, {letter | decimal digit}; upper case letter = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | '0' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'; lower case letter = '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';
- 既存のルールを変更する:
syntax = hyper rule, {hyper rule}; hyper rule = hypernotion, defining symbol, definitions list, terminator symbol; syntactic primary = optional sequence | repeated sequence | grouped sequence | hypernotion | terminal string | special sequence | empty sequence; letter = upper case letter | lower case letter; meta identifier = lower case letter, {lower case letter | decimal digit};
しかし、このような単純な定義ではメタノーションの置換が一意に定義されない可能性があること、プロダクションルールが無限に存在する可能性があること、無限の長さのプロダクションルールが存在する可能性があることなど、いくつかの問題が解決されないままとなる。
Annex B (informative) Bibliography
下記の標準や論文は導入でのみ参照している。
- ISO 1539:1980, Endorsement of ANSI X3.9-1978, American National Standard - Programming Language FORTRAN. American National Standards Institute, New York, USA. 1978.
- ISO/IEC 1539:1991, Information technology - Programming languages - FORTRAN.
- ISO 1989:1985, Endorsement of ANSI X3.23-1985, American National Standard - Programming Language COBOL. American National Standards Institute, New York, USA. 1985.
- ISO/IEC 9945-2:1993, Information technology - Portable Operating System Interface (POSIX) - Part 2: Shell and utilities.
- BS 5904, Programming languages - RTU2, British Standards Institution, 1979.
- BS 5905, Programming languages - CORAL 66, British Standards Institution, 1979.
- (Naur, 1960), P Naur (Editor}, Revised Report on the Algorithmic Language ALGOL 60, Computer Journal, Vol 5, No 4, pp349-367, Jan 1963.
- (van Wijngaarden, 1975), A van Wijngaarden, B J Mailloux, J E L Peck, C H A Kostel; M SintzofJ; C H Lindsey, L G L T Meertens, R G Fisker; Revised report on the Algorithmic Language ALGOL 68, Acta Informatica, Vol 5, parts l-3, 1975 (also published in SIGPLAN Notices, Vol 12, No 5, ppl-70, May 1977).
- (Wirth, 1977), N Wirth, What can we do about the unnecessary diversity of notation for syntactic definitions? Comm ACM, Vol 20, No 11, Nov 1977, p822.
翻訳抄
Extended BNF (EBNF) の ISO/IEC 14977:1996 規格。