Jav*_*Man 3 programming-languages operators operator-precedence associativity
在任何编程语言教科书中,我们总是被告知该语言中的每个运算符如何具有左或右相关性.似乎关联性是任何运算符的基本属性,无论它采用多少操作数.在我看来,无论我们如何将关联性分配给其他运算符,我们都可以为任何运算符分配任何关联性.
但为什么会这样呢?也许一个例子更好.假设我想设计一种假设的编程语言.以任意方式为这些运算符分配关联性是否有效(所有这些都具有相同的优先级):
unary operator:
! right associative
binary operators:
+ left associative
- right associative
* left associative
/ right associative
Run Code Online (Sandbox Code Playgroud)
!+ - */是我的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?因为大多数编程语言似乎为具有相同优先级的运算符分配相同的关联性.但我们总是谈论操作者关联性,就好像它是个体操作者的属性 - 而不是优先级的属性.
让我们记住关联性意味着什么.以任何运营商为例@
.正如我们所知,它的相关性是消除形式表达式的规则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
语法错误.在其余情况下,运营商不同意关联性.哪个运营商的选择优先?您可以设计这样的关联性优先级规则,但我认为最强烈的规则是声明任何此类案例语法错误.毕竟,如果两个运算符具有相同的优先级,为什么一个运算符优先于另一个运算符呢?
根据我刚给出的自然规则,您的示例表达式是语法错误.
现在,我们当然可以为具有相同优先级的运算符分配不同的关联性.但是,这意味着存在语法错误的相同优先级的运算符组合(例如您的示例!).大多数语言设计者似乎更愿意避免这种情况,并为所有具有相同优先级的运算符分配相同的关联性; 这样,所有组合都是合法的.我认为这只是美学.
您必须以某种方式定义结合性,并且大多数语言选择“自然地”分配结合性(和优先级)——以符合常见数学规则。
然而,也有一些值得注意的例外——APL 具有严格的从右到左关联性,所有运算符都具有相同的优先级。