Original Article: Eiffel: The Syntax
Author: www.gobosoft.com/

Eiffel: a sintaxe

A sintaxe de Anotação de Eiffel descrita aqui é destinada a escritores de ferramentas de Eiffel, como compiladores, intérpretes, verificadores de sintaxe, ferramentas curtas e planas, impressoras bonitas, etc., que desejam beneficiar de algumas dicas e truques. Embora esta não seja a especificação oficial da sintaxe de Eiffel fornecida pelo Consórcio Internacional Sem fins lucrativos para a Eiffel (NICE), partida em apenas duas ou três ocasiões bem documentadas. Em particular, explica onde, e às vezes o motivo, os compiladores existentes estenderam a sintaxe de Eiffel..

As construções de sintaxe de Eiffel estão listadas em grupos, começando por construções de alto nível como Class_declaration até componentes lexical, como Identificador. Alternativamente, essas construções também são dadas em ordem alfabetica. A notação usado para descrever a sintaxe Eiffel é especificado em outro lugar. Uma possível implementação da sintaxe Eiffel em yacc- e lex-como o formato também é fornecido como um exemplo.


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

Nota: A maioria dos compiladores de Eiffel não verifica a validade do comentário opcional após a palavra-chave final. SmallEiffel emite um aviso embora.

Nota: Um arquivo pode conter mais de uma declaração de classe. No entanto, a maioria dos compiladores de Eiffel tem uma limitação de uma classe por arquivo.


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: A palavra-chave separado não é parte do padrão Eiffel. Foi introduzido no ISE Eiffel para suportar o SCOOP mecanismo. Leia Construção de software orientado a objetos, segunda edição, para detalhes.

Class_name
Identifier

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

Nota: A lista de genéricos formais pode estar vazia. Como consequência, FOO[] e válido e significa o mesmo que FOO. No entanto, este não é o 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: Por causa dessa construção, a gramática de Eiffel não é LR(1). Isso ocorre na seguinte situação:

class FOO
inherit
    BAR
end

A palavra-chave final Será considerado parte da opção Feature_adaptation em vez de como parte do Class_declaration construir.

Uma maneira de resolver este problema seria permitir que a palavra-chave final na Feature_adaptation somente quando pelo menos uma das construções opcionais que compõem o Feature_adaptation esta 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: A sintaxe padrão requer um Feature_list em vez de Procedure_list but the Creation_clause na verdade lista os nomes dos procedimentos de criação (veja a regra de validade VGCP-2).

Procedure_list
{ Procedure_name , ... }
Procedure_name
Identifier

Nota: Prefix e Infix são nomes de funções, não nomes de procedimentos. Não é claro para mim se um Prefix poderia ser um nome de atributo, mas definitivamente não é um nome de procedimento (veja a regra de validade 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 os compiladores do Eiffel aceitam os operadores de prefixo e infix independentemente do caso de carta, como prefix "NOT" or infix "AnD".

Nota: Nenhum caracter interativo é permitido após a primeira ou última a última cotação dupla. No entanto, não está claro que tipo de ruptura deve ser usado entre as duas palavras-chave em e entao or se não. SmallEiffel aceita qualquer número de espaços em branco e caracteres de tabulação, enquanto os outros compiladores requerem um único espaço em branco.


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: A lista de declarações de entidade pode estar vazia. Como consequência, foo() e válido e significa o mesmo que foo. No entanto, esse estilo não é recomendado.


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

Nota: A maioria dos compiladores de Eiffel não verifica a validade do comentário opcional após a palavra-chave final. Não está nas diretrizes de estilo para colocar esse comentário mais.


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 Eiffel suporta sua própria mini-sintaxe no nome do idioma e nas strings de nomes externos para descrever sua interface com outras linguagens de programação. Consulte a documentação fornecida com os diferentes compiladores para detalhes.


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: Embora sejam esperados comentários como comentários de cabeçalho em algumas construções, como Routine ou Features, Este é o único lugar onde ignorar um comentário resulta em um erro de sintaxe ou uma árvore de sintaxe incorreta. Isso ocorre nas seguintes situações:

require
    tag: -- Erro de sintaxe quando ignorado!
fazem

e

requer
    tag: -- Se esse comentário for ignorado,
         -- tag será erroneamente - associado a foo.is_valid!
    foo.is_valid

Veja a segunda nota em Comment para mais detalhes.


Rescue
rescue Compound

Note: A regra de validade VXRT afirma que a Retry a instrução é válida somente em uma cláusula de resgate. Isso poderia eventualmente ser imposto pela sintaxe.


Type
Class_type |
Class_type_expanded |
Class_type_separate |
Anchored | Bit_type

Note: A sintaxe padrão de Eiffel também lista Formal_generic_name como uma possível alternativa para Type. No entanto, introduziu uma ambigüidade na sintaxe, uma vez que um identificador poderia ser reconhecido tanto como um Formal_generic_name e um Class_type sem genéricos reais.

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

Nota: A lista de tipos pode estar vazia. Como consequência, FOO[] e válido e significa o mesmo que FOO. No entanto, este não é o estilo recomendado.

Class_type_expanded
expanded Class_type
Class_type_separate
separate Class_type

Nota: Class_type_separate não é parte do padrão Eiffel. Foi introduzido no ISE Eiffel para suportar o SCOOP mecanismo. Leia Construção de software orientado a objetos, segunda edição, para detalhes.

Bit_type
BIT Bit_length

Nota: Na sintaxe padrão, Constant aparece em vez de Bit_length. No entanto, a regra de validade VTBT afirma que um Bit_type a declaração é válida se e somente se for Constant e do tipo INTEGER, o que significa que a constante é uma constante inteira manifesto ou uma constante de atributo.

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: Se o tipo estiver ausente, os dois sinais de exclamação podem ser escritos com ou sem interrupção. No padrão de estilo, a forma recomendada é a sem quebras, o que faz !! aparecem como um único símbolo léxico.

Creation_call
. Procedure_name [ Actuals ]

Nota: Na sintaxe padrão de Eiffel, o Creation_call e feito de um Unqualified_call. Mas a regra de validade VGCC-6 afirma que, se f e a característica do Creation_call, o f e um procedimento.


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 , ... }

Nota: A lista de escolhas pode estar vazia. Como consequência,

inspecionar expr
então quando
    do_something
...

embora sem sentido, é sintaticamente correto. Pode ser pensado como

se Falso entao
    do_something
...

No entanto, isso não faz parte do estilo recomendado.

Choice
Choice_constant | Interval

Nota: A sintaxe padrão especifica Constant ao invés de Choice_constant. No entanto, a regra de validade VOMB-1-2 afirma que a Constant em Choice e Interval e apenas de tipo INTEGER ou CHARACTER.

Interval
Choice_constant .. Choice_constant

Nota: O analisador lexical deve ser suficientemente inteligente no exemplo a seguir:

inspect expr
quando 1..2 então
...

De fato, '1..2' deve ser reconhecido como as duas constantes inteiras '1' e '2' separados pelo símbolo de Eiffel '..', em vez de duas constantes reais consecutivas '1.' e '.2'. Visual Eiffel erroneamente emite um erro de sintaxe ao analisar o exemplo acima.

Choice_constant
Integer_constant | Character_constant | Attribute

Nota: TowerEiffel aceita "constante remota" em Choice e Interval, assim como em:

foo: FOO
inspecionar eu
quando foo.const then
     do_something
fim

onde const e declarado como constante na turma FOO. Esta não é a sintaxe padrão de Eiffel.


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

Nota: A regra de validade VAVE afirma que Expression deve ser de tipo INTEGER. Isso poderia eventualmente ser parcialmente aplicado na sintaxe, descartando Equality, Manifest_array, Strip e todos não inteiros 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

Nota: A regra de validade VXRT afirma que Retry as instruções são válidas somente em um Rescue cláusula. Isso poderia eventualmente ser imposto pela sintaxe.


Null_instruction
empty

Nota: Esta instrução tem um papel puramente sintático: certificando-se de que os pontos-e-vírgulas adicionais sejam adicionados por supervisão a um Compound são inofensivos, como em

se c entao ; i1;;; i2; algo ;; fim

O TowerEiffel não suporta pontos e vírgulas extras, além dos terminadores. Todos os outros compiladores funcionam como esperado. SmallEiffel emite um aviso ao analisar pontos-e-vírgulas extras.


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 ]

Nota: Esta especificação de Call e um pouco diferente da versão fornecida no padrão. No entanto, a sintaxe padrão aceita construções que não são corretas, como Eiffel, como:

foo.Resultaa
Atual (5)

considerando que a especificação dada acima não.

Nota: No TowerEiffel, os recursos podem ser chamados diretamente em um Manifest_constant sem colocar parênteses ao redor da constante, como em:

str := 'a'.out

que deveria ser, usando a sintaxe padrão:

str := ('a').out

Existe um ligeiro problema léxico com Integer_constant entretanto, desde

123.out

e reconhecido como

123. out

'123.' sendo um Real_constant. O programador tem que adicionar um extra Break entre a constante inteira e o ponto para resolver esse problema.


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

Nota: O Precursor a construção não é parte da sintaxe padrão de Eiffel. Foi introduzido em Construção de software orientado a objetos, segunda edição, e uma proposta para a sua padronização foi submetida a NICE. ISE Eiffel e Halstenbach provavelmente apoiarão esta construção em seu próximo lançamento.

Note: Em Construção de software orientado a objetos, segunda edição, o nome da classe em Parent_qualification está entre chaves duplas: {{Class_name}}. No entanto, a proposta foi enviada para NICE usa a sintaxe especificada acima.


Attribute
Identifier

Nota: De acordo com a regra de validade VFFD-5, um Attribute também pode ser um Prefix.

Writable
Identifier | Result

Nota: A Entity o grupo de sintaxe da especificação de sintaxe padrão foi muito simplificado para resolver muitas ambiguidades. Por exemplo, deveria:

foo

ser reconhecido como um Attribute, um Local ou um Formal? Apenas uma análise semântica pode dar a resposta.


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

Nota: A lista de reais pode estar vazia. Como consequência, foo() e válido e significa o mesmo que foo. No entanto, esse estilo não é recomendado.

Actual
Expression | Address

Nota: Treats de TowerEiffel Address como uma expressão normal (ou seja, como uma alternativa no Expression construir). Como conseqüência, um endereço não precisa ocorrer apenas em listas reais.

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 especificação de Expression e um pouco diferente da versão fornecida no padrão. Primeiro, Current e Result foram adicionados como conseqüência de novas especificações para Call. Então, Manifest_constant foi substituído pela lista de suas alternativas. Isto é para resolver uma ambigüidade na sintaxe padrão. No seguinte código:

foo := - 2

deve o Expression no lado direito da atribuição seja reconhecido como um Integer_constant ou como um Unary_expression de quem Prefix_operator é '-' e de quem Expression é um (não assinado) Integer? Substituindo Integer_constant e Real_constant por Integer e Real resolve o problema.

Nota: Wide_character_constant, Wide_manifest_string e Hexadecimal_constant não fazem parte do padrão. Eles foram introduzidos no TowerEiffel para suportar caracteres amplos e cadeias de caracteres e inteiros hexadecimais.

Boolean_expression
Expression

Nota: A regra de validade VWBE afirma que uma expressão booleana deve ser de tipo BOOLEAN. Isso poderia eventualmente ser parcialmente aplicado na sintaxe, descartando Manifest_array, Strip e tudo non-boolean Manifest_constants.


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

Nota: Veja Operator para precedência e associatividade do operador.


Equality
Expression Comparison Expression
Comparison
= | /=

Nota: Veja Operator para precedência e associatividade do operador.


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

Nota: Wide_character_constant, Wide_manifest_string e Hexadecimal_constant não fazem parte do padrão. Eles foram introduzidos no TowerEiffel para suportar caracteres amplos e cadeias de caracteres e inteiros hexadecimais.

Boolean_constant
True | False
Integer_constant
[ Sign ] Integer

Nota: Há uma ambigüidade na sintaxe padrão aqui. No seguinte código:

foo := - 2

deve a Expression no lado direito da atribuição seja reconhecido como um Integer_constant ou como um Unary_expression de quem Prefix_operator é '-' and whose Expression é um (não assinado) Integer? Isso foi resolvido na descrição da sintaxe atual, reescrevendo a especificação for Expression.

Real_constant
[ Sign ] Real

Nota: A mesma ambiguidade que para Integer_constant acima.

Sign
+ | -
Wide_character_constant
$ Character_constant

Nota: Wide_character_constant não é parte do padrão. Foi introduzido no TowerEiffel para suportar caracteres amplos.

Nota: Não é permitido nenhum caracter interativo entre o sinal de dólar e o Character_constant.

Wide_manifest_string
$ Manifest_string

Nota: Wide_manifest_string não é parte do padrão. Foi introduzido no TowerEiffel para suportar caracteres amplos em strings.

Nota: Não é permitido nenhum caracter interativo entre o sinal de dólar e o Manifest_string.


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

Old
old Expression

Nota: A regra de validade VAOL-1 afirma que a Old a expressão só é válida em um Postcondition. Isso poderia eventualmente ser imposto pela sintaxe.


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

Identifier
Um identificador é uma seqüência de um ou mais caracteres, dos quais o primeiro é uma letra (a para z e A para Z) e cada um dos subsequentes, se houver, é uma letra, um dígito decimal (0 para 9) ou um personagem de destaque (_).
A maiúscula não é significativa para letras: os dois identificadores lInKeD_liST and LINKED_LIST são considerados os mesmos.

Nota: Infelizmente, Small Eiffel diferencia maiúsculas de minúsculas. (Surpreendentemente, não é sensível a maiúsculas e minúsculas Reserved_words.)

Nota: Um identificador é válido se e somente se não for um dos Reserved_words.

Nota: TowerEiffel não pode manipular sublinhados contíguos em nomes de recursos e nomes de classe.


Integer
Um número inteiro é uma seqüência de caracteres, cada um dos quais deve ser:
  1. um dígito decimal (0 to 9)
  2. um sublinhado (_), que pode não ser o primeiro personagem.
Se algum sublinhado estiver presente, deve haver três dígitos à direita de cada sublinhado, e não deve haver nenhum grupo consecutivo de quatro dígitos.

Nota: As últimas duas restrições relativas a sublinhados podem ser removidas no futuro, permitindo grupos de qualquer número de dígitos.

Nota: Contrario ao Integer_constant, Integer não tem sinal.

Nota: Esteja ciente do problema de valor mínimo mínimo! Por exemplo, em plataformas onde os números inteiros são armazenados em 32 bits, o seguinte código de Eiffel é válido:

Minimum_integer: INTEGER is - 2_147_483_648
        -- O menor valor suportado de tipo INTEGER

Mas o analisador deve ser inteligente o suficiente caso contrário, ele lerá um unário menos seguido pelo número inteiro 2147483648, que não se encaixa em 32 bits e, portanto, desencadeia um estouro.


Hexadecimal_constant
Uma constante hexadecimal é uma seqüência de dois ou mais caracteres, cujo primeiro caractere é um dígito decimal (0 to 9), cujos caracteres subseqüentes, mas os últimos são dígitos decimais ou letras a para f ou A to F, e seguido por x or X, sem outros personagens intervenientes.

Note: Hexadecimal_constant não é parte do padrão. Foi introduzido no TowerEiffel para suportar inteiros hexadecimais.

Nota: não está claro se os sublinhados são permitidos em constantes hexadecimais.


Real
Um número real é feito dos seguintes elementos:
  1. um opcional Integer, dando a parte integral (se esta estiver ausente, a parte integral é 0.)
  2. um ponto obrigatório (.)
  3. um opcional Integer escrito para trás, o que dá a parte fracionada (se esta estiver ausente, a parte fracionada é 0.)
  4. um expoente opcional, que é a letra e ou E seguido de um opcional Sign (+ ou -) e um Integer. O inteiro é necessário se o e or E é presente. Isso indica que o valor que aparece antes do e ou E deve ser dimensionado em 10 ^ n, onde n é o inteiro dado.
Não é permitido nenhum caracter intermediário (em branco ou não) entre esses elementos. As partes integral e fracionária podem não estar ausentes. Se os sublinhados forem usados na parte integral ou fracionada, eles também devem aparecer na outra parte, a menos que tenha três dígitos ou menos.

Nota: O estilo recomendado é usar E ao invés de e.

Nota: Contrário a Real_constant, Real não tem sinal.

Nota: A restrição que indica que as partes integrais e fraccionais podem não estar ausentes é lexicamente importante. Caso contrário, o seguinte código

a.e1

poderia ser escaneado como

a  .e1

ao inves de

a  .  e1

'.e1' ser reconhecido como um real.


Character_constant
Uma constante de personagem é ou:
  1. um personagem imprimível, exceto porcentagem (%) e uma citação única (')
  2. um Special_character
entre citações simples (').

Nota: Os caracteres para imprimir incluem, neste caso, espaços em branco e caracteres de tabulação, mas não novas linhas. Compare isso com Free_operator.


Manifest_string
Uma seqüência de manifestos é uma seqüência arbitrária de:
  1. caracteres imprimíveis, exceto porcentagem (%) e dupla cotação (")
  2. Special_characters
entre aspas (").
Um formulário estendido permite escrever uma seqüência de manifesto em duas ou mais linhas. Cada linha, mas a última deve terminar com um percentual (%) e cada linha, mas a primeira deve começar com um percentual (%) possivelmente precedido por espaços em branco ( ) e caracteres de tabulação.

Nota: Os caracteres para imprimir incluem, neste caso, espaços em branco e caracteres de tabulação, mas não novas linhas. Compare isso com Free_operator.


Bit_constant
Um pouco constante é uma seqüência de dígitos 0 ou 1, seguido por b ou B, sem outros personagens intervenientes.

Nota: O estilo recomendado é usar B ao invés de b.


Free_operator
Um operador gratuito é uma seqüência de um ou mais caracteres, cujo primeiro caracter é qualquer um dos @ # | & e cujos caracteres subsequentes, se houver, podem ser caracteres imprimíveis. A maiúscula não é significativa para cartas em operadores gratuitos.

Nota: Os caracteres para impressão não incluem, neste caso, caracteres permitidos em Breaks. Compare isso com Character_constant.

Nota: O código a seguir

a@1

e escaneado como

a  @1

que não é sintaticamente correto. Veja Eiffel gotchas para detalhes.

Nota: Eiffel: a língua, segunda impressão, permite Special_characters (embora seja imprimível) em operadores gratuitos. Nenhum compilador Eiffel suporta isso.

Nota: SmallEiffel e Visual Eiffel distinguem maiúsculas de minúsculas para operadores gratuitos.


Comment
Um comentário começa com dois personagens de traço (--) e se estende até o fim da linha.
Um formulário prolongado permite escrever um comentário em duas ou mais linhas. Cada linha, mas a primeira, deve começar com dois personagens de traço possivelmente precedidos por espaços em branco e caracteres de tabulação.
Header_comment
Comment

Nota: Esta não é a descrição oficial de Comment. No entanto, não pude ver por que o caráter percentual (%) não foi permitido na sua forma nula (ou seja, não faz parte de um Special_character) em um comentário.

Nota: Existem dois tipos de comentários: comentários gratuitos e comentários esperados. Os comentários gratuitos podem ser descartados por algumas ferramentas. No entanto, os comentários esperados aparecem como parte de quatro construções: Routine, Assertion_clause, Creation_clause e Feature_clause, e deve ser processado por ferramentas como a curta utilidade. Embora, em Routine, Creation_clause e Feature_clause, o comentário do cabeçalho é opcional e pode ser ignorado sem muito mal, é obrigatório em Assertion_clause E ignorá-lo seria um erro de sintaxe. Uma solução para implementar esses comentários esperados poderia ser usar vínculos lexicais.

Nota: O TowerEiffel emite erroneamente um erro de sintaxe quando um comentário aparece entre o feature palavra-chave e opcional Clients no Features construir. Este é provavelmente um efeito secundário do uso de vínculos léxicos sugeridos acima.

Nota: No seguinte Routine declaração:

foo is
        -- Este é o primeiro comentário.

        -- Este é o segundo comentário.

        -- Este é o terceiro comentário.
    faz
        ...
    fim

não está claro qual dos três comentários é esperado Header_comment e quais são os outros dois comentários gratuitos. A TowerEiffel escolheu o primeiro comentário para ser o comentário do cabeçalho. Alguns outros compiladores, como ISE Eiffel, Halstenbach e Visual Eiffel, mesclaram os três comentários em um que se torna o comentário do cabeçalho.

Nota: Alguns compiladores do Eiffel ignoram qualquer linha começando com '--|' em vez de apenas '--' em comentários de cabeçalho.


Break
Uma interrupção é feita de uma seqüência de um ou mais dos seguintes caracteres:
  1. em branco
  2. tab
  3. nova linha
Um intervalo pode ser inserido entre dois elementos adjacentes sem afetar a semântica.

Nota: Algumas plataformas, como o Windows, colocam um caractere de retorno de carro antes da nova linha. Nesses casos, é mais fácil considerar o retorno de carro como um quarto personagem possível que faz uma pausa.


Special_character
Um caractere especial tem uma das seguintes formas:
  1. uma sequencia %/code/ onde code e um inteiro não assinado que representa o caractere de ASCII code code em valor decimal
  2. uma sequencia %K usado para representar os seguintes caracteres especiais:
     
    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: A maioria dos compiladores de Eiffel emite um erro de sintaxe quando a seqüência %K não está listado na tabela acima. No entanto, Visual Eiffel considera que a sequência %K representa o personagem K quando a seqüência não está listada na tabela acima. Como consequência %P representa personagem P e %D representa personagem $.

Nota: Todos os compiladores de Eiffel que testei (isto é, ISE Eiffel, Halstenbach, SmallEiffel, Visual Eiffel, TowerEiffel) esperam a letra K em %K estar em maiúscula para ser reconhecido como um caractere especial da tabela acima. Como consequência %d e %D não são considerados os mesmos.

Nota: não é claro para mim se os sublinhados são permitidos no code Inteiro (especialmente quando é o código de um caractere largo).


Reserved_word
Uma palavra reservada é ou:
  1. uma palavra-chave, que serve para introduzir e delimitar os componentes variantes das construções. As palavras-chave Eiffel são: 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. um nome predefinido, que vem em posições onde os tokens variáveis também seriam permitidos. Os nomes predefinidos de Eiffel são: BIT, Current, False, Precursor, Result, Strip, True, Unique.
O caso de letra não é significativo para palavras reservadas: as duas palavras Result e rEsUlT são considerados os mesmos.

Nota: A especificação oficial de sintaxe lista os seguintes nomes de classe como palavras reservadas: BOOLEAN, CHARACTER, DOUBLE, INTEGER, NONE, POINTER, REAL, STRING. Eu entendo que essas classes devem ser conhecidas pelos compiladores de Eiffel, mas não vejo por que elas devem ser palavras reservadas. Observe que ANY, GENERAL, PLATFORM E muitos outros nomes de classe do Kernel Library Standard também não estão listados! Além disso, esses nomes de classe não aparecem em nenhuma parte nas construções de sintaxe. Finalmente, apenas o Visual Eiffel considera esses nomes de classes como palavras reservadas.

Nota: Em Eiffel: a língua, segunda impressão, False, Strip, True e Unique são considerados palavras-chave. Eu não compartilho esse ponto de vista.

Nota: Embora o SmallEiffel seja sensível a maiúsculas e minúsculas em relação a Identifier, considera que o caso de carta não é significativo para palavras reservadas!

Nota: Precursor não faz parte da sintaxe padrão. Foi introduzido para apoiar o Precursor mecanismo.


Operator
Os operadores na tabela a seguir são agrupados por nível de precedência, começando com o maior grupo de precedência. Os operadores dentro de cada grupo têm a mesma precedência. Para duas ou mais ocorrências consecutivas de operadores binários com o mesmo nível de precedência, a coluna de associatividade especifica a ordem de avaliação.
Symbol Associativity
. left
old
not
unary +
unary -
All free unary operators
 
Todos os operadores binários gratuitos  
^ right
*
/
//
\\
left
left
left
left
binary +
binay -
left
left
=
/=
<
>
<=
>=
left
left
left
left
left
left
e
e depois
left
left
ou
se não
xor
left
left
left
implies left

Nota: A razão pela qual os compiladores de Eiffel rejeitam o seguinte código:

foo := 1 < 2 < 3

não é porque os operadores de comparação não são associativos. Esses operadores são realmente deixados associativos. O código acima é sintaticamente correto, mas é simplesmente rejeitado porque '1 < 2' e de tipo BOOLEAN e não há nenhuma característica como:

infix "<" (i: INTEGER): SOME_TYPE

em aula BOOLEAN.


Semicolon
Os ponto-e-vírgula são usados como separadores em listas como Index_list ou Compound. Ponto-e-vírgula são opcionais na maioria dos lugares. No entanto, eles são necessários em alguns casos para remover ambigüidadesin Assertion e Compound. A ambigüidade aparece no seguinte código:
foo (expr).bar
onde isso poderia ser reconhecido como "bar aplicado ao resultado da função foo com argumento expr" ou como "uma chamada para foo seguido por bar aplicado para expr". A regra para resolver essa ambiguidade é colocar um ponto-e-vírgula entre 'foo' e '(expr).bar' para obter a segunda interpretação, ou deixá-la como se fosse obter o primeiro.

Nota: Para algumas construções, alguns compiladores de Eiffel considerarão os ponto-e-vírgulas como terminadores, considerá-los obrigatórios ou simplesmente emitir um aviso se estiverem faltando.