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.
- 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 endA 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.
- 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! fazeme
requer tag: -- Se esse comentário for ignorado, -- tag será erroneamente - associado a foo.is_valid! foo.is_validVeja a segunda nota em Comment para mais detalhes.
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.
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.
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.
- 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.
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.
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.
Nota: TowerEiffel aceita "constante remota" em Choice e Interval, assim como em:
foo: FOO inspecionar eu quando foo.const then do_something fimonde 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
- 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 ;; fimO 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'.outque deveria ser, usando a sintaxe padrão:
str := ('a').outExiste um ligeiro problema léxico com Integer_constant entretanto, desde
123.oute 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.
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:
fooser 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.
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 := - 2deve 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.
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.
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 := - 2deve 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.
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.
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:
- um dígito decimal (0 to 9)
- 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 INTEGERMas 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:
- um opcional Integer, dando a parte integral (se esta estiver ausente, a parte integral é 0.)
- um ponto obrigatório (.)
- um opcional Integer escrito para trás, o que dá a parte fracionada (se esta estiver ausente, a parte fracionada é 0.)
- 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.e1poderia ser escaneado como
a .e1ao inves de
a . e1'.e1' ser reconhecido como um real.
- Character_constant
- Uma constante de personagem é ou:
- um personagem imprimível, exceto porcentagem (%) e uma citação única (')
- 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:
- caracteres imprimíveis, exceto porcentagem (%) e dupla cotação (")
- 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@1e escaneado como
a @1que 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 ... fimnã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:
- em branco
- tab
- 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:
- uma sequencia %/code/ onde code e um inteiro não assinado que representa o caractere de ASCII code code em valor decimal
- 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:
- 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.
- 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 operatorsTodos os operadores binários gratuitos ^ right *
/
//
\\left
left
left
leftbinary +
binay -left
left=
/=
<
>
<=
>=left
left
left
left
left
lefte
e depoisleft
leftou
se não
xorleft
left
leftimplies left
Nota: A razão pela qual os compiladores de Eiffel rejeitam o seguinte código:
foo := 1 < 2 < 3nã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_TYPEem 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.