问题 左关联运算符与右关联运算符


如果我们有一个表达式:

a $ b @ c

$ 是一个左关联运算符, @ 是正确联想的。 它们具有相同的优先权。

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


4131
2018-04-12 05:54


起源

实际的C或C ++示例可能会更清楚。 - chris
用什么语言?你自己?那么,那不要那样做!这是一个含糊不清的语法,没有一种方法可以解决。 - Pubby
它由编译器决定如何分析语法树。阅读<<编译器原理,技术和工具>>将对您有所帮助。 - MYMNeo


答案:


具有相同优先级的运算符都是右关联或全部左关联,因此不会出现问题。


6
2018-04-12 05:57



对,我应该喝醉了才能问这个问题。由于每种语言都有不同的优先级,因此不应该有这种标准。它们由编译器设计者决定。一个聪明的设计师会像Dipstick说的那样。 - Robert Bean
@RobertBean,幸运的是,他们是由语言设计师决定的,并且针对每种语言进行了标准化。如果这将留给编译器实现者,你永远不会编写可移植代码。 - Jens Gustedt


这是一个很好的问题。虽然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中运算符解析的更多信息,请参阅第4.4.2节 Haskell的报告


10
2017-07-12 02:48