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 の構文を記述するために用いる 表記法 は、別のページで規定しています。同じく、yacc や lex に準じた書式での、Eiffel 構文の可能な実装も、例として提供しています。
注意事項: ほとんどの Eiffel コンパイラは、キーワード end の後にある付加的な注釈の有効性を検査しません。けれども、SmallEiffel は、警告を出します。
注意事項: 一つのファイルは、一つ以上のクラス宣言を含んでもよいです。しかしながら、ほとんどの Eiffel コンパイラは、ファイルごとに一クラスと制限しています。
注意事項: キーワード separate は、Eiffel 標準の一部ではありません。これは、SCOOP の仕組みをサポートするために、ISE Eiffel で導入されました。詳細については、Object-Oriented Software Construction, second edition を読んでください。
注意事項: 形式総称パラメータ群の並びは、空であってもよいです。結果として、 FOO[] は、有効であり、FOO と同じものを意味します。しかしながら、これは、推奨される様式ではありません。
注意事項: この構成要素が理由で、Eiffel の文法は、LR(1) ではありません。これは、次の状況で発生します。
class FOO inherit BAR endキーワード endは、Class_declaration(クラス宣言)の一部としての代わりに、付加的な Feature_adaptation(特徴の適応) の一部として考慮されることになります。
この問題を解決する方法は、Feature_adaptation(特徴の適応) を構成している付加的な構成要素の少なくとも一つが存在するときにだけ、Feature_adaptation(特徴の適応) の中で、キーワード end を許すことであったでしょう。
注意事項: 標準の構文は、Procedure_list(手続き並び) の代わりに、Feature_list(特徴並び) を要求しますが、Creation_clause(生成句)は、実際には、生成手続きの名前を並べます(有効性規則 VGCP-2 を見てください)。
注意事項: Prefix(前置子) と Infix(中置子) は、関数名であり、手続き名ではありません。Prefix(前置子) が属性名になり得たかどうかは、私には明らかではありませんが、明確に手続き名ではありません(有効性規則 VFFD-5 を見てください)。
注意事項: すべての Eiffel コンパイラは、 prefix "NOT" または infix "AnD" などといった、大文字か小文字かには関係なく、前置演算子と中値演算子を受け付けます。
注意事項: 間の文字は、最初の二重引用符から最後の二重引用符までのあいだ、何一つ許されません。しかしながら、 and then または or else内の二つのキーワードの間でどんな種類の切断文字が使用されているかは明らかではありません。SmallEiffel は空白文字をいくつでも受け付けますが、他のコンパイラは一つの空白文字だけを要求します。
注意事項: 実体宣言の並びは、空であってもよいです。結果として、foo() は、有効であり、foo と同じものを意味します。しかしながら、これは、推奨される様式ではありません。
注意事項: ほとんどの Eiffel コンパイラは、キーワード end の後にある付加的な注釈の有効性を検査しません。この注釈を置くことは、今はもう、様式指針にはありません。
注意事項: それそれの Eiffel コンパイラは、他のプログラミング言語とのインターフェイスを記述するために、言語名と外部名の文字列の中でコンパイラ固有のミニ構文をサポートしています。詳細については、個々のコンパイラに付いてくる文書を見てください。
注意事項: ヘッダー注釈のような注釈は、Routine(ルーチン) あるいは Features(特徴群) で拡張されるけれども、これは、注釈を無視することが結果として構文エラーまたは正しくない構文木となる唯一のところです。これは、次の状況で発生します。
require tag: -- 無視されたときには構文エラー! doand
require tag: -- もしこの注釈が無視されるならば、 -- tag は、はからずも、foo.is_valid -- と関連することになります!より詳しいことについては、Comment(注釈) の二番目の注意事項を見てください。
注意事項: 有効性規則 VXRT は、Retry 命令が reacue 句で有効なだけである、と述べています。これは、結局は、構文によって強制できました。
注意事項: 標準の Eiffel 構文はまた、Type のための可能な代替案として、Formal_generic_name(形式総称パラメータ名) を並べます。しかしながら、それは、識別子が Formal_generic_name(形式総称パラメータ名) と実総称を持たない Class_type(クラスの型) との両方として認識できるから、構文内に曖昧さを持ち込みました。
注意事項: 型の並びは、空であってもよいです。結果として、 FOO[] は、有効であり、FOO と同じものを意味します。しかしながら、これは、推奨される様式ではありません。
注意事項: Class_type_separate(クラスの型 分離) は、Eiffel 標準の一部ではありません。それは、SCOOP の機構をサポートするために、ISE Eiffel に導入されました。詳細については、Object-Oriented Software Construction, second edition を読んでください。
注意事項: 標準の構文では、Constant(定数) は、Bit_length(ビット長) の代わりに現れます。しかしながら、有効性規則 VTBT は、と述べています。Bit_type(ビット型) の宣言が有効なのは、その Constant(定数) が型 INTEGER である場合だけです。INTEGER が、定数は明示整数定数か属性定数のいずれかである、ということを意味しているのです。
注意事項: もし型が無いならば、二つの感嘆符を書く際に、間の切断文字はあっても無くてもよいです。標準の様式で、推奨される書式は、切断文字が無く、!! が現れても、一つの字句シンボルとしたものです。
注意事項: 標準の Eiffel 構文では、Creation_call(生成呼び出し) は、Unqualified_call(限定無し呼び出し) から構成されます。しかし、有効性規則 VGCC-6 は、、と述べています。もし f が Creation_call(生成呼び出し) の特徴であるならば、 f は手続きです。
注意事項: 選択の並びは空でもよいです。結果として、
inspect expr when then do_something ...意味はないけれども、構文的に正しいです。これは、次のように考えることができます。
if False then do_something ...しかしながら、これは、推奨される様式ではありません。
注意事項: 標準の構文は、Choice_constant(選択定数)の代わりにConstant(定数) を規定します。しかしながら、有効性規則 VOMB-1-2 は、Constant(定数) と Interval(間隔) は、型 INTEGER または CHARACTER だけからなる、と述べています。
注意事項: 字句解析プログラムは、次の例のように、十分整然としていなければなりません。
inspect expr when 1..2 then ...実際、'1..2' は、二つの連続した実数定数 '1.' と '.2' ではなく、Eiffel のシンボルである '..' で区切られた、二つの整数定数 '1' と '2' として認識されます。Visual Eiffel は、はからずも、上の例を解析するときに、構文エラーを出します。
注意事項: TowerEiffel は、Choice(選択) と Interval(間隔) の中で、次のような「remote constant(遠隔定数)」を受け付けます。
foo: FOO inspect i when foo.const then do_something endここで、const は、クラス FOO の定数として宣言されています。これは、標準の Eiffel 構文ではありません。
注意事項: 有効性規則 VAVE は、Expression(式) は、型 INTEGER でなければならないと述べています。これは、はからずも、Equality(等価)、Manifest_array(明示配列)、Strip(除去)、そしてすべての非整数 Manifest_constant(明示定数) 群によって、構文内で部分的に強制できました。
注意事項: 有効性規則 VXRT は、Retry(再試行) 命令は Rescue(救助) 句の中で有効なだけである、と述べています。これは、結果的に、構文によって強制できました。
注意事項: この命令は、純粋に構文上の役割でけを持っています。つまり、次のように、Compound(混成) へ見過ごすことによって加えられた余計なセミコロンが無害であることを確実にすることです。
if c then ; i1;;; i2; else ;; endTowerEiffel は、終結子<terminator>以外の他の余計なセミコロンをサポートしません。その他のすべてのコンパイラは、予期した通りに働きます。SmallEiffel は、余計なセミコロンを解析するときに、警告を出します。
注意事項: この 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(先駆者) という構成要素は、標準の Eiffel 構文の一部ではありません。それは、Object-Oriented Software Construction, second edition で導入されており、その標準に対する提案が NICE へ提出されています。ISE Eiffel と Halstenbach は、彼らの次のリリースで、ほぼ恐らく、この構成要素をサポートすることになります。
注意事項: Object-Oriented Software Construction, second edition で、Parent_qualification(親クラスの限定) 内のクラス名は、{{Class_name}} のように二重の中括弧で囲まれています。しかしながら、NICE へ提出された提案は、上で規定した構文を使用しています。
注意事項: 有効性規則 VFFD-5 に従って、 Attribute(属性) はまた、Prefix(前置子) であることができます。
注意事項: 標準構文仕様からの Entity(実体) の構文グループは、多くの曖昧さを解決するために、非常に単純化されています。たとえば、次のように、
fooAttribute(属性)、Local(局所的)、あるいは Formal(形式的)として認識されますか? 意味論の分析だけが、答えを与えることができます。
注意事項: 実パラメータ群の並びは、空でもよいです。結果として、foo() は有効であり、foo と同じものを意味します。しかしながら、これは、推奨される様式ではありません。
注意事項: TowerEiffel は、Address(アドレス)を通常の式として扱います(すなわち、Expression(式) の構成要素内の代替としてです)。けっかとして、アドレスは、実パラメータ並びの中でだけ発生する必要はありません。
注意事項: この Expression(式) の仕様は、標準で提供されたバージョンとは少し異なります。まず、Current と Result は、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 で導入されました。
注意事項: 有効性規則 VWBE は、真理値式は、型 BOOLEAN でなければならない、と述べています。これは、結局は、Manifest_array(明示配列)、Strip(除去)、そして、すべての非真理値の Manifest_constant(明示定数) 群を放棄することによって、構文内で部分的に強制できました。
注意事項: 演算子の優先順位と結合規則については、Operator(演算子) を見てください。
注意事項: 演算子の優先順位と結合規則については、Operator(演算子) を見てください。
注意事項: Wide_character_constant(幅広文字定数)、Wide_manifest_string(幅広明示文字列)、そして Hexadecimal_constant(16 進数定数) は、標準の一部ではありません。それらは、幅広の文字と文字定数、そして 16 進数定数をサポートするために TowerEiffel で導入されました。
注意事項: ここで、標準の構文には、曖昧さがあります。次のコードの断片で、
foo := - 2割り当ての左辺上の Expression(式) は、Integer_constant(整数定数) として、あるいは、Prefix_operator(前置演算子) が '-' であり、その Expression(式) が (unsigned) Integer(整数) である Unary_expression(単項式) として認識されるでしょうか? これは、現在の構文記述では、Expression(式) のための仕様を書き直すことによって解決されています。
注意事項: 上の Integer_constant(整数定数) に対するのと同じ曖昧さがあります。
注意事項: Wide_character_constant(幅広文字定数) は、標準の一部ではありません。それは、幅広文字をサポートするために TowerEiffel で導入されました。
注意事項: 間の文字は、ドル記号と Character_constant(文字定数) との間では、一切許されません。
注意事項: Wide_manifest_string(幅広明示文字列) は、標準の一部ではありません。それは、文字列内の幅広文字をサポートするために TowerEiffel で導入されました。
注意事項: 間の文字は、ドル記号と Manifest_string(明示文字列) との間では、一切許されません。
注意事項: 有効性規則 VAOL-1 は、Old 式は、Postcondition(事後条件) の中でだけ有効である、と述べています。これは、結局は、構文によって強制できました。
注意事項: 残念ながら、 SmallEiffel は、大文字と小文字を区別します(驚いたことに、Reserved_word(予約語) 類については、区別していません)。
注意事項: 識別子が有効であるのは、それが Reserved_word(予約語) の一つでないときに限ります。
注意事項: TowerEiffel は、特徴名とクラス名の中では、連続した下線文字を処理できません。
注意事項: 下線文字に関する最後の二つの制約は、どんな桁数の数字のまとまりも許すように、将来取り除かれるかもしれません。
注意事項: 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 進数定数をサポートするために、TowerEiffel で導入されました。
注意事項: 下線文字が 16 進数定数の中で許されるかどうかは、明らかではありません。
注意事項: 推奨される様式は、e よりもむしろ E を使うことです。
注意事項: Real_constant(実数定数) とは反対に、 Real(実数) は、符号を持ちません。
注意事項: 整数部と小数部の両方が無くなってはならないと述べている制約は、字句的に重要です。さもなければ、次のコードの断片は、
a.e1次のように走査されることになり、
a .e1次のように、
a . e1'.e1' は仮数部として認識されません。
注意事項: 印字可能文字は、この場合、空白文字とタブ文字を含みますが、改行文字は含みません。これを Free_operator(自由演算子) と比べてください。
注意事項: 印字可能文字には、この場合、空白文字とタブ文字を含みますが、改行は含みません。これを Free_operator(自由演算子) と比べてください。
注意事項: 推奨される様式は、b よりはむしろ B を使うことです。
注意事項: 印字可能文字は、この場合、Break(切断文字)群で許されている文字を含みません。これを Character_constant(文字定数) と比べてください。
注意事項: 次のコードは、
a@1次のように走査されますが、
a @1これは、構文的には正しくありません。詳細については、Eiffel の gotchas を見てください。
注意事項: Eiffel: The Language, second printing は、自由演算子に Special_character(特殊文字) 群 (ただし印字可能なもの) を許しています。どんな Eiffel コンパイラも、これをサポートしません。
注意事項: SmallEiffel と Visual Eiffel は、自由演算子について、大文字か小文字かを区別します。
注意事項: これは、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 コンパイラは、まさしくヘッダー注釈内の '--' ではなく、'--|' で始まるどんな行も無視します。
注意事項: Windows などといった、いくつかのプラットフォームは、改行文字の前に、復帰文字を置きます。そのような場合、復帰文字を四番目に可能な切断文字であると考えた方が、より簡単でしょう。
| Character | Code | Mnemonic name |
| @ | %A | At-sign(アットマーク) |
| BS | %B | Backspace(バックスペース−後退) |
| ^ | %C | Circumflex(サーカムフレックス) |
| $ | %D | Dollar(ダラー−ドル) |
| FF | %F | Form feed(フォームフィード−改頁) |
| \ | %H | backslasH(バックスラッシュ−逆斜線) |
| ~ | %L | tiLda(チルダ−波) |
| NL (LF) | %N | Newline(ニューライン−改行) |
| ` | %Q | back Quote(バッククォート−逆引用符) |
| CR | %R | carriage Return(キャリッジリターン−復帰) |
| # | %S | Sharp(シャープ) |
| HT | %T | horizontal Tab(水平タブ) |
| NUL | %U | nUll character(空文字) |
| | | %V | Vertical bar(バーチカルバー−縦棒) |
| % | %% | percent(パーセント) |
| ' | %' | single quote(単一引用符) |
| " | %" | double quote(二重引用符) |
| [ | %( | opening bracket(左括弧) |
| ] | %) | closing bracket(閉じ括弧) |
| { | %< | opening brace(左中括弧) |
| } | %> | closing brace(閉じ中括弧) |
注意事項: ほとんどの Eiffel コンパイラは、%K という並びが上記のテーブルに並べられていないとき、構文エラーを出します。しかしながら、Visual Eiffel は、%K という並びが、上記のテーブルに並べられていないとき、文字 K を表している、と考えます。結果として、%P は文字 P を表し、そして %D は文字 $ を表します。
注意事項: 私がテストしたすべての Eiffel コンパイラ(すなわち、ISE Eiffel、 Halstenbach、SmallEiffel、Visual Eiffel、TowerEiffel)は、%K 内の文字 K を、上記の表からの特殊文字として認識するために、大文字であることを予期しています。結果として、%d と %D は、同じであると考慮されません。
注意事項: 下線文字が code の整数の中で許されるかどうか(特に、それが幅広文字のコードであるとき)は、私には明らかではありません。
注意事項: 公式の構文仕様は、次のクラス名を予約語として挙げています。BOOLEAN、CHARACTER、DOUBLE、INTEGER、NONE、POINTER、REAL、STRING。私は、これらのクラスが Eiffel のコンパイラーによって知られていなければならないと理解していますが、どうして予約語にしなければいけないのかは分かりません。注意していただきたいのは、Kernel Library Standard からの ANY、GENERAL、PLATFORM、そして他の多くのクラス名は、いずれも挙げられていません! さらに、これらのクラスの名前は、その構文の構成要素のどこにも現れません。結局、Visual Eiffel だけが、これらのクラス名を予約語として考えています。
注意事項: Eiffel: The Language, second printing では、False、Strip、True、そして Unique が、キーワードとして考えられています。私は、この見解を共有しません。
注意事項: SmallEiffel は、Identifier(識別子) について大文字と小文字を区別するけれども、予約語については重要ではないと考えています!
注意事項: Precursor は、標準の構文の一部ではありません。それは、Precursor(先駆者) の機構をサポートするために導入されました。
| シンボル | 結合 |
| . | 左 |
| 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 "^" を左結合として考えています。
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 |