Обозначение общего оператора - Common operator notation

В языки программирования, научные калькуляторы и подобные обозначение общего оператора или же грамматика операторов это способ определения и анализа математических и других формальных выражений. В этой модели линейная последовательность токенов делится на два класса: операторы и операнды.

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

Каждому оператору дается позиция, приоритет и ассоциативность. В приоритет оператора - это число (от старшего к младшему или наоборот), определяющее, какой оператор принимает операнд, окруженный двумя операторами с разным приоритетом (или приоритетом). Умножение обычно имеет более высокий приоритет, чем сложение,[1] например, так 3 + 4 × 5 = 3+ (4 × 5) ≠ (3 + 4) × 5.

С точки зрения позиции оператора, оператор может быть префиксным, постфиксным или инфиксным. А префиксный оператор непосредственно предшествует своему операнду, как в -x. А постфиксный оператор сразу же следует за своим операндом, как в x! например. An инфиксный оператор располагается между левым и правым операндом, как в x + y. Некоторые языки, в первую очередь семейство синтаксиса C, расширяют эту традиционную терминологию и говорят также о тройной инфиксные операторы (a? b: c). Теоретически было бы даже возможно (но не обязательно практично) определить скобки как операцию унарного бификса.

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

Ассоциативность операторов определяет, что происходит, когда операнд окружен операторами с таким же приоритетом, как в 1-2-3: оператор может быть левоассоциативный, правоассоциативный, или же неассоциативный. Левоассоциативные операторы применяются к операндам в порядке слева направо, а правоассоциативные операторы - наоборот. Основные арифметические операторы обычно левоассоциативны,[1] что означает, например, что 1-2-3 = (1-2) -3 ≠ 1- (2-3). Это не относится к операторам более высокого уровня. Например, возведение в степень обычно правоассоциативна в математике,[1] но реализован как левоассоциативный в некоторых компьютерных приложениях, таких как Excel. В языках программирования, где присваивание реализовано как оператор, этот оператор часто является правоассоциативным. Если да, то утверждение вроде а: = б: = с будет эквивалентно а: = (б: = в), что означает, что значение c копируется в b, которое затем копируется в a. Неассоциативный оператор не может конкурировать за операнды с операторами равного приоритета. В Пролог например, инфиксный оператор :- неассоциативна, поэтому такие конструкции, как а: - б: - в являются синтаксическими ошибками. Унарные префиксные операторы, такие как - (отрицание) или sin (тригонометрическая функция), обычно являются ассоциативными префиксными операторами. Когда более одного ассоциативного префикса или постфиксного оператора с равным приоритетом предшествуют или следуют за операндом, операторы, наиболее близкие к операнду, идут первыми. Итак, −sin x = - (sin x) и sin -x = sin (-x).

Математически ориентированные языки (например, на научные калькуляторы ) иногда допускают неявное умножение с более высоким приоритетом, чем операторы префикса (такие как sin), так что, например, sin 2x + 1 = (sin (2x)) + 1.[нужна цитата ]

Однако префиксные (и постфиксные) операторы не обязательно имеют более высокий приоритет, чем все инфиксные операторы. В некоторых (гипотетических) языках программирования вполне может быть оператор sin с приоритетом ниже ×, но выше, например, +. На таком языке sin 2 · x + 1 = sin (2 · x) +1 будет истинным, а не (sin 2) · x + 1, как это обычно бывает.

Правила оценки выражений обычно бывают тройными:

  1. Рассматривайте любое подвыражение в круглых скобках как один рекурсивно вычисляемый операнд (хотя могут быть разные типы скобок с разной семантикой).
  2. Свяжите операнды с операторами с более высоким приоритетом перед операторами с более низким приоритетом.
  3. Для равного приоритета привяжите операнды к операторам в соответствии с ассоциативностью операторов.

Еще несколько примеров:

1-2+3/4*5+6+7 = (((1-2)+((3/4)*5))+6)+7
4 + -x + 3 = (4 + (-x)) + 3

Обобщения общей операторной записи

Использование классов приоритета операторов и ассоциативности - лишь один из способов. Однако это не самый общий способ: эта модель не может дать оператору больший приоритет при конкуренции с «-», чем при конкуренции с «+», при этом обеспечивая «+» и «-» эквивалентные приоритеты и ассоциативность. Обобщенную версию этой модели (в которой каждому оператору можно дать независимый левый и правый приоритет) можно найти по адресу [1].

Смотрите также

Рекомендации

  1. ^ а б c Бронштейн, Илья Николаевич; Семендяев, Константин Адольфович (1987) [1945]. «2.4.1.1.». В Гроше, Гюнтер; Зиглер, Виктор; Зиглер, Доротея (ред.). Taschenbuch der Mathematik (на немецком). 1. Перевод Виктор Зиглер. Вайс, Юрген (23-е изд.). Тун и Франкфурт-на-Майне: Верлаг Харри ДойчB. G. Teubner Verlagsgesellschaft, Лейпциг). С. 115–120. ISBN  3-87144-492-8.