左结合运算符和右结合运算符

11

如果我们有一个表达式:

a $ b @ c

$ 是一个左结合操作符,@ 是右结合的。它们具有相同的优先级。

这个表达式是如何解析的呢?作为 (a $ b) @ c 还是 a $ (b @ c)


1
一个实际的C或C++示例可能会更清晰。 - chris
1
用什么语言?你自己的吗?那么不要这样做!这是一个含糊不清的语法,没有一种单一的解决方法。 - Pubby
编译器决定如何分析语法树。阅读《编译原理、技术与工具》会对你有很大帮助。 - MYMNeo
2个回答

12

这是一个很好的问题。虽然Dipstick正确指出在许多语言中,运算符优先级和结合性是为了避免这样的问题而定义的,但有些语言可能会出现这种情况。

Haskell就是这样一种语言。它允许您定义自己的中缀运算符及其优先级(从0到9的整数)和结合性(左、右、非)。很容易创建您所描述的情景的前提条件:

infixl 5 $$
($$) :: Int -> Int -> Int
a $$ b = a + b

infixr 5 @@
(@@) :: Int -> Int -> Int
a @@ b = a * b

然后是情况本身:

uhoh = 1 $$ 2 @@ 3

这导致了以下错误信息:

Precedence parsing error
    cannot mix `$$' [infixl 5] and `@@' [infixr 5] in the same infix expression
当然,Haskell的解决方案——使用解析错误来中止程序——并不是处理这个问题的唯一方法,但它确实是一个合理的方法。 有关在Haskell中进行操作符解析的更多信息,请参见Haskell报告的4.4.2节。

6

在相同优先级的运算符中,要么全部是右结合,要么全部是左结合,因此问题不会出现。


1
对,我应该喝醉了才会问这个问题。由于每种语言都有不同的优先级,所以没有标准。它们是由编译器设计者决定的。聪明的设计师会像Dipstick说的那样做。 - Robert Bean
3
@RobertBean,幸运的是,语言设计者决定了这些规范,并且为每种语言制定了标准。如果将这个任务交给编译器实现者,你就永远无法编写可移植的代码。 - Jens Gustedt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接