Associatividade de operadores

Origem: Wikipédia, a enciclopédia livre.
Nota: Para o conceito matemático de associatividade veja Associatividade

Em Linguagens de programação e Notação matemática, a associatividade de um operador é uma propriedade que determina como operadores de mesma precedência são agrupados na ausência de parêntesis. Operadores podem ser associativos-à-esquerda, associativos-à-direita ou não-associativos. A associatividade e a precedência de um operador depende da linguagem de programação em questão.

Considere a expressão a ~ b ~ c. Se o operador ~ tem associatividade à esquerda, essa expressão seria interpretada como (a ~ b) ~ c e avaliada da esquerda para a direita. Se o operador tem associatividade à direita, a expressão seria interpretada como a ~ (b ~ c) e avaliada da direita para a esquerda. Se o operador não é associativo, a expressão pode resultar em um erro de sintaxe, como no caso do operador de exponenciação ** da linguagem de programação Ada, ou pode ter algum significado especial.

Muitos manuais de linguagem de programação fornecem uma tabela de precedência dos operadores e associatividade, ver, por exemplo, tabela de C e C ++.

Exemplos[editar | editar código-fonte]

Associatividade é necessária somente quando os operadores em uma expressão tem a mesma precedência. Usualmente + e - tem a mesma precedencia - são chamados de operadores aditivos. Considere a expressão 7 − 4 + 2. O resultado poderia ser tanto (7 − 4) + 2 = 5 ou 7 − (4 + 2) = 1. O resultado anterior corresponde ao caso quando + e são associativos à esquerda, este último quando + e - são associativos à direita.

Normalmente, os operadores de adição, subtração, multiplicação e divisão são associativos à esquerda, enquanto exponenciação, atribuição e os operadores condicionais ?: (das linguagens C, C++ e Java) são associativos à direita. Para evitar casos em que os operandos estariam associada com dois operadores, ou nenhum operador, os operadores com a mesma precedência devem ter a mesma associatividade.

Um exemplo detalhado[editar | editar código-fonte]

Considere a expressão 5^4^3^2. Um analisador sintático sempre lê os tokens da esquerda para a direita. Mas por causa da associatividade à direita do operador ^, acontecerá o seguinte em um analisador sintático simples:

  1. 5 é lido.
  2. O primeiro operador ^ é lido. 5 é associado a ele.
  3. 4 é lido. Ele é associado ao único operador ^ lido até o momento.
  4. O segundo operador ^ é lido. 4 é re-associado a ele devido a associatividade à direita. Então esta construção é toda associada ao primeiro operador ^ como se fosse o operando da direita.
  5. 3 é lido. Este é associado ao segundo operador ^.
  6. O terceiro operador ^ é lido. 3 é re-associado a ele devido a associatividade à direita. Então esta construção é toda associada ao segundo operador ^ como se fosse o operando da direita.
  7. 2 é lido. Este é associado ao terceiro operador ^. Resultando na árvore sintática 5^(4^(3^2)), que pode ser avaliada em uma busca por profundidade, iniciando do nodo raiz (o primeiro ^):
  8. O avaliador desce na árvore, do primeiro, sobre o segundo, até o terceiro ^.
  9. Ele avalia: 3² = 9. Então ele põe o resultado no lugar da expressão, como segundo operando da de cima (segundo operador) ^.
  10. Ele sobe um nível e avalia a expressão resultante: 49 = 262144. Então ele coloca o resultado no lugar da expressão, como segundo operando da de cima (primeiro operador) ^.
  11. De novo, ele sobe um nível, e avalia a expressão resultante: 5262144 ≈ 6.2060699 × 10183230. Este se torna o resultado remanescente, e então, a avaliação finaliza com sucesso.

A avaliação associativa à esquerda teria resultado na árvore de análise sintática ((5^4)^3)^2 e os resultados completamente diferentes 625, 244140625 e finalmente ~ 5,9604645 × 10 16.

Associatividade à direita dos operadores de atribuição[editar | editar código-fonte]

Os operadores de atribuição em linguagens de programação imperativas são geralmente definidos como associativos à direita. Por exemplo, em C, a atribuição a = b é uma expressão que retorna um valor (ou seja, b convertido para o tipo de a), com o efeito colateral de alimentar a com esse valor. Uma atribuição pode ser realizada no meio de uma expressão.(Uma expressão pode ser feita em uma instrução seguindo-a com um ponto e vírgula; ou seja, a = b é uma expressão mas a = b; é uma instrução). A associatividade à direita do operador = permite que expressões como a = b = c possam ser interpretadas como a = (b = c), alimentando desse modo ambas variáveis a e b com o valor armazenado em c. A forma alternativa (a = b) = c não faz sentido porque a = b não pode receber um valor.

Operadores Não-Associativos[editar | editar código-fonte]

Operadores não-associativos são operadores que não têm comportamento definido quando usados em conjunto em uma expressão. Em Prolog, o operador infixo :- é não-associativo porque construções tais como "a :- b :- c" constituem erros de sintaxe. Em Python, operadores de comparação (tais como >, ==, e <=) são não-associativos[1] porque expressões tais como a < b < c têm um significado distinto de (a < b) < c or a < (b < c). Neste caso, a expressão é sinónimo de (a < b) e (b < c). Em Ada, o operador de exponenciação ** é não-associativo porque construções tais como "a ** b ** c" constituem erros de sintaxe.[2]

Referências

  1. http://docs.python.org/reference/expressions.html#comparisons
  2. Lopes, Arthur Vargas (1997). Introdução à Programação com Ada 95. Canoas: Editora da ULBRA. 424 páginas. ISBN 85-85692-38-3 

Bibliografia[editar | editar código-fonte]

  • Aho, Alfred V.; Ullman, Jeffrey D. (1972). The Theory of Parsing, Translation, and Compiling, Vol. 1, Parsing. 1. Englewood Cliffs, New Jersey, EUA: Prentice Hall. 542 páginas. ISBN 0-13-914556-7 
  • Aho, Alfred V.; Ullman, Jeffrey D. (1977). Principles of Compiler Design. Reading, Massachusetts, EUA: Addison-Wesley. 604 páginas. ISBN 0-201-00022-9 
  • Aho, Alfred V.; Sethi, Ravi; Ullman, Jeffrey D. (1986). Compilers: Principles, Techniques and Tools. Reading, Massachusetts, EUA: Addison-Wesley. 796 páginas. ISBN 0-201-10088-6 
  • Crespo, Rui Gustavo (1998). Processadores de Linguagens. da Concepção à Implementação. Lisboa, Portugal: IST Press. 435 páginas. ISBN 972-8469-01-2 
  • Kowaltowski, Tomasz (1983). Implementação de Linguagens de Programação. [S.l.]: Guanabara Dois. ISBN 85-7030-009-3 

Ver também[editar | editar código-fonte]