์ปดํ์ผ๋ฌ๋ ์์ค์ฝ๋๋ฅผ ๊ธฐ๊ณ์ด๋ก ๋ฐ๊ฟ์ฃผ๋ ์ญํ ์ ํ๋ค
์ด ๋ ๊ตฌ๋ฌธ๋ถ์ -> ์ต์ ํ -> ์ฝ๋์์ฑ -> ๋งํน ์ ๊ณผ์ ์ด ์งํ๋๋ฉฐ
์์ค์ฝ๋๋ Tokenizer, Lexer, Parser๋ฅผ ์ฐจ๋ก๋๋ก ์ง๋๊ฐ๋ฉฐ
๊ตฌ๋ฌธ๋ถ์์ ์งํํ๊ฒ ๋๋๋ฐ, ํด๋น ๊ณผ์ ์ ๋ํด ์ ๋ฆฌํด๋ณด๊ณ ์ ํ๋ค
2020, NaverBoostCamp์ ์๋ฃ๋ค์ ๋ง์ด ์ฐธ๊ณ ํ์์ต๋๋ค
Tokenizer ๋ ๋ง ๊ทธ๋๋ก ์ด๋ค ๊ตฌ๋ฌธ์ ํ ํฐํ ํ๋ ์ญํ ์ ํ๋ค
์ฌ๊ธฐ์ ํ ํฐ์ด๋ ์ดํ ๋ถ์์ ์์ ๋จ์๋ฅผ ๋ปํ๋ฉฐ ๋จ์ด, ๋จ์ด๊ตฌ, ๋ฌธ์์ด ๋ฑ ์๋ฏธ์๋ ๋จ์๋ก ์ ํด์ง๋ค
ํ ํฐ์ ์ด๋ค ์์๋ค์ ๊ตฌ์กฐ์ ์ผ๋ก ํํํ ์ ์๋๋ก ๋์์ค๋ค
๋ฐ๋ผ์, ์ด๋ค ๋ช ๋ น์ด๊ฐ ๋ค์ด์ค๋ฉด ํด๋น ๋ช ๋ น์ด๋ฅผ ์๋ผ์ ํ ํฐ๋ค์ ๋ฆฌ์คํธ๋ก ๋ฐํํด์ค๋ค
Lexer๋ Tokenizer ๋ก ์ธํด ์ชผ๊ฐ์ง ํ ํฐ๋ค์ ์๋ฏธ๋ฅผ ๋ถ์ํ๋ ์ญํ ์ ํ๋ค
Tokenizer๋ฅผ ๊ฑฐ์น๋ฉฐ ์๋ฏธ์๋ ๋จ์๋ก ์ชผ๊ฐ์ง๊ณ ,
Lexer๋ฅผ ๊ฑฐ์น๋ฉฐ ํ ํฐ์ ์ ํ์ ๋ถ์ํ๋ ๊ณผ์ ์ ํตํ์ด Lexical Analyze๋ผ๊ณ ํ๋ค
return ์ด๋ผ๋ ๋ช
๋ น์ด๋ฅผ ๋ถ์ํ๋ ๊ณผ์ ์ ์๋ก ๋ค์ด๋ณด์
ex) return A ๋ช ๋ น์ด ๋ถ์
- return A๋ผ๋ ๋จ์ด์์ ์์ฒด๋ ์๋ฌด ์๋ฏธ๋ ๊ฐ์ง์ง ์์
- Tokenizer๋ฅผ ๊ฑฐ์น๋ฉฐ return๊ณผ A๋ผ๋ ์๋ฏธ์๋ ๋จ์ด๊ฐ ๋จ -> ํ ํฐํ
- Lexer๋ฅผ ๊ฑฐ์น๋ฉฐ return ํ ํฐ์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ฐํํ๋ผ๋ ๋ช ๋ น์ด๊ตฌ๋! ๋ผ๊ณ ์๋ฏธ๋ฅผ ๋ถ์
- Lexer๋ฅผ ๊ฑฐ์น๋ฉฐ A ํ ํฐ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ฐธ์กฐํ๋ ๋ณ์์ ์ฃผ์๋ฅผ ๋ํ๋ธ๋ค! ๋ผ๊ณ ์๋ฏธ๋ฅผ ๋ถ์
- ํด๋น ํ ํฐ์ {type: ๋ช ๋ น์ด, value: "return", child: []} ์ ๊ฐ์ ์์ผ๋ก ์๋ฏธ๊ฐ ๋ถ์๋์ด Parser์๊ฒ ์ ๋ฌ๋๋ค
Parser๋ Lexical Analyze๋ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ๋ํ๋ธ๋ค
๋ฐ์ดํฐ๊ฐ ์ฌ๋ฐ๋ฅธ์ง ๊ฒ์ฆํ๋ ์ญํ ๋ ์ํํ๋๋ฐ, ์ด๋ฅผ ํตํ์ด Syntax Analyze๋ผ๊ณ ํ๋ค
๋ง์ฝ ์ค์ ๋ก Tokenizer, Lexer, Parser ๊ฐ๋ ์ ์ด์ฉํ์ฌ ๋ฌด์ธ๊ฐ๋ฅผ ๊ตฌํํด๋ณผ ์๊ฐ์ด๋ผ๋ฉด,
Parser๊ฐ ํ์คํฌ๋ฅผ ์ํํ๋ ๋ถ๋ถ์์ ๋ฌด์ธ๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ ๋ฐ์ดํฐ๊ฐ ๋ฐ๊ฒฌ๋์๋ค๋ฉด
Error๋ฅผ ๋์ง๋ ์์ผ๋ก ์๋ฌ ํธ๋ค๋ง์ด ํ์ํ๋ค
Parser์ ์ํด ๋์ถ๋ ๊ฒฐ๊ณผ๋ AST(Abstract Syntax Tree) ํํ๋ก ์์ฑ๋๋ค
AST๋ ์ด๋ฆ ๊ทธ๋๋ก Tokenizer, Lexer, Parser ๊ณผ์ ์ ๊ฑฐ์น๋ฉฐ ๋ถ์๋ ๊ตฌ๋ฌธ์ ํธ๋ฆฌ์ ํํ๋ก ๋ํ๋ด๋ ์๋ฃ๊ตฌ์กฐ๋ค
๋ถ์๋ ์์ค๋ฅผ ์ปดํจํฐ๊ฐ ์ดํดํ ์ ์๋ ๊ตฌ์กฐ๋ก ๋ณ๊ฒฝ์ํจ ํธ๋ฆฌ๋ผ๊ณ ๋ณด๋ฉด ๋๋ค
AST๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค
// - Input
printf("Hello World");
// - Tokenizer : ์๋ฏธ์๋ ๋จ์๋ก ๋ถ๋ฆฌ (ํ ํฐํ)
["printf", "(", "Hello World", ")", ";"]
// - Lexer : ์ฃผ์ด์ง ํ ํฐ์ ์๋ฏธ ๋ถ์
<id, printf>
<punctuation, (>
<literal, "Hello World">
<punctuation, )>
<punctuation, ;>
// - Parser : ๋ถ์๋ ๋ฐ์ดํฐ ๊ฒ์ฆ ๋ฐ AST ๊ตฌ์กฐํ
{
type: punctuation,
value: printf,
child: [
{
type: literal,
value: "Hello World",
child: []
}
]
}
์์ ์์๋ ์ ์์ ์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์์ ์๋ฃํ์๋๋ฅผ ๋ณด์ฌ์ค๋ค
AST ์์๋ ๊ดํธ๋ ์ธ๋ฏธ์ฝ๋ก ๊ณผ ๊ฐ์ ์ ๋ณด๋ค์ ์๋ตํ๊ณ
์์ค์ฝ๋์์ ํ์ํ ์ ๋ณด๋ค๋ง ์ถ๋ ค๋ด์ด ํธ๋ฆฌํํ๋ก ๋ํ๋ธ ๊ฒ์ ์ ์ ์๋ค
Abstract ๋ผ๋ ๋จ์ด๊ฐ ๋ค์ด๊ฐ ์ด์ ๋
์์ค์ฝ๋์ ๋ถํ์ํ ์ ๋ณด๋ ์ ์ธํ๊ณ ํต์ฌ ๋ฐ์ดํฐ๋ค๋ง์ ์ด์ฉํด ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๊ธฐ ๋๋ฌธ์ด๋ค
// - Input
printf("Wrong Syntax")
// - Tokenizer : ์๋ฏธ์๋ ๋จ์๋ก ๋ถ๋ฆฌ (ํ ํฐํ)
["printf", "(", "Wrong Syntax", ")"]
// - Lexer : ์ฃผ์ด์ง ํ ํฐ์ ์๋ฏธ ๋ถ์
<id, printf>
<punctuation, (>
<literal, "Hello World">
<punctuation, )>
// - Parser : ๋ถ์๋ ๋ฐ์ดํฐ ๊ฒ์ฆ ๋ฐ AST ๊ตฌ์กฐํ
Compile Error - missing semicolon
์์ ์์์์๋ ์๋ชป๋ ์ฝ๋๋ฅผ ๋ถ์ํ๋ ๊ณผ์ ์ ๋ํ๋ธ๋ค
Tokenizer ์ Lexer ๋ ์๋ฏธ์๋ ๋จ์๋ก ์์ค๋ฅผ ๋ถ๋ฆฌํ๊ณ
์๋ฏธ๋ฅผ ๋ถ์ํ๋ ์ญํ ๋ง ํ ๋ฟ, ํด๋น ์์ค๊ฐ ์ ํจํ์ง ์๋์ง๋ ๊ฒ์ฆํ์ง ์๋๋ค
์ค์ ๊ณผ์ ์ ๋ณด๋ค ๋ณต์กํ ๋ฐฉ์์ผ๋ก ์ด๋ค์ง๊ฒ ์ง๋ง
๊ฒ์ฆ์ Parser์์ ์งํ๋๊ธฐ ๋๋ฌธ์, Parser์์ ์ปดํ์ผ ์๋ฌ๋ฅผ ๋์ ธ์ค ๊ฒ์ด๋ค
์ปดํ์ผ ์๋ฌ์ ๋๋ถ๋ถ์ ์์ ๊ฐ์ด Parser์์ ๋ฐ์ดํฐ๋ฅผ AST๋ก ๊ตฌ์กฐํํ์ง ๋ชปํ์ฌ ๋์ ธ์ฃผ๋ ์๋ฌ์ผ ํ๋ฅ ์ด ๋๋ค