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 endLa 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! doand
require tag: -- If this comment is ignored, -- tag will be erroneously -- associated with foo.is_valid! foo.is_validSee 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 endwhere 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
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.
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 ;; endTowerEiffel 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 Routine o Features, 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'.outque debería ser, usando la sintaxis estándar:
str := ('a').outHay un ligero problema léxico con Integer_constant sin embargo, desde
123.outes 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:
fooser 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 := - 2si 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.
Nota: Aquí hay una ambigüedad en la sintaxis estándar. En el siguiente fragmento de código:
foo := - 2si 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.
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.
Nota: No 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:
- un dígito decimal (0 a 9)
- 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 INTEGERpero 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:
- un opcional Integer,dando la parte integral (si no está presente, la parte integral es 0.)
- un punto requerido (.)
- un opcional Integerescrito al revés, que da la parte fraccionaria (si está ausente, la parte fraccionaria es 0.)
- 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.e1podría escanearse como
a .e1en lugar de
a . e1'.e1' ser reconocido como un verdadero.
- Character_constant
- Una constante de caracteres es:
- un personaje imprimible excepto por ciento (%) y comillas simples (‘)
- 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:
- caracteres imprimibles excepto por ciento (%) y comillas dobles (“)
- 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@1se escanea como
a @1que 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 ... endno 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:
- blanco
- lengüeta
- 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:
- 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
-
- 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:
- 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.
- 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 operatorsAll free binary operators ^ right *
/
//
\\left
left
left
leftbinary +
binay -left
left=
/=
<
>
<=
>=left
left
left
left
left
leftand
and thenleft
leftor
or else
xorleft
left
leftimplies left
Note: La razón por la cual los compiladores de Eiffel rechazan la siguiente pieza de código:
foo := 1 < 2 < 3no 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_TYPEen 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″>
