Eiffel: la sintaxis

Original Article: http://www.gobosoft.com/eiffel/syntax/

La sintaxis anotada de Eiffel descrita aquí está dirigida a escritores de herramientas de Eiffel como compiladores, intérpretes, correctores de sintaxis, herramientas breves y planas, lindas impresoras, etc., que quieran beneficiarse de algunos consejos y trucos. Aunque esta no es la especificación oficial de la sintaxis de Eiffel proporcionada por el Consorcio Internacional sin fines de lucro para Eiffel (NICE), se aparta de ella en solo dos o tres ocasiones bien documentadas. En particular, explica dónde, y a veces por qué, los compiladores existentes han extendido la sintaxis de Eiffel.

Las construcciones de sintaxis de Eiffel se enumeran en grupos, comenzando con constructos de alto nivel como Class_declaration hasta componentes léxicos como Identifier. Alternativamente, estos constructos también se dan en orden alfabético. La notación utilizada para describir la sintaxis de Eiffel se especifica en otro lugar. Una posible implementación de la sintaxis de Eiffel en formato yacc– y lex-like también se proporciona como ejemplo.

Class_declaration
[ Indexing ]
Class_header
[ Formal_generics ]
[ Obsolete ]
[ Inheritance ]
[ Creators ]
[ Features ]
[ Invariant ]
end [ -- class Class_name ]

Nota: la mayoría de los compiladores de Eiffel no verifican la validez del comentario opcional después del final de la palabra clave. SmallEiffel emite una advertencia sin embargo.

Nota: Un archivo puede contener más de una declaración de clase. Sin embargo, la mayoría de los compiladores de Eiffel tienen una limitación de una clase por archivo.


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

Nota: la palabra clave separada no es parte del estándar de Eiffel. Se ha presentado en ISE Eiffel para admitir el mecanismo SCOOP. Lea Construcción de software orientado a objetos, segunda edición, para más detalles.

Class_name
Identifier

Formal_generics
[ Formal_generic_list ]
Formal_generic_list
{ Formal_generic , ... }

Nota: la lista de genéricos formales puede estar vacía. Como consecuencia, FOO [] es válido y significa lo mismo que FOO. Sin embargo, este no es el estilo recomendado.

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

Nota: Debido a esta construcción, la gramática de Eiffel no es LR (1). Esto ocurre en la siguiente situación:

class FOO
inherit
    BAR
end

La palabra clave end se considerará como parte de la opción Feature_adaptation en lugar de como parte del constructo Class_declaration.

Una forma de resolver este problema sería permitir que la palabra clave termine en Feature_adaptation solo cuando al menos uno de los constructos opcionales que componen la Feature_adaptation está presente


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

Nota: La sintaxis estándar requiere una Feature_list en lugar de una Procedure_list pero la Creation_clause realmente enumera los nombres de los procedimientos de creación (ver la regla de validez VGCP-2).

Procedure_list
{ Procedure_name , ... }
Procedure_name
Identifier

Nota: Prefijo e Infijo son nombres de funciones, no nombres de procedimientos. No me queda claro si un Prefijo podría ser un nombre de atributo, pero definitivamente no es un nombre de procedimiento (ver la regla de validez 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

Nota: Todos los compiladores de Eiffel aceptan los operadores de prefijo e infijo, independientemente del caso de la letra, como el prefijo “NO” o infijo “AnD”.

Nota: No se permite ningún carácter intermedio después de la primera o antes de la última comilla doble. Sin embargo, no está claro qué tipo de interrupción se debe utilizar entre las dos palabras clave en y luego o bien. SmallEiffel acepta cualquier número de espacios en blanco y caracteres de pestañas, mientras que los otros compiladores requieren un solo espacio en blanco.


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

Nota: La lista de declaraciones de entidades puede estar vacía. Como consecuencia, foo () es válido y significa lo mismo que foo. Sin embargo, este no es un estilo recomendado.


Routine
[ Obsolete ]
[
Header_comment ]
[
Precondition ]
[
Local_declarations ]
Routine_body
[ Postcondition ]
[
Rescue ]
end [ -- Feature_name ]

Nota: La mayoría de los compiladores de Eiffel no verifican la validez del comentario opcional después de la palabra clave end. Ya no está en las pautas de estilo dejar este comentario.


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

Nota: Cada compilador de Eiffel admite su propia mini sintaxis en el nombre del idioma y las cadenas de nombre externas para describir su interfaz con otros lenguajes de programación. Consulte la documentación que viene con los diferentes compiladores para más detalles.


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

Nota: Aunque se esperan comentarios como los comentarios de encabezado en algunos constructos como

require
    tag: -- Syntax error when ignored!
do

and

require
    tag: -- If this comment is ignored,
         -- tag will be erroneously
         -- associated with foo.is_valid!
    foo.is_valid

See the second note in Comment for more details.


Rescue
rescue Compound

Note: The validity rule VXRT states that the Retry instruction is only valid in a rescue clause. This could eventually be enforced by the syntax.


Type
Class_type |
Class_type_expanded |
Class_type_separate |
Anchored | Bit_type

Note: The standard Eiffel syntax also lists Formal_generic_name as a possible alternative for Type. However it introduced an ambiguity in the syntax since an identifier could be recognized both as a Formal_generic_name and a Class_type with no actual generics.

Class_type
Class_name [ Actual_generics ]
Actual_generics
[ Type_list ]
Type_list
{ Type , ... }

Note: The list of types may be empty. As a consequence, FOO[] is valid and means the same as FOO. However, this is not the recommended style.

Class_type_expanded
expanded Class_type
Class_type_separate
separate Class_type

Note: Class_type_separate is not part of the Eiffel standard. It has been introduced in ISE Eiffel to support the SCOOP mechanism. Read Object-Oriented Software Construction, second edition, for details.

Bit_type
BIT Bit_length

Note: In the standard syntax, Constant appears instead of Bit_length. However the validity rule VTBT states that a Bit_type declaration is valid if and only if its Constant is of type INTEGER, which means that the constant is either a manifest integer constant or an attribute constant.

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 ]

Note: If the type is absent, the two exclamation marks may be written with or without intervening break. In the style standard, the recommended form is the one without breaks, which makes !! appear as a single lexical symbol.

Creation_call
. Procedure_name [ Actuals ]

Note: In the standard Eiffel syntax, the Creation_call is made of an Unqualified_call. But the validity rule VGCC-6 states that if f is the feature of the Creation_call, the f is a procedure.


Assignment
Writable := Expression
Assignment_attempt
Writable ?= Expression

Conditional
if Then_part_list [ Else_part ] end
Then_part_list
{ Then_part elseif ... }+
Then_part
Boolean_expression then Compound
Else_part
else Compound

Multi_branch
inspect Expression
[ When_part_list ] [ Else_part ] end
When_part_list
when { When_part when ... }+
When_part
Choices then Compound
Choices
{ Choice , ... }

Note: The list of choices may be empty. As a consequence,

inspect expr
when then
    do_something
...

although meaningless, is syntactically correct. It can be thought of as

if False then
    do_something
...

However, this is not part of the recommended style.

Choice
Choice_constant | Interval

Note: The standard syntax specifies Constant instead of Choice_constant. However the validity rule VOMB-1-2 states that the Constant in Choice and Interval is only of type INTEGER or CHARACTER.

Interval
Choice_constant .. Choice_constant

Note: The lexical analyzer has to be smart enough in the following example:

inspect expr
when 1..2 then
...

Indeed, ‘1..2‘ should be recognized as the two integer constants ‘1‘ and ‘2‘ separated by the Eiffel symbol ‘..‘, instead of as two consecutive real constants ‘1.‘ and ‘.2‘. Visual Eiffel erroneously emits a syntax error when parsing the example above.

Choice_constant
Integer_constant | Character_constant | Attribute

Note: TowerEiffel accepts “remote constant” in Choice and Interval, such as in:

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

where const is declared as constant in class FOO. This is not standard Eiffel syntax.


Loop
Initialization
[ Invariant ]
[ Variant ]
Loop_body
end
Initialization
from Compound
Variant
variant [ Tag_mark ] Expression

Note: The validity rule VAVE states that Expression must be of type INTEGER. This could eventually be partially enforced in the syntax by discarding Equality, Manifest_array, Strip and all non-integer Manifest_constants.

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

Note: The validity rule VXRT states that the Retry instruction is only valid in a Rescue clause. This could eventually be enforced by the syntax.


Null_instruction
empty

Note: This instruction has a purely syntactical role: making sure that extra semicolons added by oversight to a Compound are harmless, as in

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

TowerEiffel does not support extra semicolons other than terminators. All other compilers work as expected. SmallEiffel emits a warning when parsing extra semicolons.


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 ]

Note: This specification of Call is slightly different from the version supplied in the standard. However the standard syntax accepts constructs which are not correct Eiffel such as RoutineFeatures, este es el único lugar donde ignorar un comentario da como resultado un error de sintaxis o un árbol de sintaxis incorrecto. Esto ocurre en las siguientes situaciones

foo.Result
Current (5)

mientras que la especificación dada arriba no lo hace.

Note:En TowerEiffel, las funciones se pueden llamar directamente en un Manifest_constant sin colocar paréntesis alrededor de la constante, como en:

str := 'a'.out

que debería ser, usando la sintaxis estándar:

str := ('a').out

Hay un ligero problema léxico con Integer_constant sin embargo, desde

123.out

es reconocido como

123. out

'123.' ser un  Real_constant. El programador tiene que agregar un extra Break entre la constante entera y el punto para evitar este problema.


Precursor
[ Parent_qualification ] Precursor [ Actuals ]
Parent_qualification
{ Class_name }

Nota:La construcción precursora no es parte de la sintaxis estándar de Eiffel. Se ha presentado en la segunda edición de Construcción de software orientado a objetos y se ha presentado a NICE una propuesta para su estandarización. ISE Eiffel y Halstenbach probablemente apoyarán esta construcción en su próximo lanzamiento.

Nota: En la segunda edición de construcción de software orientada a objetos, el nombre de la clase en Parent_qualification se incluye entre dobles llaves: {{Class_name}}. Sin embargo, la propuesta presentada a NICE utiliza la sintaxis especificada anteriormente.


Attribute
Identifier

Nota: de acuerdo con la regla de validez VFFD-5, un atributo también puede ser un Prefix.

Writable
Identifier | Result

Nota: El grupo de sintaxis de Entity de la especificación de sintaxis estándar se ha simplificado mucho para resolver muchas ambigüedades. Por ejemplo, debería:

foo

ser reconocido como Atributo, Local o Formal? Solo un análisis semántico puede dar la respuesta.


Actuals
( Actual_list )
Actual_list
{ Actual , ... }

Nota: La lista de datos reales puede estar vacía. Como consecuencia, foo() es válido y significa lo mismo que foo. Sin embargo, este no es un estilo recomendado.

Actual
Expression | Address

Nota: TowerEiffel trata la dirección como una expresión normal (es decir, como una alternativa en el Expression construir). Como consecuencia, una dirección no necesita ocurrir solo en listas reales.

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

Nota: Esta especificación de Expression es ligeramente diferente de la versión suministrada en el estándar. En primer lugar, se han agregado Corriente y Resultado como consecuencia de las nuevas especificaciones para Call. Entonces, Manifest_constant ha sido reemplazado con la lista de sus alternativas. Esto es para resolver una ambigüedad en la sintaxis estándar. En el siguiente fragmento de código:

foo := - 2

si la expresión en el lado derecho de la asignación se reconoce como una Integer_constant o como una  Unary_expression cuyo Prefix_operator is ‘-‘ y cuyo Expressiones un entero (sin signo)? Reemplazando Integer_constant y Real_constant by Integer y Real resuelve el problema.

Nota: Wide_character_constant, Wide_manifest_string y Hexadecimal_constant no son parte del estándar.Se han introducido en TowerEiffel para admitir caracteres anchos y cadenas y enteros hexadecimales.

Boolean_expression
Expression

Nota: La regla de validez VWBE establece que una expresión booleana debe ser de tipo BOOLEAN. Esto podría eventualmente aplicarse parcialmente en la sintaxis mediante el descarte Manifest_array, Strip y todos los no booleanos Manifest_constants.


Operator_expression
Parenthesized | Unary_expression | Binary_expression
Parenthesized
( Expression )
Unary_expression
Prefix_operator Expression
Binary_expression
Expression Infix_operator Expression

Nota: Ver operador para la precedencia y asociatividad del operador.


Equality
Expression Comparison Expression
Comparison
= | /=

Nota: Ver operador para la precedencia y asociatividad del operador.


Manifest_constant
Boolean_constant | Character_constant |
Integer_constant | Real_constant |
Manifest_string | Bit_constant |
Wide_character_constant |
Wide_manifest_string |
Hexadecimal_constant

Note: Wide_character_constant, Wide_manifest_string  y  Hexadecimal_constant no son parte del estándar.Se han introducido en TowerEiffel para admitir caracteres anchos y cadenas y enteros hexadecimales.

Boolean_constant
True | False
Integer_constant
[ Sign ] Integer

Nota: Aquí hay una ambigüedad en la sintaxis estándar. En el siguiente fragmento de código:

foo := - 2

si el Expression en el lado derecho de la asignación se reconocerá como una Integer_constant o como un Unary_expression cuyo  Prefix_operator is ‘-‘ y cuyo Expression is an (unsigned) Integer? Esto se ha resuelto en la descripción de la sintaxis actual mediante la reescritura de la especificación de Expression.

Real_constant
[ Sign ] Real

Nota: la misma ambigüedad que para Integer_constant anterior.

Sign
+ | -
Wide_character_constant
$ Character_constant

Nota: Wide_character_constant no es parte del estándar. Se ha presentado en TowerEiffel para admitir personajes anchos.

Nota: No se permite ningún carácter intermedio entre el signo de dólar y el Character_constant.

Wide_manifest_string
$ Manifest_string

Nota: Wide_manifest_string no es parte del estándar. Se ha presentado en TowerEiffel para admitir caracteres anchos en cadenas.

NotaNo se permite ningún carácter intermedio entre el signo de dólar y el Manifest_string.


Manifest_array
<< Expression_list >>
Expression_list
{ Expression , ... }

Old
old Expression

Nota: La regla de validez VAOL-1 establece que la expresión anterior solo es válida en una Postcondition. Esto eventualmente podría ser impuesto por la sintaxis.


Strip
Strip ( Attribute_list )
Attribute_list
{ Attribute , ... }

Identifier
Un identificador es una secuencia de uno o más caracteres, de los cuales el primero es una letra (de la aa la Z y de la A a la Z) y cada uno de los siguientes, si los hay, es una letra, un dígito decimal (0 a 9) o un carácter de subrayado (_).
Letter Case no es significativo para las letras: los dos identificadores lInKeD_liST y LINKED_LIST se consideran iguales.

Nota: Desafortunadamente, SmallEiffel distingue entre mayúsculas y minúsculas. (Sorprendentemente, no distingue entre mayúsculas y minúsculas Reserved_words.)

Nota: Un identificador es válido si y solo si no es uno de los Reserved_words.

Nota: TowerEiffel no puede manejar guiones bajos contiguos en nombres de funciones y nombres de clase.


Integer
Un número entero es una secuencia de caracteres, cada uno de los cuales debe ser:

  1. un dígito decimal (0 a 9)
  2. un underscore (_), que puede no ser el primer personaje.
Si hay un guion bajo presente, debe haber tres dígitos a la derecha de cada guion bajo, y no debe haber ningún grupo consecutivo de cuatro dígitos.

Nota: Las últimas dos restricciones con respecto a los guiones bajos podrían eliminarse en el futuro, permitiendo grupos de cualquier cantidad de dígitos.

Nota:Contrariamente a Integer_constant, Integer no tiene señal.

Nota: ¡Tenga en cuenta el problema del valor entero mínimo! Por ejemplo, en plataformas donde los enteros se almacenan en 32 bits, el siguiente código de Eiffel es válido:

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

pero el analizador debe ser lo suficientemente inteligente, de lo contrario leerá un unario menos seguido del entero 2147483648, que no cabe en 32 bits y por lo tanto desencadena un desbordamiento.


Hexadecimal_constant
Una constante hexadecimal es una secuencia de dos o más caracteres, cuyo primer carácter es un dígito decimal (0 a 9), cuyos caracteres siguientes pero los últimos son dígitos decimales o letras de la a a la f de la A a la F, y seguidos de x o X , sin otros personajes intermedios.

Nota: Hexadecimal_constant no es parte del estándar. Se ha introducido en TowerEiffel para admitir enteros hexadecimales.

Nota: No está claro si los guiones bajos están permitidos en constantes hexadecimales.


Real
Un número real está compuesto de los siguientes elementos:

  1. un opcional Integer,dando la parte integral (si no está presente, la parte integral es 0.)
  2. un punto requerido (.)
  3. un opcional Integerescrito al revés, que da la parte fraccionaria (si está ausente, la parte fraccionaria es 0.)
  4. un exponente opcional, que es la letra eo E seguida de una opción Sign (+ or -) y un Integer. El entero es obligatorio si la e o E está presente. Esto indica que el valor que aparece antes de e o E debe ser escalado por 10 ^ n, donde n es el número entero dado.
No se permite ningún carácter intermedio (en blanco u otro) entre estos elementos. Las partes integrales y fraccionarias pueden no estar ausentes. Si los guiones bajos se usan en la parte integral o fraccionaria, también deben aparecer en la otra parte, a menos que tenga tres dígitos o menos.

Nota: El estilo recomendado es usar E en lugar de e.

Nota: Contrariamente a Real_constant, Real no tiene señal

Nota: La restricción que establece que las partes integral y fraccional pueden no estar ambas ausentes es léxicamente importante. De lo contrario, la siguiente pieza de código

a.e1

podría escanearse como

a  .e1

en lugar de

a  .  e1

'.e1' ser reconocido como un verdadero.


Character_constant
Una constante de caracteres es:

  1. un personaje imprimible excepto por ciento (%) y comillas simples (‘)
  2. un Special_character
encerrado entre comillas simples (‘).

Nota: Los caracteres imprimibles incluyen, en este caso, espacios en blanco y tabuladores, pero no líneas nuevas. Compare eso con Free_operator.


Manifest_string
Una cadena manifiesta es una secuencia arbitraria de:

  1. caracteres imprimibles excepto por ciento (%) y comillas dobles (“)
  2. Special_characters
encerrado entre comillas dobles (“).
Una forma extendida permite escribir una cadena de manifiesto en dos o más líneas. Cada línea, excepto la última, debe terminar con un porcentaje (%) y cada línea, excepto la primera, debe comenzar con un porcentaje (%) posiblemente precedido por espacios en blanco () y tabular caracteres.

Nota: Los caracteres imprimibles incluyen, en este caso, espacios en blanco y tabuladores, pero no líneas nuevas.Compare eso con Free_operator.


Bit_constant
Un bit constante es una secuencia de dígitos 0 o 1, seguida de bo B, sin otros caracteres intermedios.

Nota: El estilo recomendado es usar B en lugar de b.


Free_operator
Un operador libre es una secuencia de uno o más caracteres, cuyo primer carácter es cualquiera de @ # | & y cuyos caracteres posteriores, si los hay, pueden ser cualquier carácter imprimible. Letter Case no es significativo para letras en operadores libres.

Nota: Los caracteres imprimibles no incluyen, en este caso, los caracteres permitidos en Breaks. Compare eso con Character_constant.

Nota: El siguiente código

a@1

se escanea como

a  @1

que no es sintácticamente correcto. Ver Eiffel gotchas para más detalles.

Nota:Eiffel: El idioma, segunda impresión, permite caracteres especiales (aunque imprimibles) en operadores libres. Ningún compilador de Eiffel lo admite.

Nota: SmallEiffel y Visual Eiffel son sensibles a las mayúsculas y minúsculas para los operadores libres.


Comment
Un comentario comienza con dos caracteres de guion (-) y se extiende hasta el final de la línea.
Una forma extendida le permite a uno escribir un comentario en dos o más líneas. Cada línea, excepto la primera, debe comenzar con dos caracteres de guion posiblemente precedidos por espacios en blanco y caracteres tabulados.
Header_comment
Comment

Nota: Esta no es la descripción oficial de Comment. Sin embargo, no pude ver por qué el carácter de porcentaje (%) no estaba permitido en su forma desnuda (es decir, no formaba parte de  Special_character) en un comentario.

Nota: Hay dos tipos de comentarios: comentarios gratuitos y comentarios esperados. Los comentarios gratis pueden ser descartados por algunas herramientas. Sin embargo, los comentarios esperados aparecen como parte de cuatro constructos: Routine, Assertion_clause, Creation_clause and Feature_clause, y debe ser procesado por herramientas tales como la utilidad corta. Aunque, en Routine, Creation_clause and Feature_clause, el comentario del encabezado es opcional y puede ignorarse sin demasiado daño, es obligatorio in Assertion_clause e ignorarlo sería un error de sintaxis. Una solución para implementar estos comentarios esperados podría ser el uso de enlaces léxicos.

Nota: TowerEiffel emite erróneamente un error de sintaxis cuando aparece un comentario entre feature palabra clave y los clientes opcionales en el Features construir. Este es probablemente un efecto secundario del uso de los vínculos léxicos sugeridos anteriormente.

Nota: En el siguiente Routine declaración:

foo is
        -- This is the first comment.

        -- This is the second comment.

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

no está claro cuál de los tres comentarios es el esperado Header_comment y cuáles son los otros dos comentarios gratuitos. TowerEiffel eligió el primer comentario para ser el comentario del encabezado. Algunos otros compiladores, como ISE Eiffel, Halstenbach y Visual Eiffel, realmente fusionan los tres comentarios en uno que se convierte en el comentario del encabezado.

Note: Algunos compiladores de Eiffel ignoran cualquier línea que comience con ‘- |’ en lugar de simplemente ‘-‘ en los comentarios de encabezado.


Break
Se divide una secuencia de uno o más de los siguientes caracteres:

  1. blanco
  2. lengüeta
  3. nueva línea
Se puede insertar una ruptura entre dos elementos adyacentes sin afectar la semántica.

Nota: Algunas plataformas como Windows ponen un carácter de retorno de carro antes de la nueva línea. En tales casos, es más fácil considerar el retorno de carro como un cuarto personaje posible que constituye un descanso.


Special_character
Un personaje especial tiene una de las siguientes formas:

  1. un código de secuencia% / code / where es un entero sin signo que representa el carácter del código de código ASCII en valor decimal
  2. una secuencia% K utilizada para representar los siguientes caracteres especiales:
    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

Nota:La mayoría de los compiladores de Eiffel emiten un error de sintaxis cuando la secuencia% K no aparece en la tabla anterior. Sin embargo, Visual Eiffel considera que la secuencia% K representa el carácter K cuando la secuencia no figura en la tabla anterior. Como consecuencia,% P representa el carácter P y% D representa el carácter $.

Nota:Todos los compiladores de Eiffel que he probado (es decir, ISE Eiffel, Halstenbach, SmallEiffel, Visual Eiffel, TowerEiffel) esperan que la letra K en% K esté en mayúsculas para que se reconozca como un carácter especial de la tabla anterior. Como consecuencia% d y% D no se consideran lo mismo.

Nota: No me queda claro si los guiones bajos están permitidos en el code entero (especialmente cuando es el código de un personaje ancho).


Reserved_word
Una palabra reservada es:

  1. una palabra clave, que sirve para introducir y delimitar los componentes variantes de los constructos. Las palabras clave de Eiffel son:alias, all, and, as, check, class, creation, debug, deferred, do, else, elseif, end, ensure, expanded, export, external, feature, from, frozen, if, implies, indexing, infix, inherit, inspect, invariant, is, like, local, loop, not, obsolete, old, once, or, prefix, redefine, rename, require, rescue, retry, select, separate, then, undefine, until, variant, when, xor.
  2. un nombre predefinido, que viene en posiciones donde tokens variables también serían permisibles. Los nombres predefinidos de Eiffel son: BIT, Current, False, Precursor, Result, Strip, True, Unique.
El caso de la letra no es significativo para las palabras reservadas: las dos palabras Resultado y RESOLUCIÓN se consideran las mismas.

Nota: La especificación de sintaxis oficial enumera los siguientes nombres de clase como palabras reservadas: BOOLEAN, CHARACTER, DOUBLE, INTEGER, NONE, POINTER, REAL, STRING. Entiendo que estas clases deben ser conocidas por los compiladores de Eiffel, pero no veo por qué deberían ser palabras reservadas. Tenga en cuenta que ANY, GENERAL, PLATFORM ¡ y muchos otros nombres de clase del Estándar de biblioteca de Kernel no se enumeran tampoco! Además, estos nombres de clase no aparecen en ninguna parte en las construcciones de sintaxis. Finalmente, solo Visual Eiffel considera estos nombres de clase como palabras reservadas.

Nota: En Eiffel: The Language,segunda impresión, False, Strip, True  y  Unique se consideran palabras clave. No comparto este punto de vista.

Nota: Aunque SmallEiffel distingue entre mayúsculas y minúsculas con respecto a Identifier, ¡considera que el caso de las cartas no es significativo para las palabras reservadas!

Nota: Precursoris not part of the standard syntax. It has been introduced to support the Precursor mechanism.


Operator
Los operadores de la siguiente tabla están agrupados por nivel de precedencia, comenzando por el grupo de precedencia más alta. Los operadores dentro de cada grupo tienen la misma precedencia. Para dos o más ocurrencias consecutivas de operadores binarios con el mismo nivel de precedencia, la columna de asociatividad especifica el orden de evaluación.
Symbol Associativity
. left
old
not
unary +
unary -
All free unary operators
All free binary operators
^ right
*
/
//
\\
left
left
left
left
binary +
binay -
left
left
=
/=
<
>
<=
>=
left
left
left
left
left
left
and
and then
left
left
or
or else
xor
left
left
left
implies left

Note: La razón por la cual los compiladores de Eiffel rechazan la siguiente pieza de código:

foo := 1 < 2 < 3

no es porque los operadores de comparación son no asociativos. Estos operadores realmente se quedan asociativos. El código anterior es sintácticamente correcto, pero simplemente se rechaza porque ‘1 <2’ es de tipo BOOLEAN y no hay ninguna función como:

infix "<" (i: INTEGER): SOME_TYPE

en la clase BOOLEAN.


Semicolon
Los puntos y coma se usan como separadores en listas como Index_list o Compound.Los puntos y coma son opcionales en la mayoría de los lugares. Sin embargo, en algunos casos se requieren para eliminar ambigüedades en Assertion  y Compound. La ambigüedad aparece en el siguiente fragmento de código:
foo (expr).bar
donde esto podría reconocerse como “barra aplicada al resultado de la función foo con argumento expr” o como “una llamada a foo seguida de una barra aplicada a expr”. La regla para resolver esta ambigüedad es poner un punto y coma entre ‘foo’ y ‘(expr) .bar’ para obtener la segunda interpretación, o dejarla tal como está para obtener la primera.

Nota: Para algunos constructos, algunos compiladores de Eiffel considerarán los puntos y comas como terminadores, los consideran obligatorios o simplemente emiten una advertencia si faltan.

” width=”20″ height=”20″>

Leave a Reply

Your email address will not be published. Required fields are marked *