abstract syntax semantic analyze

49
Abstract Syntax & Semantic Analyze 박박박

Upload: chun92

Post on 15-Apr-2017

69 views

Category:

Science


10 download

TRANSCRIPT

Page 1: Abstract syntax semantic analyze

Abstract Syntax & Semantic Analyze박현준

Page 2: Abstract syntax semantic analyze

목차1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 3: Abstract syntax semantic analyze

컴파일러• 프로그래밍 언어를 목적 언어로 변환하는 과정

SourceCode Lexer

Parser

Semantic Analyzer

IntermediateCode Generator

Code Optimizer

Code GeneratorTargetCode

Token Stream

Parse Tree

Abstract Syntax Tree

Intermediate Representation (IR)

Optimized IR

Page 4: Abstract syntax semantic analyze

목적• 추상 구문 (Abstract Syntax) 과 추상 구문 트리 (Abstract Syntax

Tree, AST) 의 생성 방법에 대해 학습한다• 의미 해석 (Semantic Analysis) 에 대해서 학습한다• 변수 참조의 해결• 타입 참조의 해결• 타입 정의의 체크• 식의 타당성 체크• 타입 체크

Page 5: Abstract syntax semantic analyze

1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 6: Abstract syntax semantic analyze

Parse Tree

- 4 + 6 * 8

MINUS INT(4) PLUS INT(6) TIMES INT(8)

exp

expMINUS

PLUSexp exp

exp TIMESexp

INT(4) INT(6) INT(8)

Source Code

Token Stream

Parse Tree

LEXER

PARSER

Page 7: Abstract syntax semantic analyze

Parse Tree• 파싱 규칙 (Parsing Rule) 에 따라 소스코드를 파싱한 결과• 문맥 (Syntax) 규칙만 있을 뿐 의미 (Semantic) 규칙이 없음• 소스코드 구문 분석 친화적 <-> 목적코드 생성에 불리함

exp

expMINUS

PLUSexp exp

exp TIMESexp

INT(4) INT(6) INT(8)

Parsing Treeexp 의 코드 생성을 위해다른 노드도 확인

Page 8: Abstract syntax semantic analyze

Abstract Syntax Tree• 의미 규칙 (Semantic Rule) 의 모음• 의미 규칙 하나가 목적코드 생성과 바로 연결됨• 목적코드 생성을 위한 의미 해석 (Semantic Analysis) 에 유리

AddExp

MinusExp MultExp

INT(4) INT(6) INT(8)

Abstract Syntax Treeexp

expMINUS

PLUSexp exp

exp TIMESexp

INT(4) INT(6) INT(8)

Parsing Tree

Page 9: Abstract syntax semantic analyze

Parse Tree -> AST

Parsing Ruleprog -> ( stmt )

stmt -> stmt ; stmtstmt -> ID = expr

expr -> expr + exprexpr -> IDexpr -> NUM

Parsing Target( a = 4 ; b = a + 5 )

prog

stmt( )

stmt stmt;

ID(“a”) = expr ID(“b”)

NUM(4)

expr

ID(“5”)

=

ID(“a”) +

Parse Tree

Page 10: Abstract syntax semantic analyze

Parse Tree -> AST

Parsing Ruleprog -> ( stmt )

stmt -> stmt ; stmtstmt -> ID = expr

expr -> expr + exprexpr -> IDexpr -> NUM

Semantic RuleProgram = {CompoundStmt}

CompoundStmt = {AssignStmt list}AssignStmt = {DataId, Expr}

Expr -> {DataId | Int | AddExpr}AddExpr = {Expr, Expr}

Page 11: Abstract syntax semantic analyze

Parse Tree -> AST

prog

stmt( )

stmt stmt;

ID(“a”) = expr ID(“b”)

NUM(4)

expr

ID(“5”)

=

ID(“a”) +

Program

CompoundStmt

AssignStmt AssignStmt

DataId(“a”) AddExprDataId(“b”)

Int(5)DataId(“a”)

Int(4)

Parse Tree AST

의미 분석 필요Parsing Target( a = 4 ; b = a + 5 )

Page 12: Abstract syntax semantic analyze

1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 13: Abstract syntax semantic analyze

AST 생성 방법론• 파싱 과정에서 직접 생성• 완성된 파스트리에서 생성

Page 14: Abstract syntax semantic analyze

AST 생성• Parser 에서 파싱과정에서 생성• 파싱과정에서 추가적인 의미 동작 (Semantic Action) 을 수행하여 AST 를 생성

%token INT PLUS MINUS TIMES UMINUSunion {int num; string id;}%token <num> INT$token <id> ID$type <num> exp

%start exp

%left PLUS MINUS%left TIMES%left UMINUS%%

exp : INT {$$ = new Int($1);} | exp PLUS exp {$$ = new Plus($1, $3);} | exp MINUS exp {$$ = new Minus($1, $3);} | exp TIMES exp {$$ = new MultiplyExp($1, $3);} | MINUS exp %prec UMINS {$$ = new MinusExp($2)}

Page 15: Abstract syntax semantic analyze

AST 생성• 파스 트리를 순회하면서 생성 , 패턴에 따라서 Visitor 방식과

Listener 방식으로 구분• Visitor 방식 : 각각의 Node 가 하위 Node 를 방문하는 함수를 직접 호출하는 형식

• Listener 방식 : 파스 트리를 탐사하면서 각 노드마다 방문 , 탈출하는 함수가 호출됨

visit(ProgCtx ctx) { return new Program(visit(ctx.stmt()));}

visit(StmtCtx ctx) {…}

enter(ProgCtx ctx) { currentProgram = new Program();}exit(ProgCtx ctx) { …}

Page 16: Abstract syntax semantic analyze

Visitor 패턴prog

stmt( )

stmt stmt;

ID(“a”) = expr ID(“b”)

NUM(4)

expr

ID(“5”)

=

ID(“a”) +

Program

CompoundStmt

AssignStmt AssignStmt

DataId(“a”) AddExprDataId(“b”)

Int(5)DataId(“a”)

Int(4)

Parse Tree AST2

3

45

6

7

89

1011

1

2

1

3

4 5, 6

7

8 9

10 11

visit(ProgCtx ctx) { return new Program(visit(ctx.stmt()));}

12

Page 17: Abstract syntax semantic analyze

Listener 패턴prog

stmt( )

stmt stmt;

ID(“a”) = expr ID(“b”)

NUM(4)

expr

ID(“5”)

=

ID(“a”) +

Parse Tree1

23

4 28 2930

31StmtList stmtList;

enter(ProgCtx ctx) { currentProgram = new Program(); stmtList = new StmtList();}exit(ProgCtx ctx) { program->setStmtList(stmtList);}…

1

31

Page 18: Abstract syntax semantic analyze

Visitor VS. Listener• Visitor 패턴• 상위 노드가 하위 노드의 결과값에 접근할 수 있다 .• 필요한 노드만 선택적으로 방문할 수 있다 .

• Listener 패턴• Global Context 를 계속 유지하기 때문에 여러 노드의 정보를 혼합하기에 유리하다 .• 모든 노드에 방문하는 것이 보장된다 .

Page 19: Abstract syntax semantic analyze

1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 20: Abstract syntax semantic analyze

Semantic Analysis• 추상 구문에서 코드를 생성하기 위해 필요한 의미를 분석• 언어의 특성마다 의미 분석의 범주가 달라짐

• C 계열 언어의 경우• 변수 참조의 해결• 타입 참조의 해결• 타입 정의의 체크• 식의 타당성 체크• 타입 체크• …

• 의미 분석의 결과는 추상 구문 트리에 정보를 추가한 형태

변수 참조의 해결 타입 참조의 해결타입 정의의 체크

식의 타당성 체크타입 체크

Page 21: Abstract syntax semantic analyze

언어학적 비유• 언어 해석에서 문장이 가지는 의미해석과 유사• Joon is hungry. He wants to eat something.• ( 고유 명사 ) (be 동사 ) ( 형용사 ) ( 대명사 ) ( 동사 )

(to 부정사 ) ( 명사 )

• 문장 1: ( 고유 명사 ) (be 동사 ) ( 형용사 )• 문장 2: ( 대명사 ) ( 동사 ) (to 부정사 ) ( 명사 )

• 대명사 He 는 Joon 을 가리킨다• Joon 과 He 는 남자 타입을 갖는다• 문장 2 의 wants 는 to 부정사를 목적어로 갖는다• He 가 가리키는 대상이 여자 타입인지 확인한다

변수 참조의 해결타입 참조의 해결식의 타당성 체크

타입 체크

Lexing

Parsing

Page 22: Abstract syntax semantic analyze

Semantic Analysis 개요Program

CompoundStmt

AssignStmt AssignStmt

DataId(“a”) AddExprDataId(“b”)

Int(5)DataId(“a”)

Int(4)

AST

Parsing Target( a = 4 ; b = a + 5 )

Program

CompoundStmt

AssignStmt (Type O)AssignStmt(Type O)

DataId(“a”) Id:a

type:int

AddExprtype:int

DataId(“b”)Id:b

type:int

Int(5)type:int

DataId(“a”)Id:a

type:int

Int(4)type:int

AST’

Page 23: Abstract syntax semantic analyze

1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 24: Abstract syntax semantic analyze

변수 참조 해결• 변수• 정의 (definition) 와 사용 (use) 은 연결되어 있어야 함• 변수 이름을 기준으로 연결 (Binding)• 예 )

• int x = 3;• Int y = x + 1;

• 변수의 생명 기한 (life time) 과 범위 (Scope) 에 따라서 변수 해결 규칙이 달라짐• 예 )

• int sum = 0;• for(int i = 0; i < 10; ++i) {• sum += i;• }• printf (“%d\n”, i);

Binding

Page 25: Abstract syntax semantic analyze

Symbol Table• 소스 코드 상에서 정의되는 이름 (Symbol) 의 모음• 범위 (Scope) 마다 이름을 저장하며 트리 형태로 구성• 연결 리스트 , 해쉬 테이블 등을 이용하여 표현

Global Scope

main Scope func Scope

if1 Scope else1 Scope if2 Scope

int global_a, global_b;

int main () { int main_a; if (main_a > 10) { int if_a; } else { int else_a; }}

int func() { int global_a; if (global_a > 10) { int if_a; }}

global_aglobal_b

main_a

if_a else_a if_a

global_a

Page 26: Abstract syntax semantic analyze

Symbol Table 구현• 해쉬 테이블 (Hash Table) 구현 예제• 해쉬 함수 : 특정 키 값을 바탕으로 한정된 값을 가리키는 함수• 예 ) hash(x) = x mod 10

0 1 n-1

b -> int

a -> int

c -> float d -> int

void main() { int a = 1; int b = 2; float c = 3.4; int d = a + b;

for(int i = 1; i < a; ++i) { float a = 1.0; c += a; }}

main scope

0 1 n-1

a -> float i -> int

for scope

Page 27: Abstract syntax semantic analyze

Scope in OOP• C++ Scope• Local scope : 함수나 구문 블록에서 선언하여 해당 블록에서만 보임• Class scope : 클래스 멤버들에게 보임

• Public: 같은 Namespace scope 에서 보임• Private: 클래스 멤버에게만 보임

• Namespace scope : 이름공간 블록에서 보임• Using: 다른 Namespace 의 이름을 볼 수 있음

• File scope : 파일 내에서 보임• Include: 다른 파일의 이름을 볼 수 있음

• Global scope : 프로그램 전체에서 보임• Java 접근제어자• Public, Protected, Default, Private

Page 28: Abstract syntax semantic analyze

1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 29: Abstract syntax semantic analyze

Type• 데이터 타입• 데이터가 갖는 값의 의미적인 해석 방법에 따른 분류• 예 ) 0x65, char type -> ‘A’, int type-> ’0x65’

• 타입의 구성• 기본타입

• Integer• Floating point/Fixed point• String• Boolean

• 복합타입• Pointer• Structure, Class• Array, List, Map, …• Polymorphism, Generic, …• Function

Page 30: Abstract syntax semantic analyze

Type• 타입 시스템• 데이터 , 표현식이 갖는 타입에 대한 규칙 정의의 모음• 예 )

• (int) + (int) -> (int), (float) + (float) -> (float)• int main(int argc, char** argv) : (int), (char**) -> (int)

• 타입 규칙에 맞지 않은 타입의 식이 들어오면 문제가 발생

• 해야 할 일• 타입 참조의 해결• 타입 정의의 체크• 식의 타당성 체크• 타입 체크

변수 참조의 해결 타입 참조의 해결타입 정의의 체크

식의 타당성 체크타입 체크

Page 31: Abstract syntax semantic analyze

타입 참조의 해결• 타입에 대한 정의를 해결• 함수 , 구조체 , 클래스 , typedef 정의 시 새로운 복합타입이 정의타입 규칙에 추가• 예 )

• int main(int argc, char** argv);• struct 2dPoint {

int x; int y;};

• typedef list<2dPoint> PointList;

• 타입에 대한 참조를 해결• 변수 선언 시 , 변수의 정의에 대해 타입 해결• 예 )

• int a, float b, 2dPoint X;

Page 32: Abstract syntax semantic analyze

타입 정의의 체크• 복합타입의 정의가 올바르게 일어났는지 체크• C 언어의 경우• Void 를 포함한 배열 , 구조체 , 공용체

• void[3]• 타입 정의의 중복

• struct point { .. };struct point { .. };

• 정의가 순환되는 구조체 , 공용체• struct point_x {

struct point_y;};

typedef struct point_x my_point_x;

struct point_y { my_point_x x;};

sturct point_x

sturct point_y my_point_x

Page 33: Abstract syntax semantic analyze

식의 타당성 체크• 문법 (Parsing Rule) 상으로는 문제가 없으나 값을 구할 수 없는 식에 대한 오류를 체크한다 .• 대입할 수 없는 식에 대입

• 예 : 1= 2+2• 함수가 아닌 값을 사용한 함수 호출

• 예 : “string”(“%d\n”, i)• 피연산자가 적합하지 않은 배열 참조

• 예 : 1[0]• 피연산자가 적합하지 않은 멤버 참조

• 예 : 1.memb• 피연산자가 적합하지 않은 포인터 간접 멤버 창조

• 예 : 1->memb• 포인터가 아닌 값의 역참조

• 예 : *1• Lvalue 가 아닌 식의 주소 획득

• 예 : &1

Page 34: Abstract syntax semantic analyze

Lvalue 와 Rvalue• 표현식은 Lvalue 와 Rvalue 로 구분• Lvalue: 이름이 있는 개체 , const 변수를 비롯한 모든 변수• Rvalue: Rvalue 를 사용하는 식 외에서는 유지되지 않는 임시 값

https://msdn.microsoft.com/ko-kr/library/f90831hc.aspx

Page 35: Abstract syntax semantic analyze

1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 36: Abstract syntax semantic analyze

타입 체크• 타입 규칙에 따라 표현 , 구문 등이 올바른 타입을 가지고 있는지 검증• 예 ) C 언어의 타입 규칙 중 일부

• 타입 체크 방법론• 정적 타입 체크• 타입 유추

http://www.cs.arizona.edu/~debray/Teaching/CSc453/DOCS/cminusminusspec.html

Page 37: Abstract syntax semantic analyze

정적 타입 체크• Visitor 패턴을 이용하여 최하위 노드부터 타입을 확정하고 상위 표현 식의 타입을 결정 (Bottom Up 방식 )

Parsing Target( int a = 4 ; int b = a + 5 )

Program

CompoundStmt

AssignStmt AssignStmt

DataId(“a”) Id:a

type:int

AddExprDataId(“b”)Id:b

type:int

Int(5)type:int

DataId(“a”)Id:a

type:int

Int(4)type:int AddExpr 의 두 Operand 는 타입이 같아야 하며 AddExpr 의 타입은 두 Operand 의 타입이 됨

Þ 첫 번째 Operand 는 int type ( 타입 해결에서 결정됨 )Þ 두 번째 Operand 는 int type ( 타입 해결에서 결정됨 )Þ 따라서 AddExpr 은 타입 체크를 통과하며 int type 을 가짐

AssignStmt 의 두 Operand 는 타입이 같아야 함Þ 첫 번째 Operand 는 int type ( 타입 해결에서 결정됨 )Þ 두 번째 Operand 는 아직 타입이 정해지지 않음 (Ad-

dExpr 의 타입체크를 중도에 호출 )

Page 38: Abstract syntax semantic analyze

암묵적 형변환• 타입 체크 중에 타입이 불일치하지만 상위 타입으로 변환이 가능한 경우 암묵적 형변환

http://www.tutorialspoint.com/cprogramming/c_type_casting.htm

Parsing Target( int a = 4 ; float b = a + 5 )

Program

CompoundStmt

AssignStmt

DataId(“a”) Id:a

type:int

AddExprtype:int

DataId(“b”)Id:b

type:float

Int(5)type:int

DataId(“a”)Id:a

type:int

Int(4)type:int

AssignStmt

CastExprtype:float

Page 39: Abstract syntax semantic analyze

타입 유추• 표현이 어떤 타입을 가지고 있는지 추론 (Top Down 방식 )

• “ 결론”이 성립하면 “가정”도 성립할 것 .

• 예 : 1+a 의 타입추론• 결론 : 1+a 가 int type 을 갖는다• 가정 1: 1 이 int type 을 갖는다• 가정 2: a 가 int type 을 갖는다

• 타입에 대한 명세가 적은 언어 (Javascript, Lisp 등 ..) 에서 유용

Page 40: Abstract syntax semantic analyze

타입 유추 표기문장 : ⊢ e1: int ⊢ (Expr) : (Type)

( 결론 )

( 가정 1) ( 가정 2) … ( 가정 n)명제 :

⊢ e1 + e2: int

⊢ e1: int ⊢ e2: int

• Numeric

• Add

• Assign

expr -> NUMexpr -> expr + exprexpr -> id = expr ⊢ NUM: int

⊢ e1 + e2: int

⊢ e1: int ⊢ e2: int

⊢ 1 + 2: int

⊢ 1: int ⊢ 2: int1 + 2

⊢ id = e: int->int

⊢ id: int ⊢ e: int

Page 41: Abstract syntax semantic analyze

타입 유추 예제• 변수 ?

• 타입의 환경 𝑥 𝑖𝑠 𝑎 𝑣𝑎𝑟𝑖𝑎𝑏𝑙e

⊢ 𝑥: ?

Γ[𝑥: ] : T𝑇 ⊢ 𝑥function test() {

var a = 1;

var b = a + 2;

}

[a: int] ⊢ a: int ⊢ a = 1: int->int

⊢ 1: int

[a: int] ⊢ a: int

[a: int] ⊢ a + 2: int

⊢ 2: int

[a: int, b: int] ⊢ b: int

[a: int] ⊢ b = a + 2: int->int

[a: float] ⊢ a: float ⊢ a = 1: float->float

⊢ 1: int

Page 42: Abstract syntax semantic analyze

Intermediate Code Generation

SourceCode Lexer

Parser

Semantic Analyzer

IntermediateCode Generator

Code Optimizer

Code GeneratorTargetCode

Token Stream

Parse Tree

Abstract Syntax Tree

Intermediate Representation (IR)

Optimized IR

Page 43: Abstract syntax semantic analyze

정리• 파스 트리로 부터 추상 구문 트리를 생성• 추상 구문 트리는 의미 규칙의 모음• 의미 해석에 유용• 트리 탐색은 Visitor 패턴과 Listener 패턴

• 의미 해석• 변수 참조의 해결• 타입 참조

• 타입 참조 , 정의의 해결• 타입 정의의 체크

• 식의 타당성 체크• Lvalue, Rvalue

• 타입 체크• 정적 타입 체크• 타입 유추

Page 44: Abstract syntax semantic analyze

1. 개요2. Abstract Syntax

1. AST 정의2. AST 생성

3. Semantic Analysis1. 변수 참조의 해결2. 타입 참조의 해결3. 타입 정의의 체크4. 식의 타당성 체크5. 타입 체크4. Appendix: Type

Page 45: Abstract syntax semantic analyze

타입 체크• 타입 체크 관점에 따른 분류• 정적 / 동적 타입 체크• 강한 / 약한 타입 시스템• 타입 안전성 , 메모리 안전성

Page 46: Abstract syntax semantic analyze

정적 / 동적 타입 체크• 정적 타입 체크• 컴파일 타임에 일어나는 타입 체크• 컴파일시 타입 체크

• 동적 타입 체크 및 런타임 타입 정보• 런타임에 일어나는 타입 체크• Runtime Type Information(RTTI) 를 이용하여 추가적인 정보

• Dynamic Dispatch, Late binding• Downcasting• Reflection

• Duck Typing 지원• 정적 , 동적 복합 타입 체크• 정적 타입 체크 + 동적 타입 체크에 대한 지원• 예 ) C++ 의 dynamic_cast, java 의 instanceOf

Page 47: Abstract syntax semantic analyze

Duck Typing• 실행 타임에 호출하는 함수에 대해 타입과 관련하여 정보를 확인하여 있으면 실행을 , 없으면 런타임 에러를 생성• 상속없이 다형성을 지원

function calculate(a, b, c) => return (a + b)*c

example1 = calculate (1, 2, 3)example2 = calculate ([1], [2, 3], 2)example3 = calculate ('apples ', 'and oranges, ', 3)

print to_string example1print to_string example2print to_string example3

9[1, 2, 3, 1, 2, 3]apples and oranges, apples and oranges, apples and oranges,

Page 48: Abstract syntax semantic analyze

강한 / 약한 타입 시스템• 강한 타입• 타입에 대하여 명확히 명시하여 선언 , 사용• 타입 변환 (Casting) 에 대해서 명시적 사용• Java, C

• 약한 타입• 타입 변환에 대해서 암묵적 사용• 타입에 대한 선언이 없음 ( 내부적인 타입 시스템만 동작 )• 타입에 대한 추론 (Type punning) 을 내부적으로 수행• Javascript, Python

Page 49: Abstract syntax semantic analyze

타입 안전성 , 메모리 안전성• 타입 안전성 (Type Safety)• 타입 시스템의 타입 규칙과 형변환 규칙에 의거하여 프로그램이 완전성 (Completeness) 과 안전함 (Soundness) 를 보장• 타입 안전성을 보장하는 언어는 타입 이론 (Type Theory) 과 타입 추론 (Type Inference) 에 의해 타입 안정성을 증명 가능• 가령 ,

• C 는 unsigned int 에서 pointer 로의 강제 형변환 등을 지원함에 따라 타입 시스템이 프로그램의 안전성을 보장하지 않음 .• Java 는 Primitive Type 과 Reference Type 의 구분으로 타입 안전성을 강제하도록 언어가 디자인 됨 .• ArrayList<int> X• ArrayList<Integer> O

• 메모리 안전성 (Memory Safety)• 메모리 참조가 타입에 의해 안전한지 보장• C 의 포인터 , 배열 참조는 메모리 안전성을 보장하지 않음