stringtranslate.com

Asociatividad de operadores

En la teoría de lenguajes 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 es precedido y seguido por operadores (por ejemplo, ^ 3 ^), y esos operadores tienen igual 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 encadenar, a menudo porque el tipo de salida es incompatible con los tipos de entrada). La asociatividad y la precedencia de un operador son parte de la definición del lenguaje de programación; diferentes lenguajes de programación pueden tener diferentes asociatividades y precedencias para el mismo tipo de operador.

Considere la expresión a ~ b ~ c. Si el operador ~tiene asociatividad por la izquierda, esta expresión se interpretaría como (a ~ b) ~ c. Si el operador tiene asociatividad por la derecha, 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 por la izquierda como por la 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 que se describe 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 o por la derecha). Sin embargo, una operación que no es matemáticamente asociativa debe ser asociativa por la izquierda, por la derecha o no asociativa por la notacional. (Por ejemplo, la resta no tiene la propiedad asociativa, por lo tanto, debe tener asociatividad notacional).

Ejemplos

La asociatividad solo es necesaria cuando los operadores de una expresión tienen la misma precedencia. Por lo general +, y -tienen la misma precedencia. Considere la expresión 7 - 4 + 2. El resultado podría ser (7 - 4) + 2 = 5o 7 - (4 + 2) = 1. El primer resultado corresponde al caso cuando +y -son asociativos por la izquierda, el segundo al caso cuando +y -son asociativos por la 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] mientras que para un operador de exponenciación (si está presente) [4] [ se necesita una mejor fuente ] no hay un acuerdo general. 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 en absoluto, 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 toma como un operador de exponenciación asociativo por la derecha. Un analizador que lea los tokens de izquierda a derecha aplicaría la regla de asociatividad a una rama, debido a la asociatividad por la derecha de ^, de la siguiente manera:

  1. El término 5se lee.
  2. Se lee el no terminal ^. Nodo: " 5^".
  3. 4Se lee el término . Nodo: " 5^4".
  4. Se lee un no terminal ^, lo que activa la regla de asociatividad 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 activa la reaplicación de la regla de asociatividad derecha. Nodo " 5^(4^(3^".
  7. 2Se lee el término . Nodo " 5^(4^(3^2".
  8. No hay tokens para leer. Aplicar asociatividad para producir un árbol de análisis " 5^(4^(3^2))".

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

  1. El evaluador recorre el árbol desde la primera, pasando por la segunda, hasta llegar a la tercera ^expresión.
  2. Se evalúa como: 3 2 = 9. El resultado reemplaza la expresión branch como el segundo operando del segundo ^.
  3. La evaluación continúa un nivel más arriba en el árbol de análisis : 4 9 = 262 144. Nuevamente, el resultado reemplaza la expresión branch como el segundo operando del primero ^.
  4. Nuevamente, el evaluador avanza 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 derecha de los operadores de asignación

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

En C , la asignación a = bes una expresión que evalúa 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)se puede interpretar 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 evalúa 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 se puede interpretar 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 utilizan en secuencia en una expresión. En Prolog, el operador infijo no :-es asociativo porque construcciones como " a :- b :- c" constituyen errores de sintaxis.

Otra posibilidad es que las secuencias de ciertos operadores se interpreten de alguna otra manera, que no se puede expresar como asociatividad. Esto generalmente significa que sintácticamente, hay una regla especial para las secuencias de estas operaciones, y semánticamente el comportamiento es diferente. Un buen ejemplo está en Python , que tiene varias construcciones de este tipo. [5] Dado que las asignaciones son declaraciones, no operaciones, el operador de asignación no tiene un valor y no es asociativo. La asignación encadenada se implementa en cambio 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 es equivalente a ni (a < b) < ca a < (b < c). [6]

Véase también

Notas

  1. ^ Una expresión puede convertirse en una declaración si se le añade un punto y coma como complemento; es decir, a = bes una expresión pero a = b;es una declaración.

Referencias

  1. ^ Lugar de Educación: El orden de las operaciones
  2. ^ Khan Academy : El orden de las operaciones, marca de tiempo 5m40s
  3. ^ Departamento de Educación de Virginia: Uso del orden de operaciones y exploración de propiedades, sección 9
  4. ^ Exponenciación Asociatividad y Notación Matemática Estándar Codeplea. 23 de agosto de 2016. Consultado el 20 de septiembre de 2016.
  5. ^ Referencia del lenguaje Python, "6. Expresiones"
  6. ^ Referencia del lenguaje Python, "6. Expresiones": 6.9. Comparaciones