연산자 우선순위

작성

에 첫 작성.

연산자 우선순위(operator precedence)는 주어진 에서 어느 연산이 먼저 계산되는 지를 나타낸다. 예를 들어서 일반적인 사칙 연산을 기준으로 다음이 성립한다. $$3 + 4 \times 5 \times 6 = 3 + ((4 \times 5) \times 6) = 3 + (20 \times 6) = 3 + 120 = 123$$ 이 식이 성립하는 이유는 우리가 덧셈($+$)에 앞서 곱셈($\times$)을 먼저 계산하고, 덧셈과 곱셈 모두 연달아 나올 경우 왼쪽부터 계산한다고 약속했기 때문이다. 이는 곱의 합이 합의 곱보다 더 많이 나타나므로 이리 하면 괄호를 줄일 수 있다는 경험칙에 따른 것이며 그 이상 그 이하도 아니다. $48 \div 2(9 + 3)$과 같이, 이러한 약속이 없다면 굳이 해석을 하지 말고 모호하므로 잘못되었다고 판단하는 것이 옳다.

연산자 우선순위는 크게 연산자들 사이의 순서와, 같은 부류의 연산자들이 연달아 있을 때 어떻게 할지를 결정하는 결합칙으로 나눠 설명할 수 있다. 우습게도 ‘우선순위’라는 이름과는 달리 순서만을 다루진 않으며, 소괄호 ()와 같은 것은 연산자로 취급하지 않거나 가장 먼저 평가되는 연산자로 취급한다는 데도 주의.

형식 언어에서 연산자 우선순위는 연산자 우선순위 문법으로 표현할 수 있다.

순서 #

연산자의 계산 순서$a \star b \diamond c$와 같이 연산자 둘이 연달아 나올 때 둘 중 어느 쪽이 더 ‘강한’지를 나타낸다. 둘 중 한 쪽이 더 강하면 그 연산자가 먼저 계산되고, 어느 쪽도 강하지 않으면 순서에 따르는 결합칙으로 넘어가게 된다. 이를테면 사칙 연산의 경우 다음 순서에서 먼저 나올수록 더 강하다.

  1. 괄호가 있다면 맨 안쪽 괄호부터

  2. 마이너스 기호 ($-42$ 등)

  3. 곱셈($\times$)과 나눗셈($\div$)

  4. 덧셈($+$)과 뺄셈($-$)

이제 $3 + 4 \times 5$ 같은 경우 곱셈(3)이 덧셈(4)보다 먼저 나오므로 우선 계산된다. $3 - 4 + 5$ 같은 경우 뺄셈(4)과 덧셈(4)은 같은 순서이므로 왼쪽에 나오는 뺄셈이 먼저 계산된다. 마이너스 기호와 뺄셈은 모양이 같은데, 기호 앞에 숫자나 괄호가 나오면 뺄셈, 다른 연산자가 나오면 마이너스로 구분할 수 있다.

옛날 글

It is pretty common that arithmetic comparison operators are grouped to a single precedence level and that’s not a problem. But in Python is, is not, in and not in are also in that level. In particular two operands of in and not in have different types unlike others. Mixing them are, either with or without chained operators, almost surely incorrect.

This kind of precedence issue can be solved by introducing non-associative pairs of operators (or precedence levels), something that—unfortunately—I don’t see much in common programming languages. […] In fact, there is already one non-associative pair in Python: not and virtually every operator except boolean operators. It is understandable: the inability to parse 3 + not 4 is marginal but you don’t want 3 is not 4 to be parsed as 3 is (not 4). My point is that, if we already have such a pair why can’t we have more?

해커뉴스에 쓴 글

[주장:] 이 순서를 나타낼 때는 보통 위와 같이 먼저 계산되는 것부터 나중에 계산되는 것까지 순서대로 나열하는 경향이 있다. 이는 연산자 사이의 계산 순서가 전순서라는 걸 함의하는데, 이상적으로는 전순서가 아니라 부분순서여야 한다. 즉 어떤 연산자들끼리는 순서가 없으므로 $a \star b \diamond c$와 같이 연달아 쓸 수 없고 무조건 괄호를 쳐서 $(a \star b) \diamond c$$a \star (b \diamond c)$로 써야 한다는 것이다. 여기에는 그만한 이유가 있다.

결합칙 #

연산자의 결합칙은 같은 순서를 가지는 연산자들이 연속으로 나올 때, 연산자와 무관하게 어느 방향으로 계산해야 하는지를 나타낸다. 흔히 쓰이는 결합칙으로 다음이 있다.

같이 보기 #