<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>김신건의 로그 - 위키 / plt</title><description>&apos;plt&apos; 카테고리 위키 페이지 최신 업데이트</description><link>https://shinkeonkim.com/</link><language>ko-KR</language><item><title>[PLT] Abstract Syntax Tree (AST)</title><link>https://shinkeonkim.com/wiki/plt/plt-abstract-syntax-tree/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/plt-abstract-syntax-tree/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Abstract Syntax Tree (AST, 추상 구문 트리)&lt;/strong&gt; 는 프로그램의 &lt;strong&gt;문법 구조를 트리로 표현&lt;/strong&gt; 한 자료구조입니다. 파서의 출력물이자, 이후 컴파일러/인터프리터의 거의 모든 단계 (semantic 분석, 최적화, 코드 생성) 의 입력.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;핵심&lt;/strong&gt;: 소스 코드의 &lt;strong&gt;본질적 구조&lt;/strong&gt; 만 남기고, 문법 세부 (괄호, 세미콜론, 공백) 제거.&lt;/p&gt;
&lt;h2 id=&quot;왜-트리인가&quot;&gt;왜 트리인가&lt;/h2&gt;
&lt;p&gt;프로그래밍 언어의 구조는 자연스럽게 &lt;strong&gt;재귀적&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;함수는 statement 들의 목록&lt;/li&gt;
&lt;li&gt;statement 는 expression 을 포함&lt;/li&gt;
&lt;li&gt;expression 은 다른 expression 을 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;트리 = 재귀 구조 표현의 자연스러운 자료구조.&lt;/p&gt;
&lt;h2 id=&quot;ast-예시&quot;&gt;AST 예시&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;소스 코드&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;AST&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Root[&quot;IfStatement&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Root --&gt; Cond[&quot;BinaryOp: &gt;&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Root --&gt; Then[&quot;Block&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Root --&gt; Else[&quot;Block&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Cond --&gt; C1[&quot;Identifier: x&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Cond --&gt; C2[&quot;Number: 0&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Then --&gt; Assign1[&quot;Assignment&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Assign1 --&gt; T1[&quot;Identifier: y&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Assign1 --&gt; T2[&quot;BinaryOp: *&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  T2 --&gt; T3[&quot;Identifier: x&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  T2 --&gt; T4[&quot;Number: 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Else --&gt; Assign2[&quot;Assignment&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Assign2 --&gt; E1[&quot;Identifier: y&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Assign2 --&gt; E2[&quot;Number: 0&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 노드는 의미 있는 구조:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IfStatement&lt;/strong&gt;: cond, then, else 세 자식&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BinaryOp&lt;/strong&gt;: op, left, right&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assignment&lt;/strong&gt;: target, value&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Block&lt;/strong&gt;: statements 리스트&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ast-vs-parse-tree-concrete-syntax-tree&quot;&gt;AST vs Parse Tree (Concrete Syntax Tree)&lt;/h2&gt;
&lt;p&gt;두 개념 자주 혼동.&lt;/p&gt;
&lt;h3 id=&quot;parse-tree-cst&quot;&gt;Parse Tree (CST)&lt;/h3&gt;
&lt;p&gt;문법 규칙을 &lt;strong&gt;그대로&lt;/strong&gt; 반영. 모든 non-terminal 이 노드.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Expression&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── Term&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── Factor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   │   └── Number(2)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── OP(+)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── Term&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│       ├── Factor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│       │   └── Number(3)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│       └── OP(*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│       └── Factor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│           └── Number(4)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;2 + 3 * 4&lt;/code&gt; 의 CST 는 &lt;code&gt;Expression → Term → Factor&lt;/code&gt; 등 중간 노드 다수.&lt;/p&gt;
&lt;h3 id=&quot;ast&quot;&gt;AST&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;본질 구조만&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;BinaryOp(+)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── Number(2)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└── BinaryOp(*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ├── Number(3)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    └── Number(4)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;간결. 이후 처리에 유리.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;언제 CST 유지?&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;소스 코드 포매터 (원본 재구성 필요)&lt;/li&gt;
&lt;li&gt;리팩터링 도구 (주석/공백 보존)&lt;/li&gt;
&lt;li&gt;IDE (원본 위치 정확성)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ast-노드-정의-typescript-예시&quot;&gt;AST 노드 정의 (TypeScript 예시)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 표현식&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; NumberLiteral&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; StringLiteral&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; BooleanLiteral&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Identifier&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; BinaryOp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; UnaryOp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Call&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; MemberAccess&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Assignment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; NumberLiteral&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;NumberLiteral&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  location&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Identifier&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Identifier&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  location&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; BinaryOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BinaryOp&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  op&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;+&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;-&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;*&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;==&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;#x3C;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;#x26;&amp;#x26;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;||&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  left&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  right&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  location&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; UnaryOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;UnaryOp&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  op&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;-&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;!&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;++&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;--&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  operand&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  location&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Call&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Call&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  callee&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  args&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  location&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 문장&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Statement&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ExpressionStatement&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; VariableDeclaration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; IfStatement&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; WhileStatement&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ReturnStatement&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; FunctionDeclaration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Block&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; IfStatement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;IfStatement&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  condition&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  thenBranch&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Statement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  elseBranch&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Statement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  location&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; FunctionDeclaration&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;FunctionDeclaration&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  params&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Identifier&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  body&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Block&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  location&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  file&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  line&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  column&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;ast-순회-traversal&quot;&gt;AST 순회 (Traversal)&lt;/h2&gt;
&lt;p&gt;AST 를 처리할 때 대부분 &lt;strong&gt;재귀 순회&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;depth-first&quot;&gt;Depth-First&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function visit(node):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    switch node.kind:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case &apos;NumberLiteral&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            processNumber(node)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case &apos;BinaryOp&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            visit(node.left)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            visit(node.right)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            processBinaryOp(node)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case &apos;IfStatement&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            visit(node.condition)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            visit(node.thenBranch)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if node.elseBranch:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                visit(node.elseBranch)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            processIf(node)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;방문-시점&quot;&gt;방문 시점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pre-order&lt;/strong&gt;: 자식 방문 전 노드 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Post-order&lt;/strong&gt;: 자식 모두 방문 후 노드 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In-order&lt;/strong&gt;: 이진 트리 특수 (프로그래밍 언어 AST 는 잘 안 씀)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;visitor-pattern&quot;&gt;Visitor Pattern&lt;/h2&gt;
&lt;p&gt;전형적 OOP 패턴:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Visitor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visitNumber&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; NumberLiteral&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visitBinaryOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; BinaryOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visitIdentifier&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Identifier&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visitIf&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; IfStatement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Evaluator&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Visitor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visitNumber&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; node.value;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visitBinaryOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; left&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;visit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.left);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; right&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;visit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.right);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; applyOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.op, left, right);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visitIdentifier&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.env.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  visit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    switch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (node.kind) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      case&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;NumberLiteral&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;visitNumber&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      case&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BinaryOp&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;visitBinaryOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      case&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Identifier&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;visitIdentifier&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;      // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Discriminated union + switch&lt;/strong&gt; 방식 (TypeScript, Rust 스타일) 이 최근 관용.&lt;/p&gt;
&lt;h2 id=&quot;ast-변환-transformation&quot;&gt;AST 변환 (Transformation)&lt;/h2&gt;
&lt;p&gt;새 AST 를 만들어 반환하는 함수:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; replaceConstants&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (node.kind &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Identifier&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; node.name &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;PI&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { kind: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;NumberLiteral&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, value: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3.14159&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, location: node.location };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (node.kind &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BinaryOp&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      ...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;node,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      left: &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replaceConstants&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.left),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      right: &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replaceConstants&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.right),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; node;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Babel plugin, TypeScript transformer, ESLint auto-fix&lt;/strong&gt; 가 이 패턴.&lt;/p&gt;
&lt;h2 id=&quot;실전-사용-사례&quot;&gt;실전 사용 사례&lt;/h2&gt;
&lt;h3 id=&quot;1-인터프리터&quot;&gt;1. 인터프리터&lt;/h3&gt;
&lt;p&gt;AST 순회하며 실행. Tree-walking interpreter.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; evaluate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Expression&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Environment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  switch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (node.kind) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    case&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;NumberLiteral&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; node.value;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    case&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BinaryOp&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; l&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; evaluate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.left, env);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; evaluate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.right, env);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; applyOp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.op, l, r);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    case&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Identifier&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; env.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;lookup&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node.name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Crafting Interpreters 의 첫 인터프리터.&lt;/p&gt;
&lt;h3 id=&quot;2-컴파일러-코드-생성&quot;&gt;2. 컴파일러 (코드 생성)&lt;/h3&gt;
&lt;p&gt;AST → 목표 코드:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;NumberLiteral 42       → PUSH 42&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;BinaryOp(+, l, r)      → visit(l); visit(r); ADD&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;3-정적-분석--린터&quot;&gt;3. 정적 분석 / 린터&lt;/h3&gt;
&lt;p&gt;ESLint 는 AST 를 순회하며 규칙 적용:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// no-unused-vars 규칙&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Program&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; declared&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; collectDeclared&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; used&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; collectUsed&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(node);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; varName&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; declared) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;used.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;has&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(varName)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;      report&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`Unused variable: ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;varName&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;4-트랜스파일러&quot;&gt;4. 트랜스파일러&lt;/h3&gt;
&lt;p&gt;Babel: ES2020+ AST → ES5 AST (다운그레이드).&lt;/p&gt;
&lt;p&gt;TypeScript: TS AST → JS AST + 별도 타입 검사.&lt;/p&gt;
&lt;h3 id=&quot;5-ide-지원&quot;&gt;5. IDE 지원&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;자동완성&lt;/strong&gt;: 커서 위치 AST 노드 확인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go to definition&lt;/strong&gt;: identifier → declaration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rename&lt;/strong&gt;: 같은 심볼의 모든 참조 재작성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;포매팅&lt;/strong&gt;: AST → 표준 형식으로 재출력 (Prettier)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;6-code-mods-자동-리팩터링&quot;&gt;6. Code Mods (자동 리팩터링)&lt;/h3&gt;
&lt;p&gt;jscodeshift, ts-morph: 대규모 자동 리팩터링. AST 변환.&lt;/p&gt;
&lt;h2 id=&quot;ast-explorer&quot;&gt;AST Explorer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://astexplorer.net/&quot;&gt;https://astexplorer.net/&lt;/a&gt; 에서 여러 언어 파서의 AST 를 실시간 확인 가능. 학습 필수 도구.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: JavaScript &lt;code&gt;const x = 42;&lt;/code&gt; 의 AST:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Program&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;body&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;VariableDeclaration&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;kind&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;const&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;      &quot;declarations&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;VariableDeclarator&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Identifier&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;          &quot;init&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Literal&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;언어별-ast-표기법&quot;&gt;언어별 AST 표기법&lt;/h2&gt;
&lt;h3 id=&quot;javascript&quot;&gt;JavaScript&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ESTree&lt;/strong&gt; 명세: 사실상 표준. Acorn, Babel, ESLint 채택.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SWC AST&lt;/strong&gt;, &lt;strong&gt;Oxc AST&lt;/strong&gt;: Rust 기반 최근 도구, 대부분 ESTree 호환.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;typescript&quot;&gt;TypeScript&lt;/h3&gt;
&lt;p&gt;TypeScript 자체 컴파일러 AST. ESTree 와 다름 (typescript-eslint 는 변환).&lt;/p&gt;
&lt;h3 id=&quot;python&quot;&gt;Python&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ast&lt;/code&gt; 모듈. &lt;code&gt;ast.parse(source)&lt;/code&gt; → AST.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ast&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tree &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ast.parse(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;x = 42&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ast.dump(tree))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;rust&quot;&gt;Rust&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rustc_ast&lt;/code&gt;, &lt;code&gt;syn&lt;/code&gt; (proc macro 용).&lt;/p&gt;
&lt;h3 id=&quot;go&quot;&gt;Go&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;go/ast&lt;/code&gt; 표준 패키지.&lt;/p&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Source location 저장&lt;/strong&gt;. AST 노드에 원본 위치 (파일/줄/열) 없으면 에러 메시지 최악.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;주석/공백 처리&lt;/strong&gt;. Prettier / 포매터 하려면 AST 에 관련 정보 유지 필요. 대부분 컴파일러는 버림.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;AST 재사용 시 immutable 지향&lt;/strong&gt;. 변환은 새 AST 생성. 원본 수정은 버그 온상.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Discriminated union + switch&lt;/strong&gt; 가 OOP visitor 보다 현대적. TypeScript exhaustive check.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;AST 순회 순서가 의미 결정&lt;/strong&gt;. Pre-order 인지 post-order 인지 명확히 (예: 순회 중 변수 정의 발견 순서).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[programming-language-theory|PLT 개요]]&lt;/li&gt;
&lt;li&gt;[[plt-lexical-analysis|Lexical Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-parsing|Parsing]]&lt;/li&gt;
&lt;li&gt;[[plt-semantic-analysis|Semantic Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-interpreter-compiler|Interpreter vs Compiler]]&lt;/li&gt;
&lt;li&gt;[[plt-ir-optimization-codegen|IR &amp;#x26; Code Gen]]&lt;/li&gt;
&lt;li&gt;[[ts-decorators|TypeScript Decorators]] - 실전 AST 변환&lt;/li&gt;
&lt;li&gt;[[js-bundling|JS 번들링]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>ast</category><category>tree</category><category>visitor-pattern</category><author>koa (김신건)</author></item><item><title>[PLT] Interpreter vs Compiler</title><link>https://shinkeonkim.com/wiki/plt/plt-interpreter-compiler/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/plt-interpreter-compiler/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;프로그래밍 언어의 실행 모델 두 접근:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Compiler (컴파일러)&lt;/strong&gt;: 소스 → 목표 코드 (기계어, 바이트코드) 로 변환. 실행은 나중.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interpreter (인터프리터)&lt;/strong&gt;: 소스 (또는 AST) 를 &lt;strong&gt;직접 실행&lt;/strong&gt;. 별도 목표 코드 없음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;현대는 하이브리드&lt;/strong&gt;. 순수 컴파일러/인터프리터는 드묾. JIT, 바이트코드 VM 등 조합.&lt;/p&gt;
&lt;h2 id=&quot;compiler-파이프라인&quot;&gt;Compiler 파이프라인&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Src[Source] --&gt; L[Lexer] --&gt; P[Parser] --&gt; A[AST]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  A --&gt; S[Semantic] --&gt; IR[IR Gen] --&gt; Opt[Optimizer]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Opt --&gt; CG[Code Gen] --&gt; Bin[Machine Code / Bytecode]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Bin --&gt; R[Runtime Execution]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Ahead-Of-Time (AOT)&lt;/strong&gt;: 실행 전 전체 컴파일.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: C, C++, Rust, Go, Swift (native), Kotlin/Native.&lt;/p&gt;
&lt;h2 id=&quot;interpreter-파이프라인&quot;&gt;Interpreter 파이프라인&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Src[Source] --&gt; L[Lexer] --&gt; P[Parser] --&gt; A[AST]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  A --&gt; E[Evaluator]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  E --&gt; Out[Output]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Tree-walking interpreter&lt;/strong&gt;: AST 순회하며 실행.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: 초기 Python (인터프리티브), Ruby MRI 초기, Lua 5.1, PHP 초기.&lt;/p&gt;
&lt;h2 id=&quot;tree-walking-interpreter-의사코드&quot;&gt;Tree-Walking Interpreter (의사코드)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;evaluate(node, env):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    switch node.kind:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case NumberLiteral:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            return node.value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case BinaryOp:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            l = evaluate(node.left, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            r = evaluate(node.right, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            return applyOp(node.op, l, r)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case Identifier:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            return env.lookup(node.name)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case Assignment:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            v = evaluate(node.value, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            env.set(node.target.name, v)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            return v&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case IfStatement:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if isTruthy(evaluate(node.cond, env)):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                return evaluate(node.then, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            elif node.else:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                return evaluate(node.else, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case WhileLoop:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            while isTruthy(evaluate(node.cond, env)):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                evaluate(node.body, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case FunctionCall:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            fn = evaluate(node.callee, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            args = [evaluate(a, env) for a in node.args]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            return callFunction(fn, args)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: 단순, 이해 쉬움.
&lt;strong&gt;단점&lt;/strong&gt;: 느림. 매 노드가 dict lookup + case switch.&lt;/p&gt;
&lt;h2 id=&quot;bytecode-vm&quot;&gt;Bytecode VM&lt;/h2&gt;
&lt;p&gt;Tree-walking 을 개선. AST → &lt;strong&gt;바이트코드&lt;/strong&gt; (스택 기반 명령) 로 컴파일 후 VM 이 실행.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Source: 1 + 2 * 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Compile to bytecode:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  PUSH 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  PUSH 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  PUSH 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  MUL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ADD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;VM 실행:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  스택: [1, 2, 3]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  MUL: 2*3=6, 스택 [1, 6]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ADD: 1+6=7, 스택 [7]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: CPython (bytecode + VM), JVM (bytecode + JIT), .NET (CIL + JIT), Lua (bytecode).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tree-walking 대비 훨씬 빠름 (10-100배)&lt;/li&gt;
&lt;li&gt;Portable (VM 만 있으면 어디서든)&lt;/li&gt;
&lt;li&gt;최적화 여지&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컴파일 단계 필요&lt;/li&gt;
&lt;li&gt;VM 자체 오버헤드&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;jit-just-in-time&quot;&gt;JIT (Just-In-Time)&lt;/h2&gt;
&lt;p&gt;바이트코드 (또는 소스) 를 &lt;strong&gt;실행 중 native 기계어로 컴파일&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Warm-up&lt;/strong&gt;: 초기에는 인터프리터 (또는 baseline 컴파일)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hot path 감지&lt;/strong&gt;: 자주 실행되는 코드 발견&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimizing JIT&lt;/strong&gt;: hot path 를 최적화된 native 로 재컴파일&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deoptimization&lt;/strong&gt;: 가정 (타입, inline) 이 깨지면 인터프리터로 fallback&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;V8 (Chrome, Node.js)&lt;/strong&gt;: Ignition (interpreter) + TurboFan/Maglev (JIT)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HotSpot (Java)&lt;/strong&gt;: C1/C2 컴파일러&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LuaJIT&lt;/strong&gt;: 세계에서 가장 빠른 JIT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PyPy&lt;/strong&gt;: Python JIT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SpiderMonkey (Firefox)&lt;/strong&gt;: Ion, Warp&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;성능&lt;/strong&gt;: JIT 언어는 종종 C++ 성능의 50-90% 도달.&lt;/p&gt;
&lt;h2 id=&quot;aot-vs-jit-vs-interpreter&quot;&gt;AOT vs JIT vs Interpreter&lt;/h2&gt;





















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;축&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;AOT&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;JIT&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Interpreter&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;시작 속도&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름 (컴파일 완료)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;느림 (warm-up)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름 (파싱만)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;최대 성능&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;최고&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 높음&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;낮음&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;동적 최적화&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;불가&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;가능 (runtime info)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;불가&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;배포 크기&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;큼 (native binary)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;작음 (bytecode)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;소스&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;크로스 플랫폼&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;재컴파일&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;VM 있으면&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;인터프리터 있으면&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;개발 iteration&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;느림&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;빠름&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;매우 빠름&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;예&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;C, Rust, Go&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Java, V8&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Bash, 초기 Ruby&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;하이브리드-현대&quot;&gt;하이브리드 (현대)&lt;/h2&gt;
&lt;p&gt;대부분 현대 언어는 &lt;strong&gt;여러 접근 조합&lt;/strong&gt;:&lt;/p&gt;
&lt;h3 id=&quot;javascript-v8&quot;&gt;JavaScript (V8)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Parse&lt;/strong&gt; → AST&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignition&lt;/strong&gt;: bytecode 인터프리터 (빠른 시작)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sparkplug&lt;/strong&gt;: baseline JIT (한 번 실행된 함수)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maglev&lt;/strong&gt;: mid-tier JIT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TurboFan&lt;/strong&gt;: optimizing JIT (hot 함수)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deoptimization&lt;/strong&gt;: 가정 깨지면 이전 계층으로&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;java-hotspot&quot;&gt;Java (HotSpot)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;javac&lt;/strong&gt; → bytecode (.class)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interpreter&lt;/strong&gt; (인터프리팅)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C1 compiler&lt;/strong&gt; (client JIT, 빠른 컴파일)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C2 compiler&lt;/strong&gt; (server JIT, 고급 최적화)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;python-cpython&quot;&gt;Python (CPython)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Parse&lt;/strong&gt; → AST&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compile&lt;/strong&gt; → bytecode (.pyc)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VM 실행&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;(&lt;strong&gt;PyPy&lt;/strong&gt;: JIT 추가)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;c-net&quot;&gt;C# (.NET)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Roslyn&lt;/strong&gt; → CIL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RyuJIT&lt;/strong&gt; 또는 &lt;strong&gt;AOT (Native AOT)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;transpiler-소스-대-소스-컴파일러&quot;&gt;Transpiler (소스-대-소스 컴파일러)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;소스 → 다른 소스&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Babel&lt;/strong&gt;: 최신 JS → 옛 JS (호환성)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;: TS → JS (타입 제거)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kotlin → JVM/JS/Native&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CoffeeScript → JS&lt;/strong&gt; (legacy)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vue SFC compiler&lt;/strong&gt;: &lt;code&gt;.vue&lt;/code&gt; → JS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sass → CSS&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;차이점&lt;/strong&gt;: 컴파일러이지만 목표가 기계어가 아닌 다른 고급 언어.&lt;/p&gt;
&lt;h2 id=&quot;cross-compilation&quot;&gt;Cross-Compilation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;한 플랫폼에서 다른 플랫폼용 바이너리 생성&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rust: &lt;code&gt;cargo build --target=x86_64-unknown-linux-gnu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Go: &lt;code&gt;GOOS=linux GOARCH=amd64 go build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;임베디드 (Rust, C): x86 머신에서 ARM 바이너리&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;repl-read-eval-print-loop&quot;&gt;REPL (Read-Eval-Print Loop)&lt;/h2&gt;
&lt;p&gt;인터프리터의 확장. 사용자 입력 즉시 실행.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: Python REPL, Node.js, GHCi (Haskell), rusti (Rust).&lt;/p&gt;
&lt;p&gt;컴파일 언어도 REPL 가능: Kotlin, Scala (컴파일 후 실행).&lt;/p&gt;
&lt;h2 id=&quot;meta-circular-interpreter&quot;&gt;Meta-Circular Interpreter&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;언어 X 로 X 를 구현&lt;/strong&gt;. Lisp 이 유명.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: JavaScript 로 JavaScript 파서 (Acorn, Babel).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: bootstrap, self-hosting.&lt;/p&gt;
&lt;h2 id=&quot;interpreter-vs-compiler-선택-기준&quot;&gt;Interpreter vs Compiler 선택 기준&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;컴파일러가 좋을 때&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;성능 우선 (게임, 시스템)&lt;/li&gt;
&lt;li&gt;배포 크기 (native binary)&lt;/li&gt;
&lt;li&gt;최적화 여지 극대화&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;인터프리터가 좋을 때&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;개발 iteration 빠름&lt;/li&gt;
&lt;li&gt;동적 (eval, reflection)&lt;/li&gt;
&lt;li&gt;이식성 우선 (같은 소스 여러 플랫폼)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;JIT 가 좋을 때&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;두 이익 모두 (개발 편의 + 성능)&lt;/li&gt;
&lt;li&gt;런타임 정보 활용 (동적 타입 최적화)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;인터프리티드 언어 = 느림 은 오해&lt;/strong&gt;. JIT (V8, LuaJIT, HotSpot) 는 C 급 성능.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;JIT warmup&lt;/strong&gt;. 짧은 CLI 프로그램은 JIT 이점 없음. Java 는 특히 startup 느림 → AOT (GraalVM) 로 해결.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Bytecode 도 크로스플랫폼 아님&lt;/strong&gt;. JVM 바이트코드는 JVM 필요. WASM 은 다양한 호스트.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Transpiler 도 컴파일러&lt;/strong&gt;. AST 변환은 동일. 다만 출력이 소스 코드.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Tree-walking interpreter 는 프로덕션 부적합&lt;/strong&gt;. 학습용. 실전은 bytecode + JIT.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[programming-language-theory|PLT 개요]]&lt;/li&gt;
&lt;li&gt;[[plt-abstract-syntax-tree|AST]]&lt;/li&gt;
&lt;li&gt;[[plt-semantic-analysis|Semantic Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-ir-optimization-codegen|IR &amp;#x26; Code Gen]]&lt;/li&gt;
&lt;li&gt;[[plt-type-systems|Type Systems]]&lt;/li&gt;
&lt;li&gt;[[js-bundling|JS 번들링]] - Transpiler 실전&lt;/li&gt;
&lt;li&gt;[[typescript|TypeScript]] - Transpiler&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>interpreter</category><category>jit</category><category>aot</category><category>vm</category><category>bytecode</category><author>koa (김신건)</author></item><item><title>[PLT] IR, 최적화, 코드 생성 (Compiler Backend)</title><link>https://shinkeonkim.com/wiki/plt/plt-ir-optimization-codegen/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/plt-ir-optimization-codegen/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;컴파일러의 &lt;strong&gt;백엔드&lt;/strong&gt; 는 semantic 분석까지 마친 AST 를 실제 실행 가능한 목표 코드로 변환합니다. 세 주요 단계:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;IR (Intermediate Representation) 생성&lt;/strong&gt;: AST → 중간 표현&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;최적화&lt;/strong&gt;: IR 을 더 효율적인 IR 로 변환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;코드 생성&lt;/strong&gt;: IR → 목표 코드 (native, bytecode, WASM)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 문서는 세 단계를 통합 소개합니다.&lt;/p&gt;
&lt;h2 id=&quot;왜-ir-인가&quot;&gt;왜 IR 인가&lt;/h2&gt;
&lt;p&gt;AST 는 언어 특유의 구조. 그대로 다루면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;언어마다 다른 최적화 코드&lt;/li&gt;
&lt;li&gt;아키텍처마다 다른 코드 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;IR&lt;/strong&gt; 은 &lt;strong&gt;언어 독립 + 아키텍처 독립&lt;/strong&gt; 중간 지점:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[C 소스] ─┐              ┌─→ [x86 어셈블리]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Rust]  ─┼─→ [LLVM IR] ─┼─→ [ARM 어셈블리]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[Swift] ─┘              └─→ [WASM]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;LLVM&lt;/strong&gt; 이 이 개념의 극한. LLVM IR 은 사실상 산업 표준.&lt;/p&gt;
&lt;h2 id=&quot;ir-종류&quot;&gt;IR 종류&lt;/h2&gt;
&lt;h3 id=&quot;1-ast-자체&quot;&gt;1. AST 자체&lt;/h3&gt;
&lt;p&gt;가장 원시. 처리 어려움. 트리 순회 인터프리터 급.&lt;/p&gt;
&lt;h3 id=&quot;2-three-address-code-tac&quot;&gt;2. Three-Address Code (TAC)&lt;/h3&gt;
&lt;p&gt;각 명령이 최대 3개 피연산자 (source1, source2, destination):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;t1 = a + b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;t2 = t1 * c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;t3 = t2 + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;d = t3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;원본:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;d &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (a &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; c &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;한 명령 = 한 연산&lt;/strong&gt;. 최적화하기 쉬움.&lt;/p&gt;
&lt;h3 id=&quot;3-static-single-assignment-ssa&quot;&gt;3. Static Single Assignment (SSA)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;각 변수는 정확히 한 번 할당&lt;/strong&gt;. 새 값은 새 변수 이름.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// 원본&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = x + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = x * 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// SSA&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x_1 = 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x_2 = x_1 + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x_3 = x_2 * 2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;phi-함수-φ&quot;&gt;Phi 함수 (Φ)&lt;/h3&gt;
&lt;p&gt;분기 후 합류 시 어떤 정의를 선택:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if cond:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x = 1        // x_1 = 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;else:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x = 2        // x_2 = 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;y = x + 1        // x_3 = Φ(x_1, x_2); y_1 = x_3 + 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Φ(x_1, x_2)&lt;/code&gt; = “실행 경로에 따라 x_1 또는 x_2”.&lt;/p&gt;
&lt;h3 id=&quot;왜-ssa-인가&quot;&gt;왜 SSA 인가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Def-use chain 명확&lt;/strong&gt;: 각 변수 정의는 유일, 사용 곳 추적 쉬움&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;최적화 알고리즘 단순&lt;/strong&gt;: constant propagation, dead code elimination&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Register allocation 개선&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;모든 현대 컴파일러&lt;/strong&gt;: LLVM, JVM (Hotspot C2), V8 Turbofan, GCC (GIMPLE) 가 SSA.&lt;/p&gt;
&lt;h3 id=&quot;4-control-flow-graph-cfg&quot;&gt;4. Control Flow Graph (CFG)&lt;/h3&gt;
&lt;p&gt;프로그램을 &lt;strong&gt;기본 블록 (basic block)&lt;/strong&gt; 으로 나누고 분기를 간선으로:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  E[&quot;Entry&quot;] --&gt; B1[&quot;b1: x = 1&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  B1 --&gt; C{&quot;if x &gt; 0&quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  C --&gt;|true| B2[&quot;b2: y = 2&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  C --&gt;|false| B3[&quot;b3: y = 3&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  B2 --&gt; B4[&quot;b4: return y&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  B3 --&gt; B4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;기본 블록&lt;/strong&gt;: 분기 없이 순차 실행되는 명령의 최대 시퀀스.&lt;/p&gt;
&lt;p&gt;CFG 위에서 &lt;strong&gt;data flow analysis&lt;/strong&gt; 수행.&lt;/p&gt;
&lt;h3 id=&quot;5-llvm-ir&quot;&gt;5. LLVM IR&lt;/h3&gt;
&lt;p&gt;산업 표준 IR. 텍스트/바이너리 두 형식.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;llvm&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; @add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;i32&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; %a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;i32&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; %b&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;entry:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  %sum&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; %a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;%b&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  ret&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; i32&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; %sum&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Typed&lt;/strong&gt; (i32, i64, ptr)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSA&lt;/strong&gt; (기본)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Portable&lt;/strong&gt; (아키텍처 독립)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimizer + Backend 도구 풍부&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;optimization-최적화&quot;&gt;Optimization (최적화)&lt;/h2&gt;
&lt;p&gt;컴파일러의 각종 최적화 pass. 100+ 가지 존재.&lt;/p&gt;
&lt;h3 id=&quot;constant-folding&quot;&gt;Constant Folding&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = 2 + 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = 5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;컴파일 시 상수 표현 미리 계산.&lt;/p&gt;
&lt;h3 id=&quot;constant-propagation&quot;&gt;Constant Propagation&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;y = x + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;y = 6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;상수 값을 전파.&lt;/p&gt;
&lt;h3 id=&quot;dead-code-elimination&quot;&gt;Dead Code Elimination&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;y = 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;z = x + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;return z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;y&lt;/code&gt; 는 사용 안 됨 → 제거:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;x = 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;z = x + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;return z&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;common-subexpression-elimination-cse&quot;&gt;Common Subexpression Elimination (CSE)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;a = (x + y) * 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;b = (x + y) * 3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;x + y&lt;/code&gt; 중복. 한 번만 계산:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;t = x + y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;a = t * 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;b = t * 3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;function-inlining&quot;&gt;Function Inlining&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function add(a, b) { return a + b; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;result = add(1, 2);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→ (inlined)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;result = 1 + 2;  // 그 다음 constant folding → 3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;작은 함수는 호출 오버헤드 제거 + 추가 최적화 활성.&lt;/p&gt;
&lt;h3 id=&quot;loop-optimizations&quot;&gt;Loop Optimizations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Loop-invariant code motion&lt;/strong&gt;: 루프 안 불변식을 밖으로&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loop unrolling&lt;/strong&gt;: 반복 횟수 줄이고 iteration 확장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strength reduction&lt;/strong&gt;: 곱셈 → 덧셈 (&lt;code&gt;i*4&lt;/code&gt; → &lt;code&gt;i+i+i+i&lt;/code&gt; 아니 &lt;code&gt;i&amp;#x3C;&amp;#x3C;2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vectorization&lt;/strong&gt;: SIMD 명령 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;tail-call-optimization&quot;&gt;Tail Call Optimization&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function factorial(n, acc=1) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  if (n &amp;#x3C;= 1) return acc;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return factorial(n - 1, n * acc);   // tail call&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tail call = 함수 마지막 액션이 함수 호출. 스택 프레임 재사용 가능 → 무한 재귀 없이 실행.&lt;/p&gt;
&lt;p&gt;Scheme, Haskell 필수. JavaScript ES2015 스펙에는 있지만 실구현 미미.&lt;/p&gt;
&lt;h3 id=&quot;escape-analysis&quot;&gt;Escape Analysis&lt;/h3&gt;
&lt;p&gt;객체가 함수 밖으로 escape 안 하면 &lt;strong&gt;스택 할당&lt;/strong&gt; (heap 대신):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; arr&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 함수 안에서만 사용 → stack alloc 가능&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; arr[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;V8, JVM 이 활용.&lt;/p&gt;
&lt;h2 id=&quot;실행-순서-pass-manager&quot;&gt;실행 순서 (Pass Manager)&lt;/h2&gt;
&lt;p&gt;최적화들은 &lt;strong&gt;순서&lt;/strong&gt; 대로 적용. 한 최적화가 다른 것을 활성:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1. Function inlining&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2. Constant propagation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3. Dead code elimination&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4. Common subexpression elimination&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5. Loop invariant code motion&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;6. ... (반복)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 pass 는 IR 을 읽고 새 IR 을 출력. 여러 번 실행하기도 (fixed-point).&lt;/p&gt;
&lt;h2 id=&quot;code-generation&quot;&gt;Code Generation&lt;/h2&gt;
&lt;p&gt;IR → 목표 코드.&lt;/p&gt;
&lt;h3 id=&quot;register-allocation&quot;&gt;Register Allocation&lt;/h3&gt;
&lt;p&gt;CPU 는 유한한 &lt;strong&gt;레지스터&lt;/strong&gt; (예: x86-64 는 16개 일반 레지스터). IR 은 무한 가상 레지스터 사용 → 물리 레지스터에 매핑.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Graph Coloring&lt;/strong&gt;: interference graph 색칠 문제 (NP-hard, 근사).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linear Scan&lt;/strong&gt;: 빠른 근사, JIT 에 자주 사용.&lt;/p&gt;
&lt;p&gt;Spilling: 레지스터 부족 시 메모리 (stack) 로.&lt;/p&gt;
&lt;h3 id=&quot;instruction-selection&quot;&gt;Instruction Selection&lt;/h3&gt;
&lt;p&gt;IR 명령 → 실제 CPU 명령.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IR: &lt;code&gt;%c = mul %a, %b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;x86: &lt;code&gt;imul %eax, %ebx, %ecx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ARM: &lt;code&gt;MUL R0, R1, R2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tree matching&lt;/strong&gt;, &lt;strong&gt;BURS (bottom-up rewriting)&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;instruction-scheduling&quot;&gt;Instruction Scheduling&lt;/h3&gt;
&lt;p&gt;CPU 는 pipeline. 명령 순서 재배열로 stall 최소화. Superscalar 활용.&lt;/p&gt;
&lt;h3 id=&quot;peephole-optimization&quot;&gt;Peephole Optimization&lt;/h3&gt;
&lt;p&gt;작은 명령 시퀀스를 더 나은 것으로:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;MOV eax, 0    →    XOR eax, eax  (더 짧고 빠름)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;llvm-파이프라인&quot;&gt;LLVM 파이프라인&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Source (C, Rust, ...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓ (Language frontend)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;LLVM IR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓ (opt: optimization passes)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Optimized LLVM IR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓ (llc: code generation)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Assembly&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓ (as: assembler)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Object file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   ↓ (ld: linker)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Executable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 단계 도구화. 개별 실행/디버그 가능.&lt;/p&gt;
&lt;h2 id=&quot;목표-코드-종류&quot;&gt;목표 코드 종류&lt;/h2&gt;
&lt;h3 id=&quot;native-기계어&quot;&gt;Native (기계어)&lt;/h3&gt;
&lt;p&gt;CPU 아키텍처별 (x86-64, ARM64, RISC-V, …).&lt;/p&gt;
&lt;h3 id=&quot;bytecode&quot;&gt;Bytecode&lt;/h3&gt;
&lt;p&gt;VM 용 중간 코드 (JVM bytecode, .NET CIL, Python .pyc).&lt;/p&gt;
&lt;h3 id=&quot;webassembly-wasm&quot;&gt;WebAssembly (WASM)&lt;/h3&gt;
&lt;p&gt;브라우저용 저수준 VM. 여러 언어 대상 (C, C++, Rust, Go).&lt;/p&gt;
&lt;h3 id=&quot;intermediate-llvm-ir-spir-v&quot;&gt;Intermediate (LLVM IR, SPIR-V)&lt;/h3&gt;
&lt;p&gt;LLVM IR 자체를 목표로 배포 (Rust &lt;code&gt;no-std&lt;/code&gt; 라이브러리 등).&lt;/p&gt;
&lt;h3 id=&quot;transpiled-high-level&quot;&gt;Transpiled (High-level)&lt;/h3&gt;
&lt;p&gt;다른 고급 언어. TypeScript → JavaScript, Kotlin → JS.&lt;/p&gt;
&lt;h2 id=&quot;최적화의-한계&quot;&gt;최적화의 한계&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Rice’s Theorem&lt;/strong&gt; (계산 가능성 이론): 비자명한 프로그램 성질은 undecidable.&lt;/p&gt;
&lt;p&gt;즉, 컴파일러는 &lt;strong&gt;완벽한 최적화 불가&lt;/strong&gt;. 근사만 가능.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;보수적 근사&lt;/strong&gt;: “안전하지 않으면 최적화 안 함”. 옳지 않은 최적화 &gt; 아쉬운 최적화.&lt;/p&gt;
&lt;h2 id=&quot;최적화-vs-가독성&quot;&gt;최적화 vs 가독성&lt;/h2&gt;
&lt;p&gt;컴파일러가 훌륭하다면 &lt;strong&gt;가독성 우선&lt;/strong&gt;. 손으로 최적화 (loop unrolling 등) 는 대개 컴파일러가 이미 하거나 오히려 방해.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예외&lt;/strong&gt;: 알고리즘 선택 (Big-O), 데이터 구조. 이건 컴파일러가 못 함.&lt;/p&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;최적화 = 항상 빠름 은 아님&lt;/strong&gt;. Inlining 은 코드 크기 폭발. Loop unrolling 은 캐시 miss. 프로파일링 우선.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;-O0 (최적화 X)&lt;/strong&gt; 에서 잘 되던 코드가 -O3 에서 실패. UB (undefined behavior) 원인 (C/C++). Sanitizer 사용.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;JIT 는 옛 코드 무효화&lt;/strong&gt;. 가정 (타입, inline) 이 깨지면 deoptimize. 이 원인 이해가 hot path 튜닝의 핵심.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;LLVM IR 이 표준&lt;/strong&gt;. 새 언어 만들 때 backend 재발명 X. LLVM 활용.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Register allocation 이 컴파일러 성능 큰 요인&lt;/strong&gt;. JIT 는 특히 speed vs quality trade-off.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[programming-language-theory|PLT 개요]]&lt;/li&gt;
&lt;li&gt;[[plt-lexical-analysis|Lexical Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-parsing|Parsing]]&lt;/li&gt;
&lt;li&gt;[[plt-abstract-syntax-tree|AST]]&lt;/li&gt;
&lt;li&gt;[[plt-semantic-analysis|Semantic Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-type-systems|Type Systems]]&lt;/li&gt;
&lt;li&gt;[[plt-interpreter-compiler|Interpreter vs Compiler]]&lt;/li&gt;
&lt;li&gt;[[js-bundling|JS 번들링]] - 실전 컴파일러 도구&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>ir</category><category>optimization</category><category>codegen</category><category>ssa</category><category>llvm</category><author>koa (김신건)</author></item><item><title>[PLT] Lexical Analysis (어휘 분석)</title><link>https://shinkeonkim.com/wiki/plt/plt-lexical-analysis/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/plt-lexical-analysis/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;어휘 분석 (Lexical Analysis)&lt;/strong&gt; 은 소스 코드 &lt;strong&gt;문자 시퀀스&lt;/strong&gt; 를 의미 있는 최소 단위인 &lt;strong&gt;토큰 (Token)&lt;/strong&gt; 으로 분해하는 과정입니다. 담당 컴포넌트를 &lt;strong&gt;Lexer (또는 Tokenizer, Scanner)&lt;/strong&gt; 라고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;한 줄 요약&lt;/strong&gt;: 문자열을 프로그래밍 언어의 “단어” 로 자름.&lt;/p&gt;
&lt;h2 id=&quot;왜-필요한가&quot;&gt;왜 필요한가&lt;/h2&gt;
&lt;p&gt;파서가 매 문자를 다루면 매우 복잡합니다. 어휘 분석이 미리 &lt;strong&gt;의미 없는 것 (공백, 주석) 제거&lt;/strong&gt; + &lt;strong&gt;의미 있는 것 그룹핑&lt;/strong&gt; 하면 파서는 훨씬 단순.&lt;/p&gt;
&lt;h2 id=&quot;토큰-token&quot;&gt;토큰 (Token)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;의미 있는 최소 단위&lt;/strong&gt;. 예: JavaScript &lt;code&gt;let x = 42;&lt;/code&gt; 를 lex 하면:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[LET]           value: &quot;let&quot;        type: keyword&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[IDENTIFIER]    value: &quot;x&quot;          type: identifier&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[EQUAL]         value: &quot;=&quot;          type: operator&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[NUMBER]        value: &quot;42&quot;         type: literal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[SEMICOLON]     value: &quot;;&quot;          type: punct&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 토큰:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt; (Kind): 카테고리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Value / Lexeme&lt;/strong&gt;: 원본 문자열&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Location&lt;/strong&gt;: 파일/줄/열 (에러 메시지용)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;토큰-카테고리&quot;&gt;토큰 카테고리&lt;/h2&gt;
&lt;p&gt;일반적 언어의 토큰 유형:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Keyword&lt;/strong&gt;: &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;, &lt;code&gt;function&lt;/code&gt; (예약어)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identifier&lt;/strong&gt;: 변수/함수 이름 (&lt;code&gt;x&lt;/code&gt;, &lt;code&gt;myFunc&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Literal&lt;/strong&gt;: 값
&lt;ul&gt;
&lt;li&gt;Number: &lt;code&gt;42&lt;/code&gt;, &lt;code&gt;3.14&lt;/code&gt;, &lt;code&gt;0xFF&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;String: &lt;code&gt;&quot;hello&quot;&lt;/code&gt;, &lt;code&gt;&apos;world&apos;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Boolean: &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Null: &lt;code&gt;null&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operator&lt;/strong&gt;: &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;&amp;#x26;&amp;#x26;&lt;/code&gt;, &lt;code&gt;&amp;#x3C;=&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Punctuation&lt;/strong&gt;: &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;{&lt;/code&gt;, &lt;code&gt;}&lt;/code&gt;, &lt;code&gt;;&lt;/code&gt;, &lt;code&gt;,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Whitespace / Comment&lt;/strong&gt;: 대개 건너뜀 (일부 언어는 유의미)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;정규-표현식과-토큰-정의&quot;&gt;정규 표현식과 토큰 정의&lt;/h2&gt;
&lt;p&gt;각 토큰 유형은 &lt;strong&gt;정규 표현식&lt;/strong&gt; 으로 정의:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;NUMBER      = [0-9]+ (\.[0-9]+)?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;IDENTIFIER  = [a-zA-Z_][a-zA-Z0-9_]*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;KEYWORD_IF  = &quot;if&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;OPERATOR_EQ = &quot;==&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;STRING      = &quot;[^&quot;]*&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;중요&lt;/strong&gt;: 규칙 순서. &lt;code&gt;if&lt;/code&gt; 는 identifier 패턴에도 매치 → keyword 먼저 확인.&lt;/p&gt;
&lt;h2 id=&quot;longest-match-rule&quot;&gt;Longest Match Rule&lt;/h2&gt;
&lt;p&gt;여러 규칙이 매치 시 &lt;strong&gt;가장 긴 매치&lt;/strong&gt; 선택.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;== 는 [EQUAL_EQUAL] (2 문자) vs [EQUAL][EQUAL] (1 문자씩)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;→ 항상 longest = [EQUAL_EQUAL]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&amp;#x3C;=&lt;/code&gt; vs &lt;code&gt;&amp;#x3C;&lt;/code&gt;, &lt;code&gt;**&lt;/code&gt; vs &lt;code&gt;*&lt;/code&gt; 등.&lt;/p&gt;
&lt;h2 id=&quot;시각화-lexer-흐름&quot;&gt;시각화: Lexer 흐름&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  I[&quot;let x = 42;&quot;] --&gt; C[Character Stream]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  C --&gt;|read| S[State Machine]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  S --&gt;|match keyword| T1[&quot;LET&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  S --&gt;|match ident| T2[&quot;x&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  S --&gt;|match op| T3[&quot;=&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  S --&gt;|match number| T4[&quot;42&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  S --&gt;|match punct| T5[&quot;;&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;유한-오토마타-finite-automata&quot;&gt;유한 오토마타 (Finite Automata)&lt;/h2&gt;
&lt;p&gt;정규 표현식은 &lt;strong&gt;유한 상태 머신&lt;/strong&gt; 으로 구현.&lt;/p&gt;
&lt;h3 id=&quot;dfa-deterministic-finite-automaton&quot;&gt;DFA (Deterministic Finite Automaton)&lt;/h3&gt;
&lt;p&gt;각 상태에서 각 입력에 대해 &lt;strong&gt;유일한&lt;/strong&gt; 다음 상태.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: 정수 인식 DFA&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     [0-9]         [0-9]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;State 0 ─────&gt; State 1 &amp;#x3C;─┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  (start)      (accept)  │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                └────────┘&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Start (0): 첫 숫자 도착 시 State 1 로&lt;/li&gt;
&lt;li&gt;State 1 (accept): 계속 숫자 소비, 아니면 종료&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;nfa-nondeterministic-finite-automaton&quot;&gt;NFA (Nondeterministic Finite Automaton)&lt;/h3&gt;
&lt;p&gt;한 상태에서 여러 다음 상태 가능. &lt;strong&gt;정규 표현식 → NFA 는 자연스러움&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;NFA → DFA 변환 알고리즘 (subset construction) 이 존재.&lt;/p&gt;
&lt;h3 id=&quot;실전&quot;&gt;실전&lt;/h3&gt;
&lt;p&gt;컴파일러 구현 시:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;수동 구현&lt;/strong&gt;: 상태를 switch 문으로. Crafting Interpreters, 대부분 프로덕션 컴파일러.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자동 생성&lt;/strong&gt;: Lex/Flex 가 정규식 → C 코드 생성. Legacy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;대부분 현대 컴파일러는 수동 lexer&lt;/strong&gt; (에러 메시지, 성능, 유연성 이유).&lt;/p&gt;
&lt;h2 id=&quot;실전-lexer-구현-의사코드&quot;&gt;실전 Lexer 구현 (의사코드)&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function lex(source):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    tokens = []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    pos = 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    while pos &amp;#x3C; len(source):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        char = source[pos]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if char is whitespace:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            pos += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if char is &apos;/&apos; and source[pos+1] is &apos;/&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            # line comment&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            while pos &amp;#x3C; len(source) and source[pos] != &apos;\n&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                pos += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if char is digit:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            start = pos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            while pos &amp;#x3C; len(source) and source[pos] is digit:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                pos += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            tokens.append(Token(NUMBER, source[start:pos]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if char is letter or &apos;_&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            start = pos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            while pos &amp;#x3C; len(source) and (source[pos] is letter/digit/_):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                pos += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            lexeme = source[start:pos]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if lexeme in KEYWORDS:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                tokens.append(Token(KEYWORDS[lexeme], lexeme))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            else:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                tokens.append(Token(IDENTIFIER, lexeme))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if char is &apos;&quot;&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            # string literal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            pos += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            start = pos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            while pos &amp;#x3C; len(source) and source[pos] != &apos;&quot;&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                pos += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            tokens.append(Token(STRING, source[start:pos]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            pos += 1   # skip closing quote&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        if char is operator:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            # ==, !=, &amp;#x3C;=, etc.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if source[pos:pos+2] in TWO_CHAR_OPS:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                tokens.append(Token(TWO_CHAR_OPS[source[pos:pos+2]], source[pos:pos+2]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                pos += 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            else:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                tokens.append(Token(ONE_CHAR_OPS[char], char))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                pos += 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        raise LexError(f&quot;Unknown character: {char}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    tokens.append(Token(EOF, &quot;&quot;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return tokens&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;핵심 패턴&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Position pointer 로 문자열 순회&lt;/li&gt;
&lt;li&gt;각 상태별 while 로 매치&lt;/li&gt;
&lt;li&gt;Longest match 자연스럽게 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;에러-처리&quot;&gt;에러 처리&lt;/h2&gt;
&lt;p&gt;Lexer 오류:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;알 수 없는 문자&lt;/li&gt;
&lt;li&gt;종료되지 않은 문자열 (&lt;code&gt;&quot;hello&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;종료되지 않은 주석 (&lt;code&gt;/* ...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;잘못된 숫자 형식 (&lt;code&gt;3.14.15&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;전략&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;즉시 실패 (초기 예)&lt;/li&gt;
&lt;li&gt;에러 토큰 생성 후 계속 (파서에서 recovery)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;좋은 에러 메시지&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: unterminated string literal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&gt; src/main.rs:3:15&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 3 |     let x = &quot;hello&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |             ^ expected closing quote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;파일/줄/열 정보를 토큰마다 저장.&lt;/p&gt;
&lt;h2 id=&quot;special-cases&quot;&gt;Special Cases&lt;/h2&gt;
&lt;h3 id=&quot;whitespace-significant-languages&quot;&gt;Whitespace-Significant Languages&lt;/h3&gt;
&lt;p&gt;Python, Haskell, YAML 은 들여쓰기가 의미 있음. Lexer 가 &lt;strong&gt;INDENT / DEDENT 토큰&lt;/strong&gt; 생성:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;def foo():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    x = 1        ← INDENT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if x:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        y = 2    ← INDENT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    z = 3        ← DEDENT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                 ← DEDENT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;template-literals-jsts&quot;&gt;Template Literals (JS/TS)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;`hello ${name}`&lt;/code&gt; 는 lexer 가 특수 처리. 문자열 안에 표현식 삽입.&lt;/p&gt;
&lt;h3 id=&quot;다국어-지원&quot;&gt;다국어 지원&lt;/h3&gt;
&lt;p&gt;Unicode identifier. 이모지 변수 (&lt;code&gt;💰 = 100&lt;/code&gt;). 언어 스펙에 따라.&lt;/p&gt;
&lt;h2 id=&quot;유명-언어의-lexer&quot;&gt;유명 언어의 Lexer&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;: &lt;a href=&quot;https://tc39.es/ecma262/#sec-ecmascript-language-lexical-grammar&quot;&gt;ECMAScript 스펙&lt;/a&gt; 에 정의된 문법. V8, SpiderMonkey 등이 각자 구현.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt;: &lt;code&gt;tokenize&lt;/code&gt; 모듈로 노출.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt;: &lt;code&gt;rustc_lexer&lt;/code&gt; crate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;: TS 컴파일러의 scanner.ts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;도구&quot;&gt;도구&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lex / Flex&lt;/strong&gt; (C): 정규식 → C lexer. Legacy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ANTLR&lt;/strong&gt;: 파서 생성기 (lexer 포함), Java 기반.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rply, PLY&lt;/strong&gt; (Python): 옛 방식.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chumsky, Pest&lt;/strong&gt; (Rust): parser combinator.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;대부분 현대 컴파일러는 수동 lexer&lt;/strong&gt;. 유연성, 성능, 에러 메시지.&lt;/p&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Longest match&lt;/strong&gt; 잘못 구현하면 &lt;code&gt;==&lt;/code&gt; 이 &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt; 두 개로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Keyword 를 identifier 로&lt;/strong&gt;. &lt;code&gt;if&lt;/code&gt; 를 identifier 처리하면 파서가 이상해짐. Keyword 먼저 매치.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;위치 정보 저장 잊음&lt;/strong&gt;. 에러 메시지에 line/col 없으면 UX 최악.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Lookahead&lt;/strong&gt;. &lt;code&gt;==&lt;/code&gt; 인지 확인하려면 다음 문자 미리 봄. 1-2 문자 lookahead 흔함.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[programming-language-theory|PLT 개요]]&lt;/li&gt;
&lt;li&gt;[[plt-parsing|Parsing &amp;#x26; Grammars]]&lt;/li&gt;
&lt;li&gt;[[plt-abstract-syntax-tree|AST]]&lt;/li&gt;
&lt;li&gt;[[js-regex|JavaScript Regex]] - 정규식 배경&lt;/li&gt;
&lt;li&gt;[[discrete-mathematics|이산수학]] - 오토마타 이론&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>lexer</category><category>tokenizer</category><category>regex</category><category>automata</category><author>koa (김신건)</author></item><item><title>[PLT] Parsing &amp; Grammars</title><link>https://shinkeonkim.com/wiki/plt/plt-parsing/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/plt-parsing/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Parsing (구문 분석)&lt;/strong&gt; 은 lexer 의 &lt;strong&gt;토큰 스트림&lt;/strong&gt; 을 언어의 &lt;strong&gt;문법 규칙&lt;/strong&gt; 에 따라 구조화된 트리 (&lt;strong&gt;AST&lt;/strong&gt;, Abstract Syntax Tree) 로 조립하는 과정입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;토큰들이 &lt;strong&gt;어떤 구문 구조&lt;/strong&gt; 를 이루는가&lt;/li&gt;
&lt;li&gt;우선순위 (precedence): &lt;code&gt;2 + 3 * 4&lt;/code&gt; = &lt;code&gt;2 + (3 * 4)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;결합성 (associativity): &lt;code&gt;1 - 2 - 3&lt;/code&gt; = &lt;code&gt;(1 - 2) - 3&lt;/code&gt; (좌결합)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;문법-grammar&quot;&gt;문법 (Grammar)&lt;/h2&gt;
&lt;p&gt;프로그래밍 언어의 &lt;strong&gt;문법 규칙 을 형식적으로 기술&lt;/strong&gt; 하는 표기법.&lt;/p&gt;
&lt;h3 id=&quot;bnf-backus-naur-form&quot;&gt;BNF (Backus-Naur Form)&lt;/h3&gt;
&lt;p&gt;가장 기초적인 표기:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;expression&gt; ::= &amp;#x3C;term&gt; | &amp;#x3C;expression&gt; &quot;+&quot; &amp;#x3C;term&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;term&gt;       ::= &amp;#x3C;factor&gt; | &amp;#x3C;term&gt; &quot;*&quot; &amp;#x3C;factor&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;factor&gt;     ::= &amp;#x3C;number&gt; | &quot;(&quot; &amp;#x3C;expression&gt; &quot;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;number&gt;     ::= [0-9]+&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;::=&lt;/code&gt;&lt;/strong&gt;: “정의”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;|&lt;/code&gt;&lt;/strong&gt;: “또는”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;#x3C;...&gt;&lt;/code&gt;&lt;/strong&gt;: 비단말 (non-terminal, 다른 규칙 참조)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;문자열&lt;/strong&gt;: 단말 (terminal, 실제 토큰)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ebnf-extended-bnf&quot;&gt;EBNF (Extended BNF)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;?&lt;/code&gt; (선택), &lt;code&gt;*&lt;/code&gt; (0+), &lt;code&gt;+&lt;/code&gt; (1+) 확장:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;expression = term ( &quot;+&quot; term )*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;term       = factor ( &quot;*&quot; factor )*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;factor     = number | &quot;(&quot; expression &quot;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;number     = digit+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;digit      = &quot;0&quot; | &quot;1&quot; | ... | &quot;9&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;정규식 같이 간결.&lt;/p&gt;
&lt;h3 id=&quot;cfg-context-free-grammar&quot;&gt;CFG (Context-Free Grammar)&lt;/h3&gt;
&lt;p&gt;BNF/EBNF 의 이론 이름. &lt;strong&gt;문맥 자유&lt;/strong&gt; = 규칙 적용이 주변 문맥과 무관.&lt;/p&gt;
&lt;p&gt;프로그래밍 언어 대부분이 CFG (완전히는 아니고 근사).&lt;/p&gt;
&lt;h2 id=&quot;시각화-파싱&quot;&gt;시각화: 파싱&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;입력&lt;/strong&gt;: &lt;code&gt;2 + 3 * 4&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;토큰&lt;/strong&gt;: &lt;code&gt;[NUM 2] [PLUS] [NUM 3] [STAR] [NUM 4]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;파스 트리&lt;/strong&gt; (문법 규칙 따라):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                expression&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;               /    |     \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            term   &quot;+&quot;   term&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;             |            |  \  \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;           factor       factor &quot;*&quot; factor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;             |            |         |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;           NUM 2        NUM 3     NUM 4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;AST&lt;/strong&gt; (더 간결):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        +&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       / \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      2   *&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;         / \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        3   4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;AST&lt;/strong&gt; 는 파스 트리에서 불필요한 노드 (&lt;code&gt;expression&lt;/code&gt;, &lt;code&gt;term&lt;/code&gt;, &lt;code&gt;factor&lt;/code&gt; 같은 중간) 제거.&lt;/p&gt;
&lt;h2 id=&quot;ambiguity-모호성&quot;&gt;Ambiguity (모호성)&lt;/h2&gt;
&lt;p&gt;같은 입력이 여러 파스 트리를 가지면 문법이 &lt;strong&gt;모호&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: &lt;code&gt;2 + 3 * 4&lt;/code&gt; 를 아래 문법으로:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;expr ::= expr op expr | number&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;op   ::= &quot;+&quot; | &quot;*&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;두 파스 트리 가능:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(2 + 3) * 4 = 20&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2 + (3 * 4) = 14&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;해결&lt;/strong&gt;: 우선순위/결합성 반영한 문법 재작성 (위의 &lt;code&gt;expression → term → factor&lt;/code&gt; 계층).&lt;/p&gt;
&lt;h2 id=&quot;하향식-vs-상향식&quot;&gt;하향식 vs 상향식&lt;/h2&gt;
&lt;h3 id=&quot;top-down-하향식&quot;&gt;Top-Down (하향식)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Start 규칙&lt;/strong&gt; 부터 시작해 규칙 적용:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LL(k)&lt;/strong&gt;: Left-to-right, Leftmost derivation, k 토큰 lookahead&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recursive Descent&lt;/strong&gt;: 재귀 함수로 각 규칙 표현&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Predictive Parser&lt;/strong&gt;: 다음 토큰 보고 어떤 규칙 적용할지 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;bottom-up-상향식&quot;&gt;Bottom-Up (상향식)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;토큰&lt;/strong&gt; 부터 시작해 규칙으로 결합:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LR(k)&lt;/strong&gt;: Left-to-right, Rightmost derivation reversed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LALR(1)&lt;/strong&gt;: LR 축약, yacc/bison 이 채택&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SLR&lt;/strong&gt;: LR 의 단순 변종&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;recursive-descent-가장-흔한-실전-방식&quot;&gt;Recursive Descent (가장 흔한 실전 방식)&lt;/h2&gt;
&lt;p&gt;각 non-terminal 을 함수로:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function parseExpression():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    left = parseTerm()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    while peek() is &quot;+&quot;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        consume(&quot;+&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        right = parseTerm()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        left = BinaryOp(&quot;+&quot;, left, right)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return left&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function parseTerm():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    left = parseFactor()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    while peek() is &quot;*&quot;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        consume(&quot;*&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        right = parseFactor()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        left = BinaryOp(&quot;*&quot;, left, right)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return left&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function parseFactor():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if peek() is number:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        return NumberLiteral(consumeNumber())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    if peek() is &quot;(&quot;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        consume(&quot;(&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        expr = parseExpression()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        consume(&quot;)&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        return expr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    error(&quot;expected number or &apos;(&apos;&quot;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;손으로 쉽게 작성&lt;/li&gt;
&lt;li&gt;에러 메시지 세밀 제어&lt;/li&gt;
&lt;li&gt;디버깅 쉬움&lt;/li&gt;
&lt;li&gt;재귀 자연스러움&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;좌측 재귀 (&lt;code&gt;expr → expr + term&lt;/code&gt;) 처리 어려움 → while loop 로 변환&lt;/li&gt;
&lt;li&gt;문법 규모 크면 코드도 큼&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;대부분 실전 언어 (Rust, TypeScript, Go, Swift) 는 recursive descent.&lt;/p&gt;
&lt;h2 id=&quot;연산자-우선순위-pratt-parser--precedence-climbing&quot;&gt;연산자 우선순위 (Pratt Parser / Precedence Climbing)&lt;/h2&gt;
&lt;p&gt;Recursive descent 의 확장. 각 연산자에 우선순위 부여, 하나의 함수로 처리.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;function parseExpr(minPrec):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    left = parsePrimary()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    while peek() is operator and precedence(peek()) &gt;= minPrec:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        op = consume()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        rightPrec = precedence(op) + (rightAssociative(op) ? 0 : 1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        right = parseExpr(rightPrec)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        left = BinaryOp(op, left, right)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    return left&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;여러 연산자 (&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;**&lt;/code&gt;) 를 한 함수로&lt;/li&gt;
&lt;li&gt;우선순위 표 관리만 하면 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vaughan Pratt 의 원래 알고리즘. Rust, Kotlin, Swift 등에서 사용.&lt;/p&gt;
&lt;h2 id=&quot;lr-parser-자동-생성&quot;&gt;LR Parser (자동 생성)&lt;/h2&gt;
&lt;p&gt;Yacc, Bison, ANTLR 이 사용.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LR(1) 파서&lt;/strong&gt;: 상향식, 1 토큰 lookahead. 대부분 실용 문법 수용.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shift-Reduce&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Shift&lt;/strong&gt;: 다음 토큰을 스택에.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduce&lt;/strong&gt;: 스택 상단이 규칙 우변과 매치되면 좌변으로 축약.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;LALR(1)&lt;/strong&gt;: LR(1) 상태를 병합해 크기 축소. Yacc/Bison 기본.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: 어떤 CFG 든 처리, 자동 생성.
&lt;strong&gt;단점&lt;/strong&gt;: 에러 메시지 어색, 디버깅 어려움, 상태 폭발 가능.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2020년대 트렌드&lt;/strong&gt;: 파서 생성기 → 수동 recursive descent. 이유는 UX.&lt;/p&gt;
&lt;h2 id=&quot;peg-parsing-expression-grammar&quot;&gt;PEG (Parsing Expression Grammar)&lt;/h2&gt;
&lt;p&gt;CFG 대안. &lt;strong&gt;결정적 파싱&lt;/strong&gt; (모호성 없음). Ordered choice: &lt;code&gt;a | b&lt;/code&gt; 는 &lt;code&gt;a&lt;/code&gt; 먼저 시도.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Expr    &amp;#x3C;- Term (&apos;+&apos; Term)*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Term    &amp;#x3C;- Factor (&apos;*&apos; Factor)*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Factor  &amp;#x3C;- Number / &apos;(&apos; Expr &apos;)&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/&lt;/code&gt;&lt;/strong&gt;: ordered choice (좌 우선)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;#x26;&lt;/code&gt;&lt;/strong&gt;: positive lookahead&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;!&lt;/code&gt;&lt;/strong&gt;: negative lookahead&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Packrat parsing&lt;/strong&gt;: 메모이제이션으로 선형 시간. Peg 스타일 대표.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;도구&lt;/strong&gt;: Pest (Rust), TatSu (Python), PEG.js.&lt;/p&gt;
&lt;h2 id=&quot;parser-combinator&quot;&gt;Parser Combinator&lt;/h2&gt;
&lt;p&gt;파서를 값처럼 다루는 접근. Haskell 스타일:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;expr = do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  left &amp;#x3C;- term&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  rest &amp;#x3C;- many (do op &amp;#x3C;- symbol &quot;+&quot;; t &amp;#x3C;- term; return (op, t))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  return (foldl (BinaryOp) left rest)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;: 파싱 로직 조합, 언어 임베딩.
&lt;strong&gt;단점&lt;/strong&gt;: 에러 메시지, 성능.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;도구&lt;/strong&gt;: parsec (Haskell), Chumsky (Rust), nom (Rust).&lt;/p&gt;
&lt;h2 id=&quot;ast-생성&quot;&gt;AST 생성&lt;/h2&gt;
&lt;p&gt;파서의 &lt;strong&gt;출력물&lt;/strong&gt; 은 AST. 노드 예시:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Number&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Identifier&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BinaryOp&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;+&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;-&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;*&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;left&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;right&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Assignment&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;target&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;If&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;cond&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;While&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;cond&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[] }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Function&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;params&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[]; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[] }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;Call&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;callee&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ASTNode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[] }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;자세한 것은 [[plt-abstract-syntax-tree|AST]] 참조.&lt;/p&gt;
&lt;h2 id=&quot;에러-복구&quot;&gt;에러 복구&lt;/h2&gt;
&lt;p&gt;파서가 오류 만나면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Panic mode&lt;/strong&gt;: 다음 세미콜론까지 건너뜀&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phrase-level recovery&lt;/strong&gt;: 특정 토큰 삽입/삭제&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error productions&lt;/strong&gt;: 문법에 흔한 오류 규칙 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;좋은 컴파일러는 &lt;strong&gt;한 파일에 여러 오류를 함께 보고&lt;/strong&gt;. 하나 발견 후 즉시 중단 X.&lt;/p&gt;
&lt;h2 id=&quot;실전-파서-예시&quot;&gt;실전 파서 예시&lt;/h2&gt;
&lt;h3 id=&quot;typescript&quot;&gt;TypeScript&lt;/h3&gt;
&lt;p&gt;Recursive descent. &lt;code&gt;parser.ts&lt;/code&gt; 안에 각 &lt;code&gt;parseXXX&lt;/code&gt; 함수.&lt;/p&gt;
&lt;h3 id=&quot;rust&quot;&gt;Rust&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rustc_parse&lt;/code&gt; crate. Pratt 스타일 우선순위 처리.&lt;/p&gt;
&lt;h3 id=&quot;python&quot;&gt;Python&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;PEG parser&lt;/strong&gt; (Python 3.9+). 이전에는 LL(1). PEP 617 이 이관.&lt;/p&gt;
&lt;h3 id=&quot;javascript-v8-spidermonkey&quot;&gt;JavaScript (V8, SpiderMonkey)&lt;/h3&gt;
&lt;p&gt;수동 recursive descent, 성능 극도로 튜닝.&lt;/p&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;좌측 재귀&lt;/strong&gt; 는 recursive descent 에서 무한 재귀. &lt;code&gt;expr → expr + term&lt;/code&gt; 은 while loop 로 재작성.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;우선순위 오류&lt;/strong&gt;. &lt;code&gt;2 + 3 * 4&lt;/code&gt; 가 20 이 나오면 문법 재점검.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;에러 메시지 개선을 후순위로&lt;/strong&gt;. 실전에서는 좋은 에러가 언어 채택 좌우. 초기 설계부터.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Comment / trailing comma&lt;/strong&gt; 등 언어 UX. 문법 규칙에 명시 필요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;파서 생성기의 유혹&lt;/strong&gt;. 초기엔 빠르지만 유지보수 어려움. 수동 recursive descent 검토.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[programming-language-theory|PLT 개요]]&lt;/li&gt;
&lt;li&gt;[[plt-lexical-analysis|Lexical Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-abstract-syntax-tree|AST]]&lt;/li&gt;
&lt;li&gt;[[plt-semantic-analysis|Semantic Analysis]]&lt;/li&gt;
&lt;li&gt;[[discrete-mathematics|이산수학]] - CFG 이론 배경&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>parser</category><category>grammar</category><category>cfg</category><category>bnf</category><author>koa (김신건)</author></item><item><title>[PLT] Semantic Analysis (의미 분석)</title><link>https://shinkeonkim.com/wiki/plt/plt-semantic-analysis/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/plt-semantic-analysis/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Semantic Analysis (의미 분석)&lt;/strong&gt; 는 파서가 생성한 AST 를 검사하여 &lt;strong&gt;문법적으로 올바르지만 의미상 오류인 경우&lt;/strong&gt; 를 발견하고, 각 이름 (identifier) 이 무엇을 가리키는지 결정하는 단계입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;한 줄 요약&lt;/strong&gt;: “코드가 문법적으로 맞는 건 알겠는데, 말이 되나?”&lt;/p&gt;
&lt;h2 id=&quot;무엇을-검사하는가&quot;&gt;무엇을 검사하는가&lt;/h2&gt;
&lt;p&gt;파서가 통과시킨 것들:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;undefinedVar &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // 정의되지 않은 변수&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;             // 잘못된 타입 (문자열 * 숫자? 파이썬은 가능, JS 는?)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;myFunc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()                &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 함수 없음&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;     &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// const 재할당&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 42&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;              &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 함수 밖 return&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;파서는 이런 것을 발견 못 함. Semantic analyzer 가:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;이름 해석&lt;/strong&gt;: 각 identifier 가 어떤 declaration 을 가리키는지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope 규칙&lt;/strong&gt;: 어느 변수가 여기서 보이는지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;타입 검사&lt;/strong&gt;: 값의 타입이 문맥에 맞는지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컨트롤 흐름&lt;/strong&gt;: &lt;code&gt;return&lt;/code&gt; 이 함수 안에 있는지, &lt;code&gt;break&lt;/code&gt; 가 루프 안에 있는지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;접근 제어&lt;/strong&gt;: private 필드 접근 금지, immutable 재할당 금지&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;symbol-table&quot;&gt;Symbol Table&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;이름 → 정보 매핑&lt;/strong&gt;. Semantic analyzer 의 핵심 자료구조.&lt;/p&gt;
&lt;p&gt;각 심볼의 정보:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;이름&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;종류&lt;/strong&gt; (variable, function, class, module)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;타입&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;선언 위치&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;가시성&lt;/strong&gt; (scope)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;속성&lt;/strong&gt; (const, static, private)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Symbol&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  kind&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;variable&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;function&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;class&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;parameter&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  type&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  declLocation&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SourceLocation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  isConst&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; boolean&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  isExported&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; boolean&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SymbolTable&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  private&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; scopes&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Symbol&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;[] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  enterScope&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.scopes.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()); }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  exitScope&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.scopes.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;pop&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  declare&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;sym&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Symbol&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; current&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.scopes[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.scopes.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (current.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;has&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(sym.name)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      throw&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`Duplicate declaration: ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;sym&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    current.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(sym.name, sym);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  lookup&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Symbol&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; undefined&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.scopes.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.scopes[i].&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;has&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(name)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.scopes[i].&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; undefined&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;scope-범위&quot;&gt;Scope (범위)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Scope&lt;/strong&gt;: 한 이름이 유효한 코드 영역.&lt;/p&gt;
&lt;h3 id=&quot;lexical-scope-정적-스코프&quot;&gt;Lexical Scope (정적 스코프)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;소스 코드의 위치로 결정&lt;/strong&gt;. 대부분 언어 (JavaScript, Python, Rust, Java, C).&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; outer&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; inner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// ← outer 의 x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  inner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;inner&lt;/code&gt; 안의 &lt;code&gt;x&lt;/code&gt; 는 &lt;strong&gt;정의 시점의 outer&lt;/strong&gt; 를 가리킴 (lexical).&lt;/p&gt;
&lt;h3 id=&quot;dynamic-scope-동적-스코프&quot;&gt;Dynamic Scope (동적 스코프)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;호출 시점의 스택&lt;/strong&gt; 으로 결정. 초기 Lisp, Emacs Lisp, Perl &lt;code&gt;local&lt;/code&gt; 등.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;lisp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;defun&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; outer&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ((x &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) (inner)))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;defun&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; inner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x))    &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;; ← 호출한 outer 의 x&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;대부분 언어는 lexical scope. Dynamic scope 는 예측 어려워 지양.&lt;/p&gt;
&lt;h3 id=&quot;nested-scope&quot;&gt;Nested Scope&lt;/h3&gt;
&lt;p&gt;Scope 는 &lt;strong&gt;중첩&lt;/strong&gt; 가능. 안쪽 scope 가 바깥 참조 가능:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Global scope&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  └── Module scope&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        └── Function scope&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              └── Block scope&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    └── (nested block)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이름 해석: 가장 안쪽부터 바깥으로 확인.&lt;/p&gt;
&lt;h2 id=&quot;shadowing-섀도잉&quot;&gt;Shadowing (섀도잉)&lt;/h2&gt;
&lt;p&gt;내부 scope 가 외부 이름을 &lt;strong&gt;가림&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;    &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 바깥 x 를 가림&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x); &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Rust 는 shadowing 을 명시적 언어 기능&lt;/strong&gt; 으로:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 다른 타입도 가능&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python 은 함수 scope 안에서만 shadowing.&lt;/p&gt;
&lt;h2 id=&quot;이름-해석-알고리즘&quot;&gt;이름 해석 알고리즘&lt;/h2&gt;
&lt;p&gt;각 identifier 참조를 declaration 에 연결.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;resolve(node, symbolTable):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    switch node.kind:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case Identifier:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            sym = symbolTable.lookup(node.name)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if sym is None:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                error(f&quot;Undefined: {node.name}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            node.resolvedSymbol = sym&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case VariableDeclaration:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            resolve(node.init, symbolTable)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            sym = Symbol(name=node.name, type=...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            symbolTable.declare(sym)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case Block:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            symbolTable.enterScope()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            for stmt in node.statements:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                resolve(stmt, symbolTable)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            symbolTable.exitScope()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case Function:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            fn = FunctionSymbol(...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            symbolTable.declare(fn)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            symbolTable.enterScope()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            for param in node.params:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                symbolTable.declare(param)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            resolve(node.body, symbolTable)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            symbolTable.exitScope()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;hoisting-호이스팅&quot;&gt;Hoisting (호이스팅)&lt;/h2&gt;
&lt;p&gt;일부 언어 (JavaScript) 는 선언을 &lt;strong&gt;scope 상단으로 끌어올림&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;());   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// OK, 호이스팅&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; foo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(x);       &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// undefined (var 는 호이스팅되지만 값 아님)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(y);       &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// ReferenceError (let 은 TDZ)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Semantic analyzer 는 &lt;strong&gt;두 pass&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;선언 수집 pass&lt;/strong&gt;: block 전체를 훑어 선언 등록&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;참조 해석 pass&lt;/strong&gt;: 표현식의 identifier 해석&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;TypeScript, Rust 는 이 방식 (선언 순서와 무관하게 참조 가능).&lt;/p&gt;
&lt;h2 id=&quot;type-checking&quot;&gt;Type Checking&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;각 표현식의 타입&lt;/strong&gt; 을 결정하고 문맥에 맞는지 확인.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 오류: string 을 number 에&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);              &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 오류 여부는 언어 나름&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;간단한 규칙:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NumberLiteral&lt;/strong&gt;: type = number&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;StringLiteral&lt;/strong&gt;: type = string&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BinaryOp(+)&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;number + number → number&lt;/li&gt;
&lt;li&gt;string + string → string&lt;/li&gt;
&lt;li&gt;number + string → 언어별 (JS 는 coercion, Python 은 오류, Rust 는 오류)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Type inference&lt;/strong&gt; (Hindley-Milner, TypeScript, Rust): 명시 없이도 타입 추론. 자세한 것은 [[plt-type-systems|Type Systems]] 참조.&lt;/p&gt;
&lt;h2 id=&quot;control-flow-check&quot;&gt;Control Flow Check&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;return&lt;/code&gt; 이 함수 안?&lt;/li&gt;
&lt;li&gt;&lt;code&gt;break&lt;/code&gt; / &lt;code&gt;continue&lt;/code&gt; 가 loop / switch 안?&lt;/li&gt;
&lt;li&gt;모든 경로가 return 하는가? (&lt;code&gt;noImplicitReturns&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;예외 처리 (&lt;code&gt;throws&lt;/code&gt; 선언 vs actual throw)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;checkReturn(node, insideFunction=false):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    switch node.kind:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case ReturnStatement:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if not insideFunction:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                error(&quot;&apos;return&apos; outside function&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case FunctionDeclaration:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            checkReturn(node.body, insideFunction=True)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case Block:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            for stmt in node.statements:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                checkReturn(stmt, insideFunction)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;상수-검사&quot;&gt;상수 검사&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;const&lt;/code&gt; 는 재할당 금지:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;    &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 오류&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; arr&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;arr.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// OK (내부 변경, 재할당 X)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Semantic analyzer 는 &lt;code&gt;const&lt;/code&gt; 변수의 &lt;strong&gt;재할당 사이트&lt;/strong&gt; 를 검사.&lt;/p&gt;
&lt;h2 id=&quot;symbol-table-구현-전략&quot;&gt;Symbol Table 구현 전략&lt;/h2&gt;
&lt;h3 id=&quot;chained-hash-tables&quot;&gt;Chained Hash Tables&lt;/h3&gt;
&lt;p&gt;각 scope 가 별도 map, 안쪽 → 바깥 순회.&lt;/p&gt;
&lt;h3 id=&quot;flat--depth&quot;&gt;Flat + Depth&lt;/h3&gt;
&lt;p&gt;하나의 map 에 &lt;code&gt;(name, depth)&lt;/code&gt; 키. 스코프 depth 로 shadowing.&lt;/p&gt;
&lt;h3 id=&quot;persistent-immutable&quot;&gt;Persistent (Immutable)&lt;/h3&gt;
&lt;p&gt;각 scope 변화가 새 map. 함수형 언어에 자연스러움.&lt;/p&gt;
&lt;h2 id=&quot;오류-메시지-개선&quot;&gt;오류 메시지 개선&lt;/h2&gt;
&lt;p&gt;좋은 semantic error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error[E0425]: cannot find value `undefined_var` in this scope&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  --&gt; src/main.rs:5:9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 5 |     let x = undefined_var + 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |             ^^^^^^^^^^^^^ not found in this scope&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   = help: did you mean `undefined_val`?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;유사 이름 제안 (Levenshtein distance)&lt;/li&gt;
&lt;li&gt;Import 제안&lt;/li&gt;
&lt;li&gt;정의 위치 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust 컴파일러가 이 방면 최상.&lt;/p&gt;
&lt;h2 id=&quot;두-언어의-대비&quot;&gt;두 언어의 대비&lt;/h2&gt;
&lt;h3 id=&quot;javascript-동적-타입-hoisting&quot;&gt;JavaScript (동적 타입, hoisting)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;대부분 검사는 &lt;strong&gt;런타임&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;undefined_var&lt;/code&gt; 는 파싱/semantic 통과, 런타임 &lt;code&gt;ReferenceError&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Static analysis 는 ESLint, TypeScript 가 담당&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;rust-정적-타입-ownership-검사&quot;&gt;Rust (정적 타입, ownership 검사)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;매우 엄격한 semantic 분석&lt;/li&gt;
&lt;li&gt;Ownership + borrow checking (semantic 안)&lt;/li&gt;
&lt;li&gt;컴파일 오류가 대부분 실제 버그&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;semantic-analysis-결과&quot;&gt;Semantic Analysis 결과&lt;/h2&gt;
&lt;p&gt;AST 에 정보 주석 (annotated AST):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; AnnotatedIdentifier&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; extends&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Identifier&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  resolvedSymbol&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Symbol&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 이 identifier 가 가리키는 declaration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;  inferredType&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이후 단계 (IR 생성, 최적화, 코드 생성) 가 이 정보 활용.&lt;/p&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;이름 해석 순서&lt;/strong&gt; 실수. Hoisting 있는 언어는 2-pass 필요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Scope stack 관리&lt;/strong&gt;. enterScope/exitScope 짝 맞지 않으면 버그.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;좋은 에러 메시지 = 좋은 언어&lt;/strong&gt;. 초기 개발 시부터 신경.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;정적 분석은 완전 X&lt;/strong&gt;. &lt;code&gt;eval&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;, 리플렉션 있는 언어는 불가피한 undecidable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;캐시 이슈&lt;/strong&gt;. 큰 IDE 는 심볼 테이블을 지속 유지. 파일 변경 시 정확한 무효화.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[programming-language-theory|PLT 개요]]&lt;/li&gt;
&lt;li&gt;[[plt-lexical-analysis|Lexical Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-parsing|Parsing]]&lt;/li&gt;
&lt;li&gt;[[plt-abstract-syntax-tree|AST]]&lt;/li&gt;
&lt;li&gt;[[plt-type-systems|Type Systems]]&lt;/li&gt;
&lt;li&gt;[[plt-interpreter-compiler|Interpreter vs Compiler]]&lt;/li&gt;
&lt;li&gt;[[plt-ir-optimization-codegen|IR &amp;#x26; Code Gen]]&lt;/li&gt;
&lt;li&gt;[[ts-strict-mode|TypeScript Strict Mode]]&lt;/li&gt;
&lt;li&gt;[[js-lexical-environment|JavaScript Lexical Environment]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>semantic-analysis</category><category>scope</category><category>symbol-table</category><author>koa (김신건)</author></item><item><title>[PLT] Type Systems (타입 시스템)</title><link>https://shinkeonkim.com/wiki/plt/plt-type-systems/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/plt-type-systems/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;타입 시스템 (Type System)&lt;/strong&gt; 은 프로그램의 값과 표현식에 &lt;strong&gt;타입 (type)&lt;/strong&gt; 을 부여하고, 이 타입들이 규칙에 맞게 결합되는지 검증하는 형식 체계입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;타입 = 값의 집합 + 그 값들에 정의된 연산&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;number&lt;/code&gt;: 수의 집합 + 산술 연산&lt;/li&gt;
&lt;li&gt;&lt;code&gt;string&lt;/code&gt;: 문자열 + 결합/추출&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Array&amp;#x3C;T&gt;&lt;/code&gt;: T의 배열 + push/pop 등&lt;/li&gt;
&lt;li&gt;&lt;code&gt;() =&gt; number&lt;/code&gt;: 인자 없이 number 반환하는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;목적&lt;/strong&gt;: 특정 종류의 오류를 컴파일 시 (또는 런타임 시) 방지.&lt;/p&gt;
&lt;h2 id=&quot;왜-타입-시스템인가&quot;&gt;왜 타입 시스템인가&lt;/h2&gt;
&lt;h3 id=&quot;방지하는-오류&quot;&gt;방지하는 오류&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&quot;hello&quot; + 3&lt;/code&gt; (문자열/숫자 혼합, 언어별)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;null.foo&lt;/code&gt; (null 참조)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;array[100]&lt;/code&gt; (index out of bounds)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;divideByZero(10, 0)&lt;/code&gt; (0 나눗셈)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Map&amp;#x3C;string, number&gt;&lt;/code&gt; 에 boolean 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;얻는-이익&quot;&gt;얻는 이익&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문서화&lt;/strong&gt;: 함수 시그니처로 사용법 명시&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자동완성&lt;/strong&gt;: IDE 가 타입 기반 제안&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;리팩터링 안전성&lt;/strong&gt;: rename, extract method&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;성능&lt;/strong&gt;: 컴파일러가 최적화 (JIT 는 타입 추측)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;정적-vs-동적&quot;&gt;정적 vs 동적&lt;/h2&gt;
&lt;h3 id=&quot;static-typing-정적-타이핑&quot;&gt;Static Typing (정적 타이핑)&lt;/h3&gt;
&lt;p&gt;컴파일 시 타입 검사.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: TypeScript, Rust, Java, C++, Haskell, Go, Kotlin&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; a &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 컴파일 오류&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;오류 조기 발견&lt;/li&gt;
&lt;li&gt;리팩터링 안전&lt;/li&gt;
&lt;li&gt;컴파일러 최적화 여지&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;프로토타이핑 느림&lt;/li&gt;
&lt;li&gt;표현력 제약 (극한 케이스)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;dynamic-typing-동적-타이핑&quot;&gt;Dynamic Typing (동적 타이핑)&lt;/h3&gt;
&lt;p&gt;런타임 시 타입 검사.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;: Python, JavaScript (기본), Ruby, PHP, Lua, Clojure&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; a &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; b;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// &quot;hello1&quot; (JS 자동 변환)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;장점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;유연성, 빠른 프로토타이핑&lt;/li&gt;
&lt;li&gt;메타프로그래밍 자연스러움&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;단점&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;런타임 오류&lt;/li&gt;
&lt;li&gt;IDE 지원 부족&lt;/li&gt;
&lt;li&gt;대규모 코드베이스에서 유지보수 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;strong-vs-weak&quot;&gt;Strong vs Weak&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Strong Typing&lt;/strong&gt;: 타입을 엄격히 지킴. 자동 변환 최소.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python: &lt;code&gt;&quot;hello&quot; + 3&lt;/code&gt; → TypeError&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Weak Typing&lt;/strong&gt;: 자유로운 자동 변환.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JavaScript: &lt;code&gt;&quot;hello&quot; + 3&lt;/code&gt; → &lt;code&gt;&quot;hello3&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PHP: &lt;code&gt;&quot;1&quot; == 1&lt;/code&gt; → true&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Strong&lt;/strong&gt; vs &lt;strong&gt;Weak&lt;/strong&gt; 은 스펙트럼. Static 인지 동적인지와 무관.&lt;/p&gt;
&lt;h2 id=&quot;type-checking&quot;&gt;Type Checking&lt;/h2&gt;
&lt;h3 id=&quot;nominal-typing&quot;&gt;Nominal Typing&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;이름 기반&lt;/strong&gt;. 두 타입이 같은 이름을 가지면 호환.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Cat&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { String name; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Dog&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { String name; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Cat c &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Cat&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Dog d &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; c;   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Java: 오류 (다른 이름)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C++, Java, C# 대표.&lt;/p&gt;
&lt;h3 id=&quot;structural-typing&quot;&gt;Structural Typing&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;구조 기반&lt;/strong&gt;. 같은 shape 이면 호환.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Named&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Cat&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; n&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Named&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Cat&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// TypeScript: OK (구조 같음)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TypeScript, Go, OCaml 대표.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Duck typing&lt;/strong&gt; = “오리처럼 걷고 꽥꽥 하면 오리” = structural typing 의 dynamic 버전.&lt;/p&gt;
&lt;h3 id=&quot;trade-offs&quot;&gt;Trade-offs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nominal&lt;/strong&gt;: 명확한 의도. 실수로 호환 불가.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structural&lt;/strong&gt;: 유연. Boilerplate 감소.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;type-inference&quot;&gt;Type Inference&lt;/h2&gt;
&lt;p&gt;명시 없이 컴파일러가 타입 추론.&lt;/p&gt;
&lt;h3 id=&quot;local-지역-추론&quot;&gt;Local (지역 추론)&lt;/h3&gt;
&lt;p&gt;변수 초기값에서 타입 결정:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 42&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;         &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// number&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; s &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;hello&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;    &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// string&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C++ (auto), Java (var), C# (var), Swift, Go (&lt;code&gt;:=&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&quot;global-전역-추론-hindley-milner&quot;&gt;Global (전역 추론): Hindley-Milner&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;함수 시그니처도 추론&lt;/strong&gt;. Haskell, ML, OCaml, Elm.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;haskell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;add x y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;-- 추론: add :: Num a =&gt; a -&gt; a -&gt; a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;컴파일러가 사용 문맥으로부터 타입 방정식 세우고 통합 (unification).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Damas-Milner 알고리즘&lt;/strong&gt;: 다항 시간 안에 principal type 결정.&lt;/p&gt;
&lt;h3 id=&quot;typescript--rust&quot;&gt;TypeScript / Rust&lt;/h3&gt;
&lt;p&gt;지역 추론 + contextual typing. 완전한 Hindley-Milner 는 아니지만 실용적.&lt;/p&gt;
&lt;h2 id=&quot;sound-vs-unsound&quot;&gt;Sound vs Unsound&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sound 타입 시스템&lt;/strong&gt;: 컴파일 통과한 프로그램은 런타임에 타입 오류 없음.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unsound&lt;/strong&gt;: 통과해도 런타임 오류 가능.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Haskell, Rust, OCaml&lt;/strong&gt;: sound (거의)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java, C#&lt;/strong&gt;: sound (array covariance 등 예외)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;: &lt;strong&gt;의도적으로 unsound&lt;/strong&gt;. 실용성 우선.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// TypeScript 는 unsound 인 예&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; arr&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; anyArr&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; any&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;[] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; arr;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;anyArr.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 컴파일 OK&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;arr[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toFixed&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);        &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 런타임 오류&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TypeScript 는 “developer productivity” 우선. 100% soundness 는 실전 부담.&lt;/p&gt;
&lt;h2 id=&quot;주요-타입-시스템-개념&quot;&gt;주요 타입 시스템 개념&lt;/h2&gt;
&lt;h3 id=&quot;union--intersection&quot;&gt;Union / Intersection&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Union&lt;/strong&gt; (&lt;code&gt;A | B&lt;/code&gt;): A 또는 B&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intersection&lt;/strong&gt; (&lt;code&gt;A &amp;#x26; B&lt;/code&gt;): A 이고 B&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;자세한 것은 [[ts-union-intersection|TypeScript Union/Intersection]] 참조.&lt;/p&gt;
&lt;h3 id=&quot;generics-parametric-polymorphism&quot;&gt;Generics (Parametric Polymorphism)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;타입 매개변수&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; identity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; T&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; x; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Java &lt;code&gt;&amp;#x3C;T&gt;&lt;/code&gt;, C++ &lt;code&gt;template&amp;#x3C;T&gt;&lt;/code&gt;, Haskell &lt;code&gt;forall a&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;subtyping&quot;&gt;Subtyping&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Dog extends Animal&lt;/code&gt; → &lt;code&gt;Dog&lt;/code&gt; 는 &lt;code&gt;Animal&lt;/code&gt; 의 subtype. Liskov Substitution.&lt;/p&gt;
&lt;h3 id=&quot;variance&quot;&gt;Variance&lt;/h3&gt;
&lt;p&gt;Generic 안 subtype 관계:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Covariant&lt;/strong&gt; (&lt;code&gt;out T&lt;/code&gt;): &lt;code&gt;List&amp;#x3C;Dog&gt;&lt;/code&gt; → &lt;code&gt;List&amp;#x3C;Animal&gt;&lt;/code&gt; OK&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contravariant&lt;/strong&gt; (&lt;code&gt;in T&lt;/code&gt;): &lt;code&gt;Consumer&amp;#x3C;Animal&gt;&lt;/code&gt; → &lt;code&gt;Consumer&amp;#x3C;Dog&gt;&lt;/code&gt; OK&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invariant&lt;/strong&gt;: 관계 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;higher-rank--higher-kinded-types&quot;&gt;Higher-Rank / Higher-Kinded Types&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HKT&lt;/strong&gt;: 타입 생성자를 타입 매개변수로. &lt;code&gt;Functor&amp;#x3C;F&gt;&lt;/code&gt;. Haskell, Scala.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rank-N&lt;/strong&gt;: 함수 인자로 다형 함수. Rust &lt;code&gt;for&amp;#x3C;&apos;a&gt; ...&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;dependent-types&quot;&gt;Dependent Types&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;값이 타입을 결정&lt;/strong&gt;. &lt;code&gt;Vector&amp;#x3C;N: nat&gt;&lt;/code&gt; (길이 N의 벡터).&lt;/p&gt;
&lt;p&gt;Idris, Agda, Coq, Lean, F*. 형식 증명.&lt;/p&gt;
&lt;h3 id=&quot;refinement-types&quot;&gt;Refinement Types&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;서브셋 타입&lt;/strong&gt;. &lt;code&gt;PositiveInt = { x: int | x &gt; 0 }&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;LiquidHaskell, F*.&lt;/p&gt;
&lt;h2 id=&quot;type-erasure-vs-reified&quot;&gt;Type Erasure vs Reified&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Type Erasure&lt;/strong&gt;: 컴파일 후 타입 사라짐. Java generics, TypeScript.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reified&lt;/strong&gt;: 런타임에 타입 유지. C#, Kotlin (&lt;code&gt;reified&lt;/code&gt;), Rust (monomorphization).&lt;/p&gt;
&lt;h2 id=&quot;gradual-typing&quot;&gt;Gradual Typing&lt;/h2&gt;
&lt;p&gt;정적 + 동적 혼합. &lt;code&gt;any&lt;/code&gt; 타입으로 escape.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;예&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;: JavaScript 위에 점진 도입&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python + mypy / TypeScript-like&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PHP with type hints&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sorbet (Ruby)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flow&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;프로덕션 코드베이스에 실용적.&lt;/p&gt;
&lt;h2 id=&quot;언어별-특징&quot;&gt;언어별 특징&lt;/h2&gt;
&lt;h3 id=&quot;typescript&quot;&gt;TypeScript&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;구조 타이핑 + 강력한 추론&lt;/li&gt;
&lt;li&gt;Union / intersection / mapped / conditional&lt;/li&gt;
&lt;li&gt;Unsound (intentionally)&lt;/li&gt;
&lt;li&gt;자세한 것은 [[typescript|TypeScript]] 참조&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;rust&quot;&gt;Rust&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sound, ownership + lifetimes&lt;/li&gt;
&lt;li&gt;Trait 기반 (Haskell type class 스타일)&lt;/li&gt;
&lt;li&gt;Monomorphization (reified)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;haskell&quot;&gt;Haskell&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hindley-Milner 완전 추론&lt;/li&gt;
&lt;li&gt;타입 클래스 (ad-hoc polymorphism)&lt;/li&gt;
&lt;li&gt;Pure (side effect 도 타입 안)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;java&quot;&gt;Java&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Nominal, subtyping&lt;/li&gt;
&lt;li&gt;Erased generics&lt;/li&gt;
&lt;li&gt;Wildcard variance&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;python&quot;&gt;Python&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;동적 + gradual (typing module, mypy)&lt;/li&gt;
&lt;li&gt;Duck typing&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;type-safe-programming-팁&quot;&gt;Type-safe Programming 팁&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;any&lt;/code&gt; 최소화&lt;/strong&gt; (TypeScript, Python)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Discriminated union&lt;/strong&gt; 활용 (Rust &lt;code&gt;enum&lt;/code&gt;, TS union)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exhaustive matching&lt;/strong&gt; (compiler 가 case 누락 감지)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NewType 패턴&lt;/strong&gt;: &lt;code&gt;UserId&lt;/code&gt; vs &lt;code&gt;ProductId&lt;/code&gt; (branded types)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Immutability by default&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;실전-튜토리얼&quot;&gt;실전 튜토리얼&lt;/h2&gt;
&lt;h3 id=&quot;간단한-타입-검사기-의사코드&quot;&gt;간단한 타입 검사기 (의사코드)&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;check(expr, env):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    switch expr.kind:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case NumberLiteral: return NumberType&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case StringLiteral: return StringType&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case BooleanLiteral: return BoolType&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case Identifier:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if sym in env: return sym.type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            error(f&quot;Undefined: {expr.name}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case BinaryOp:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            lt = check(expr.left, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            rt = check(expr.right, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if expr.op in [&apos;+&apos;, &apos;-&apos;, &apos;*&apos;, &apos;/&apos;]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                if lt == NumberType and rt == NumberType:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    return NumberType&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                error(f&quot;Type mismatch: {lt} {expr.op} {rt}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if expr.op in [&apos;==&apos;, &apos;&amp;#x3C;&apos;, &apos;&gt;&apos;]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                if lt == rt:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    return BoolType&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                error(...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case IfExpr:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            ct = check(expr.cond, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if ct != BoolType: error(&quot;if condition must be bool&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            tt = check(expr.then, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            et = check(expr.else, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if tt != et: error(&quot;if branches must have same type&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            return tt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        case FunctionCall:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            ft = check(expr.callee, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            if not isinstance(ft, FunctionType):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                error(&quot;Not callable&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            for arg, paramType in zip(expr.args, ft.paramTypes):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                argType = check(arg, env)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                if not isAssignable(argType, paramType):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                    error(...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            return ft.returnType&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;TypeScript 는 sound 아님&lt;/strong&gt;. 100% 타입 안전을 가정하면 런타임 오류.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Type inference 함정&lt;/strong&gt;. &lt;code&gt;let x = []&lt;/code&gt; 는 &lt;code&gt;never[]&lt;/code&gt; 로 추론. 명시 필요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;Structural typing 실수&lt;/strong&gt;. 우연히 같은 shape 이면 호환 → branded types 로 방어.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;Type-driven development&lt;/strong&gt;. 타입을 먼저 정의하고 구현. Haskell / Rust 방식.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;동적 언어에 억지 타입&lt;/strong&gt;. Python 은 mypy 로 좋아지지만, 원래 동적으로 짜인 라이브러리는 타입 부착 어려움.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[programming-language-theory|PLT 개요]]&lt;/li&gt;
&lt;li&gt;[[plt-semantic-analysis|Semantic Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-abstract-syntax-tree|AST]]&lt;/li&gt;
&lt;li&gt;[[typescript|TypeScript]]&lt;/li&gt;
&lt;li&gt;[[ts-generics|TypeScript Generics]]&lt;/li&gt;
&lt;li&gt;[[ts-union-intersection|Union/Intersection]]&lt;/li&gt;
&lt;li&gt;[[ts-strict-mode|TypeScript Strict Mode]]&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>types</category><category>type-system</category><category>type-checking</category><category>inference</category><author>koa (김신건)</author></item><item><title>프로그래밍 언어론 (Programming Language Theory)</title><link>https://shinkeonkim.com/wiki/plt/programming-language-theory/</link><guid isPermaLink="true">https://shinkeonkim.com/wiki/plt/programming-language-theory/</guid><pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;정의&quot;&gt;정의&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;프로그래밍 언어론 (Programming Language Theory, PLT)&lt;/strong&gt; 은 프로그래밍 언어를 &lt;strong&gt;어떻게 설계하고, 정의하고, 처리하는가&lt;/strong&gt; 를 다루는 컴퓨터 과학 분야입니다.&lt;/p&gt;
&lt;p&gt;크게 두 갈래:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;언어 설계 (Language Design)&lt;/strong&gt;: 문법, 의미론, 타입 시스템&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;언어 구현 (Language Implementation)&lt;/strong&gt;: 어휘 분석, 파싱, 의미 분석, 최적화, 코드 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;컴퓨터가 소스 코드를 이해하고 실행하는 &lt;strong&gt;모든 단계&lt;/strong&gt; 를 이론적으로 뒷받침합니다.&lt;/p&gt;
&lt;h2 id=&quot;왜-배워야-하는가&quot;&gt;왜 배워야 하는가&lt;/h2&gt;
&lt;p&gt;프로그래머는 매일 언어를 사용합니다. 하지만 이 언어가 &lt;strong&gt;어떻게 작동하는지&lt;/strong&gt; 이해하지 않으면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컴파일 오류 메시지 해석 어려움&lt;/li&gt;
&lt;li&gt;타입 시스템의 제약 이유를 모름&lt;/li&gt;
&lt;li&gt;왜 특정 코드가 느린지 (컴파일러 최적화 이슈)&lt;/li&gt;
&lt;li&gt;새 언어를 배울 때 표면적 문법만 익힘&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PLT 를 알면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;디버깅 능력 향상&lt;/strong&gt;: “왜 이 오류가?”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;성능 튜닝&lt;/strong&gt;: 컴파일러가 뭘 최적화하고 뭘 못 하는지&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DSL 구축&lt;/strong&gt;: 자체 언어 만들 수 있음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정적 분석 도구 개발&lt;/strong&gt;: 린터, 포매터, 리팩터링 도구&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;언어 선택 판단&lt;/strong&gt;: Rust vs Go 의 근본 차이&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;언어-처리기의-큰-그림&quot;&gt;언어 처리기의 큰 그림&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;컴파일러/인터프리터&lt;/strong&gt; 는 소스 코드를 다음 파이프라인으로 처리합니다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart LR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Src[&quot;Source Code&amp;#x3C;br/&gt;(text)&quot;] --&gt; Lex[&quot;Lexer&amp;#x3C;br/&gt;(Tokenizer)&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Lex --&gt;|Tokens| Par[&quot;Parser&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Par --&gt;|AST| Sem[&quot;Semantic&amp;#x3C;br/&gt;Analyzer&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Sem --&gt;|Annotated AST| IR[&quot;IR Generator&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  IR --&gt;|IR| Opt[&quot;Optimizer&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Opt --&gt;|Optimized IR| CG[&quot;Code Generator&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  CG --&gt; Out[&quot;Target Code&amp;#x3C;br/&gt;(machine / bytecode)&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각 단계:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Lexer&lt;/strong&gt;: 문자열을 &lt;strong&gt;토큰&lt;/strong&gt; (의미 있는 최소 단위) 으로 분해&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parser&lt;/strong&gt;: 토큰을 &lt;strong&gt;AST (Abstract Syntax Tree)&lt;/strong&gt; 로 조립&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Semantic Analyzer&lt;/strong&gt;: 이름 해석, 타입 검사, scope 결정&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IR Generator&lt;/strong&gt;: 플랫폼 독립 중간 표현&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimizer&lt;/strong&gt;: 성능 개선 (죽은 코드 제거, 인라인 등)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code Generator&lt;/strong&gt;: 목표 (x86 어셈블리, JVM 바이트코드, WASM 등)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;frontend-vs-backend&quot;&gt;Frontend vs Backend&lt;/h2&gt;
&lt;p&gt;전통적으로 컴파일러를 두 부분으로 나눔:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Frontend&lt;/strong&gt;: Source → AST → IR (&lt;strong&gt;언어 의존&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backend&lt;/strong&gt;: IR → Target Code (&lt;strong&gt;하드웨어 의존&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;LLVM&lt;/strong&gt; 은 이 분리를 극한으로: 각 언어는 LLVM IR 을 생성만 하면, LLVM 이 x86, ARM, WASM, RISC-V 등 다양한 백엔드 지원.&lt;/p&gt;
&lt;h2 id=&quot;compiler-vs-interpreter&quot;&gt;Compiler vs Interpreter&lt;/h2&gt;
&lt;p&gt;두 접근법이 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;컴파일러&lt;/strong&gt;: 소스 → 목표 코드 (실행 파일). 한 번 컴파일, 여러 번 실행.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인터프리터&lt;/strong&gt;: 소스 → 즉시 실행. AST 를 순회하며 실행.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;혼합&lt;/strong&gt; (Modern):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JIT (Just-In-Time)&lt;/strong&gt;: 실행 중 자주 쓰이는 부분만 컴파일 (V8, HotSpot, LuaJIT, PyPy)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AOT (Ahead-Of-Time)&lt;/strong&gt;: 사전 컴파일 (Java native image, Rust)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bytecode + VM&lt;/strong&gt;: 중간 형태 (JVM, .NET, CPython)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;자세한 것은 [[plt-interpreter-compiler|Interpreter vs Compiler]] 참조.&lt;/p&gt;
&lt;h2 id=&quot;주요-학습-주제&quot;&gt;주요 학습 주제&lt;/h2&gt;
&lt;p&gt;이 코스가 다루는 순서:&lt;/p&gt;
&lt;h3 id=&quot;1-lexical-analysis-어휘-분석&quot;&gt;1. Lexical Analysis (어휘 분석)&lt;/h3&gt;
&lt;p&gt;문자열을 &lt;strong&gt;토큰&lt;/strong&gt; 으로 분해. 정규 표현식, 유한 오토마타 (DFA/NFA).&lt;/p&gt;
&lt;p&gt;→ [[plt-lexical-analysis|Lexical Analysis]]&lt;/p&gt;
&lt;h3 id=&quot;2-parsing-구문-분석&quot;&gt;2. Parsing (구문 분석)&lt;/h3&gt;
&lt;p&gt;토큰을 &lt;strong&gt;문법 규칙 (grammar)&lt;/strong&gt; 에 따라 AST 로. Top-down (LL, recursive descent) vs Bottom-up (LR, LALR).&lt;/p&gt;
&lt;p&gt;→ [[plt-parsing|Parsing &amp;#x26; Grammars]]&lt;/p&gt;
&lt;h3 id=&quot;3-abstract-syntax-tree&quot;&gt;3. Abstract Syntax Tree&lt;/h3&gt;
&lt;p&gt;프로그램의 &lt;strong&gt;본질 구조&lt;/strong&gt; 를 트리로. 코드 → AST → 실행/변환/분석.&lt;/p&gt;
&lt;p&gt;→ [[plt-abstract-syntax-tree|AST]]&lt;/p&gt;
&lt;h3 id=&quot;4-semantic-analysis&quot;&gt;4. Semantic Analysis&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;이름 해석, scope, 타입 검사&lt;/strong&gt;. AST 의 각 노드에 “무엇을 가리키는지” 주석.&lt;/p&gt;
&lt;p&gt;→ [[plt-semantic-analysis|Semantic Analysis]]&lt;/p&gt;
&lt;h3 id=&quot;5-type-systems&quot;&gt;5. Type Systems&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;정적 vs 동적, sound vs unsound, 타입 추론&lt;/strong&gt;. 언어 안전성의 근간.&lt;/p&gt;
&lt;p&gt;→ [[plt-type-systems|Type Systems]]&lt;/p&gt;
&lt;h3 id=&quot;6-interpreter-vs-compiler&quot;&gt;6. Interpreter vs Compiler&lt;/h3&gt;
&lt;p&gt;두 실행 모델의 근본 차이. 각 접근법의 트레이드오프.&lt;/p&gt;
&lt;p&gt;→ [[plt-interpreter-compiler|Interpreter vs Compiler]]&lt;/p&gt;
&lt;h3 id=&quot;7-ir--최적화--코드-생성&quot;&gt;7. IR + 최적화 + 코드 생성&lt;/h3&gt;
&lt;p&gt;컴파일러 &lt;strong&gt;백엔드&lt;/strong&gt;. 3-address code, SSA, dead code elimination, register allocation.&lt;/p&gt;
&lt;p&gt;→ [[plt-ir-optimization-codegen|IR, 최적화, 코드 생성]]&lt;/p&gt;
&lt;h2 id=&quot;이론-vs-실전&quot;&gt;이론 vs 실전&lt;/h2&gt;
&lt;p&gt;이 코스는 &lt;strong&gt;실전 언어 구현&lt;/strong&gt; 관점. 하지만 배경 이론도 관련:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;형식 언어 이론&lt;/strong&gt;: Chomsky 위계 (Regular, CFG, CSG, Recursive)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;오토마타 이론&lt;/strong&gt;: DFA, NFA, PDA, Turing Machine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;람다 계산법&lt;/strong&gt;: 함수형 언어 근본&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;타입 이론&lt;/strong&gt;: Hindley-Milner, System F, Dependent Types&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;의미론 (Semantics)&lt;/strong&gt;: Operational, Denotational, Axiomatic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이론에 관심 있으면 &lt;strong&gt;Pierce, Types and Programming Languages&lt;/strong&gt; 부터.&lt;/p&gt;
&lt;h2 id=&quot;형식-언어-계층-chomsky-hierarchy&quot;&gt;형식 언어 계층 (Chomsky Hierarchy)&lt;/h2&gt;
&lt;p&gt;프로그래밍 언어의 이론적 토대는 &lt;strong&gt;Chomsky 위계&lt;/strong&gt; 다. 계층마다 표현력과 인식 오토마타가 다르다.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;mermaid&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;flowchart BT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RE[&quot;Type 3: 정규 언어&amp;#x3C;br/&gt;DFA / NFA / 정규식&amp;#x3C;br/&gt;어휘 분석 (Lexer) 에 사용&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CFL[&quot;Type 2: 문맥 자유 언어 CFL&amp;#x3C;br/&gt;Push-Down Automata&amp;#x3C;br/&gt;대부분의 프로그래밍 언어 문법&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CSL[&quot;Type 1: 문맥 의존 언어&amp;#x3C;br/&gt;선형 유한 오토마타 LBA&amp;#x3C;br/&gt;자연어 일부&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RE0[&quot;Type 0: 귀납적 열거 언어&amp;#x3C;br/&gt;Turing Machine&amp;#x3C;br/&gt;계산 가능한 모든 언어&quot;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    RE --&gt;|&quot;부분집합&quot;| CFL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CFL --&gt;|&quot;부분집합&quot;| CSL&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    CSL --&gt;|&quot;부분집합&quot;| RE0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;실전 연관:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;어휘 분석&lt;/strong&gt;: 정규 언어 (Type 3). 정규식이나 DFA 로 토큰 인식.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;구문 분석&lt;/strong&gt;: 문맥 자유 언어 (Type 2). LL, LR 파서가 CFG 를 처리.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;의미 분석&lt;/strong&gt;: CFG 를 벗어난 규칙 (같은 타입 변수 선언 등) 은 별도 통과.&lt;/li&gt;
&lt;li&gt;C++ / Rust 의 일부 구문은 CFG 의 표현 한계를 벗어나 파서가 의미 정보를 참조.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;파서-기법-선택&quot;&gt;파서 기법 선택&lt;/h2&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;기법&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;방향&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;사용 예&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;LL(1)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Top-down&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;예측 파싱, 왼쪽 재귀 금지&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;교육용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Recursive Descent&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Top-down&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;손으로 작성, 에러 메시지 우수&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Rust, Go, TypeScript&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;LALR(1)&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Bottom-up&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;파서 생성기 (yacc/bison)&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;구형 컴파일러&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Pratt Parser&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Top-down&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;중위 연산자 우선순위 처리 탁월&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;실전 언어 구현&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;PEG / Packrat&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Top-down&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;백트래킹, 결정적&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;pest, PEGN&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;현대 컴파일러 (Clang, Rust, Go, TypeScript) 는 대부분 &lt;strong&gt;hand-written recursive descent&lt;/strong&gt; 채택. 에러 메시지 품질과 IDE 지원 (incremental parsing) 때문.&lt;/p&gt;
&lt;h2 id=&quot;명작-자료&quot;&gt;명작 자료&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Crafting Interpreters&lt;/strong&gt; (Robert Nystrom, 무료 웹): 실전 인터프리터 구현. &lt;strong&gt;최고 입문서&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dragon Book&lt;/strong&gt; (Aho et al.): 정통 교과서. 두꺼움.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Engineering a Compiler&lt;/strong&gt; (Cooper &amp;#x26; Torczon): 현대 관점.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Programming Language Pragmatics&lt;/strong&gt; (Scott): 언어 설계 관점.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TAPL&lt;/strong&gt; (Pierce): 타입 이론.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PLAI&lt;/strong&gt; (Krishnamurthi, 무료 온라인): 함수형 관점.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;실전-언어-만들기&quot;&gt;실전 언어 만들기&lt;/h2&gt;
&lt;p&gt;이 코스를 마치면 다음 프로젝트를 스스로 할 수 있어야:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;작은 인터프리터&lt;/strong&gt; (calculator, Lisp subset)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;트리 순회 인터프리터&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;바이트코드 VM&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;간단한 컴파일러&lt;/strong&gt; (자체 문법 → LLVM IR 또는 C)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DSL&lt;/strong&gt; (config 언어, query 언어)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정적 분석 도구&lt;/strong&gt; (린터, 포매터)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;컴퓨터-과학-응용&quot;&gt;컴퓨터 과학 응용&lt;/h2&gt;
&lt;p&gt;PLT 지식이 쓰이는 곳:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;컴파일러 / 트랜스파일러&lt;/strong&gt;: gcc, clang, Babel, TypeScript, SWC&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인터프리터&lt;/strong&gt;: Python, Ruby, Lua&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VM&lt;/strong&gt;: JVM, V8, .NET CLR&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JIT&lt;/strong&gt;: V8 TurboFan, LLVM ORC, PyPy, LuaJIT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정적 분석&lt;/strong&gt;: ESLint, mypy, Clippy, Sonar&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IDE&lt;/strong&gt;: Language Server Protocol, 자동완성, 리팩터링&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DSL&lt;/strong&gt;: SQL, GraphQL, HTML, CSS, regex&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;템플릿 엔진&lt;/strong&gt;: Handlebars, Jinja2&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;쿼리 옵티마이저&lt;/strong&gt;: SQL query planner&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;정규식 엔진&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;암호화 회로&lt;/strong&gt;: 형식 검증&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI&lt;/strong&gt;: 코드 생성 LLM 이 AST 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;실전-도구와-언어-처리기&quot;&gt;실전 도구와 언어 처리기&lt;/h2&gt;
&lt;p&gt;PLT 지식이 직접 들어가는 실전 도구 분류:&lt;/p&gt;













































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;도구 / 프레임워크&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;언어&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;관련 PLT 개념&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Babel / SWC&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;JS&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;AST 변환 트랜스파일러&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;TypeScript&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;TS&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;타입 시스템, 타입 추론, 타입 체킹&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;ESLint / Clippy&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;JS / Rust&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;정적 분석, 패턴 매칭 on AST&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;LLVM&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다언어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;IR, 최적화 패스, 코드 생성&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Tree-sitter&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다언어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;증분 파서, IDE 심볼 추출&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;ANTLR&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;다언어&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;LL(*) 파서 생성기&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Cranelift&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Rust&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;JIT 백엔드 (Wasmtime, Cranelift)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;babel-ast-변환-예시&quot;&gt;Babel AST 변환 예시&lt;/h3&gt;
&lt;p&gt;JSX 를 일반 JS 함수 호출로 변환하는 것이 Babel 트랜스파일의 핵심:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// 입력 (JSX)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;!-- mdx-component: Button --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Click&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// AST 변환 후 출력&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;React.createElement(Button, { onClick: fn }, &quot;Click&quot;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Babel 은:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;소스를 파싱 → AST (parser: &lt;code&gt;@babel/parser&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;플러그인 체인에서 AST visitor 로 노드 변환&lt;/li&gt;
&lt;li&gt;변환된 AST → 코드 생성 (&lt;code&gt;@babel/generator&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 파이프라인이 PLT 컴파일러 프론트엔드와 완전히 동일한 구조다.&lt;/p&gt;
&lt;h3 id=&quot;오토마타와-실전-연결&quot;&gt;오토마타와 실전 연결&lt;/h3&gt;





















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;오토마타&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;실전&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;DFA&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Lexer 토큰 인식, 정규식 엔진&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;PDA&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;CFG 파서 (LL, LR)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;Turing Machine&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;범용 계산, 정지 문제&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Lex (flex) 는 정규식 → DFA 변환으로 빠른 lexer 생성. Yacc/bison 은 LALR(1) 파서 테이블 생성.&lt;/p&gt;
&lt;h2 id=&quot;함정&quot;&gt;함정&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;이론만 배우고 구현 안 하면 잊음&lt;/strong&gt;. 반드시 작은 언어를 직접 구현해봐야.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
&lt;strong&gt;Dragon Book 부터 시작하면 좌절&lt;/strong&gt;. 두껍고 오래됨. Crafting Interpreters 로 시작.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
&lt;strong&gt;파서 생성기 만능 아님&lt;/strong&gt;. yacc/bison 이 옛 관용, 요즘은 hand-written recursive descent 가 더 흔함 (에러 메시지 우수).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;최신 언어는 표준 파이프라인을 따르지 않음&lt;/strong&gt;. Rust 는 여러 pass, Swift 는 별도 SIL, Go 는 매우 단순. 원리 이해 후 각 언어 특성.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;관련-위키&quot;&gt;관련 위키&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[plt-lexical-analysis|Lexical Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-parsing|Parsing &amp;#x26; Grammars]]&lt;/li&gt;
&lt;li&gt;[[plt-abstract-syntax-tree|Abstract Syntax Tree]]&lt;/li&gt;
&lt;li&gt;[[plt-semantic-analysis|Semantic Analysis]]&lt;/li&gt;
&lt;li&gt;[[plt-type-systems|Type Systems]]&lt;/li&gt;
&lt;li&gt;[[plt-interpreter-compiler|Interpreter vs Compiler]]&lt;/li&gt;
&lt;li&gt;[[plt-ir-optimization-codegen|IR, 최적화, 코드 생성]]&lt;/li&gt;
&lt;li&gt;[[discrete-mathematics|이산수학]] - 형식 언어 기초&lt;/li&gt;
&lt;li&gt;[[typescript|TypeScript]] - 실전 타입 시스템&lt;/li&gt;
&lt;li&gt;[[js-bundling|JS 번들링]] - 컴파일러 실전&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>plt</category><category>compiler</category><category>language</category><category>foundations</category><category>computer-science</category><author>koa (김신건)</author></item></channel></rss>