디자인 패턴인터프리터 패턴

[ Programming > Design Pattern ]

[디자인 패턴] 인터프리터 패턴

 Carrot Yoon
 2025-11-28
 5

인터프리터 패턴(Interpreter Pattern)

인터프리터 패턴은 문법 규칙이 있는 어떤 언어를 해석하는 해석기를 만들 때 사용하는 행동 패턴이에요. 대표적으로 SQL Parser, 정규식 엔진, 구문 해석기(Typescript 같은 언어 해석) 같은 것들이 있어요.

인터프리터 패턴 구조

인터프리터 패턴은 크게 4가지 요소로 구성돼요. Abstract Expression , Terminal Expression, Nonterminal Expression, Context로 이루어져요.

Interpreter-UML.webp

1. Abstract Expression

모든 표현식이 따라야할 interpret 메서드를 정의해요. 문법 구조의 최소 인터페이스 역할을 해요.

2. Terminal Expression

문법에서 가장 기본 단위(토큰)을 해석하는 클래스에요. 숫자, 단어 같은 단일 토큰을 해석해요. Interpreter 패턴의 대부분이 이 Terminal Expression으로 구성돼요.

3. NonTerminalExpression

보통 문법 규칙을 조합하는 표현식 이에요. (+, -, *, %) 여러 Expression을 조합해서 더 큰 의미를 구성해요. 재귀적으로 하위 Expression을 interpret 호출해서 의미를 계산해요.

4. Context

해석 과정에 필요한 데이터를 담고 있어요. 변수의 값, 환경 설정, 캐시 등을 저장해서 필요하면 Expression에 제공해요.

예시들

이번에는 코드 예시를 직접 가져오지는 않을게요. 왜냐하면 개념적인 이해가 더 중요하다고 생각하기 때문이에요. 이건 프로그래머로서 가장 기초적이고 중요한 개념이라고 생각해요. 모든 언어가 거의 같은 과정으로 CPU에서 실행 가능하도록 기계어로 혹은 인터프리터를 통한 실행을 위한 바이트 코드로 번역할 수 있도록 만들기 때문이에요.

자바스크립트 파싱.webp

위 그림은 자바스크립트를 바이트 코드까지 만드는 예시에요. Scanner(Tokenizer)를 통해 소스코드를 토큰화하고, 토큰화한 정보를 통해 Parser를 이용해서 AST를 만들어요. 그리고 AST를 보고 Interpreter가 바이트 코드를 만들고요.

한번 순서대로 간략하게 예시를 봐요.

  1. 토큰화

const x = 5 + 3

Lexer(토크나이저) 단계

토큰

타입

const

Keyword (예약어, 키원드)

x

Identifier (식별자)

=

Operator (연산자)

5

Number (숫자)

+

Operator

3

Number

;

Punctuation (구두점)

  1. AST 생성

Parser 단계로 AST를 구성할 트리 구조를 만들어요.

image.webp
  1. 인터프리터 단계

AST 노드를 Expression 객체로 만들어요. 이때 AST의 리프 노드를 TerminalExpression으로 보면 편해요. 5, 3, X같은게 있겠네요.

아래는 연산에 대한 Expression노드 생성 예시를 더 간단하게 만들어 봤어요.

image.webp

그런데 왜 갑자기 이상한 거를 말하나 쉽죠? Client는 root에서 interpret()을 하기 위해서는 AST를 가지고 있어야하기 때문이에요.

그리고 인터프리터는 사실 context를 관리하고, expression 객체를 생성하고, argument로 Terminal Expression을 넣어주며 문법에 맞게 expression tree를 구성해야 하는 일들을 캡슐화 하고 있어야해요. 그리고 사실 이 패턴을 알아봤자, 앞 단의 과정들이 뭐가 있어야할 지 모르면 큰 의미가 없다고 생각했어요.

인터프리터 패턴 특징

인터프리터 패턴은 문법 규칙을 클래스로 분리해 새로운 문법 추가가 용이하게 만들기 좋아요. 그리고 재귀적 구조를 갖게되기 때문에 Composite 패턴과 유사해요. 하지만 컴포지트 패턴은 단일 객체와 복합 객체를 동일하게 다루어 단순화하는데 사용하고, 인터프리터 패턴은 문법 규칙을 다루기 위해 사용해요.

장점

  • 문법 규칙을 클래스로 분리해 관리 및 추가가 편해요.

  • DSL(도메인 특화 언어, 코드에서 string SQL문을 처리하는 예시)을 직접 만들 수 있어요.

  • 재귀 구조라 표현력이 좋고 Composite 패턴과 궁합이 좋아요.

단점

  • 문법이 추가되면서 Expression 클래스가 많이 늘어나요.

  • 보통 복잡한 문법을 구현하려면 Tokenizer, Parser까지 구현해야 해요(컴파일러 구조).

마무리

이번에는 인터프리터 패턴에 대해서 알아봤어요. 이 패턴은 이 활용법 자체보다는, 언어의 해석 과정과 바탕 지식이 더 필요하다 생각해요. 그래서 저는 이 패턴이 중요하다고 생각하지 않아요. 이 패턴으로 무언가를 구현하는 경우도 살면서 몇번 없을 것 같아요. 여러분이 유명한 "엄랭"같은거를 만든다면 모를까요...

그래서 저는 이 패턴 자체 보다는 "어떻게 내가 쓴 코드가 기계어까지 번역되어 CPU에서 실행될까??"를 알면 좋겠어요. 그 과정에서 어떤식으로 최적화가 이루어지는지 알려주기도 하거든요. 그러면 코드를 작성할 때, 더 최적화가 잘 되도록 코드를 짤 수도 있는 경우도 있어요.