프로그래밍이 언어를 처리하는 방법

컴퓨터는 2진수로 짜여져있다. 그리고 10진수를 사용하는 우리들이 2진수로 된 프로그램을 직접 짜는것은 여간 어려운 일이 아닐것이다. 과거의 프로그래머들은 해냈을지몰라도, 현재의 우리들은 프로그래밍 언어로 좀 더 쉽게 프로그램의 작성을 쉽게 할 수 있게 되었다.

어셈블리 언어

과거의 프로그래머들은 프로그램을 정말 원시적으로 개발했다. 프로그램의 각 명령어에 대한 비트 조합을 하나하나 알아내고 입력하고.. 그래서 어셈블리 언어라는 프로그래밍 언어를 개발했다. 어셈블리 언어를 사용하면 비트 조합을 사용하지 않고도 니모닉을 통해 명령어를 쓸 수 있고, 주소에 레이블을 붙이고 주석을 달아 코드에 대한 코멘트를 달 수 있었다. 이 언어를 기계어 코드로 번역해주는 프로그램을 어셈블러라고 한다. 어셈블러는 번역하는 과정에서 심볼이나 레이블의 값을 결정해주어서 명령어 위치가 바뀔 때 생길 수 있는 오류를 방지해준다.

고수준 언어

원시적인 방법으로 어셈블러를 만들고, 초기의 어셈블러를 활용해 개선된 어셈블러를 만들고.. 만들고.. 언어가 시대가 지남에 따라 발전하고 발전함에 따라 어셈블리 언어보다 더 높은 추상화 단계에서 작동하는 고수준 언어가 세상에 나오게 되었다. 고수준 언어는 컴파일러(혹은 인터프리터)라는 프로그램에 의해 실행되는데, 컴파일러는 소스 코드를 기계어로 번역(컴파일)해준다.

구조적 프로그래밍

구조적structured 프로그래밍비구조적unstructured 프로그래밍스파게티 코드(프로그램이 단순한 연결로는 관리할 수 없을 정도로 복잡해지고 코드를 변경하다보면 순서가 뒤섞이고 레이블의 위치가 찾기 어려워지는걸 말함) 문제를 해결하기 위해 개발되었다.

정규식

유닉스 grep 유틸리티 명령의 grep은 ‘globally search a regular expression and print’라는 뜻을 가지고 있다. ‘정규식을 전역으로 찾아서 출력하라’라는 뜻이다. 여기서 나온 정규식이라는 말이 널리 알려졌고, 이제는 정규식을 대부분의 프로그래밍 언어에서 사용한다. 쉽게 말해 언어를 지정하기 위한 언어라고 생각하면 된다. 문자열의 일정한 패턴을 표현하는 일종의 형식 언어이고 RegEx 혹은 RegExp로 많이 쓰인다.

파스트리

고수준 언어 헤더에서 설명했듯이, 컴퓨터는 컴파일러 이외에도 인터프리터라는 녀석으로도 고수준 언어를 실행하고 인터프리트할 수 있다. 인터프리터 언어는 가상 머신이라고 하는 소프트웨어로 만들어진 기계에서 실행된다. 일반적으로 컴파일이 된 코드보다는 느리지만 하드웨어로 구현하기에 힘든 기능을 제공할 수 있다는 장점이 있다. 번역된 영어 책을 읽는 것과 번역가를 통해 영어 책을 한국어로 그 자리에서 번역받는 느낌의 차이라고 생각하면 된다. 컴퓨터의 속도가 나날이 발전하고 있기 때문에 인터프리터로 인해 느려진 속도와 트레이드할 가치가 있다.

컴파일러나 인터프리터는 파스 트리라는 녀석을 구성하는데 이 파스 트리라는 녀석은 문법으로부터 만들어낸 DAG(유향 비순환 그래프) 데이터 구조이다.

최적화

대부분의 언어 도구에는 최적화기라는 추가 단계가 파스 트리와 코드 생성기 사이에 들어간다. 최적화기는 파스 트리를 분석하고 분석한 결과를 토대로 더 효율적인 코드를 만들어낸다. 예를 들어 코드의 루프 문 안에 x = a + b라는 변수가 있을 때 a + b가 루프 불변 요소(루프를 반복해도 값이 바뀌지 않는 요소)라는 사실을 알아내고 루프 밖으로 이 식을 보내서 루프 만큼 반복을 하지 않고 단 1번만 계산을 하게 만든다. 또는 곱연산은 덧셈연산보다 비용이 더 많이 드는데, 최적화기는 곱연산을 덧셈연산으로 바꿔준다.

하드웨어를 다룰 때 최적화기

최적화기는 매력적인 도구이지만 하드웨어를 다룰 때는 주의가 필요하다. 예를 들어 PORTB라는 변수에 0x01이라는 값을 넣어주지만 읽는 코드가 없을 때, 최적화기는 읽는 코드가 없다고 판단해서 PORTB = 0x01 라는 코드 자체를 삭제시켜버린다.

댓글남기기