Jump to content

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

(Перенаправлено с Лево-ассоциативного )

В теории языков программирования ассоциативность — это оператора приоритета свойство, определяющее, как группируются операторы одного и того же круглых при отсутствии скобок . Если операнду предшествуют и после него следуют операторы (например, ^ 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, в котором ^ в качестве оператора возведения в степень принимается правоассоциативный оператор. Парсер, читающий токены слева направо, применил бы правило ассоциативности к ветке из-за правоассоциативности ^, следующим образом:

  1. Срок 5 читается.
  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 2 = 9. Результат заменяет ветвь выражения в качестве второго операнда второго ^.
  3. Вычисление продолжается на один уровень вверх по дереву синтаксического анализа как: 4 9 = 262 144. Опять же, результат заменяет ветвь выражения в качестве второго операнда первой. ^.
  4. Опять же, вычислитель поднимается по дереву до корневого выражения и оценивает как: 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]

См. также

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

Примечания

[ редактировать ]
  1. ^ Выражение можно превратить в оператор , поставив после него точку с запятой; т.е. a = b это выражение, но a = b; это заявление.
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 5810d793271f22f94b2d7f77b03c38d5__1714842480
URL1:https://arc.ask3.ru/arc/aa/58/d5/5810d793271f22f94b2d7f77b03c38d5.html
Заголовок, (Title) документа по адресу, URL1:
Operator associativity - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)