ONC+ 開発ガイド

XDR 言語仕様

表記方法

この節では、XDR 言語を修正バッカス-ナウア記法で記述します。その表記規則を次に簡単に説明します。

  1. 特殊文字として、|()[]* を使用する

  2. 終端記号は、引用符 (") で囲んだ文字列または文字とする

  3. 非終端記号は、非特殊文字からなる文字列で、イタリックで表示する

  4. 代替項目は縦棒 (|) で区切って並べる

  5. 省略可能な項目は角括弧で囲む

  6. 項目をグループ化するときは、括弧で囲む

  7. 項目の後に * が付いている場合は、その項目の 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. コメントは、/**/ で囲む

  2. 空白は項目と項目の区切りに使用し、意味を持たない

  3. 識別子は英字で始まり、英字、数字、下線 (_) を含むことができる。識別子では、大文字と小文字を区別する

  4. 任意の桁数の 10 進数を定数といい、始めに負符号 (-)を付けることができる


    例 C-1 XDR 仕様

    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 *
     

構文ノート

  1. 次に示すものはキーワードとして予約されており、識別子として使用できない。

    表 C-1 XDR キーワード

    bool

    const

    enum

    int

    string

    typedef

    void

    cas

    default

    float

    opaque

    struct

    union

     

    cha

    double

    hyper

    quadruple

    switch

    unsigned

     

  1. 配列のサイズ指定に使用できるのは、符号なし定数だけである。識別子で指定するときは、その識別子をそれまでに const 定義を使用して符号なし定数として宣言しておく必要がある

  2. 指定範囲内の識別子の定数と型は、同じ名前空間内にあり、この範囲内で一意に宣言されている必要がある

  3. 同様に、構造体と共用体の宣言の有効範囲内では、変数名は一意的にする。構造体と共用体の宣言がネストしている場合は、新たな有効範囲ができる

  4. 共用体の要素識別子は、整数を表す型でなければならない。すなわち、intunsigned intboolenum、または、このどれかの型を typedef で定義したものでなければならない。case で指定する値は、要素識別子の型に応じた値でなければならない。また、union 宣言の有効範囲内で case の値を 2 回以上指定してはならない

XDR データ記述

ファイルのデータ構造を XDR で記述した簡単な例を次に示します。このデータは、マシン間のファイル転送に使用することができます。


例 C-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>;            /* ファイルデータ*/
};

john というユーザーが、(quit) というデータだけが入った自分の LISP プログラム sillyprog を XDR 形式で保存するとします。このファイルは次のように符号化されます。

表 C-2 XDR データ記述の例

オフセット 

バイト (16 進) 

ASCII 

説明 

00 00 00 09 

.... 

ファイル名の長さ = 9 

73 69 6c 6c 

sill 

ファイル名の文字列 

79 70 72 6f 

ypro 

ファイル名の文字列 (続き) 

12 

67 00 00 00 

g... 

ファイル名の文字列 (続き) と 3 バイトのヌルパディング 

16 

00 00 00 02 

.... 

ファイルタイプは 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 

john 

所有者名 

36  

00 00 00 06 

.... 

ファイルデータの長さ = 6 

40  

28 71 75 69 

(qu 

ファイルデータ 

44  

74 29 00 00 

t).. 

ファイルデータ (続き) と 2 バイトのヌルパディング