Why Associativity is a Fundamental Property of Operators But Not that of Precedence Levels

二次信任 提交于 2020-01-02 08:09:05

问题


In any programming language textbooks, we are always told how each operator in that language has either left or right associativity. It seems that associativity is a fundamental property of any operator regardless of the number of operands it takes. It also seems to me that we can assign any associativity to any operator regardless of how we assign associativity to other operators.

But why is it the case? Perhaps an example is better. Suppose I want to design a hypothetical programming language. Is it valid to assign associativity to these operators in this arbitrary way (all having the same precedence):

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

! + - * / are my 5 operators all having the same precedence.

If yes, how would an expression like 2+2!3+5*6/3-5!3!3-3*2 is parenthesized by my hypothetical parser? And why.

EDIT:

The first example (2+2!3+5*6/3-5!3!3-3*2) is incorrect. Perhaps forget about the unary op and let me put it this way, can we assign operators having the same precedence different associativity like the way I did above? If yes how would an example,say 2+3-4*5/3+2 be evaluated? Because most programming language seems to assign the same associativity to the operators having the same precedence. But we always talk about OPERATOR ASSOCIATIVITY as if it is a property of an individual operator - not a property of a precedence level.


回答1:


Let us remember what associativity means. Take any operator, say @. Its associativity, as we all know, is the rule that disambiguates expressions of the form a @ b @ c: if @ is left associative, it's parsed as (a @ b) @ c; if it's right associative, a @ (b @ c). It could also be nonassociative, in which case a @ b @ c is a syntax error.

What about if we have two different operators, say @ and #? If one is of higher precedence than the other, there's nothing more to say, no work for associativity to do; precedence takes care of the disambiguation. However, if they are of equal precedence, we need associativity to help us. There are three easy cases:

  • If both operators are left associative, a @ b # c means (a @ b) # c.
  • If both operators are right associative, a @ b # c means a @ (b # c).
  • If both operators are nonassociative, then a @ b @ c is a syntax error.

In the remaining cases, the operators do not agree about associativity. Which operator's choice gets precedence? You could probably devise such associativity-precedence rules, but I think the most natural rule to impose is to declare any such case syntax errors. After all, if two operators are of equal precedence, why one would have associativity-precedence over the other?

Under the natural rule I just gave, your example expression is a syntax error.

Now, we could certainly assign differing associativities to operators of the same precedence. However, this would mean that there are combinations of operators of equal precedence (such as your example!) that are syntax errors. Most language designers seem to prefer to avoid that and assign the same associativity to all operators of equal precedence; that way, all combinations are legal. It's just aesthetics, I think.




回答2:


You have to define associativity somehow, and most languages choose to assign associativity (and precedence) "naturally" -- to match the rules of common mathematics.

There are notable exceptions, however -- APL has strict right-to-left associativity, with all operators at the same precedence level.



来源:https://stackoverflow.com/questions/11700550/why-associativity-is-a-fundamental-property-of-operators-but-not-that-of-precede

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!