[구현 연습] 컴파일러 이론을 이용한, JsonDecoder
👋 들어가기 전
뜬금 없지만, 구현력 문제를 코틀린으로 조금씩 정리해볼 생각이다.
약간 혼자만의 부트캠프 같은 느낌??
역시 언어 문법 늘리는데는 구현만한게 없다..
🏁 학습할 내용
- File read
- enum class
- seald class
- Stack
- 컴파일러 이론 Tokenizer, Lexer, Parser
- Reflection
🗒️문제
주어진 json 데이터를 이용해, Playlist 코틀린 객체로 파싱해라
{
"playlistName": "드라이브할 때 듣기 좋은 노래",
"createdAt": "2025-08-25",
"songs": [
{
"title": "Dynamite",
"artist": "BTS",
"album": "BE",
"duration": 199
},
{
"title": "As It Was",
"artist": "Harry Styles",
"album": "Harry's House",
"duration": 167
},
{
"title": "한 페이지가 될 수 있게",
"artist": "DAY6",
"album": "The Book of Us",
"duration": 230
},
{
"title": "Good 4 U",
"artist": "Olivia Rodrigo",
"album": "SOUR",
"duration": 178
},
{ "title": "Shape of You",
"artist": "Ed Sheeran",
"album": "Divide",
"duration": 233
}
],
"totalSongs": 5,
"totalDuration": 1007
}
문제 코드
fun main() {
val file = File("./src/main/resources/playlist.json") // 현재 디렉토리
}
🤖 컴파일러 이론
컴파일러는 소스코드를 기계어로 바꾸는 과정이다.
이 과정에서 3가지 중요한 역할을 하는 객체가 등장하는데, 바로 Tokenizer, Lexer, Parse이다.
각각 역할을 살펴보자
✂️Tokenizer
가장 처음 등장하는 객체는 Tokenizer다.
조금 이상하지만 질문이지만 소스코드는 무슨 타입일까 ??
var a: Int = 10
당연히도, 소스코드는 원시 문자열이다.
이 때, 코드를 이렇게 잘게 쪼갤 수 있다.
- var (키워드)
- a (식별자)
- : (구분자)
- = (연산자)
- 10(숫자 원시값)
그렇다, Tokenizer의 역할은 바로, 컴파일러가 이해할 수 있는 단위로 쪼개는 것
쪼개는 기준은 공백, 기호 등 다양하다.
🚀Lexer
두번 쨰 객체는 Lexer다.
위에서 소스코드를 잘랐다면, 이제는 그 의미를 해석하는 단계
그냥하는 것이 아니라, 해당 토큰에 티켓을 붙혀놓는 방식이라고 생각하면 편하다.
var(keywrod) a(variable):(seperator) Int(type) =(operator) 10(value)
Tokenizer + Lexer 과정을 합쳐서 Lexical analyze 라고 부른다.
🏢Parser
마지막 Parser은 많이 사용했던 개념으로, 정해진 구조로 쌓아 올리는 역할이다.
컴파일러 과정에서는 AST(Abstract Syntax Tree)가 정해진구조겠지??

🪞Reflection
코틀린 한정, 이번 과제의 핵심 개념은 Reflection인 것 같다.
런타임에 객체를 들여다 볼 수 있는게, 생각보다 생산성이 높아진다는 것
🌟 정의
런타임에, 프로그램 구조를 검사를 도와주는 라이브러리
Reflection is a set of language and library features that allows you to introspect the structure of your program at runtime.
Functions and properties are first-class citizens in Kotlin, and the ability to introspect them
(for example, learning the name or the type of a property or function at runtime) is essential when using a functional or reactive style.
⬇️Dependencies
implementation(kotlin("reflect"))
📌예제
reflect 라이브러리의 , memberProperties를 이용하면, 참조하고 있는 인스턴의 멤버 변수를 런타임에 알 수있다.

import kotlin.reflect.full.memberProperties
fun main() {
val a: Int = 3
val kClass = a::class // kClass<out Int>
kClass.memberProperties.forEach {
it // KProperty<out Int, *>
}
}
🔑나만의 정답
추후 공개
출처
https://kotlinlang.org/docs/sealed-classes.html
Sealed classes and interfaces | Kotlin
kotlinlang.org
https://kotlinlang.org/docs/reflection.html
Reflection | Kotlin
kotlinlang.org
컴파일러 이론에서 토크나이저(Tokenizer), 렉서(Lexer), 파서(Parse) 의 역할
토크나이저, 렉서, 파서의 역할
velog.io
https://dev.to/codingwithadam/introduction-to-lexers-parsers-and-interpreters-with-chevrotain-5c7b
Introduction to Lexers, Parsers and Interpreters with Chevrotain
In this exciting tutorial we are going to learn how to use a library called Chevrotain. It can be...
dev.to