본문 바로가기

책/코딩을 지탱하는 기술

코딩을 지탱하는 기술 - 4


문법의 탄생

  1. 문법이란
  2. 스택 머신과 FORTH
  3. 구문트리와 LISP
  4. 중위 표기법
  5. 정리

 

문법이란?

프로그래밍 언어에는 여러 가지 규칙이 있으며 그 규칙 또한 프로그래밍 언어가 사람을 편리하게 하기 위해 만들어 진것처럼 무언가를 편하게 하기 위해서 만들어졌다.

'식'을 표현하는 규칙을 통해 설명하며 언어는 FORTH 와 LISP를 통해서 설명한다.

FORTH의 경우 문법이 거의 없으며 LISP는 괄호로 코드 구조를 표현한다.

이 두 언어가 가지고 있는 기능은 현재의 프로그래밍 언어에서도 중요한 역활을 한다.

 

연산자 우선순위

1 + 2 * 3 라는 소스코드가 있다면 이것은 9인가 7인가?

그건 아마도 '( 1 + 2 ) * 3 와 1 + ( 2 * 3 ) 의 규칙중 어떤것을 적용하였는가?' 에 따라서 다를 것이다.

하지만 지금 대부분의 프로그래밍 언어는 결과 값이 7이 된다. 이는 프로그래밍 설계자가 '+보다 *가 우선쉬이가 높기 때문에 먼저 계산한다.'는 규칙을 정했고 

이는 사칙연산과 같아야 이해하기 쉽기 때문이다.

또한 나눗셈의 경우에는 좌결합성1이기 때문에 나열되어 있는 순서대로 먼저 계산한다.

(3/3)/2, 3/(3/2) 의 경우 (3/3)/2

한마디로 언어 설계자가 정한 규칙이 문법이다.

문법은 언어에 따라 다르고 연산자의 종류도 언어에 따라 다르다.

C 언어에서는 '='가 연산자이고 가감승제와는 다르게 2 이다.

x=y=1의 경우 x=(y=1)로 해석한다.

 

스택 머신과 FORTH

FORTH는 1958년 경에 개발되어 문법이 거의 존재하지 않는 언어이다.

설계자 Charles H. Moore에 따르면 'FORTH는 가장 간단한 컴퓨터 언어'라고 말했고 '세상의 모든 언어가 가독성이 있다고 주장하지만, 처음 그 언어를 다루는 사람은 항상 당황하며 이는 난해하고 변덕스러운 문법 때문이다. FORTH는 구문을 최대한 제한함으로 문제를 해결한다.'라고 주장한다.

계산 순서

FORTH에서는 1 과 2를 더한다 라는 코드가 아래와 같다

1 2 +

이 코드는 어떻게 실행되는가? FORTH의 가장 큰 특징은 '3', 즉 값을 쌓아 둔다.

우선 1을 만다고 그 다음 스택에 1을 담아둔다. 그 다음 2를 만나 2를 담는다. 마지막으로 +를 만나면 스택에서 두개를 꺼내서 그것을 더한 결과를 스택에 담는다.

//(1+2)*3
1 2 + 3 *

//1+(2*3)
2 3 * 1 +

//1+(2*3)
1 2 3 * +

한국어로는 순서상 오류를 피하기 위해 어디까지가 한 구역인지 괄호를 사용했지만 FORTH에서는 괄호도'우선순위라는 규칙'도 도입하지 않고 표현했다.

 

현재도 살아있는 스택머신

스택 기반의 언어를 직접 입력하는 경우는 많이 줄어들었으며 Java, Python, Ruby 1.9 등은 스택 머신 형의 VM을 사용하고 있다. VM이 실행하는 명령열도 FORTH와 같은 구조로 되어 있다.

 

구문 트리와 LISP

1958년에 탄생한 LISP의 경우에 '하나의 구역을 표현하기 위해 항상 괄호를 사용하자'의 규칙?을 가지고 있다.

계산의 흐름

LISP으로 '1과 3를 더한다'

(+ 1 3)

먼저 괄호를 시작하고 어떤 연산을 할지 작성 후 공란으로 간격을 만들고 그 다음 무엇을 더할 것인지 쓴다.

계산 순서를 어떻게 표시할까?

그렇다면 (1+2)*3은 어떻게 쓸까?

(* (+ 1 2) 3)

이러한 구문을 4라고 한다.

현재도 살아있는 구문 트리

구문 트리가 사용되고 있는 것은 Python을 통해 확인 할 수 있다. Python에 ast 라이브러리를 사용하면 특정 코드가 어떤 구문 트리로 구성되어 있는지 알 수 있다.

LISP와 Python의 두 구조를 보면 공통된 구조를 찾을 수 있다. LISP은 문법이 간단해서 코드와 구문이 알기 쉽게 연결이된다. LISP는 구문트리를 바꿔주는 메커니즘을 가지고있는데 그것을 '매크로'라고 한다.

 

중위 표기법

표기법에는 3가지가있다

  1. 전위 표기법 예) + 2 2
  2. 중위 표기법 예) 2 + 2
  3. 후위 표기법 예) 2 2 +

이 3가지 방법은 식을 표현하기 위한 약속에 불과하지만 프로그래밍 언어가 탄생하기 이전부터 사람들은 대체로 중위 표기법을 사용했다.

 

정리

문법이란?

똑같은 처리도, 언어에 따라 표현 방법이 다르다 하지만 구문 트리로 표현하면 거의 동일하다. 언어의 차이가 생기는 것은 '어떤 문자열을 쓰면 어던 구문 트리가 생기는가'라는 규칙이다.

FORTH,LISP는 규칙이 적은것을 중시했다면

FORTRAN은 다가가기 쉬운 작성법을 대량으로 도입하고 적용하면서 이러한 설계 방침이 성공하면서 FORTRAN방식이 사람들한테 인기를 얻었다.

프로그래밍 언어는 FORTRAN 식을 목표로 하고있다. 하지만 모순 없이 해석할 수 있는 문법을 만들어내는 것은 어려운 일이며 특히 나중에 문법을 추가할 때 기존 문법과 마찰이 되지 않도록 하는것은 더욱 어려운 일이다.

그렇기 때문에 프로그래밍 언어에서는 이해하기 어려운 작성법이 존재한다.

1 좌결합성은(왼쪽에서 오른쪽으로 결합한다.) 이것이 (a 연산자 b) 연산자 c로 처리됨을 뜻한다.
2 우결합성(오른쪽에서 왼쪽으로 결합한다.)은 이것이 a 연산자 (b 연산자 c) 로 해석됨
3 스택은 일종의 바닥이 막힌 상자라고 보면 된다. 나중에 넣은 물건이 위에 있으므로 먼저 꺼낼 수 밖에 없다.
4 이 트리의 각 노드는 소스 코드에서 발생되는 구조체를 나타낸다. 구문이 추상적이라는 의미는 실제 구문에서 나타나는 모든 세세한 정보를 나타내지는 않는다는 것을 의미한다.