Почему ассоциативность является фундаментальным свойством операторов, а не уровнем предшествования

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

Но почему это так? Возможно, лучше пример. Предположим, я хочу создать гипотетический язык программирования. Допустимо ли назначать этим операторам ассоциативность таким произвольным образом (все они имеют одинаковый приоритет):

unary operator: 
! right associative 
binary operators:
+ left associative
- right associative
* left associative 
/ right associative

! + - * / все мои 5 операторов имеют одинаковый приоритет.

Если да, то как мой гипотетический синтаксический анализатор заключит в скобки такое выражение, как 2 + 2! 3 + 5 * 6 / 3-5! 3! 3-3 * 2? И почему.

РЕДАКТИРОВАТЬ:

Первый пример (2 + 2! 3 + 5 * 6 / 3-5! 3! 3-3 * 2) неверен. Возможно, забудьте об унарной операции и позвольте мне сказать так: можем ли мы назначать операторам с одинаковым приоритетом и разной ассоциативностью, как это было сделано выше? Если да, то как будет оцениваться пример, скажем, 2 + 3-4 * 5/3 + 2? Потому что большинство языков программирования, кажется, приписывают одинаковую ассоциативность операторам, имеющим одинаковый приоритет. Но мы всегда говорим об АССОЦИАЦИИ ОПЕРАТОРОВ, как если бы это свойство отдельного оператора, а не свойство уровня приоритета.


person JavaMan    schedule 28.07.2012    source источник
comment
Вы читали en.wikipedia.org/wiki/Operator_associativity? Кроме того, ваш пример не имеет смысла, поскольку ! унарный и, следовательно, 2!3 недопустим.   -  person Felix Kling    schedule 28.07.2012
comment
Да, мой первый пример неверен. И я перефразировал свой вопрос. Смотрите мой РЕДАКТИРОВАТЬ   -  person JavaMan    schedule 28.07.2012
comment
Мне кажется, что ваш пример станет 2 + 3 - (4 * 5 / (3 + 2)).   -  person Felix Kling    schedule 28.07.2012
comment
Вы имеете в виду, что мы можем назначать произвольную ассоциативность операторам с одинаковым приоритетом?   -  person JavaMan    schedule 28.07.2012
comment
Я бы сказал да, но все, что я нашел до сих пор, - это ассоциативность по уровню приоритета. Но это вполне могло упростить реализацию парсера.   -  person Felix Kling    schedule 28.07.2012


Ответы (2)


Вспомним, что такое ассоциативность. Возьмите любого оператора, скажите @. Его ассоциативность, как мы все знаем, - это правило, которое устраняет неоднозначность выражений формы a @ b @ c: если @ остается ассоциативным, он анализируется как (a @ b) @ c; если это правильно ассоциативно, a @ (b @ c). Он также может быть неассоциативным, и в этом случае a @ b @ c является синтаксической ошибкой.

Что если у нас есть два разных оператора, скажем @ и #? Если один имеет более высокий приоритет, чем другой, больше нечего сказать, ассоциативность не выполняет никакой работы; приоритет заботится об устранении неоднозначности. Однако, если они имеют равный приоритет, нам нужна ассоциативность, чтобы помочь нам. Есть три простых случая:

  • Если оба оператора оставлены ассоциативными, a @ b # c означает (a @ b) # c.
  • Если оба оператора правильно ассоциативны, a @ b # c означает a @ (b # c).
  • Если оба оператора неассоциативны, a @ b @ c является синтаксической ошибкой.

В остальных случаях операторы не договариваются об ассоциативности. Выбор оператора имеет приоритет? Вы, вероятно, могли бы разработать такие правила приоритета ассоциативности, но я думаю, что наиболее естественным правилом является объявление любых синтаксических ошибок такого рода. В конце концов, если два оператора имеют равный приоритет, почему один имеет приоритет ассоциативности над другим?

Согласно естественному правилу, которое я только что дал, ваше примерное выражение является синтаксической ошибкой.

Теперь мы, безусловно, могли бы присвоить оператору с одинаковым приоритетом разную ассоциативность. Однако это будет означать, что существуют комбинации операторов с равным приоритетом (например, ваш пример!), Которые являются синтаксическими ошибками. Большинство разработчиков языков предпочитают избегать этого и присваивают одинаковую ассоциативность всем операторам с равным приоритетом; таким образом, все комбинации допустимы. Думаю, это просто эстетика.

person ibid    schedule 29.07.2012

Вы должны каким-то образом определить ассоциативность, и большинство языков предпочитают присваивать ассоциативность (и приоритет) «естественным образом» - в соответствии с правилами общей математики.

Однако есть заметные исключения - APL имеет строгую ассоциативность справа налево, при этом все операторы имеют одинаковый уровень приоритета.

person Hot Licks    schedule 28.07.2012
comment
да, но мне интересно, зачем нам такое понятие, как ассоциативность? Может ли приоритетность определять, как связаны друг с другом операнды и операторы? И почему большинство языков программирования приписывают одинаковую ассоциативность операциям с одинаковым приоритетом. Означает ли это, что ассоциативность - это свойство одного уровня приоритета, а не оператора? - person JavaMan; 28.07.2012
comment
Очевидно, a§b§c для двоичного оператора § может означать либо (a§b)§c, либо a§(b§c). Если вы хотите разрешить a§b§c, вам нужно что-то, чтобы гарантировать согласованность. - person tiwo; 28.07.2012
comment
Легко понять a§b§c, потому что существует только 1 ассоциативность - ассоциативность §. Но как насчет того, что, скажем, a # b @ c и # @ имеют разную ассоциативность? Скажем, # слева, @ справа? Имеет ли смысл иметь разную ассоциативность для op в пределах одного уровня приоритета? - person JavaMan; 28.07.2012