この節では XDR 言語の仕様について説明します。
この節では、XDR 言語を修正バッカス-ナウア記法で記述します。その表記規則を次に簡単に説明します。
特殊文字として、|、(、)、[、]、* を使用する
終端記号は、引用符 (") で囲んだ文字列または文字とする
非終端記号は、非特殊文字からなる文字列で、イタリックで表示する
代替項目は縦棒 (|) で区切って並べる
省略可能な項目は角括弧で囲む
項目をまとめてグループ化するときは、括弧で囲む
項目の後に * が付いている場合は、その項目の 0 回以上の繰り返しを表す
たとえば、次のパターンを考えてみます。
"a " "very" (", " " very")* [" cold " "and"] " rainy "
("day" | "night")
このパターンには、次の文字列を始めとして無数の文字列が一致します。
a very rainy day a very, very rainy day a very cold and rainy day a very, very, very cold and rainy night
仕様では次の決まりが使用されます。
空白は項目と項目の区切りに使用し、意味を持たない
定数は 1 つ以上の 10 進数のシーケンスで、次のコーディング例のように、オプションで先頭にマイナス記号 (-) を付けることができる。
Syntax Information
declaration:
type-specifier identifier
| type-specifier identifier "[" value "]"
| type-specifier identifier "<" [ value ] ">"
| "opaque" identifier "[" value "]"
| "opaque" identifier "<" [ value ] ">"
| "string" identifier "<" [ value ] ">"
| type-specifier "*" identifier
| "void"
value:
constant
| identifier
type-specifier:
[ "unsigned" ] "int"
| [ "unsigned" ] "hyper"
| "float"
| "double"
| "quadruple"
| "bool"
| enum-type-spec
| struct-type-spec
| union-type-spec
| identifier
enum-type-spec:
"enum" enum-body
enum-body:
"{"
( identifier "=" value )
( "," identifier "=" value )*
"}"
struct-type-spec:
"struct" struct-body
struct-body:
"{"
( declaration ";" )
( declaration ";" )*
"}"
union-type-spec:
"union" union-body
union-body:
"switch" "(" declaration ")" "{"
( "case" value ":" declaration ";" )
( "case" value ":" declaration ";" )*
[ "default" ":" declaration ";" ]
"}"
constant-def:
"const" identifier "=" constant ";"
type-def:
"typedef" declaration ";"
| "enum" identifier enum-body ";"
| "struct" identifier struct-body ";"
| "union" identifier union-body ";"
definition:
type-def
| constant-def
specification:
definition *
次に示すものはキーワードとして予約されており、識別子として使用できません。
配列のサイズ指定に使用できるのは、符号なし定数だけです。識別子で指定するときは、その識別子をそれまでに const 定義を使用して符号なし定数として宣言しておく必要があります。
指定範囲内の識別子の定数と型は、同じ名前空間内にあり、この範囲内で一意に宣言されている必要があります。
同様に、構造体と共用体の宣言の有効範囲内では、変数名は一意にする必要があります。構造体と共用体の宣言が入れ子になっている場合は、新しい有効範囲ができます。
共用体の要素識別子は、整数を表す型にする必要があります。すなわち、int、unsigned int、bool、enum、または、このどれかの型を typedef で定義したものでなければなりません。case で指定する値は、要素識別子の型に応じた値にする必要があります。また、union 宣言の有効範囲内で case の値を 2 回以上指定することはできません。
ファイルのデータ構造を XDR で記述した簡単な例を次に示します。このデータは、マシン間のファイル転送に使用することができます。
const MAXUSERNAME = 32;/* ユーザー名の長さの最大値 */
const MAXFILELEN = 65535; /* ファイルの長さの最大値 */
const MAXNAMELEN = 255; /* ファイル名の長さの最大値 */
/* ファイルのタイプ: */
enum filekind {
TEXT = 0, /* ASCII データ */
DATA = 1, /* raw データ */
EXEC = 2 /* 実行可能ファイル */
};
/* ファイルタイプ別のファイル情報: */
union filetype switch (filekind kind) {
case TEXT:
void; /* 追加情報なし */
case DATA:
string creator<MAXNAMELEN>; /* データ作成者 */
case EXEC:
string interpreter<MAXNAMELEN>; /*プログラムインタプリタ*/
};
/* 完全なファイル: */
struct file {
string filename<MAXNAMELEN>; /* ファイル名 */
filetype type; /* ファイル情報 */
string owner<MAXUSERNAME>; /* ファイルの所有者 */
opaque data<MAXFILELEN>; /* ファイルデータ */
};
linda というユーザーが、(quit) というデータだけが入った自分の LISP プログラム sillyprog を XDR 形式で保存するとします。このファイルは次の表に示すように符号化されます。
表 C–1 XDR データ記述の例|
オフセット |
バイト (16 進) |
ASCII |
説明 |
|---|---|---|---|
|
0 |
00 00 00 09 |
– |
ファイル名の長さ = 9 |
|
4 |
73 69 6c 6c |
sill |
ファイル名の文字列 |
|
8 |
79 70 72 6f |
ypro |
ファイル名の文字列 (続き) |
|
12 |
67 00 00 00 |
g |
ファイル名の文字列 (続き) と 3 バイトのヌルパディング |
|
16 |
00 00 00 02 |
– |
ファイルタイプ Filekind は EXEC = 2 |
|
20 |
00 00 00 04 |
– |
インタプリタ名の長さ = 4 |
|
24 |
6c 69 73 70 |
lisp |
インタプリタの文字列 |
|
28 |
00 00 00 04 |
– |
所有者名の長さ = 4 |
|
32 |
6a 6f 68 6e |
linda |
所有者名 |
|
36 |
00 00 00 06 |
– |
ファイルデータの長さ = 6 |
|
40 |
28 71 75 69 |
(qu |
ファイルデータ |
|
44 |
74 29 00 00 |
t) |
ファイルデータ (続き) と 2 バイトのヌルパディング |