출처 : 프로그래밍 언어론 : 원리와 실제 (창병모, 인피니티북스, 2021)
4.1 변수 선언
1) 변수 선언과 유효범위
- 변수 선언 : 사용 전 선언
- 변수의 유효범위 (scope) : 선언된 변수가 유효한(사용될 수 있는) 프로그램 내의 범위/영역
- 정적 유효범위(Static scope) 규칙
- 선언된 이름은 선언된 블록 내에서만 유효함
- 대부분의 언어에서 표준 규칙으로 사용됨
2) 변수 선언
- 변수 id는 <type>타입 변수이며 초기화가 가능하다.
- 변수 id는 지역 변수로 유효범위는 선언된 블록 내이다.
<stmt> → ... | let <decls> in <stmts> end;
<decls> → {<type> id [=<expr>];}
3) 블록의 중첩
- let 블록 내의 문장 S에 다시 let 블록이 나타날 수 있다.
4) 언어 S의 전역 변수
- 지역 변수 : let문 내에서 선언된 변수
- 전역 변수 : let문 밖에서 선언된 변수
5) 타입 없는 변수 선언
- 동적 타입 언어 (dynamically typed language)
- 변수의 타입을 선언하지 않고 바로 사용
- 변수에 어떤 타입의 값이든지 서장 가능
- Lisp/Scheme, JavaScript, Python 등
4.2 블록 구조 언어
1) 블록
- 블록
- 서로 연관된 선언문과 실행문들을 묶어놓은 프로그래밍 단위
- 블록은 변수나 함수를 선언하는 선언문들과 실행문들로 구성됨
- 블록을 나타내는 기호
- 중괄호 : C
- begin-end : Ada
- 프로시저 또는 함수 : C, Pascal 등
2) 블록 구조 언어
- 블록의 중첩을 허용하는 언어
- 대형 프로그램을 여러 블록으로 나눠 작성 ➡️ 복잡한 수행 내용을 단순화하며 프로그램의 해독성을 높여줌.
- 프로그램의 오류 발생 ➡️ 범위가 블록 단위로 한정되므로 수정이 쉬워짐.
- 블록의 첨가, 수정, 삭제 등이 용이
- 블록 내에 선언된 변수들은 그 안에서만 유효하며 실행이 종료되면 기존에 선언되었던 변수들은 모두 무효화됨.
- 사용자로 하여금 변수의 사용과 기억장소의 할당에 대한 경계를 명확히 할 수 있음.
3) C언어의 유효범위 규칙
- 핵심 아이디어
- 사용 전 선언
- 선언의 유효범위는 선언된 지점~선언된 블록 끝까지.
- 지역 변수의 유효 범위 : 선언된 지점 ~ 함수 끝까지
- 전역 변수의 유효 범위 : 선언된 지점 ~ 파일 끝까지
4.3 변수의 상태와 의미
1) 변수의 의미
- 변수 : 메모리 위치(주소)를 나타내는 이름
- 대입문의 예
- x = x + 1;
- 오른쪽 변수 x의 의미 : 메모리 위치에 저장된 값 (r-value)
- 왼쪽 변수 x의 의미 : 메모리 위치 (l-value)
2) 상태
- 상태 (state) : 변수들의 현재 값
- 모든 가능한 상태들의 집합
- State = Identifier → Value
- 상태 s에서 변수 값 : s(x)
- 상태 갱신 : s' = s[y ↦ v]
- s'(x) = s(x) if x != y
- s'(x) = v if x == y
3) 수식
- 상태에서 수식의 값
- V(State, Expr) → Value
4) 문장의 의미
- 문장 S의 의미
- 문장 S가 상태 s를 후상태 s'으로 변경시킨다.
- 상태 변환
- 상태 변환 함수 (state transform function)
- Eval : (State, Statement) → State
- Eval(s, S) = s' for each statement S
- 의미론
- 각 문장 S마다 상태 변환 함수 정의
- 프로그램의 실행 과정을 상태 변환 과정으로 설명
ex)
- 대입문 id = E
- Eval(s, id) = s[id ↦ V(s, E)]
- 복합문 S;S
- Eval(s, S1;S2) = Eval(Eval(s, S1), S2)
4.4 변수의 유효범위 관리
1) 블록 구조를 위한 상태 관리
- 블록 시작을 만났을 때
- 블록 내에 선언된 변수는 유효해짐
- 선언된 변수에 대한 상태 정보를 새로 생성
- 블록 내 문장을 만났을 때
- 유효한 변수들의 상태 정보를 이용해서 문장들을 해석(실행)
- 블록 끝을 만났을 때
- 블록 내의 선언된 변수들은 더 이상 유효하지 않음
- 블록 내의 선언된 변수들의 상태 정보를 제거
- 상태(state)를 스택(stack) 형태로 유지 관리

4.5 구현
1) 상태 구현
- 상태 구현 : 변수의 값을 나타내는 <변수 이름, 값> 쌍들의 집합으로 표현
class Pair {
Identifier id;
Value val;
Pair (Identifier id, Value v) {
this.id = id;
this.val = v;
}
}
- 스택의 형태로 유지 관리
class State extends Stack<Pair> {
//
}
2) 수식의 값 계산
Value V(Expr e, State state) {
if (e instanceof Value)
return (Value) e;
if (e instanceof Identifier) {
Identifier v = (Identifier) e;
return (Value)(state.get(v));
}
if (e instanceof Binary) {
Binary b = (Binary) e;
Value v1 = V(b.expr1, state);
Value v2 = V(b.expr2, state);
return binaryOperation (b.op, v1, v2);
}
if (e instanceof Unary) {
Unary u = (Unary) e;
Value v = V(u.expr, state);
return unaryOperation(u.op, v);
}
}
Value binaryOperation(Operator op, Value v1, Value v2) {
switch (op.val) {
case "+":
return new Value(v1.intValue() + v2.intValue());
// ...
}
}
3) 대입문 실행
State Eval(Assignment a, State state) {
Value value = V(a.expr, state);
return state.set(a.id, value);
}
4) let 문 실행
State Eval(Let l, State state) {
State s = allocate(l.decls, state);
s = Eval(l.stmts,s);
return free(l.decls, s);
}
5) let 블록 실행
- allocate 함수
- State allocate (Decls ds, State state) { ... }
- 선언된 변수들을 위한 엔트리들을 상태에 추가
- 엔트리 추가 함수 : State push(Identifier id, Value val)
- free 함수
- State free (Decls ds, State state) { ... }
- 선언된 변수들의 엔트리를 상태에서 제거
6) 전역 변수 선언
State Eval(Command c, State state) {
if (c instanceof Decl) {
Decls decls = new Decls();
decls.add((Decl) c);
return allocate(decls, state);
}
if (c instanceof Stmt)
return Eval((Stmt) c, state);
}
'전공과목 정리 > 프로그래밍언어론' 카테고리의 다른 글
| [프로그래밍언어론📐] 6장 자료형 (1) | 2025.08.31 |
|---|---|
| [프로그래밍언어론📐] 5장 의미론 (2) | 2025.08.30 |
| [프로그래밍언어론📐] 3장 언어 설계와 파서 구현 (0) | 2025.08.23 |
| [프로그래밍언어론📐] 2장 구문법 (Syntax) (0) | 2025.08.22 |
| [프로그래밍언어론📐] 1장 서론 (0) | 2025.08.21 |