This document is encoded by Japanese<Shift-JIS>.
This document was translated with original author's permision.


Eiffel: 構文


 ここで記述する注釈付きの Eiffel 構文は、コンパイラ、インタープリタ、構文チェッカ、簡潔平坦書式ツール、整形印刷などといった Eiffel のツールを書いており、何らかの助言<tips>や秘訣<tricks>から恩恵を得たいと願っている人を対象としています。これは、Nonprofit International Consortium for Eiffel(NICE)によって提供された公式な Eiffel の構文仕様ではないけれども、二、三の明確に文書化された資料だけから出発しています。とりわけ、既存のコンパイラが Eiffel の構文のどこを拡張し、ときには何故そうしたのかを解説しています。

 Eiffel の構文要素は、グループにまとめて並べてあり、Class_declaration(クラス宣言) といった上位の要素から始めて、Identifier(識別子) といった字句要素へ落とします。代わりに、これらの構成要素は、アルファベット順 でも提供しています。 Eiffel の構文を記述するために用いる 表記法 は、別のページで規定しています。同じく、yacclex に準じた書式での、Eiffel 構文の可能な実装も、例として提供しています。


Class_declaration(クラス宣言)
[ Indexing(索引付け) ]
Class_header(クラス ヘッダー)
[ Formal_generics(形式総称パラメータ群) ]
[
Obsolete(先駆者) ]
[
Inheritance(継承) ]
[
Creators(生成子群) ]
[
Features(特徴群) ]
[
Invariant(不変条件) ]
end [ -- class Class_name(クラス名) ]

注意事項: ほとんどの Eiffel コンパイラは、キーワード end の後にある付加的な注釈の有効性を検査しません。けれども、SmallEiffel は、警告を出します。

注意事項: 一つのファイルは、一つ以上のクラス宣言を含んでもよいです。しかしながら、ほとんどの Eiffel コンパイラは、ファイルごとに一クラスと制限しています。


Indexing(索引付け)
indexing Index_list(索引並び)
Index_list(索引並び)
{ Index_clause(索引句) ; ... }
Index_clause(索引句)
[ Index(索引) ] Index_terms(索引項群)
Index(索引)
Identifier(識別子) :
Index_terms(索引項群)
{ Index_value(索引の値) , ... }+
Index_value(索引の値)
Identifier(識別子) | Manifest_constant(明示定数)


Class_header(クラス ヘッダー)
[ Header_mark(ヘッダー標識) ] class Class_name(クラス名)
Header_mark(ヘッダー標識)
deferred | expanded | separate

注意事項: キーワード separate は、Eiffel 標準の一部ではありません。これは、SCOOP の仕組みをサポートするために、ISE Eiffel で導入されました。詳細については、Object-Oriented Software Construction, second edition を読んでください。

Class_name(クラス名)
Identifier(識別子)


Formal_generics(形式総称パラメータ群)
[ Formal_generic_list(形式総称パラメータ並び) ]
Formal_generic_list(形式総称パラメータ並び)
{ Formal_generic(形式総称パラメータ) , ... }

注意事項: 形式総称パラメータ群の並びは、空であってもよいです。結果として、 FOO[] は、有効であり、FOO と同じものを意味します。しかしながら、これは、推奨される様式ではありません。

Formal_generic(形式総称パラメータ)
Formal_generic_name(形式総称パラメータ名) [ Constraint(制約) ]
Formal_generic_name(形式総称パラメータ名)
Identifier(識別子)
Constraint(制約)
-> Class_type(クラスの型)


Obsolete(先駆者)
obsolete Message(メッセージ)
Message(メッセージ)
Manifest_string(明示文字列)


Inheritance(継承)
inherit Parent_list(親クラス並び)
Parent_list(親クラス並び)
{ Parent(親クラス) ; ... }
Parent(親クラス)
Class_type(クラスの型) [ Feature_adaptation(特徴の適応) ]
Feature_adaptation(特徴の適応)
[ Rename(名前変更) ]
[
New_exports(新たな公開群) ]
[
Undefine(定義取消) ]
[
Redefine(再定義) ]
[
Select(選抜) ]
end

注意事項: この構成要素が理由で、Eiffel の文法は、LR(1) ではありません。これは、次の状況で発生します。

class FOO
inherit
    BAR
end

 キーワード endは、Class_declaration(クラス宣言)の一部としての代わりに、付加的な Feature_adaptation(特徴の適応) の一部として考慮されることになります。

 この問題を解決する方法は、Feature_adaptation(特徴の適応) を構成している付加的な構成要素の少なくとも一つが存在するときにだけ、Feature_adaptation(特徴の適応) の中で、キーワード end を許すことであったでしょう。


Rename(名前変更)
rename Rename_list(名前変更並び)
Rename_list(名前変更並び)
{ Rename_pair(名前変更の対) , ... }
Rename_pair(名前変更の対)
Feature_name(特徴名) as Feature_name(特徴名)


New_exports(新たな公開群)
export New_export_list(新たな公開並び)
New_export_list(新たな公開並び)
{ New_export_item(新たな公開項目) ; ... }
New_export_item(新たな公開項目)
Clients(クライアント群) Feature_set(特徴の集合)
Feature_set(特徴の集合)
Feature_list(特徴並び) | all
Feature_list(特徴並び)
{ Feature_name(特徴名) , ... }


Clients(クライアント群)
{ Class_list(クラス並び) }
Class_list(クラス並び)
{ Class_name(クラス名) , ... }


Redefine(再定義)
redefine Feature_list(特徴並び)
Undefine(定義取消)
undefine Feature_list(特徴並び)
Select(選抜)
select Feature_list(特徴並び)


Creators(生成子)
creation { Creation_clause(生成句) creation ... }+
Creation_clause(生成句)
[ Clients(クライアント群) ] [ Header_comment(ヘッダー注釈) ] Procedure_list(手続き並び)

注意事項: 標準の構文は、Procedure_list(手続き並び) の代わりに、Feature_list(特徴並び) を要求しますが、Creation_clause(生成句)は、実際には、生成手続きの名前を並べます(有効性規則 VGCP-2 を見てください)。

Procedure_list(手続き並び)
{ Procedure_name(手続き名) , ... }
Procedure_name(手続き名)
Identifier(識別子)

注意事項: Prefix(前置子)Infix(中置子) は、関数名であり、手続き名ではありません。Prefix(前置子) が属性名になり得たかどうかは、私には明らかではありませんが、明確に手続き名ではありません(有効性規則 VFFD-5 を見てください)。


Features(特徴群)
feature { Feature_clause(特徴句) feature ... }+
Feature_clause(特徴句)
[ Clients(クライアント群) ] [ Header_comment(ヘッダー注釈) ] Feature_declaration_list(特徴宣言並び)
Feature_declaration_list(特徴宣言並び)
{ Feature_declaration(特徴宣言) ; ... }


Feature_declaration(特徴宣言)
New_feature_list(新たな特徴並び) Declaration_body(宣言本体)
Declaration_body(宣言本体)
[ Formal_arguments(形式引数) ] [ Type_mark(型標識) ] [ Constant_or_routine(定数またはルーチン) ]
Constant_or_routine(定数またはルーチン)
is Feature_value(特徴の値)
Feature_value(特徴の値)
Manifest_constant(明示定数) | Unique(唯一属性) | Routine(ルーチン)
Unique(唯一属性)
Unique


New_feature_list(新たな特徴並び)
{ New_feature(新たな特徴) , ... }+
New_feature(新たな特徴)
[ frozen ] Feature_name(特徴名)


Feature_name(特徴名)
Identifier(識別子) | Prefix(前置子) | Infix(中置子)
Prefix(前置子)
prefix " Prefix_operator(前置演算子) "
Infix(中置子)
infix " Infix_operator(中置演算子) "
Prefix_operator(前置演算子)
Unary(単項演算子) | Free_operator(自由演算子)
Infix_operator(前置演算子)
Binary(二項演算子) | Free_operator(自由演算子)

注意事項: すべての Eiffel コンパイラは、 prefix "NOT" または infix "AnD" などといった、大文字か小文字かには関係なく、前置演算子と中値演算子を受け付けます。

注意事項: 間の文字は、最初の二重引用符から最後の二重引用符までのあいだ、何一つ許されません。しかしながら、 and then または or else内の二つのキーワードの間でどんな種類の切断文字が使用されているかは明らかではありません。SmallEiffel は空白文字をいくつでも受け付けますが、他のコンパイラは一つの空白文字だけを要求します。


Unary(単項演算子)
not | + | -
Binary(二項演算子)
+ | - | * | / | < | > | <= | >= | // | \\ | ^ |
and | or | xor | and then | or else | implies


Formal_arguments(形式引数)
( Entity_declaration_list(実体宣言並び) )
Entity_declaration_list(実体宣言並び)
{ Entity_declaration_group(実体宣言グループ) ; ... }
Entity_declaration_group(実体宣言グループ)
Identifier_list(識別子並び) Type_mark(型標識)
Identifier_list(識別子並び)
{ Identifier(識別子) , ... }+
Type_mark(型標識)
: Type(型)

注意事項: 実体宣言の並びは、空であってもよいです。結果として、foo() は、有効であり、foo と同じものを意味します。しかしながら、これは、推奨される様式ではありません。


Routine(ルーチン)
[ Obsolete(先駆者) ]
[
Header_comment(ヘッダー注釈) ]
[
Precondition(事前条件) ]
[
Local_declarations(局所宣言群) ]
Routine_body(ルーチン本体)
[ Postcondition(事後条件) ]
[
Rescue(救助) ]
end [ -- Feature_name(特徴名) ]

注意事項: ほとんどの Eiffel コンパイラは、キーワード end の後にある付加的な注釈の有効性を検査しません。この注釈を置くことは、今はもう、様式指針にはありません。


Routine_body(ルーチン本体)
Effective(実効的) | Deferred(延期の)
Effective(実効的)
Internal(内部の) | External(外部の)
Internal(内部の)
Routine_mark(ルーチン標識) Compound(混成)
Routine_mark(ルーチン標識)
do | once
Deferred(延期の)
deferred


External(外部の)
external Language_name(言語名) [ External_name(外部名) ]
Language_name(言語名)
Manifest_string(明示文字列)
External_name(外部名)
alias Manifest_string(明示文字列)

注意事項: それそれの Eiffel コンパイラは、他のプログラミング言語とのインターフェイスを記述するために、言語名と外部名の文字列の中でコンパイラ固有のミニ構文をサポートしています。詳細については、個々のコンパイラに付いてくる文書を見てください。


Local_declarations(局所宣言群)
local Entity_declaration_list(実体宣言並び)


Precondition(事前条件)
require [ else ] Assertion(表明)
Postcondition(事後条件)
ensure [ then ] Assertion(表明)
Invariant(不変条件)
invariant Assertion(表明)
Assertion(表明)
{ Assertion_clause(表明句) ; ... }
Assertion_clause(表明句)
[ Tag_mark(札標識) ] Unlabeled_assertion_clause(ラベル無し表明句)
Unlabeled_assertion_clause(ラベル無し表明句)
Boolean_expression(真理値式) | Comment(注釈)
Tag_mark(札標識)
Tag(札) :
Tag(札)
Identifier(識別子)

注意事項: ヘッダー注釈のような注釈は、Routine(ルーチン) あるいは Features(特徴群) で拡張されるけれども、これは、注釈を無視することが結果として構文エラーまたは正しくない構文木となる唯一のところです。これは、次の状況で発生します。

require
    tag: -- 無視されたときには構文エラー!
do

and

require
    tag: -- もしこの注釈が無視されるならば、
         -- tag は、はからずも、foo.is_valid
         -- と関連することになります!

 より詳しいことについては、Comment(注釈) の二番目の注意事項を見てください。


Rescue(救助)
rescue Compound(混成)

注意事項: 有効性規則 VXRT は、Retry 命令が reacue 句で有効なだけである、と述べています。これは、結局は、構文によって強制できました。


Type(型)
Class_type(クラスの型) |
Class_type_expanded(クラスの型 拡張) |
Class_type_separate(クラスの型 分離) |
Anchored(アンカー付き) | Bit_type(ビット型)

注意事項: 標準の Eiffel 構文はまた、Type のための可能な代替案として、Formal_generic_name(形式総称パラメータ名) を並べます。しかしながら、それは、識別子が Formal_generic_name(形式総称パラメータ名) と実総称を持たない Class_type(クラスの型) との両方として認識できるから、構文内に曖昧さを持ち込みました。

Class_type(クラスの型)
Class_name(クラス名) [ Actual_generics(実総称群) ]
Actual_generics(実総称群)
[ Type_list(型並び) ]
Type_list(型並び)
{ Type(型) , ... }

注意事項: 型の並びは、空であってもよいです。結果として、 FOO[] は、有効であり、FOO と同じものを意味します。しかしながら、これは、推奨される様式ではありません。

Class_type_expanded(クラスの型 拡張)
expanded Class_type(クラスの型)
Class_type_separate(クラスの型 分離)
separate Class_type(クラスの型)

注意事項: Class_type_separate(クラスの型 分離) は、Eiffel 標準の一部ではありません。それは、SCOOP の機構をサポートするために、ISE Eiffel に導入されました。詳細については、Object-Oriented Software Construction, second edition を読んでください。

Bit_type(ビット型)
BIT Bit_length(ビット長)

注意事項: 標準の構文では、Constant(定数) は、Bit_length(ビット長) の代わりに現れます。しかしながら、有効性規則 VTBT は、と述べています。Bit_type(ビット型) の宣言が有効なのは、その Constant(定数) が型 INTEGER である場合だけです。INTEGER が、定数は明示整数定数か属性定数のいずれかである、ということを意味しているのです。

Bit_length(ビット長)
Integer_constant(整数定数) | Attribute(属性)
Anchored(アンカー付き)
like Anchor(アンカー)
Anchor(アンカー)
Identifier(識別子) | Current


Compound(混成)
{ Instruction(命令) ; ... }
Instruction(命令)
Creation(生成) | Call(呼び出し) | Assignment(割り当て) |
Assignment_attempt(試行割り当て) | Conditional(条件命令) |
Multi_branch(多岐分岐) | Loop(ループ) | Debug(デバッグ) |
Check(検査) | Retry(再試行) | Null_instruction(空命令)


Creation(生成)
! [ Type(型) ] ! Writable(書き込み可能) [ Creation_call(生成呼び出し) ]

注意事項: もし型が無いならば、二つの感嘆符を書く際に、間の切断文字はあっても無くてもよいです。標準の様式で、推奨される書式は、切断文字が無く、!! が現れても、一つの字句シンボルとしたものです。

Creation_call(生成呼び出し)
. Procedure_name(手続き名) [ Actuals(実パラメータ群) ]

注意事項: 標準の Eiffel 構文では、Creation_call(生成呼び出し) は、Unqualified_call(限定無し呼び出し) から構成されます。しかし、有効性規則 VGCC-6 は、、と述べています。もし f Creation_call(生成呼び出し) の特徴であるならば、 f は手続きです。


Assignment(割り当て)
Writable(書き込み可能) := Expression(式)
Assignment_attempt(試行割り当て)
Writable(書き込み可能) ?= Expression(式)


Conditional(条件命令)
if Then_part_list(then 部並び) [ Else_part(else 部) ] end
Then_part_list(then 部並び)
{ Then_part(then 部) elseif ... }+
Then_part(then 部)
Boolean_expression(真理値式) then Compound(混成)
Else_part(else 部)
else Compound(混成)


Multi_branch(多岐分岐)
inspect Expression(式)
[ When_part_list(when 部並び) ] [ Else_part(else 部) ] end
When_part_list(when 部並び)
when { When_part(when 部) when ... }+
When_part(when 部)
Choices(選択) then Compound(混成)
Choices(選択)
{ Choice(選択) , ... }

注意事項: 選択の並びは空でもよいです。結果として、

inspect expr
when then
    do_something
...

意味はないけれども、構文的に正しいです。これは、次のように考えることができます。

if False then
    do_something
...

しかしながら、これは、推奨される様式ではありません。

Choice(選択)
Choice_constant(選択定数) | Interval(間隔)

注意事項: 標準の構文は、Choice_constant(選択定数)の代わりにConstant(定数) を規定します。しかしながら、有効性規則 VOMB-1-2 は、Constant(定数) と Interval(間隔) は、型 INTEGER または CHARACTER だけからなる、と述べています。

Interval(間隔)
Choice_constant(選択定数) .. Choice_constant(選択定数)

注意事項: 字句解析プログラムは、次の例のように、十分整然としていなければなりません。

inspect expr
when 1..2 then
...

 実際、'1..2' は、二つの連続した実数定数 '1.' と '.2' ではなく、Eiffel のシンボルである '..' で区切られた、二つの整数定数 '1' と '2' として認識されます。Visual Eiffel は、はからずも、上の例を解析するときに、構文エラーを出します。

Choice_constant(選択定数)
Integer_constant(整数定数) | Character_constant(文字定数) | Attribute(属性)

注意事項: TowerEiffel は、Choice(選択)Interval(間隔) の中で、次のような「remote constant(遠隔定数)」を受け付けます。

foo: FOO
inspect i
when foo.const then
     do_something
end

 ここで、const は、クラス FOO の定数として宣言されています。これは、標準の Eiffel 構文ではありません。


Loop(ループ)
Initialization(初期化)
[ Invariant(不変条件) ]
[
Variant(変化条件) ]
Loop_body(ループ本体)
end
Initialization(初期化)
from Compound(混成)
Variant(変化条件)
variant [ Tag_mark(札標識) ] Expression(式)

注意事項: 有効性規則 VAVE は、Expression(式) は、型 INTEGER でなければならないと述べています。これは、はからずも、Equality(等価)Manifest_array(明示配列)Strip(除去)、そしてすべての非整数 Manifest_constant(明示定数) 群によって、構文内で部分的に強制できました。

Loop_body(ループ本体)
Exit(脱出) loop Compound(混成)
Exit(脱出)
until Boolean_expression(真理値式)


Debug(デバッグ)
debug [ Debug_keys(デバッグ キー群) ] Compound(混成) end
Debug_keys(デバッグ キー群)
( Debug_key_list(デバッグ キー並び) )
Debug_key_list(デバッグ キー並び)
{ Debug_key(デバッグ キー) , ... }
Debug_key(デバッグ キー)
Manifest_string(明示文字列)


Check(検査)
check Assertion(表明) end


Retry(再試行)
retry

注意事項: 有効性規則 VXRT は、Retry(再試行) 命令は Rescue(救助) 句の中で有効なだけである、と述べています。これは、結果的に、構文によって強制できました。


Null_instruction(空命令)
empty

注意事項: この命令は、純粋に構文上の役割でけを持っています。つまり、次のように、Compound(混成) へ見過ごすことによって加えられた余計なセミコロンが無害であることを確実にすることです。

if c then ; i1;;; i2; else ;; end

 TowerEiffel は、終結子<terminator>以外の他の余計なセミコロンをサポートしません。その他のすべてのコンパイラは、予期した通りに働きます。SmallEiffel は、余計なセミコロンを解析するときに、警告を出します。


Call(呼び出し)
Qualified_call(限定付き呼び出し) | Precursor(先駆者)
Qualified_call(限定付き呼び出し)
[ Call_qualifier(呼び出し限定子) ] Call_chain(呼び出し連鎖)
Call_qualifier(呼び出し限定子)
Call_target(呼び出し標的) .
Call_target(呼び出し標的)
Parenthesized(括弧付き式) | Result | Current(現在) | Precursor(先駆者)
Call_chain(呼び出し連鎖)
{ Unqualified_call(限定無し呼び出し) . ... }+
Unqualified_call(限定無し呼び出し)
Identifier(識別子) [ Actuals(実パラメータ群) ]

注意事項: この Call(呼び出し) の仕様は、標準で提供された版とは少し異なります。しかしながら、標準の構文は、次のように、正しい Eiffel ではない構成要素を受け付けます。

foo.Result Current (5)

は、上で与えられた仕様に反して、受け付けません。

注意事項: TowerEiffelでは、次のように、特徴群は、定数の周囲の括弧を置くこと無く、Manifest_constant(明示定数) 上で直接呼び出してもよいです。

str := 'a'.out

 標準の構文を使用すれば、次のようになるはずです。

str := ('a').out

 けれども、Integer_constant(整数定数) 上に些細な字句上の問題があり、

123.out

が、次のように認識されるからです。

123. out

 '123.' は、Real_constant(実数定数)なのです。プログラマは、この問題を避けるために、整数定数とドットの間に余計な Break(切断文字) を加えるべきです。


Precursor(先駆者)
[ Parent_qualification(親クラスの限定) ] Precursor [ Actuals(実パラメータ群) ]
Parent_qualification(親クラスの限定)
{ Class_name(クラス名) }

注意事項: Precursor(先駆者) という構成要素は、標準の Eiffel 構文の一部ではありません。それは、Object-Oriented Software Construction, second edition で導入されており、その標準に対する提案が NICE へ提出されています。ISE Eiffel と Halstenbach は、彼らの次のリリースで、ほぼ恐らく、この構成要素をサポートすることになります。

注意事項: Object-Oriented Software Construction, second edition で、Parent_qualification(親クラスの限定) 内のクラス名は、{{Class_name}} のように二重の中括弧で囲まれています。しかしながら、NICE へ提出された提案は、上で規定した構文を使用しています。


Attribute(属性)
Identifier(識別子)

注意事項: 有効性規則 VFFD-5 に従って、 Attribute(属性) はまた、Prefix(前置子) であることができます。

Writable(書き込み可能)
Identifier(識別子) | Result

注意事項: 標準構文仕様からの Entity(実体) の構文グループは、多くの曖昧さを解決するために、非常に単純化されています。たとえば、次のように、

foo

Attribute(属性)Local(局所的)、あるいは Formal(形式的)として認識されますか? 意味論の分析だけが、答えを与えることができます。


Actuals(実パラメータ群)
( Actual_list(実パラメータ並び) )
Actual_list(実パラメータ並び)
{ Actual(実パラメータ) , ... }

注意事項: 実パラメータ群の並びは、空でもよいです。結果として、foo() は有効であり、foo と同じものを意味します。しかしながら、これは、推奨される様式ではありません。

Actual(実パラメータ)
Expression(式) | Address(アドレス)

注意事項: TowerEiffel は、Address(アドレス)を通常の式として扱います(すなわち、Expression(式) の構成要素内の代替としてです)。けっかとして、アドレスは、実パラメータ並びの中でだけ発生する必要はありません。

Address(アドレス)
$ Address_mark(アドレス標識)
Address_mark(アドレス標識)
Feature_name(特徴名) | Current | Result


Expression(式)
Current | Result |
Call(呼び出し) | Operator_expression(演算子式) |
Equality(等値) | Manifest_array(明示配列) |
Old(直前値) | Strip(除去) | Boolean_constant(真理値定数) |
Bit_constant(ビット定数) | Integer(整数) | Real(実数) |
Manifest_string(明示文字列) | Character_constant(文字定数) |
Wide_character_constant(幅広文字定数) |
Wide_manifest_string(幅広明示文字列) |
Hexadecimal_constant(16 進数定数)

注意事項: この Expression(式) の仕様は、標準で提供されたバージョンとは少し異なります。まず、CurrentResult は、Call(呼び出し) のための新仕様の結果として追加されています。それから、Manifest_constant(明示定数) は、その代替の並びと置き換えられています。これは、標準の構文における曖昧さを解決するためのものです。次のコードの断片では、

foo := - 2

割り当ての左辺上の Expression(式) は、Integer_constant(整数定数) として、あるいは、Prefix_operator(前置演算子) が '-' で、その Expression(式) が (unsigned) Integer(整数) である Unary_expression(単項式) として認識されるでしょうか? Integer_constant(整数定数)Real_constant(実数定数)Integer(整数)Real(実数) によって置き換えることが、問題を解決します。

注意事項: Wide_character_constant(幅広文字定数)Wide_manifest_string(幅広明示文字列)、そして Hexadecimal_constant(16 進数定数) は、標準の一部ではありません。それらは、幅広の文字と文字列、そして 16 進の整数をサポートするために、TowerEiffel で導入されました。

Boolean_expression(真理値式)
Expression(式)

注意事項: 有効性規則 VWBE は、真理値式は、型 BOOLEAN でなければならない、と述べています。これは、結局は、Manifest_array(明示配列)Strip(除去)、そして、すべての非真理値の Manifest_constant(明示定数) 群を放棄することによって、構文内で部分的に強制できました。


Operator_expression(演算子式)
Parenthesized(括弧付き式) | Unary_expression(単項式) | Binary_expression(二項式)
Parenthesized(括弧付き式)
( Expression(式) )
Unary_expression(単項式)
Prefix_operator(前置演算子) Expression(式)
Binary_expression(二項式)
Expression(式) Infix_operator(中置演算子) Expression(式)

注意事項: 演算子の優先順位と結合規則については、Operator(演算子) を見てください。


Equality(等値)
Expression(式) Comparison(比較) Expression(式)
Comparison(比較)
= | /=

注意事項: 演算子の優先順位と結合規則については、Operator(演算子) を見てください。


Manifest_constant(明示定数)
Boolean_constant(真理値定数) | Character_constant(文字定数) |
Integer_constant(整数定数) | Real_constant(実数定数) |
Manifest_string(明示文字列) | Bit_constant(ビット定数) |
Wide_character_constant(幅広文字定数) |
Wide_manifest_string(幅広明示文字列) |
Hexadecimal_constant(16 進数定数)

注意事項: Wide_character_constant(幅広文字定数)Wide_manifest_string(幅広明示文字列)、そして Hexadecimal_constant(16 進数定数) は、標準の一部ではありません。それらは、幅広の文字と文字定数、そして 16 進数定数をサポートするために TowerEiffel で導入されました。

Boolean_constant(真理値定数)
True | False
Integer_constant(整数定数)
[ Sign(符号) ] Integer(整数)

注意事項: ここで、標準の構文には、曖昧さがあります。次のコードの断片で、

foo := - 2

割り当ての左辺上の Expression(式) は、Integer_constant(整数定数) として、あるいは、Prefix_operator(前置演算子) が '-' であり、その Expression(式) が (unsigned) Integer(整数) である Unary_expression(単項式) として認識されるでしょうか? これは、現在の構文記述では、Expression(式) のための仕様を書き直すことによって解決されています。

Real_constant(実数定数)
[ Sign(符号) ] Real(実数)

注意事項: 上の Integer_constant(整数定数) に対するのと同じ曖昧さがあります。

Sign(符号)
+ | -
Wide_character_constant(幅広文字定数)
$ Character_constant(文字定数)

注意事項: Wide_character_constant(幅広文字定数) は、標準の一部ではありません。それは、幅広文字をサポートするために TowerEiffel で導入されました。

注意事項: 間の文字は、ドル記号と Character_constant(文字定数) との間では、一切許されません。

Wide_manifest_string(幅広明示文字列)
$ Manifest_string(明示文字列)

注意事項: Wide_manifest_string(幅広明示文字列) は、標準の一部ではありません。それは、文字列内の幅広文字をサポートするために TowerEiffel で導入されました。

注意事項: 間の文字は、ドル記号と Manifest_string(明示文字列) との間では、一切許されません。


Manifest_array(明示配列)
<< Expression_list(式並び) >>
Expression_list(式並び)
{ Expression(式) , ... }


Old(直前値)
old Expression(式)

注意事項: 有効性規則 VAOL-1 は、Old 式は、Postcondition(事後条件) の中でだけ有効である、と述べています。これは、結局は、構文によって強制できました。


Strip(除去)
Strip ( Attribute_list(属性並び) )
Attribute_list(属性並び)
{ Attribute(属性) , ... }


Identifier(識別子)
 識別子は、一字以上の文字を並べたものであり、最初は文字 (a から z までと、A から Z まで)であり、そして、それ以降に文字があれば、その各々は文字、十進数字 (0から 9 まで)、あるいは下線文字(_) です。
大文字か小文字かは、文字に対して重要ではありません。つまり、二つの識別子 lInKeD_liSTLINKED_LIST は、同じものと考えられます。

注意事項: 残念ながら、 SmallEiffel は、大文字と小文字を区別します(驚いたことに、Reserved_word(予約語) 類については、区別していません)。

注意事項: 識別子が有効であるのは、それが Reserved_word(予約語) の一つでないときに限ります。

注意事項: TowerEiffel は、特徴名とクラス名の中では、連続した下線文字を処理できません。


Integer(整数)
 整数は文字が連続したものであり、それぞれの文字は、次のいずれかでなければなりません。
 もし下線文字があるならば、あらゆる下線文字の右側に、数字が三つ無ければならず、4桁の数字が連続するまとまりがあってはなりません。

注意事項: 下線文字に関する最後の二つの制約は、どんな桁数の数字のまとまりも許すように、将来取り除かれるかもしれません。

注意事項: Integer_constant(整数定数)とは反対に、Integer(整数)には符号はありません。

注意事項: 最小の整数の値の問題に用心してください! たとえば、整数が 32 ビットで格納されるプラットフォーム上では、次の Eiffel コードは有効です。

Minimum_integer: INTEGER is - 2_147_483_648 
        -- Smallest supported value of type INTEGER

しかし、構文解析プログラムは、十分に整然としているべきであり、そうでなければ、単項のマイナス演算子に続く整数 2147473648 を読むことになります。これは、32 ビットには合わず、そのため桁溢れを誘発します。


Hexadecimal_constant(16 進数定数)
 16 進数定数は、二字以上の文字が並んだものであり、最初の文字は十進数字(0 から 9 まで)であり、 続く文字は最後の数字を除き十進数字か文字(a から f、または A から F まで)であり、その後に x または X が続き、他の文字を間に伴わないものです。

注意事項: Hexadecimal_constant(16 進数定数) は、標準の一部ではありません。それは、16 進数定数をサポートするために、TowerEiffel で導入されました。

注意事項: 下線文字が 16 進数定数の中で許されるかどうかは、明らかではありません。


Real(実数)
実数は、次の要素から成ります。
間の文字(空白または他の文字)は、これらの要素の間では一切認められません。整数部と小数部は、両方を無くしてはいけません。もし下線文字が整数部または小数部で使われるならば、それらは、三桁以下の数字でない限りは、他の部にも同様に現れなければなりません。

注意事項: 推奨される様式は、e よりもむしろ E を使うことです。

注意事項: Real_constant(実数定数) とは反対に、 Real(実数) は、符号を持ちません。

注意事項: 整数部と小数部の両方が無くなってはならないと述べている制約は、字句的に重要です。さもなければ、次のコードの断片は、

a.e1

次のように走査されることになり、

a  .e1

次のように、

a  .  e1

'.e1' は仮数部として認識されません。


Character_constant(文字定数)
文字定数は、次のいずれかで、
単一引用符 (')で囲ったものです。

注意事項: 印字可能文字は、この場合、空白文字とタブ文字を含みますが、改行文字は含みません。これを Free_operator(自由演算子) と比べてください。


Manifest_string(明示文字列)
 明示文字列は、次のような、任意の並びです。
これらを二重引用符 (")で囲ったものです。
 拡張形式が、二行以上にわたって明示文字列を書くために許されています。あらゆる行は、しかし少なくとも、パーセント(%)で終わらなければならず、最初の行はパーセント(%)で始まらなければなりません。このとき、ひょっとしたら空白文字( ) やタブ文字が先行することもあります。

注意事項: 印字可能文字には、この場合、空白文字とタブ文字を含みますが、改行は含みません。これを Free_operator(自由演算子) と比べてください。


Bit_constant(ビット定数)
 ビット定数は、数字 01 を並べ、その後に b または B を続け、間に他の文字を伴わないものです。

注意事項: 推奨される様式は、b よりはむしろ B を使うことです。


Free_operator(自由演算子)
 自由演算子は、一字以上の文字の並びであり、その最初の文字が @ # | & のどれか一つであり、それ以降に続く文字があれば、どの印字可能文字でもよいです。大文字か小文字かは、自由演算子内の文字については重要ではありません。

注意事項: 印字可能文字は、この場合、Break(切断文字)群で許されている文字を含みません。これを Character_constant(文字定数) と比べてください。

注意事項: 次のコードは、

a@1

次のように走査されますが、

a  @1

これは、構文的には正しくありません。詳細については、Eiffel の gotchas を見てください。

注意事項: Eiffel: The Language, second printing は、自由演算子に Special_character(特殊文字) 群 (ただし印字可能なもの) を許しています。どんな Eiffel コンパイラも、これをサポートしません。

注意事項: SmallEiffel と Visual Eiffel は、自由演算子について、大文字か小文字かを区別します。


Comment(注釈)
 注釈は、二重のダッシュ文字(--)で始まり、行末までの続きます。
 拡張された書式は、二行以上にわたる注釈を書くことを許します。あらゆる行は、しかし最初の行は二字のダッシュ文字で始まらなければならず、ひょっとしたら、空白文字とタブ文字が先行することもあります。
Header_comment(ヘッダ注釈)
Comment(注釈)

注意事項: これは、Comment(注釈) の公式な記述ではありません。しかしながら、私は、どうしてパーセント(%)が、注釈内の公然とした書式(すなわち、Special_character(特殊文字) の一部ではない)で許されなかったのかを理解できません。

注意事項: 注釈には、任意の注釈と予期された注釈の二種類があります。任意の注釈は、何らかのツールによって除去できます。しかしながら、予期された注釈は、次の四つの構成要素の一部として現れます。それは、 Routine(ルーチン)Assertion_clause(表明句)Creation_clause(生成句)、そして Feature_clause(特徴句) であり、short ユーティリティなどといったツールによって処理されるはずです。けれども、Routine(ルーチン)Creation_clause(生成句) 、そして Feature_clause(特徴句) では、ヘッダー注釈はオプションであり、まった区外を及ぼさないで無視されることもあります。それは、Assertion_clause(表明句) では強制的であり、無視すれば構文エラーになるでしょう。これらの予期された注釈を実装するための解決策は、字句的な連結<tie-ins>を使うことであったでしょう。

注意事項: TowerEiffel は、はからずも、Features(特徴群) の構成要素の中に、 feature というキーワードとオプションの Clients(クライアント群) との間に注釈が現れたときに、構文エラーを出します。これは、おそらく、上で提案した字句的な連結<tie-ins>の使用の二次的効果です。

注意事項: 次の Routine(ルーチン) 宣言で、

foo is
        -- This is the first comment.

        -- This is the second comment.

        -- This is the third comment.
    do
        ...
    end

三つの内のどの注釈が予期された Header_comment(ヘッダー注釈) であるのか、そして何が二つの他の任意の注釈であるのかは、明らかではありません。TowerEiffel は、最初の注釈をヘッダー注釈であると選びます。ISE Eiffel、Halstenbach、そして Visual Eiffel といった、いくつかの他のコンパイラは、実際、三つの注釈を一つのヘッダー注釈になるように併合します。

注意事項: いくつかの Eiffel コンパイラは、まさしくヘッダー注釈内の '--' ではなく、'--|' で始まるどんな行も無視します。


Break(切断文字)
切断文字は、次の文字からなる、一字以上の並びです。
切断文字は、意味的な影響を及ぼさずに、二つの隣接する要素の間に挿入できます。

注意事項: Windows などといった、いくつかのプラットフォームは、改行文字の前に、復帰文字を置きます。そのような場合、復帰文字を四番目に可能な切断文字であると考えた方が、より簡単でしょう。


Special_character(特殊文字)
特殊文字は、次の書式の中の一つを取ります。

注意事項: ほとんどの Eiffel コンパイラは、%K という並びが上記のテーブルに並べられていないとき、構文エラーを出します。しかしながら、Visual Eiffel は、%K という並びが、上記のテーブルに並べられていないとき、文字 K を表している、と考えます。結果として、%P は文字 P を表し、そして %D は文字 $ を表します。

注意事項: 私がテストしたすべての Eiffel コンパイラ(すなわち、ISE Eiffel、 Halstenbach、SmallEiffel、Visual Eiffel、TowerEiffel)は、%K 内の文字 K を、上記の表からの特殊文字として認識するために、大文字であることを予期しています。結果として、%d%D は、同じであると考慮されません。

注意事項: 下線文字が code の整数の中で許されるかどうか(特に、それが幅広文字のコードであるとき)は、私には明らかではありません。


Reserved_word(予約語)
予約語は、次のいずれかです。
大文字か小文字かの区別は、予約語については重要ではありません。つまり、二つの語 ResultrEsUlT は、同じものとして考えれます。

注意事項: 公式の構文仕様は、次のクラス名を予約語として挙げています。BOOLEANCHARACTERDOUBLEINTEGERNONEPOINTERREALSTRING。私は、これらのクラスが Eiffel のコンパイラーによって知られていなければならないと理解していますが、どうして予約語にしなければいけないのかは分かりません。注意していただきたいのは、Kernel Library Standard からの ANYGENERALPLATFORM、そして他の多くのクラス名は、いずれも挙げられていません! さらに、これらのクラスの名前は、その構文の構成要素のどこにも現れません。結局、Visual Eiffel だけが、これらのクラス名を予約語として考えています。

注意事項: Eiffel: The Language, second printing では、FalseStripTrue、そして Unique が、キーワードとして考えられています。私は、この見解を共有しません。

注意事項: SmallEiffel は、Identifier(識別子) について大文字と小文字を区別するけれども、予約語については重要ではないと考えています!

注意事項: Precursor は、標準の構文の一部ではありません。それは、Precursor(先駆者) の機構をサポートするために導入されました。


Operator(演算子)
 次の表の中の演算子は、優先順位の水準によってまとめてあり、最も高い優先順位のものから始まります。各まとまりの中の演算子は、同じ優先順位を持ちます。同じ優先順位の水準を持つ二項演算子が連続して二つ以上出現したときについては、結合欄で評価の順序を規定しています。
シンボル 結合
.
old
not
単項 +
単項 -
すべての自由単項演算子
すべての自由二項演算子
^
*
/
//
\\



二項 +
二項 -

=
/=
<
>
<=
>=





and
and then

or
or else
xor


implies

注意事項: どうして Eiffel コンパイラが次のコードの断片を排出するかという理由は、

foo := 1 < 2 < 3

比較演算子が非結合であるというのが理由ではありません。比較演算子は、実際、左結合です。上記のコードは、構文的には正しいが、'1 < 2' が型 BOOLEAN であり、かつ次のような特徴が無いという理由で、単純に排出されます。

infix "<" (i: INTEGER): SOME_TYPE

これは、クラス BOOLEAN の中においてです。

注意事項: SmallEiffel は、はからずも、 infix "^" を左結合として考えています。


Semicolon(セミコロン)
 セミコロンは、Index_list(索引並び) あるいは Compound(混成) などといった並びの中で、区切り文字として使われます。セミコロンは、ほとんどの所でオプションです。しかしながら、それらは、ある場合には、Assertion(表明)Compound(混成) における曖昧さを取り除くために要求されます。この曖昧さは、次のコードの断片に現れます。
foo (expr).bar
 ここで、このコードは、「引数 expr での関数 foo の結果へ適用された bar 」として、あるいは「foo への呼び出しに、expr へ適用された bar が続いたもの」として認識されます。この曖昧さを解決するための規則は、二番目の解釈を得るためには、'foo' と '(expr).bar' の間にセミコロンを置くことであり、あるいは、最初の解釈を得るためには、そのままにしておくことです。

注意事項: いくつかの構成要素について、いくつかの Eiffel コンパイラは、セミコロンを終結子<terminator>として考えたり、強制と考えたり、あるいは、もしセミコロンが無ければ警告を出すだけだったりするでしょう。


Copyright (C) 1997, Eric Bezault
ericb@gobo.demon.co.uk
http://www.gobo.demon.co.uk
Last Updated: 6 September 1997
HomeHome