separator

구분자

나루 위키
둘러보기로 가기 검색하러 가기

구분자는 두 개의 문장이나 지시, 또는 (최상위) 바인딩을 구분하는 문자이며, 둘 중 하나이다.

두 토큰은 거의 같은 의미를 가지고 있으나, 개행은 구획 안에서는 무시된다는 차이가 있다.

p := 4 +         -- 오류: `+` 뒤에 수식이 나타나지 않음
       5
p := 4 +; 5      -- 오류: 위와 같은 의미
p := (4 +
        5)       -- OK
p := 3; q := 4   -- OK

논의

일반적으로 언어들이 구분자를 다루는 방식은 크게 몇 가지로 나눌 수 있다.

  1. 명시적인 구분자를 사용 (예: C, 파스칼, ML, 러스트[1])
    • 구분자는 대부분 문법적인 요소이며 그 자체로 코드 이해에 도움을 주진 않는다.
    • 구분자가 연산자적인 요소를 가지고 있는 경우(ML이나 러스트가 여기에 해당)가 아니면 지양하고 싶다.
  2. 개행이 나오고 구분자가 나올 위치면 구분자로 취급 (예: 자바스크립트, Go, 루비, 하스켈)
    • 코드만 보고 어느 개행이 구분자인지 확인하기 어려운 경우가 종종 있다. 문법을 주의 깊게 작성하면 대부분 피할 수 있지만 완벽하진 않다.
  3. 개행이 나오면 일반적으로 구분자로 취급 (예: 베이직, 파이썬)
    • 한 줄 안에 여러 문장을 넣고자 하고 싶다면 그 때만 사용할 별도의 구분자가 필요하다(베이직은 :, 파이썬은 ;).
    • 한 문장을 여러 줄로 나누고자 할 경우 그 때만 사용할 별도의 역개행문자가 필요할 수 있다(비주얼 베이직은 _, 파이썬은 \). 역개행문자를 쓰는 대신에 파이썬처럼 괄호 안에 있는 개행은 구분자가 절대로 될 수 없기 때문에 구분자로 취급하지 않는 휴리스틱을 쓸 수도 있다.
  4. 구분자가 필요하지 않도록 문법을 구성 (예: 루아)
    • 통상의 명령형 언어에서는 수식을 문장으로 쓸 수 있게 하는데, 여러 수식을 연달아 쓸 경우 구분되지 않는 경우가 많아 문법 모호성이 발생할 수 있다. 루아는 shift-reduce conflict를 감수하고 이 문법을 사용하고 있다.

나루는 3번, 즉 파이썬과 유사한 방법을 채택했다. 구분자를 고려하고 문법을 만들면 2번과 3번의 차이는 크지 않으나, 2번은 문법 전체를 구분자에 맞춰서 조정해야 하는 반면 3번은 토큰화만을 제약하기 때문에 운신의 폭이 더 넓다는 판단 때문이다.

  1. 러스트는 최후의 구분자가 구분자 이외의 기능(해당 블록의 반환값을 ()로 치환)을 가지고 있다는 점에서 엄밀히 말하면 조금 다르다.