在任何编程语言教科书中,我们总是被告知该语言中的每个运算符是如何具有左或右结合性的。看起来结合性是任何运算符的基本属性,无论它需要多少个操作数。在我看来,无论我们如何将结合性分配给其他操作符,我们都可以将任何结合性分配给任何运算符。
但为什么会这样呢?也许举个例子更好。假设我想设计一种假设的编程语言。以这种任意的方式为这些运算符分配结合性(所有运算符都具有相同的优先级)是否有效:
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?因为大多数编程语言似乎将相同的结合性分配给具有相同优先级的运算符。但我们总是谈论操作符结合性,就好像它是单个操作符的属性-而不是优先级别的属性。
发布于 2012-07-30 04:27:18
让我们记住结合性的含义。以任何运算符为例,比如@。众所周知,它的关联性是消除a @ b @ c形式表达式歧义的规则:如果@是左关联的,则解析为(a @ b) @ c;如果它是右关联的,则解析为a @ (b @ c)。它也可以是非关联的,在这种情况下,a @ b @ c是一个语法错误。
如果我们有两个不同的运算符,比如@和#呢?如果其中一个比另一个具有更高的优先级,那么就没有什么可说的了,结合性也不需要做任何工作;优先级负责消除歧义。然而,如果它们具有相同的优先级,我们需要结合性来帮助我们。有三种简单的情况:
a @ b # c表示两个运算符都是右关联的,a @ b # c表示两个运算符都是非关联的,则a @ b @ c是语法错误。在其余情况下,运算符在关联性方面不一致。哪个运算符的选择优先?您可能会设计这样的结合性优先规则,但我认为最自然的规则是声明任何这样的case语法错误。毕竟,如果两个运算符具有相等的优先级,为什么其中一个会比另一个具有结合性优先级?
根据我刚才给出的自然规则,您的示例表达式是一个语法错误。
现在,我们当然可以为相同优先级的运算符分配不同的关联性。但是,这意味着存在具有相同优先级的运算符组合(例如您的示例!)都是语法错误。大多数语言设计者似乎倾向于避免这种情况,并为所有具有相同优先级的运算符分配相同的结合性;这样,所有组合都是合法的。我想,这只是一种美学。
发布于 2012-07-28 19:26:04
您必须以某种方式定义结合性,并且大多数语言选择“自然”地分配结合性(和优先级) --以符合常见数学规则。
然而,也有值得注意的例外-- APL具有严格的从右到左的结合性,所有运算符都处于相同的优先级。
https://stackoverflow.com/questions/11700550
复制相似问题