stringtranslate.com

Asociatividad de operadores

En la teoría del lenguaje de programación , la asociatividad de un operador es una propiedad que determina cómo se agrupan los operadores de la misma precedencia en ausencia de paréntesis . Si un operando está precedido y seguido por operadores (por ejemplo, ^ 3 ^), y esos operadores tienen la misma precedencia, entonces el operando puede usarse como entrada para dos operaciones diferentes (es decir, las dos operaciones indicadas por los dos operadores). La elección de a qué operaciones aplicar el operando está determinada por la asociatividad de los operadores. Los operadores pueden ser asociativos (lo que significa que las operaciones se pueden agrupar arbitrariamente), asociativos por la izquierda (lo que significa que las operaciones se agrupan desde la izquierda), asociativos por la derecha (lo que significa que las operaciones se agrupan desde la derecha) o no asociativos (lo que significa que las operaciones no se pueden agrupar desde la derecha). encadenados, a menudo porque el tipo de salida es incompatible con los tipos de entrada). La asociatividad y precedencia de un operador es parte de la definición del lenguaje de programación; Diferentes lenguajes de programación pueden tener diferente asociatividad y precedencia para el mismo tipo de operador.

Considere la expresión a ~ b ~ c. Si el operador ~ha abandonado la asociatividad, esta expresión se interpretaría como (a ~ b) ~ c. Si el operador tiene asociatividad correcta, la expresión se interpretaría como a ~ (b ~ c). Si el operador no es asociativo, la expresión podría ser un error de sintaxis o podría tener algún significado especial. Algunos operadores matemáticos tienen asociatividad inherente. Por ejemplo, la resta y la división, tal como se usan en la notación matemática convencional, son inherentemente asociativas por la izquierda. La suma y la multiplicación, por el contrario, son asociativas tanto de izquierda como de derecha. (p.ej (a * b) * c = a * (b * c)).

Muchos manuales de lenguajes de programación proporcionan una tabla de precedencia y asociatividad de operadores; consulte, por ejemplo, la tabla para C y C++ .

El concepto de asociatividad notacional descrito aquí está relacionado con la asociatividad matemática, pero es diferente de ella . Una operación que es matemáticamente asociativa, por definición, no requiere asociatividad notacional. (Por ejemplo, la suma tiene la propiedad asociativa, por lo tanto no tiene que ser asociativa por la izquierda ni por la derecha). Sin embargo, una operación que no es matemáticamente asociativa debe ser notacionalmente por la izquierda, por la derecha o no asociativa. (Por ejemplo, la resta no tiene la propiedad asociativa, por lo tanto debe tener asociatividad notacional).

Ejemplos

La asociatividad sólo es necesaria cuando los operadores de una expresión tienen la misma precedencia. Generalmente +y -tienen la misma precedencia. Considere la expresión 7 - 4 + 2. El resultado podría ser cualquiera (7 - 4) + 2 = 5o 7 - (4 + 2) = 1. El primer resultado corresponde al caso en que +y -son asociativos por izquierda, el segundo al caso en que +y -son asociativos por derecha.

Para reflejar el uso normal, los operadores de suma , resta , multiplicación y división suelen ser asociativos por la izquierda, [1] [2] [3] [4] [5] mientras que para un operador de exponenciación (si está presente) [6] y No existe un acuerdo general sobre los operadores de flecha hacia arriba de Knuth . Todos los operadores de asignación suelen ser asociativos por la derecha. Para evitar casos en los que los operandos se asocien con dos operadores, o con ningún operador, los operadores con la misma precedencia deben tener la misma asociatividad.

Un ejemplo detallado

Considere la expresión 5^4^3^2, en la que ^se considera un operador de exponenciación asociativo derecho. Un analizador que lea los tokens de izquierda a derecha aplicaría la regla de asociatividad a una rama, debido a la asociatividad derecha de ^, de la siguiente manera:

  1. 5Se lee el término .
  2. ^Se lee no terminal . Nodo: " 5^".
  3. 4Se lee el término . Nodo: " 5^4".
  4. Se lee el no terminal ^, lo que activa la regla de asociatividad por la derecha. La asociatividad decide el nodo: " 5^(4^".
  5. 3Se lee el término . Nodo: " 5^(4^3".
  6. Se lee el no terminal ^, lo que desencadena la reaplicación de la regla de asociatividad por la derecha. Nodo " 5^(4^(3^".
  7. 2Se lee el término . Nodo " 5^(4^(3^2".
  8. No hay fichas para leer. Aplicar asociatividad para producir el árbol de análisis " 5^(4^(3^2))".

Luego, esto se puede evaluar primero en profundidad, comenzando en el nodo superior (el primero ^):

  1. El evaluador recorre el árbol, desde la primera, pasando por la segunda y hasta la tercera ^expresión.
  2. Se evalúa como: 3 2 = 9. El resultado reemplaza la rama de expresión como segundo operando del segundo ^.
  3. La evaluación continúa un nivel más arriba en el árbol de análisis como: 4 9 = 262,144. Nuevamente, el resultado reemplaza la rama de expresión como segundo operando del primero ^.
  4. Nuevamente, el evaluador sube por el árbol hasta la expresión raíz y evalúa como: 5 2621446.206 0699 × 10 183 230 . La última rama restante colapsa y el resultado se convierte en el resultado general, completando así la evaluación general.

Una evaluación asociativa por la izquierda habría dado como resultado el árbol de análisis ((5^4)^3)^2y el resultado completamente diferente (625 3 ) 2 = 244,140,625 25,960 4645 × 10 16 .

Asociatividad por derecha de operadores de asignación

En muchos lenguajes de programación imperativos , el operador de asignación se define como asociativo por la derecha y la asignación se define como una expresión (que se evalúa como un valor), no solo una declaración. Esto permite la asignación encadenada utilizando el valor de una expresión de asignación como operando derecho de la siguiente expresión de asignación.

En C , la asignación a = bes una expresión que se evalúa con el mismo valor que la expresión bconvertida al tipo de a, con el efecto secundario de almacenar el valor R de ben el valor L de a. [a] Por lo tanto la expresión a = (b = c)puede interpretarse como b = c; a = b;. La expresión alternativa (a = b) = cgenera un error porque a = bno es una expresión de valor L, es decir, tiene un valor R pero no un valor L donde almacenar el valor R de c. La asociatividad derecha del =operador permite que expresiones como a = b = cse interpreten como a = (b = c).

En C++ , la asignación a = bes una expresión que se evalúa con el mismo valor que la expresión a, con el efecto secundario de almacenar el valor R de ben el valor L de a. Por lo tanto, la expresión a = (b = c)todavía puede interpretarse como b = c; a = b;. Y la expresión alternativa (a = b) = cse puede interpretar como a = b; a = c;en lugar de generar un error. La asociatividad derecha del =operador permite que expresiones como a = b = cse interpreten como a = (b = c).

Operadores no asociativos

Los operadores no asociativos son operadores que no tienen un comportamiento definido cuando se usan en secuencia en una expresión. En Prolog, el operador infijo no:- es asociativo porque construcciones como " " constituyen errores de sintaxis.a :- b :- c

Otra posibilidad es que las secuencias de ciertos operadores se interpreten de alguna otra manera, lo que no puede expresarse como asociatividad. Esto generalmente significa que sintácticamente existe una regla especial para las secuencias de estas operaciones y semánticamente el comportamiento es diferente. Un buen ejemplo es Python , que tiene varias construcciones de este tipo. [7] Dado que las asignaciones son declaraciones, no operaciones, el operador de asignación no tiene un valor y no es asociativo. En cambio, la asignación encadenada se implementa al tener una regla gramatical para secuencias de asignaciones a = b = c, que luego se asignan de izquierda a derecha. Además, las combinaciones de asignación y asignación aumentada, como a = b += cno son legales en Python, aunque sí lo son en C. Otro ejemplo son los operadores de comparación, como >, ==y <=. Una comparación encadenada como a < b < cse interpreta como (a < b) and (b < c)no equivalente a ni (a < b) < ca ni a a < (b < c). [8]

Ver también

Notas

  1. ^ Una expresión se puede convertir en una declaración siguiéndola con un punto y coma; es decir, a = bes una expresión pero a = b;es una declaración.

Referencias

  1. ^ Bronstein, Ilja Nikolaevič; Semendjajew, Konstantin Adolfovič (1987) [1945]. "2.4.1.1." En Grosche, Günter; Ziegler, Víktor; Ziegler, Dorothea (eds.). Taschenbuch der Mathematik (en alemán). vol. 1. Traducido por Ziegler, Viktor. Weiß, Jürgen (23 ed.). Thun y Fráncfort del Meno: Verlag Harri Deutsch (y BG Teubner Verlagsgesellschaft , Leipzig). págs. 115-120. ISBN 3-87144-492-8.
  2. ^ Universidad Tecnológica de Chemnitz : Prioridad y asociatividad de los operadores (traducción archivada)
  3. ^ Lugar de educación: el orden de las operaciones
  4. ^ Khan Academy : El orden de las operaciones, marca de tiempo 5m40s
  5. ^ Departamento de Educación de Virginia: uso del orden de operaciones y exploración de propiedades, sección 9
  6. ^ Codeplea de asociatividad de exponenciación y notación matemática estándar. 23 de agosto de 2016. Consultado el 20 de septiembre de 2016.
  7. ^ Referencia del lenguaje Python, "6. Expresiones"
  8. ^ Referencia del lenguaje Python, "6. Expresiones": 6.9. Comparaciones