step 01
한 외국인 친구가 내게 영어로 말을 걸었다고 하자. 나는 영어를 한국어로 번역할 수 있는 사전과 문법 책을 가지고 있고, 나는 영어를 전혀 할 줄 모른다. 그러면 내가 그 영어를 해석하기 위해 제일 먼저 해야 할 일은 무엇일까?
이다. 그래야 단어의 의미를 사전에서 찾고, 그 단어들을 문법을 적용하여 해석할 수 있기 때문이다.
프로그래밍 언어도 마찬가지이다. 사람들이 입력한 코드를 번역하려면, 가장 먼저 이해할 수 있는 단위로 쪼개야 한다. 각각의 요소가 무엇을 의미하는지 미리 입력해 둔 사전과 대응시키면서 문법을 적용할 준비를 마쳐야 한다. 이 과정을 lexing이라고 부른다. 이 기능을 담당하는 부분을 Lexer라고 부르는데, 편의상 이후에는 '어휘 분석기'라고 부르도록 하겠다.
영어를 단어 단위로 나눌 때에도 영어 사전은 필요하다. 이게 어디서부터 어디까지 단어로 봐야 하는지에 대한 정보를 제공해 주기 때문이다. 영어를 처음 접하는 사람들 입장에선 I am a boy.라는 문장을 나누기 위해서 I와 am, a와 boy가 모두 단어라는 사실을 알아야 한다. 이를 알게 해주는 것이 영어 사전이다. 그래서 프로그래밍 언어를 개발할 때에도 내가 만들 언어가 어떤 단어들을 가지고 있는지 알려주는 사전을 만들어야 한다. 실제로 이름을 어떻게 붙이는지는 잘 모르겠지만, 앞으로는 이 사전을 '토큰 사전'이라고 부를 것이다. 토큰들을 해석할 수 있게 모아 둔 사전이라는 뜻이다.
우리가 프로그래밍 언어를 입력할 때, 사전에 있는 것들을 기준으로 어휘를 쪼개야 한다. 하지만, 대부분의 코드에서는 사전에 존재하지 않는 어휘들이 자주 등장한다. 바로 '변수'이다. 보통 변수는 사용자가 이름을 지정하며, 이는 사전에 존재해서는 안된다. 그래서 변수는 사전에 존재하지 않더라도 띄어쓰기 단위로 묶어야 한다. 이처럼 쪼개진 단위들이 이미 사전에 등록되어 있는 것인지 아닌지에 대해서도 표시해주어야 한다. 추가로 단위가 숫자인지, 문자열인지도 표시해 주면 당연히 좋다.
우리는 어휘 분석기를 다음과 같은 구조로 디자인할 것이다.
입력값 -> 자르기 -> 이름 붙이기 -> 출력
어휘 분석기를 이 구조로 만드는 이유는, 번역기를 만드는 과정에서 수많은 오류들이 발생할 텐데, 이때 오류가 어디에서 발생하는지 쉽게 찾을 수 있도록 하기 위함이다. 예를 들어 나중에 어떤 오류가 발생했을 때 어휘 분석기에서 오류가 발생한 것 같다면, 어휘 분석기의 출력 결과를 확인해 보면 된다. 어휘 분석기가 문장을 잘못 잘랐거나 이름을 잘못 붙였다면, 출력 결과를 통해 바로 확인할 수 있을 것이다.
번역기를 만들기 위한 첫 단계, 어휘 분석기에 대해 알아보았다. 다음 글부터는 코드가 등장할 예정이나, 굳이 개발을 직접 해보고 싶지 않은 사람들은 바로 다음 챕터로 넘어가도 무방하다.