Syntax diagrams

From SmartEiffelWiki

Syntax diagrams for the whole Eiffel language.


All items in alphabetical order: Agent_creation, Assertion, Assignment, Binary_operator, Call, Check, Class_declaration, Class_name, Class_type, Clients, Comment, Compound, Create_expression, Create_instruction, Creation_clause, Current, Debug, Entity_declaration_list, Expression, Feature_clause, Feature_declaration, Feature_name, Formal_generic_list, If_then_else, Infix_operator, Inspect, Instruction, Loop, Manifest_notation, Manifest_string, New_export_item, Open_target_or_operand, Parent_list, Parent_type, Precursor_call, Prefix_operator, Result, Retry, Routine, Routine_body, Type, Unary_operator, Unqualified_call, Void, Writable.



Comment

A comment is made of one or more line segments, each beginning with two consecutive dash characters -- and extending to the end of the line:

Comment

Inside the comment, the convention for denoting Eiffel entities (i.e. variables, arguments and the names of primitives) is to enclose the corresponding name between ` and ' as follows:

-- Here `my_variable' is supposed to be bla bla bla ...

This convention allows some tools like eiffeldoc or short and emacs as well to use a different character font or color to emphasize the fact that my_variable refers to some existing entity of the Eiffel code. Warning: this convention must not be used for class names (Class_name), which are to be treated normally, that is written in capitals, like this:

-- My FOO class is bla bla bla bla ...

Note too that comments can use a syntax like this wiki's; in that case, the eiffeldoc tool changes your asterisks into bullets and your square brackets into links.

For example, the following comment processed by eiffeldoc would have the effect of sending us to this very site:

-- See also [[Syntax_diagrams#Comment]]

Class_declaration

Class_declaration

The diagram shows the general scheme of a class, which must be stored in a file with exactly the same name using only lower case letters plus the ".e" suffix. For example, the ARRAY class must be stored, alone, in the "array.e" file. Class LINKED_LIST must be stored, alone, in the "linked_list.e" file.

Related items: Assertion, Class_name, Creation_clause, Feature_clause, Formal_generic_list, Manifest_string, Parent_list.

Formal_generic_list

Formal_generic_list

To be used only when the class is generic. The Identifier is not the name of an existing class, but usually, just a simple upper case letter (see also Class_name). The Class_type part, when used, is the generic constraint.

Related items: Class_type.

Parent_list

Parent_list

Related items: Feature_name, New_export_item.

New_export_item

New_export_item

To modify only the inherited export status of some inherited features.

Related items: Clients, Feature_name.

Creation_clause

Creation_clause

In this diagram, Feature_name always has to correspond to a procedure name. The procedures mentioned in this list comprise the list of possible constructors for the enclosing class. Thus, as well as being a procedure of the enclosing class, a procedure from the Creation_clause list is also a creation procedure, that can be used in a Create_expression or else with a Create_instruction.

The Clients section of this diagram allows you to specify the export status of the constructors. Note that the export status of a creation procedure is not linked to nor affected by the export status of an ordinary procedure, and vice versa.

Related items: Clients, Comment, Feature_name,

Feature_clause

Feature_clause

Related items: Clients, Comment, Feature_declaration.

Clients

Clients

Related items: Class_name.

Feature_declaration

Feature_declaration

This diagram describes the syntax to define features: attributes, functions and procedures. The optional frozen keyword indicates that the definition is the final one (i.e. it is forbidden to redefine this feature in subclasses).

In case of the definition of a constant, Manifest_constant can only be a constant whose type is chosen in the following type set: { BOOLEAN, CHARACTER, INTEGER_8, INTEGER_16, INTEGER_32, INTEGER, INTEGER_64, REAL_32, REAL_64, REAL, REAL_80, REAL_128, REAL_EXTENDED, STRING, UNICODE_STRING }. See the file SmartEiffel/tutorial/manifest_notation.e to have a detailed explaination plus examples about all available notations for constants.

Related items: Entity_declaration_list, Feature_name, Routine, Type.

Routine

Routine

This diagram explain how to define routines: procedures and functions.

The optional obsolete branch indicates that the routine is now obsolete, that is to say that the routine should not be used any more. The string after the obsolete keyword must be used to indicate the reason and/or the new routine to use in place of the obsolete one. Compilation tools will warn you when an obsolete routine is being used. Also note that the short tool does not display obsolete routines, so as not to promote their use.

The require branch describes the routine's pre-condition.

The local part is for local variable declarations. All local variables of the routines must be declared here.

The ensure part is for the post-condition.

The optional rescue branch is actually the exceptions handler.

Related items: Assertion, Compound, Entity_declaration_list, Feature_name, Manifest_string, Routine_body.

Routine body

Routine_body

By selecting the deferred branch you indicates that the body of the routine is not given here thus making the routine defined an abstract routine. One may use an abstract routine when there is not enough information in the enclosing class to implement it. To become executable, subclasses have to define the corresponding missing body.

Conversely, by selecting the do branch you can give the definition of the actual routine body as a sequence of instructions. Note that defining a routine with an empty body (i.e. do with no instruction) is not the same as defining an abstract routine (i.e. deferred).

The once branch solution indicates that the routine must be executed only once whatever the number of calls and whatever the number of instances of the enclosing class. For a whole library, the maximum number of executed once routines is equal to the number of times the once keyword is written.

When the once routine is a function, the value obtained at the end of the first and unique execution is internally memorized. Subsequent calls are then replaced by the value memorized during this first execution. Note that a once function is the only way to memorize global information. There are no global variables in Eiffel.

The external branch is used to distinguish compiler builtin as well as routines written in another language than Eiffel.

Related items: Compound, Manifest_string.

Entity_declaration_list

Entity_declaration_list

This notation is used for declaration of local variable list as well as for formal argument list of routines. Thus, the Identifier can only be the name of some local variable or the name of some formal argument in a routine. The Identifier must only use lower case letters plus the '_' underscore character.

Related items: Type.

Type

Type

This diagram describes all available type mark notations. Notations that include the like keyword are known as anchored types, where Identifier can be either the name of some existing function or the name of some existing attribute or even, when defining some routine, the name of a formal argument of the routine being defined.

The Formal_generic_name element is the name of one item of the Formal_generic_list of the enclosing class.

Related items: Class_name.

Class_name

A class name must use only upper case letters and digits plus the '_' underscore character. A class name must start with a letter (an upper case letter, like all other letters used in the class name). It is bad practice to have two consecutive '_' underscore characters, or to end with an underscore character. (By convention we reserve simple names with a trailing underscore character, like E_, for the names of formal generic parameters).

Some examples of valid class names: ARRAY, INTEGER_64, ANY, LINKED_LIST or TWO_WAY_LINKED_LIST.

Class_type

Class_type

A class type is the subset of Type which involves no anchored types and no formal generic names. A Class_type can only be an existing class name, and hence denotes a single actual type.

Related items: Class_name.

Parent_type: allowed types for the parents of a class

Parent_type

A Parent_type notation is a valid type notation to be used for a Parent_list definition. The Formal_generic_name element must be an item of the Formal_generic_list of the enclosing class.

The set of types one can denote with Parent_type is a subset of notations obtained with the Type diagram. The Parent_type notation set includes all notations of the Class_type diagram.

Related items: Class_name.

Binary_operator

The following operators can be redefined in your own class:

Binary_operator

Infix_operator

Infix_operator

Related items: Binary_operator, Free_operator.

Prefix_operator

Prefix_operator

Related items: Unary_operator, Free_operator.

Unary_operator

Unary_operator

Writable

What we call Writable here is anything that can be on the left-hand-side of the := assignment operator. Complicated expressions are not allowed on the left-hand side of :=. You have only 3 choices:

  • the name of one local variable of the enclosing method,
  • the name of one writable attribute of Current,
  • or the Result variable used to prepare the return value of the enclosing function.

Also note that you cannot use an argument of the enclosing method on the left-hand side of :=. An argument is not a Writable. As explained above, you have only 3 choices: a local variable, an attribute or Result.

Feature_name

Feature_name

Related items: Infix_operator, Prefix_operator.

Compound

Compound

Related items: Instruction.

Instruction

Instruction

Related items: Assignment, Call, Check, Create_instruction, Debug, If_then_else, Inspect, Loop, Precursor_call, Retry.

Assignment

Assignment

Related items: Expression, Writable.

Call: procedure or function call as well as attribute read

Call

Such a construct can be either an Expression or an Instruction.

Related items: Expression, Unqualified_call.


Precursor_call: calling the inherited definition

Precursor_call

This notation is a call to the corresponding ancestor definition of the enclosing routine. Thus, the Precursor notation is valid only when it is used inside a method which is currently redefined. The call of the inherited version is made using the same object (the Current object). The signature of the Precursor call must conform to the inherited signature. So, inside a function, a Precursor call is an Expression, but it is an Instruction when written inside a procedure.

The Parent_type branch is useful only in case of multiple inheritance and when there is a possible ambiguity, that is to say, when there is more than one inherited concrete definition.

For details about the $ branch, see the Unqualified_call diagram.

Related items: Expression, Parent_type.


Loop: the only construct for iterative computation

Loop

Related items: Assertion, Compound, Expression.

If_then_else statement

If_then_else

Related items: Assertion, Compound, Expression.

Inspect: the multi-branch selection statement

Inspect

The order in which the when branches are written does not influence the effect of an inspect instruction.

Also note that the Expression can only be of type INTEGER, CHARACTER or STRING. All used Constants must have the same type as the type of Expression. Furthermore, all constants must be statically computable in order to allow the compiler to check for disjunction of various when parts (only one Compound is ever selected).

By writing no else part at all (no keyword else used), you state that you do not expect the Expression ever to take on a value not covered by the inspect constants. If your expectations prove wrong, the effect is to trigger a run-time error when the code is compiled with appropriate options.

Related items: Expression, Compound.

Create_instruction

Create_instruction

See also the Create_expression variant form.

Related items: Type, Unqualified_call, Writable.

Check_list

A check instruction helps express a property that you believe will be satisfied whenever system execution reaches this instruction.

check

Related items: Assertion.

Debug only compound

The Debug instruction serves to request the conditional execution of a certain sequence of Instructions, depending on a compilation option.

Debug

Related items: Compound, Instruction.

Retry for exceptions

The retry instruction is only for exceptions purpose and the retry statement is valid only when used inside the rescue clause of some enclosing routine. The form of this instruction is just:

Retry

The effect of a the retry instruction is to restart nearly from scratch the execution of the enclosing routine. Actually, even the require assertion of the routine is re-checked. Local variables, including Result, remain unchanged.

Expression

Expression

Related items: Agent_creation, Binary_operator, Call, Create_expression, Current, Manifest_notation, Open_target_or_operand Result, Type, Unary_operator, Void, Writable.

Current is an expression

And this Expression denotes the Current object. The notation is simply:

Current

Void expression

The Void expression indicates that we have no object. The notation is simply:

Void

Consult the special page about Void for full details.

The Result variable for functions

The Result variable is valid only inside the definition of some function. The notation is simply:

Result

The purpose of the Result variable is to prepare the result of the enclosing function. Result's type is always the return type of the enclosing function. Result behaves like an ordinary local variable. Like a local variable, Result is automatically initialized with the default value of the corresponding type (see automatic initialization). Using the Result variable does not makes you return from the enclosing function: it is just like a local variable.


Manifest_notation

Manifest notation includes:

  • True and False for BOOLEAN,
  • 'A', 'B', 'C', ... for CHARACTER
  • 1, 2, 3, ... for INTEGER
  • ...

See the file SmartEiffel/tutorial/manifest_notation.e for a detailed explanation, with examples of all available notations for constants of types: BOOLEAN, CHARACTER, INTEGER, REAL, STRING and UNICODE_STRING.

Furthermore, the file SmartEiffel/tutorial/manifest_notation.e also explains how to create explicitly objects of types ARRAY, FAST_ARRAY, LINKED_LIST, DICTIONARY, SET, etc., ...


Manifest_string

Manifest_string

To denote an object of type STRING. For full details of escape sequences of characters to be used inside the String part, as well as the multi-line notations, consult the file SmartEiffel/tutorial/manifest_notation.e.

Create_expression

Create_expression

This diagram shows the syntactic form of create used as an expression: a new object of the Type in question is returned by this Create_expression. See also the Create_instruction variant form.

Related items: Type, Unqualified_call.

Agent_creation

Agent_creation

An Agent_creation expression creates what is called an agent which is actually some Expression for which the execution is delayed. The type of an agent can only be one of the following types: PROCEDURE, FUNCTION or PREDICATE. See directory SmartEiffel/tutorial/agent for examples and details.

Related items: Expression, Open_target_or_operand.

Open_target_or_operand

Open_target_or_operand

An Open_target_or_operand expression is meaningful only when used inside an Agent_creation expression. An Open_target_or_operand expression denotes some value which is not yet known at the time the agent is created.

Related items: Type.

Unqualified_call

Unqualified_call

When not explicitly preceded by a target (see the Call diagram), an Unqualified_call is applied to the Current object. This can be either an Expression or an Instruction.

In this diagram Identifier_1 is the name of the feature (function, procedure or attribute) which is called. When no arguments are given (i.e. parentheses are not used), Identifier_1 can be either an attribute name or some function with no argument or even some procedure with no argument. As soon as arguments are given, Identifier_1 can only be some function or some procedure.

The $ facility is not intended to be used as a matter of course, but only for some external interface facility (for example, when some C code has to be called). The $ character indicates that the address of Identifier_2 is passed to the callee. Thus, Identifier_2 can be either some local variable name of the enclosing routine, the Result name, or even the name of some attribute of Current.

Related items: Expression.

Assertion

Assertion

The vital part of an assertion is of course the Expression, which has to be an expression returning a boolean result, that is, a BOOLEAN expression. The idea is to write an expression that is expected always to be true -- with the value True -- at runtime, hence the name 'assertion'.

In this diagram, Identifier is just a label associated with the assertion. This label is optional and is useful only when Expression's code is not obvious. If the assertion is violated, the label Identifier is printed as well as (or instead of) the unobvious assertion code. The syntax to use for Identifier is the same as for local variables, attributes or argument names: use only lower-case characters and the '_' underscore character.

When one is truly unable to write an Expression (which is rather bad news!) the replacement Comment text is equivalent to the constant True.

Finally, the semi-colon used as a separator can be considered as equivalent to using the logical operator and (from the BOOLEAN class) between the different assertions.

Related items: Comment, Expression.

Other languages