2010-03-02

C++0x本:文法を説明する記法をどうするか

言語の文法をどのように説明すればいいのだろうか。規格では、Syntax Notationという記法を用いている。当初、これを使えばいいのではないかと思ったが、これは、あまりにも、普通のユーザーには不向きだ。

たとえば、整数リテラルのSyntax Notationは、いかに正しいとはいえ、こんな記述は、Language Lawyerでなければ、読む気がしないだろう。

integer-literal:
    decimal-literal integer-suffixopt
    octal-literal integer-suffixopt
    hexadecimal-literal integer-suffixopt
decimal-literal:
    nonzero-digit
    decimal-literal digit
octal-literal:
    0 octal-literal octal-digit
hexadecimal-literal:
    0x hexadecimal-digit
    0X hexadecimal-digit
    hexadecimal-literal hexadecimal-digit
nonzero-digit: one of
    1 2 3 4 5 6 7 8 9
octal-digit: one of
    0 1 2 3 4 5 6 7
hexadecimal-digit: one of
    0 1 2 3 4 5 6 7 8 9
    a b c d e f
    A B C D E F
integer-suffix:
    unsigned-suffix long-suffixopt
    unsigned-suffix long-long-suffixopt
    long-suffix unsigned-suffixopt
    long-long-suffix unsigned-suffixopt
unsigned-suffix: one of
    u U
long-suffix: one of
    l L
long-long-suffix: one of
    ll LL

しかし、たとえば、if文の場合(イタリック体などの修飾は省略)、

if ( condition ) statement
if ( condition ) statement else statement

このぐらいなら、使っても構わないだろう。あるいは、訳すか。

if ( 条件 ) 文
if ( 条件 ) 文 else 文

if文のような文であれば、別に、文法記法などといった、たいそうなものを使わなくても、サンプルコードひとつあれば、理解できるかもしれない。しかし、関数の宣言は、非常に厄介だ。

たとえば、関数の宣言は、T Dという形をとる。Dは、以下のようになる(文字の修飾は省略)。

D1 ( parameter-declaration-clause ) attribute-specifier opt cv-qualifier-seq opt ref-qualifier opt exception-specification opt

これは、この順番でなければならない。つまり、

struct Foo {

int // 戻り値の型
func // 関数名
(int x)// 仮引数の宣言句
[[]] // アトリビュート指定子
const // CV修飾子
& // リファレンス修飾子
throw() // 例外指定
}

もしこれらが、間違った順番であれば、文法違反である。

規格のSyntax Notationを使うべきか。あるいは、独自の文法記法を考えだすべきか。もし、規格の文法記法を使う場合、その文法カテゴリー(syntactic categories)、たとえば、parameter-declaration-clauseなどといったものは、翻訳するべきか。

現時点では、ユーザーにも分かる範囲の、規格の文法記法に準じた記法を使い、文法カテゴリーは、翻訳するべきであると考えている。つまり、関数の宣言の場合、T Dという形をとり、Dは、

D1 ( 仮引数の宣言句 ) アトリビュート指定子(省略可) CV修飾子(省略可) リファレンス修飾子(省略可) 例外指定(省略可) 

となる。

たとえば、選択文の場合、

選択文:
    if ( 条件 ) 文
    if ( 条件 ) 文 else 文
    switch ( 条件 ) 文

条件:
    式
    変数の宣言

となる。これは、普通のユーザーでも、理解できる範囲内だと思う。厳密には、条件(condition)は、以下のようになっている。

condition:
    expression
    type-specifier-seq attribute-specifier opt declarator = initializer-clause
    type-specifier-seq attribute-specifier opt declarator braced-init-list

しかし、こんな文法記法が、一般に受け入れられるわけがない。変数の宣言は宣言で、また、別の場所で解説すればいいのだ。

No comments: