새로운 Smart Contract 프로그래밍 언어 만들기 — Lexer

zeroFruit
teamNexters
Published in
5 min readJan 11, 2019

안녕하세요. koa팀 김주형입니다. 저번 주에는 koa 프로젝트를 시작하게 된 계기와 컨셉 그리고 블록체인 & UX에 대해 적어보았는데요. 이번 주도 그냥 미션만 달랑 쓰기에는 또 좀 그래서 이번에는 지난 포스트에서 보여드렸던 koa architecture 중 lexer 컴포넌트에 대해서 좀 더 자세히 설명해드리려고 합니다. 그리고 진행 중인 koa 프로젝트는 여기서 만나보실 수 있습니다.

koa architecture
  • Lexer: 소스 코드를 받아서 token들로 바꿉니다.
  • Parser: token들을 받아서 AST(Abstract Syntax Tree)로 바꿉니다.
  • Compiler: AST를 이용해서 컴퓨터가 이해할 수 있는 ByteCode로 바꿉니다.
  • VM: Bytecode를 직접 실행시켜 결과물을 얻습니다.

Lexer?

우선 lexer은 무엇일까요? 여기서는 어떤 일을 하는 걸까요? lexer는 lexical analysis를 합니다. 직역하면 ‘어휘 분석’ 인데요. 좀 더 풀어서 설명하면 lexer는 텍스트를 받아서 한 글자 한 글자 읽어나가다가 의미를 가진 단어를 만나면 lexer에서는 그 단어를 전체 텍스트로부터 잘라서 token이란 것으로 만듭니다. token에 대해서는 조금 뒤에서 더 설명할게요. lexer에서 하는 일은 마치 가래떡을 뽑는 기계에서 가래떡을 뽑아내다가(한 글자) 적당한 길이가 될 때(단어) 잘라내는 것처럼 상상할 수 있습니다.

넘어가기 전에 쉬운 예를 한 번 더 들어볼까요? 예를 들어, 우리가 lexer에게 ‘메로나’ 라는 텍스트를 건네주었다고 생각해봅시다. 그러면 lexer는 ‘메’, ‘로’, ‘나’라는 텍스트를 차례대로 읽습니다. 그러다가 lexer가 ‘나’라는 글자를 읽을 때 lexer는 이미 ‘메로’를 읽었고 ‘나’라는 글자를 ‘메로’ + ‘나’와 같이 합쳐보았을 때 ‘메론맛이 나는, 보통 지각할 때 사오는 아이스크림’과 같이 의미있는 단어를 만들기 때문에 lexer는 ‘메로나’라는 단어를 token으로 만듦과 동시에 자신이 읽었던 ‘메로’를 잊어버리고 다시 텍스트를 읽어나갑니다.

이제 ‘메로나’에서 koa programming language로 작성한 소스코드로 바뀌었습니다. lexer가 하는 역할은 변함이 없습니다. 한 글자 한 글자 읽어나가면서 의미를 가진 단어를 만나면 끊어서 token으로 만듭니다. 바뀐 점이 있다면 이전 예시에서는 ‘메로나’가 의미를 가진 단어였다면 이제 ‘{’, ‘return’, ‘func’ 등과 같은 것들이 의미를 가진 단어들이 되었다는 것입니다.

Token?

마지막으로 token에 대해서 설명하고 마무리하도록 하겠습니다. 위에서 lexer가 하는 일이 글자들을 모아서 단어를 만드는 것이었습니다. 그런데 글자는 데이터라고 볼 수 있습니다. 하지만 다들 아시다시피 데이터는 가공하지 않거나 그것을 구조적으로 표현하지 않으면 다른 곳에서 쉽게 사용할 수가 없습니다. token의 역할이 여기서 등장하는데요. token은 단어를 구조적으로 표현할 수 있게 도와주는 구조체라고 볼 수 있습니다. ‘자료구조’라고 불리기도 하죠.

type Token struct {
Type TokenType
Val string
Column Pos
Line int
}

koa에서 정의한 token입니다. (최대한 코드는 넣지않으려고 했으나 워낙 간단한 코드이기도 하고 이해를 돕기 위해서 넣었습니다.) Type 은 글자의 종류를 나타내는 타입이고 Val 은 실제 글자를 나타냅니다. 나중에 이렇게 만들어둔 token 구조체를 이용해서 parser에서는 TypeVal 을 이용해 자신의 역할을 효율적으로 수행할 수 있습니다.

그 밖에 koa의 lexer가 실제로 어떤 아이디어를 가지고 어떻게 구현되었는지에 대해서는 이 포스트에 쓰기에는 양이 많기도하고 적절하지 않을 것 같아서 다른 포스트로 작성하였습니다. 혹시 기술적인 부분이나 구현 아이디어에 대해서 알고싶으신 분들은 이 포스트를 봐주세요.

Reference

기본적인 구조는 Writing An Interpreter In Go 책을 통해서 잡았고 Lexical Scanning in Go 영상과 golang template package코드, go-ethereum의 코드를 참고해서 좀 더 발전시켰습니다.

기능 구현범위 정의

koa language 초기 버전 문법에 대해서 정했습니다. 추후에 초기버전이 완성되면 확장할 예정입니다.

  • 자료형: string, int, bool
  • 연산자: Arithmetic(+, -, / , *, %), Comparison(==, !=, >, <, >=, <=), prefix(!, -)
  • if, else 조건문
  • return 을 통해서 값을 넘겨줍니다.
  • =을 통해서 변수에 값을 할당합니다.
  • ; 대신 \n을 통해서 statement를 마칩니다.

다음 포스트: Parser는 어떤 일을 할까?

--

--