제4장 블록 및 유효범위 Reading Chap. 5 © 숙대 창병모
4.1 변수 선언 및 유효범위 © 숙대 창병모
변수 선언과 유효범위 변수 선언 변수의 유효범위(scope) 정적 유효범위(Static scope) 규칙 Declaration before Use ! 대부분의 언어에서 변수는 사용 전에 먼저 선언해야 한다. 변수의 유효범위(scope) 선언된 변수가 유효한(사용될 수 있는) 프로그램 내의 범위/영역 변수 이름뿐 아니라 함수 등 다른 이름도 생각해야 한다. 정적 유효범위(Static scope) 규칙 선언된 이름은 선언된 블록 내에서만 유효함 대부분 언어에서 표준 규칙으로 사용됨 © 숙대 창병모
변수 선언 Syntax S … T int | bool | let T x = E in S {;S} end Semantics 변수 x는 T 타입이다. 변수 x의 유효범위는 선언된 블록 내이다. Syntactic sugar let D1,D2 in S end let D1 in let D2 in S end © 숙대 창병모
변수 선언 Example in S Example in C let int x = 1 in x = x + 1 end Example in C { int x = 1; x = x + 1; } © 숙대 창병모
변수의 의미(시맨틱스) 대입문 변수 x의 의미 x = E; 예를 들어 x = x + 1; V[x]s = s(x) 메모리 위치에 저장된 값(r-value) (s, x = E) s[x ↦[E]s] 메모리 위치(l-value) © 숙대 창병모
중첩 블록 Example in C Example in S let int x = 2 in let int y = 3 in x = y + 2 end Example in C { int x = 2; { int y = 3; x = y+2; } new variables declared in nested blocks outer block global variable inner block local variable © 숙대 창병모
블록(Blocks) Pascal C, C++, Java Ada ML procedure or function { . . . } { . . . } Ada declare . . . begin … end ML let … in … end © 숙대 창병모
같은 이름의 변수 같은 이름의 변수가 여러 개 선언될 수 있다. Example let int x = 1 in let int y = 2 in x = x + y end; let int x = 5 in x = x + 1 x = x * 2 end Example in C { int x = 1; { int y = 2; x = x + y; } { int x = 5; x = x + 1; x = x * 2; © 숙대 창병모
시맨틱스 수식 혹은 문장의 의미 파악 각 변수의 바인딩 정보 컴파일러/인터프리터 실행 현재 유효한 변수들에 대한 바인딩 정보가 필요하다. 같은 이름의 변수가 여러 개 있을 수도 있다. 각 변수의 바인딩 정보 변수의 선언된 타입 변수의 유효범위 변수의 위치 컴파일러/인터프리터 번역/해석을 위해서 변수의 바인딩 정보 유지 관리 실행 실행을 위해서 변수 값을 저장하기 위한 메모리(memory) 관리 © 숙대 창병모
4.2 함수 및 유효범위 규칙 © 숙대 창병모
함수 선언 S … Syntax Semantics Example | let fun T1 f(T2 x) : S in S {;S} end | return E | f(E) Semantics 이름 f는 선언된 블록 내에서만 유효하다. 이름 f는 정의된 함수를 나타낸다. Example let int y = 0, fun int square(int x) : return x * x in y = square(5) end © 숙대 창병모
함수의 시맨틱스 수식 혹은 문장의 의미 파악 함수의 바인딩 정보 컴파일러/인터프리터 현재 유효한 함수들에 대한 바인딩 정보가 필요하다. 함수의 바인딩 정보 함수의 선언된 타입 함수의 유효범위 함수의 코드 위치 컴파일러/인터프리터 번역/해석을 위해서 함수의 바인딩 정보도 유지 관리 © 숙대 창병모
선언의 유효범위 선언된 식별자(이름)의 유효범위(scope) 정적 유효범위(static scope) 규칙 선언된 이름이 유효한(사용 가능한) 프로그램의 범위 혹은 영역 변수 이름뿐 아니라 함수 이름 등도 생각해야 한다. 정적 유효범위(static scope) 규칙 선언된 이름은 선언된 블록 내에서만 유효함 대부분 언어에서 표준 규칙으로 사용됨 동적 유효범위(dynamic scope) 선언된 이름은 선언된 블록의 실행이 끝날 때까지 유효함 실행 경로에 따라 유효범위가 달라질 수 있다. Old Lisp와 SNOBOL에서 사용됨 © 숙대 창병모
Example 2 정적 유효범위 규칙 동적 유효범위 규칙 0 let int x = 0 in 1 let fun int addsq(int y) : x = x + y * y in 2 let int x = 2 in 3 addsq(5) 4 end 5 end 6 end 정적 유효범위 규칙 동적 유효범위 규칙 © 숙대 창병모
4.3 바인딩 정보 유지/관리 © 숙대 창병모
왜 바인딩 정보를 관리 ? 유효한 이름(식별자) 컴파일러/인터프리터 프로그램 각 지점에서 유효한 이름들은 다르다. 프로그램을 한 줄씩 읽으면서 번역/해석한다. 프로그램의 각 지점에서 유효한 이름들에 대한 정보가 있어야 번역/해석할 수 있다. 따라서 프로그램 각 지점에서 유효한 이름들에 대한 정보를 유지 관리해야 한다. © 숙대 창병모
바인딩 유지 관리 다음 블록을 살펴보자 아이디어 let int x = 2 in let int y = 3 in x = y + 2 end 아이디어 블록 시작 선언된 변수들의 바인딩 정보를 유지한다. 문장 바인딩 정보를 이용해서 문장들을 컴파일/인터프리터 한다. 블록 끝 선언된 변수들은 더 이상 유효하지 않으므로 바인딩 정보를 제거한다. © 숙대 창병모
Example 0 let int x = 0 in 1 let fun int addsq(int y) : x = x + y * y in 2 let int x = 2 in 3 addsq(5) 4 end 5 end 6 end 변수 이름뿐만 아니라 함수 이름의 바인딩 정보도 유지/관리해야 한다. © 숙대 창병모
바인딩 유지 관리 심볼 테이블(Symbol Table) 심볼 테이블 유지/관리 현재 유효한 바인딩 정보를 유지/관리하기 위한 자료 구조 환경(environment)라고도 한다. 심볼 테이블 유지/관리 컴파일러 컴파일 하기 위해 바인딩 정보 유지/관리 인터프리터 해석해서 실행하기 위해 바인딩 정보 유지/관리 © 숙대 창병모
블록 구조를 위한 심볼 테이블 스택 형태로 유지 관리 블록 시작 블록의 끝 블록 내의 선언을 처리한다. 선언된 이름의 바인딩 정보를 심볼 테이블에 추가한다. 블록의 끝 블록 내의 선언의 바인딩 정보를 제거한다. 더 이상 필요 없다. © 숙대 창병모
예 symtable[] let int x = 1 in let int y = 2 in x = x + y end; token val lexptr ID ID 5 2 ID 1 … lexemes[] x \0 y \0 x \0 x \0 © 숙대 창병모
HW #3 let 블록을 포함한 언어 S에 대한 인터프리터 작성 Syntax S … T int | bool 심볼 테이블 관리 Syntax S … | let T id = E {,T id = E} in S {;S} end T int | bool Semantics 변수 id는 T 타입이다. 변수 id의 유효범위는 선언된 블록 내이다. © 숙대 창병모
4.4 Case Study © 숙대 창병모
다른 언어에서 선언 및 유효범위 무엇을 선언하는가? 어디에 선언하는가? 어떻게 선언하는가? 상수, 변수, 함수, 클래스 블록 내 혹은 밖 구조체(struct) 클래스 어떻게 선언하는가? 명시적 선언: Pascal, C, C++, Java, … 묵시적 선언: Lisp, partly in FORTRAN © 숙대 창병모
블록 구조 언어 블록의 중첩을 허용하는 언어 Algol, Pascal, Modula, Ada, C, ... A B D C © 숙대 창병모
C의 블록 int x; double y; void p (void) { int x = 2; /* p의 블록 */ … { int y = 3; /* 또 하나의 중첩 블록 */ x = y + 2; } © 숙대 창병모
Ada 블록 declare x:integer; y: boolean; begin x := 2; y := true; x := x+1; … end © 숙대 창병모
Pascal의 블록 program ex; (* main 프로그램 *) var x: integer; (* 전역 선언 *) procedure p; (* 전역 선언 *) var y: boolean; (* p 내의 선언 *) begin if x = 2 then begin … end; end; begin (* main *) (* 선언할 수 없음 *) … end. (* 프로그램 *) © 숙대 창병모
클래스 내의 선언 public class IntWithGcd { private int value; /* value 필트 지역 선언 */ public int intValue() /* intValue 메쏘드 지역선언 */ return value; } public int gcd(int v) /* gcd 메쏘드 지역선언 */ … © 숙대 창병모
예: C 언어의 유효범위 규칙 핵심 아이디어 지역 변수의 유효 범위 전역 변수의 유효범위 사용 전 선언(Declaration before use) 선언의 유효범위는 선언된 지점부터 선언된 블록 끝까지 지역 변수의 유효 범위 선언된 지점부터 함수 끝까지 전역 변수의 유효범위 선언된 지점부터 파일 끝까지 © 숙대 창병모
예제 void p( ) p { char y; y … } int x; x void q( ) q { double z; z main() main { int w[10]; w © 숙대 창병모
예: Ada 언어의 유효범위 규칙 핵심 아이디어 예 선언의 유효범위는 선언된 블록 내 B1: declare x: integer; y: boolean; begin x := 2; y := false; B2: declare a, b: integer; if y then a := x; else b := x; end if end B2; … end B1; © 숙대 창병모
중첩 블록에서 선언 최중첩 우선 규칙(Most closely nested rule) 예 한 식별자가 여러 번 선언된 경우 최중첩된 선언을 우선한다. 예 int x; void p( ) { char x; x = ‘a’; /* local x */ … } main() { x = 2; /* global x */ © 숙대 창병모