Ассоциативность оператора
В теории языков программирования ассоциативность — это оператора приоритета свойство, определяющее, как группируются операторы одного и того же круглых при отсутствии скобок . Если операнду предшествуют и после него следуют операторы (например, ^ 3 ^
), и эти операторы имеют одинаковый приоритет, то операнд может использоваться в качестве входных данных для двух разных операций (т. е. двух операций, указанных двумя операторами). Выбор операций, к которым применяется операнд, определяется ассоциативностью операторов . Операторы могут быть ассоциативными (означает, что операции могут быть сгруппированы произвольно), левоассоциативными (означают, что операции группируются слева), правоассоциативными (означают, что операции группируются справа) или неассоциативными (означают, что операции не могут быть сгруппированы слева). связаны цепочкой, часто потому, что тип вывода несовместим с типами ввода). Ассоциативность и приоритет оператора являются частью определения языка программирования; разные языки программирования могут иметь разную ассоциативность и приоритет для одного и того же типа оператора.
Рассмотрим выражение a ~ b ~ c
. Если оператор ~
оставило ассоциативность, это выражение можно было бы интерпретировать как (a ~ b) ~ c
. Если оператор имеет правильную ассоциативность, выражение будет интерпретироваться как a ~ (b ~ c)
. Если оператор неассоциативен, выражение может быть синтаксической ошибкой или иметь какое-то особое значение. Некоторым математическим операторам присуща ассоциативность. Например, вычитание и деление, используемые в обычных математических обозначениях, по своей сути являются левоассоциативными. Сложение и умножение, напротив, ассоциативны как слева, так и справа. (например (a * b) * c = a * (b * c)
).
Многие руководства по языкам программирования содержат таблицу приоритета и ассоциативности операторов; см., например, таблицу для C и C++ .
Описанная здесь концепция нотационной ассоциативности связана с математической ассоциативностью , но отличается от нее . Операция, которая является математически ассоциативной, по определению не требует нотационной ассоциативности. (Например, сложение обладает ассоциативным свойством, поэтому оно не обязательно должно быть левоассоциативным или правоассоциативным.) Однако операция, которая не является математически ассоциативной, должна быть нотационно лево-, право- или неассоциативной. (Например, вычитание не обладает свойством ассоциативности, поэтому оно должно иметь нотационную ассоциативность.)
Примеры
[ редактировать ]Ассоциативность необходима только в том случае, если операторы в выражении имеют одинаковый приоритет. Обычно +
и -
имеют одинаковый приоритет. Рассмотрим выражение 7 - 4 + 2
. Результат может быть либо (7 - 4) + 2 = 5
или 7 - (4 + 2) = 1
. Первый результат соответствует случаю, когда +
и -
левоассоциативны, последние при +
и -
правоассоциативны.
Чтобы отразить нормальное использование, операторы сложения , вычитания , умножения и деления обычно являются левоассоциативными. [1] [2] [3] while для оператора возведения в степень (если присутствует) [4] [ нужен лучший источник ] общего согласия нет. Любые операторы присваивания обычно правоассоциативны. Чтобы предотвратить случаи, когда операнды будут связаны с двумя операторами или вообще не будут связаны с операторами, операторы с одинаковым приоритетом должны иметь одинаковую ассоциативность.
Подробный пример
[ редактировать ]Рассмотрим выражение 5^4^3^2
, в котором ^
в качестве оператора возведения в степень принимается правоассоциативный оператор. Парсер, читающий токены слева направо, применил бы правило ассоциативности к ветке из-за правоассоциативности ^
, следующим образом:
- Срок
5
читается. - Нетерминальный
^
читается. Узел: "5^
". - Срок
4
читается. Узел: "5^4
". - Нетерминальный
^
читается, запуская правило правой ассоциативности. Ассоциативность решает узел: "5^(4^
". - Срок
3
читается. Узел: "5^(4^3
". - Нетерминальный
^
читается, вызывая повторное применение правила правой ассоциативности. Узел "5^(4^(3^
". - Срок
2
читается. Узел "5^(4^(3^2
". - Нет токенов для чтения. Применить ассоциативность для создания дерева разбора "
5^(4^(3^2))
".
Затем это можно оценить в глубину, начиная с верхнего узла (первого узла). ^
):
- Оценщик спускается по дереву от первого, через второй, к третьему.
^
выражение. - Он оценивается как: 3 2 = 9. Результат заменяет ветвь выражения в качестве второго операнда второго
^
. - Вычисление продолжается на один уровень вверх по дереву синтаксического анализа как: 4 9 = 262 144. Опять же, результат заменяет ветвь выражения в качестве второго операнда первой.
^
. - Опять же, вычислитель поднимается по дереву до корневого выражения и оценивает как: 5 262144 ≈ 6.206 0699 × 10 183 230 . Последняя оставшаяся ветвь сворачивается, и результат становится общим результатом, тем самым завершая общую оценку.
Левоассоциативная оценка привела бы к дереву разбора ((5^4)^3)^2
и совсем другой результат (625 3 ) 2 = 244,140,625 2 ≈ 5.960 4645 × 10 16 .
Правоассоциативность операторов присваивания
[ редактировать ]Во многих императивных языках программирования оператор присваивания определяется как правоассоциативный, а присваивание определяется как выражение (которое возвращает значение), а не просто оператор. Это позволяет использовать цепное присваивание , используя значение одного выражения присваивания в качестве правого операнда следующего выражения присваивания.
В C задание a = b
это выражение, которое имеет то же значение, что и выражение b
преобразован в тип a
, с побочным эффектом сохранения R- значения b
в L- значение a
. [а] Поэтому выражение a = (b = c)
можно интерпретировать как b = c; a = b;
. Альтернативное выражение (a = b) = c
выдает ошибку, потому что a = b
не является выражением L-значения, т.е. оно имеет R-значение, но не L-значение, в котором можно хранить R-значение c
. Правая ассоциативность =
оператор позволяет использовать такие выражения, как a = b = c
интерпретироваться как a = (b = c)
.
В C++ присваивание a = b
это выражение, которое имеет то же значение, что и выражение a
, с побочным эффектом сохранения R-значения b
в L-значение a
. Поэтому выражение a = (b = c)
все еще можно интерпретировать как b = c; a = b;
. И альтернативное выражение (a = b) = c
можно интерпретировать как a = b; a = c;
вместо того, чтобы вызывать ошибку. Правая ассоциативность =
оператор позволяет использовать такие выражения, как a = b = c
интерпретироваться как a = (b = c)
.
Неассоциативные операторы
[ редактировать ]Неассоциативные операторы — это операторы, которые не имеют определенного поведения при последовательном использовании в выражении. В Прологе инфиксный оператор :-
неассоциативен , поскольку такие конструкции, как " a :- b :- c
"представляют собой синтаксические ошибки.
Другая возможность состоит в том, что последовательности определенных операторов интерпретируются каким-то другим способом, который не может быть выражен как ассоциативность. Обычно это означает, что синтаксически для последовательностей этих операций существует особое правило, а семантически поведение иное. Хороший пример — Python , в котором есть несколько таких конструкций. [5] Поскольку присваивания являются операторами, а не операциями, оператор присваивания не имеет значения и не является ассоциативным. Вместо этого цепное присваивание реализуется за счет наличия грамматического правила для последовательностей присваиваний. a = b = c
, которые затем назначаются слева направо. Кроме того, комбинации присваивания и дополненного присваивания, например a = b += c
недопустимы в Python, но допустимы в C. Другим примером являются операторы сравнения, такие как >
, ==
, и <=
. Цепное сравнение типа a < b < c
интерпретируется как (a < b) and (b < c)
, не эквивалентный ни тому, ни другому (a < b) < c
или a < (b < c)
. [6]
См. также
[ редактировать ]- Порядок операций (в арифметике и алгебре)
- Общие обозначения операторов (в языках программирования)
- Ассоциативность (математическое свойство ассоциативности)
Примечания
[ редактировать ]Ссылки
[ редактировать ]- ^ Место обучения: Порядок действий
- ^ Академия Хана : Порядок действий , временная метка 5:40 с.
- ^ Департамент образования Вирджинии: использование порядка действий и изучение свойств , раздел 9
- ^ Ассоциативность возведения в степень и стандартная математическая запись Codeplea. 23 августа 2016 г. Проверено 20 сентября 2016 г.
- ^ Справочник по языку Python , « 6. Выражения »
- ^ Справочник по языку Python , « 6. Выражения »: 6.9. Сравнения