Ассоциативность оператора

редактировать

В языках программирования, ассоциативность оператора - это свойство, определяющее, как операторы с одинаковым приоритетом группируются при отсутствии скобок. Если перед операндом идут операторы (например, ^ 3 ^), и эти операторы имеют одинаковый приоритет, то операнд может использоваться в качестве входных данных для двух разных операций. (т.е. две операции, указанные двумя операторами). Выбор операций, к которым следует применить операнд, определяется ассоциативностью операторов. Операторы могут быть ассоциативными (то есть операции могут быть сгруппированы произвольно), левоассоциативными (что означает, что операции сгруппированы слева), правоассоциативными ( означает, что операции сгруппированы справа) или неассоциативный (что означает, что операции нельзя связать, часто потому, что тип вывода несовместим с типами ввода). Ассоциативность и приоритет оператора являются частью определения языка программирования; разные языки программирования могут иметь разную ассоциативность и приоритет для одного и того же типа оператора.

Рассмотрим выражение a ~ b ~ c. Если оператор ~оставил ассоциативность, это выражение будет интерпретироваться как (a ~ b) ~ c. Если оператор имеет правую ассоциативность, выражение будет интерпретироваться как a ~ (b ~ c). Если оператор неассоциативен, выражение может быть синтаксической ошибкой или иметь особое значение. Некоторым математическим операторам присуща ассоциативность. Например, вычитание и деление, используемые в обычных математических обозначениях, по своей сути левоассоциативны. Сложение и умножение, напротив, ассоциативны как слева, так и справа. (например, (a * b) * c = a * (b * c)).

Многие руководства по языкам программирования содержат таблицы приоритета и ассоциативности операторов; см., например, таблицу для C и C ++..

Описанная здесь концепция нотационной ассоциативности связана с математической ассоциативностью, но отличается от нее. Математически ассоциативная операция по определению не требует ассоциативности обозначений. (Например, сложение обладает свойством ассоциативности, поэтому оно не обязательно должно быть либо левоассоциативным, либо правоассоциативным.) Однако операция, которая не является математически ассоциативной, должна быть условно левой, правой или неассоциативной. (Например, вычитание не обладает свойством ассоциативности, поэтому оно должно обладать ассоциативностью обозначений.)

Содержание
  • 1 Примеры
    • 1.1 Подробный пример
  • 2 Правоассоциативность операторов присваивания
  • 3 Неассоциативные операторы
  • 4 См. Также
  • 5 Примечания
  • 6 Ссылки
Примеры

Ассоциативность необходима, только если операторы в выражении имеют одинаковый приоритет. Обычно +и -имеют одинаковый приоритет. Рассмотрим выражение 7 - 4 + 2. Результатом может быть (7-4) + 2 = 5или 7 - (4 + 2) = 1. Первый результат соответствует случаю, когда +и -левоассоциативны, второй - когда +и -правосторонний ассоциативный.

Чтобы отразить нормальное использование, операторы сложения, вычитания, умножения и деления обычно используются слева направо. ассоциативно, в то время как для оператора возведения в степень (если он присутствует) и операторов стрелки вверх Кнута не существует общего согласия. Любые операторы присваивания обычно являются правоассоциативными. Чтобы предотвратить случаи, когда операнды были бы связаны с двумя операторами или вообще без операторов, операторы с одинаковым приоритетом должны иметь одинаковую ассоциативность.

Подробный пример

Рассмотрим выражение 5 ^ 4 ^ 3 ^ 2, в котором ^рассматривается как правоассоциативное возведение в степень. оператор. Синтаксический анализатор, читающий токены слева направо, применит правило ассоциативности к ветви из-за правоассоциативности ^следующим образом:

  1. Term 5is прочитано.
  2. Нетерминал ^прочитан. Узел: «5^".
  3. Термин 4прочитан. Узел:« 5 ^ 4".
  4. Нетерминал ^прочитан, запускает правило правоассоциативности. Ассоциативность определяет узел: "5 ^ (4 ^".
  5. Термин 3читается. Узел:" 5 ^ (4 ^ 3".
  6. Нетерминальный ^читается, вызывая повторное применение правила правой ассоциативности. Узел "5 ^ (4 ^ (3 ^".
  7. Член 2читается. Узел" 5 ^ ( 4 ^ (3 ^ 2".
  8. Нет токенов для чтения. Примените ассоциативность для создания дерева синтаксического анализа "5 ^ (4 ^ (3 ^ 2))".

Затем это можно оценить в глубину, начиная с верхний узел (первый ^):

  1. Оценщик проходит вниз по дереву, от первого, по второму, к третьему ^выражению.
  2. Он оценивается как: 3 = 9. Результат заменяет ветвь выражения, поскольку второй операнд второго ^.
  3. Оценка продолжается на один уровень вверх по дереву синтаксического анализа как: 4 = 262144. И снова результат заменяет ветвь выражения как второй операнд первого ^.
  4. Опять же, оценщик переходит вверх по дереву к корневому выражению и вычисляет: 5 ≈ 6,2060699 × 10. Последняя оставшаяся ветвь сворачивается, и результат становится общим результатом, поэтому завершается общая оценка.

Левоассоциативная оценка привела бы к дереву синтаксического анализа ((5 ^ 4) ^ 3) ^ 2и совершенно другим результатам 625, 244140625 и, наконец, ~ 5.9604645 × 10.

Правоассоциативность операторов присваивания

Во многих императивных языках программирования оператор присваивания определен как правоассоциативный, а присваивание определяется как выражение (со значением), а не просто инструкция. Это позволяет связанное присваивание с использованием значения одного выражения присваивания в качестве входных данных (правый операнд) следующего.

Например, в C присвоение a = b- это выражение, которое возвращает значение (а именно, b, преобразованное в тип of a) с побочным эффектом установки aна это значение. Присваивание может быть выполнено в середине выражения. Правая ассоциативность оператора =позволяет интерпретировать такие выражения, как a = b = c, как a = (b = c), тем самым устанавливая оба aи bдо значения c. В C альтернатива (a = b) = cне имеет смысла, потому что a = bне является l-Value, а просто r-значением. Однако в C ++ присвоение a = bвозвращает значение, относящееся к левому члену в назначении. Следовательно, (a = b) = cможно интерпретировать как a = b; a = c;.

Неассоциативные операторы

Неассоциативные операторы - это операторы, которые не имеют определенного поведения при последовательном использовании в выражении. В Прологе инфиксный оператор : -является неассоциативным, потому что такие конструкции, как «a: - b: - c», представляют собой синтаксические ошибки.

Другая возможность состоит в том, что последовательности определенных операторов интерпретируются другим способом, который не может быть выражен как ассоциативность. Обычно это означает, что синтаксически существует особое правило для последовательностей этих операций, а семантически поведение отличается. Хороший пример - Python, в котором есть несколько таких конструкций. Поскольку присваивания являются операторами, а не операциями, оператор присваивания не имеет значения и не ассоциативен. Цепное присвоение вместо этого реализуется с помощью правила грамматики для последовательностей назначений a = b = c, которые затем назначаются слева направо. Кроме того, комбинации присваивания и расширенного присваивания, такие как a = b + = c, недопустимы в Python, хотя они допустимы C. Другим примером являются операторы сравнения, такие как >, ==и <=. Связанное сравнение, такое как a < b < c, интерпретируется как (< b) and (b < c), не эквивалентно (< b) < cили a < (b < c).

См. Также
Примечания
Ссылки
Последняя правка сделана 2021-06-01 13:13:29
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте