기본 콘텐츠로 건너뛰기

방송대 프로그래밍언어론 4강: 구문 문법과 형식 의미론

0-썸네일-요약노트-프로그래밍언어론-4강

방송대 프로그래밍언어론 4강: 구문 문법과 형식 의미론

겉모양이 문법에 맞는 프로그램도 타입이 어긋나거나 실행 결과가 의도와 다를 수 있다. 프로그램 문장을 토큰·구문·정적 의미·동적 효과라는 네 관문으로 나누어 검사하면, CFG와 BNF·EBNF가 무엇을 정의하고 여러 형식 의미론이 어떤 질문에 답하는지 일관되게 판단할 수 있다.

문법에 맞는다는 말만으로 프로그램을 이해할 수는 없다

다음 세 줄을 보자.

int x12;
x12 = 1 + 5 * 2;
if (x12 > 10) { /* ... */ }

문자들은 int, x12, =, 1, + 같은 토큰을 만들고, 토큰들은 선언문·대입문·조건문이라는 허용된 형태를 이룬다. 여기까지가 주로 구문론(syntax)의 질문이다. 실행하면 1+5×2=11x12에 저장되고 조건 x12>10이 참이 되어 블록을 수행한다. 이것이 의미론(semantics)의 질문이다.

검사 관문핵심 질문이 예에서 확인할 것
문자·토큰의미 있는 최소 단위로 나뉘는가?x12는 하나의 식별자 토큰인가?
구문토큰 배열이 문법으로 도출되는가?선언과 대입, 조건문의 형태가 맞는가?
정적 의미실행 전에 적용 가능한 타입·제약을 만족하는가?정수 변수에 저장할 수 있는 식인가?
동적 의미실행하면 상태와 결과가 어떻게 달라지는가?x12가 11이 되고 어느 블록이 실행되는가?

네 관문 원칙: “형태가 맞는가?”와 “그 형태가 무엇을 뜻하는가?”를 섞지 않는다. 먼저 구문을 확인하고, 그다음 실행 전 제약과 실행 중 효과를 나누어 해석한다.

형식적 정의는 컴퓨터와 작성자의 모호함을 함께 줄인다

언어의 형식적 정의는 구문론과 의미론을 통해 언어를 엄밀하게 규정하는 일이다. 자연어에서도 같은 뜻을 한국어의 ‘주어+목적어+서술어’와 영어의 ‘주어+동사+목적어’처럼 다른 형태로 표현할 수 있다. 프로그래밍 언어도 같은 출력 의도를 BASIC과 C에서 서로 다른 구문으로 나타낸다.

BASIC: PRINT "GCD is"; A
C:     printf("GCD is %d", a);

BASIC 문장은 문자열 뒤에 변수 값을 순차적으로 출력하고, C 문장은 형식 문자열의 %d 자리에 변수 값을 넣어 출력한다. 구문이 명확하면 컴퓨터는 프로그램을 어느 구조로 해석해야 하는지 결정할 수 있고, 작성자는 실행 동작을 예측할 수 있다.

오개념 교정: 구문은 단순한 철자 검사만이 아니다. 어떤 토큰이 어떤 구조를 이루는지 정의한다. 반대로 의미는 프로그램의 ‘주제’를 설명하는 것이 아니라 문장이 실행될 때 발생하는 내용적 효과와 실행 전 제약을 설명한다.

문맥 자유 문법은 가능한 프로그램 형태를 생성하는 장치다

프로그래밍 언어의 구문은 일반적으로 문맥 자유 문법(CFG: Context-Free Grammar)으로 표현한다. 강의의 예에서는 문맥 자유 문법을 G=(N,T,P,E)로 나타내며, E를 시작 비단말기호로 사용한다.

구성요소역할강의 예
비단말기호 집합 N규칙으로 더 정의해야 할 대상{E,D}
단말기호 집합 T언어에서 직접 나타나는 표현{+,*,0,1}
생성규칙 집합 P비단말기호를 기호 조합으로 바꾸는 규칙E→E+E, D→0
시작 비단말기호 S전체 문장을 도출하기 시작하는 기호E

예를 들어 시작기호 E에서 E→E+E를 적용하고 두 E를 각각 D로, 두 D를 1과 0으로 바꾸면 1+0을 만든다.

E ⇒ E+E ⇒ D+E ⇒ 1+E ⇒ 1+D ⇒ 1+0

이처럼 문법은 정상적인 프로그램을 생성할 수 있게 하며, 반대로 주어진 토큰열이 규칙으로 도출되는지 확인해 문법에 맞는지 판정하게 한다.

BNF는 정의·택일·비단말기호를 명시한다

BNF(Backus-Naur Form)는 Algol의 구문을 정의하기 위해 사용된 문법 표현법이다. 핵심 메타기호는 세 가지다.

  • ::=는 왼쪽 비단말기호를 오른쪽 형태로 정의한다.
  • |는 여러 후보 중 하나를 고르는 택일을 나타낸다.
  • < >비단말기호를 묶는다.

강의의 조건문 문법은 else가 있는 형태와 없는 형태를 두 대안으로 나열한다.

<if문> ::= if <논리식> then <문장> else <문장>
           | if <논리식> then <문장>
           ;

규칙 왼쪽은 정의 대상이고 오른쪽은 가능한 구조다. if, then, else는 실제 문장에 나타나는 단말기호이며, 꺾쇠괄호로 묶인 논리식과 문장은 다른 규칙으로 계속 정의될 비단말기호다.

EBNF는 선택과 반복을 한 줄에 압축한다

EBNF(Extended Backus-Naur Form)는 BNF에 메타기호를 더해 규칙을 간결하게 표현한다. 기호의 모양을 외우기보다 규칙이 허용하는 횟수를 읽어야 한다.

EBNF 기호허용 횟수·범위판단 질문
[ X ]X를 0번 또는 1번이 부분을 생략할 수 있는가?
{ X }X를 0번 이상같은 부분을 반복할 수 있는가?
(A | B)묶인 범위에서 A 또는 B택일의 범위가 어디까지인가?
'X'메타기호까지 실제 단말기호로 취급기호 자체를 문장에 써야 하는가?

조건문은 선택 부분을 사용해 다음처럼 줄일 수 있다.

<if문> ::= if <논리식> then <문장> [ else <문장> ] ;

대괄호 전체를 생략하면 else 없는 조건문이고, 한 번 선택하면 else와 뒤 문장까지 함께 나타난다. else만 단독으로 선택하는 규칙이 아니다.

부호 없는 정수는 첫 숫자가 반드시 하나 있고 뒤 숫자가 0개 이상 이어진다.

<unsigned integer> ::= <digit> { <digit> } ;

따라서 빈 문자열은 허용하지 않고 7, 42, 1058처럼 한 자리 이상의 숫자열을 허용한다.

괄호는 택일 범위를 묶고 따옴표는 기호 자체를 단말로 만든다

EBNF의 소괄호는 일반 프로그램의 연산 괄호가 아니라 메타기호 |가 적용되는 범위를 정한다. 강의의 수식 규칙은 네 연산자 중 하나를 고르게 한다.

<수식> ::= <수식> ( + | - | * | / ) <수식> ;

소괄호가 없으면 택일이 규칙의 더 넓은 부분에 걸리는 것으로 오해할 수 있다. 한편 문법을 설명하는 데 쓰는 ::=; 같은 메타기호를 실제 문장의 단말기호로 적으려면 따옴표로 묶어 구분한다.

잘못된 읽기: {<digit>}를 “정확히 한 번 반복”으로 읽으면 한 자리 정수와 세 자리 이상 정수를 설명하지 못한다. 중괄호 안 요소는 0번 이상이므로, 앞에 별도로 적힌 첫 <digit>과 합쳐 전체가 1번 이상 나타난다.

구문도표는 같은 규칙을 경로로 읽게 한다

구문도표(syntax diagram)는 순서도와 비슷한 그림으로 구문을 표현한다. 강의자료의 표기에서는 사각형이 비단말기호, 타원이 단말기호이며 화살표가 규칙의 진행 방향을 나타낸다.

조건문 도표의 기본 경로는 if → 논리식 → then → 문장이다. 그 뒤 곧바로 출구로 가거나, 아래 분기로 내려가 else → 문장을 지나 다시 합류한다. 이는 EBNF의 [ else <문장> ]과 같은 선택 구조다.

부호 없는 정수 도표에서는 첫 digit을 반드시 통과한 뒤, 추가 digit을 거쳐 앞 지점으로 돌아오는 순환 경로가 있다. 순환을 0번 선택하면 한 자리, 여러 번 선택하면 여러 자리 정수가 된다.

표현법 선택: 정확한 텍스트 규칙을 쓰고 변환하려면 BNF, 선택·반복을 짧게 표현하려면 EBNF, 가능한 진행 경로를 눈으로 추적하려면 구문도표가 유리하다. 세 표현법은 서로 다른 언어가 아니라 같은 문법을 나타내는 방식이다.

구문이 허용해도 의미가 거부할 수 있다

의미론은 프로그램의 내용적 효과와 구문만으로 표현하기 어려운 제약을 기술한다. 학습용 예로 다음 코드를 가정하자.

integer count;
count = true;

‘식별자에 식을 대입한다’는 형태만 보면 대입문 문법에 맞을 수 있다. 그러나 정수 변수에 논리값을 대입하지 못하도록 타입 규칙을 정한 언어라고 가정하면 정적 의미 검사를 통과하지 못한다. 문법이 맞다는 사실은 타입과 선언 관계까지 자동으로 보장하지 않는다.

의미는 자연어로도 설명할 수 있지만 문장이 복잡해질수록 해석이 모호해질 수 있다. 그래서 속성문법, 기능적 의미론, 표기적 의미론, 공리적 의미론처럼 목적이 다른 형식적 표현법을 사용한다.

정적 의미론은 실행 전에 타입과 제약을 계산한다

정적 의미론은 프로그램을 실행하기 전에 의미 제약을 만족하는지 파악한다. 강의에서는 대표적으로 타입 검사에 활용하며, 표현 방법으로 속성문법을 소개한다.

속성문법은 각 비단말기호가 타입 같은 속성을 가진다고 가정하고, 구문 규칙 옆에 속성 계산 규칙을 붙인다. 예를 들어 선언의 타입 비단말기호 T가 정수 속성을 가지면 뒤의 식별자 목록에도 같은 타입 속성을 전달한다. 구문 트리가 ‘어떤 모양인가’를 보여 준다면 속성 계산은 각 노드가 ‘어떤 타입 정보를 가져야 하는가’를 추가로 결정한다.

정적 의미론은 프로그램의 최종 실행 결과를 대신 계산하는 방법이 아니다. 실행 전에 알 수 있는 타입 일치, 선언 관계 같은 제약을 검사해 잘못된 프로그램을 조기에 걸러 내는 데 초점이 있다.

기능적 의미론은 명령과 메모리의 상태 변화를 추적한다

기능적 의미론은 동적 의미론의 한 방법으로, 추상기계의 상태가 바뀌는 과정으로 수행 의미를 표현한다. 상태는 보통 ‘앞으로 수행할 명령어’와 ‘현재 메모리 상태’의 쌍이다.

강의의 세 대입문은 초기에 x=5, y=7, z=0인 상태에서 다음처럼 진행된다.

< z=x; x=y; y=z;, [x→5, y→7, z→0] >
⇒ < x=y; y=z;,      [x→5, y→7, z→5] >
⇒ < y=z;,           [x→7, y→7, z→5] >
⇒ <                , [x→7, y→5, z→5] >

첫 대입이 옛 x 값을 z에 보존하고, 둘째가 x를 7로 바꾼 뒤, 셋째가 보존된 5를 y에 넣는다. 명령을 한 줄씩 제거하면서 메모리 상태를 함께 갱신하므로 실행 순서가 결과에 미치는 영향을 확인할 수 있다.

표기적 의미론은 구문을 수학적 값에 대응시킨다

표기적 의미론은 각 구문요소를 수학적 표기에 대응시켜 수행 의미를 표현한다. 대응을 담당하는 함수를 의미함수라 한다. 강의의 이진수 의미함수 Bin은 끝에 0이 붙으면 앞부분 값의 두 배, 끝에 1이 붙으면 두 배에 1을 더한다.

Bin⟦0⟧ = 0
Bin⟦1⟧ = 1
Bin⟦B0⟧ = 2 × Bin⟦B⟧
Bin⟦B1⟧ = 2 × Bin⟦B⟧ + 1

직접 구성한 계산으로 1011의 의미를 구하면 다음과 같다.

Bin⟦1⟧=1

Bin⟦10⟧=2×1=2

Bin⟦101⟧=2×2+1=5

Bin⟦1011⟧=2×5+1=11

구문 문자열이 수학적 정수 11에 대응되므로 실행 장치의 세부 상태를 일일이 나열하지 않고도 그 의미를 정의한다.

공리적 의미론은 사전조건에서 사후조건을 보증한다

공리적 의미론은 프로그램의 효과를 논리식으로 표현한다. {P} S {Q}는 사전조건 P가 참일 때 프로그램 S를 실행하면 사후조건 Q가 성립함을 뜻한다.

강의의 대입문 a=b×2를 실행한 뒤 a<10을 보장하려면 사후조건의 a를 대입될 식 b×2로 치환한다.

(a<10)[a→b×2] ⇔ b×2<10 ⇔ b<5

따라서 {b<5} a=b×2; {a<10}이 된다. 직접 구성한 예로 x=y+3 실행 뒤 x≤10을 원한다면 y+3≤10, 즉 y≤7이 필요한 사전조건이다.

거꾸로 계산: 대입문의 사전조건은 실행 전 값을 임의로 추측하지 않는다. 원하는 사후조건에서 대입 대상 변수를 오른쪽 식으로 치환하고 부등식이나 논리식을 정리해 구한다.

의미론 표현법은 해결하려는 질문에 맞춰 고른다

표현법주요 질문강의에서 제시한 활용
속성문법구문 트리의 각 요소에 어떤 타입·속성이 전달되는가?트리 생성, 타입 검사, 코드 생성
기능적 의미론명령을 수행할 때 추상기계 상태가 어떻게 변하는가?실행 과정의 단계별 상태 표현
표기적 의미론구문요소가 어떤 수학적 대상과 값에 대응하는가?언어 특성의 명확한 정의
공리적 의미론주어진 사전조건에서 원하는 사후조건이 보장되는가?프로그램의 특정 조건 만족 여부 확인

프로그래밍 언어 전체의 의미를 한 방법으로 완전히 표현하려 하면 지나치게 복잡해진다. 따라서 모든 방법을 우열로 정렬하기보다 질문에 맞는 표현을 선택한다. 실행 전 오류를 찾으면 속성문법, 상태 변화를 추적하면 기능적 의미론, 수학적 대응을 정의하면 표기적 의미론, 조건 보증을 확인하면 공리적 의미론이 알맞다.

핵심 개념 정리

  • 구문론은 올바른 문장 형태를, 의미론은 그 문장의 제약과 실행 효과를 정의한다.
  • CFG는 비단말기호·단말기호·생성규칙·시작 비단말기호로 구성되며 프로그램 형태를 생성하고 검사한다.
  • BNF는 규칙과 택일을 명시하고, EBNF는 선택·반복·묶음을 압축하며, 구문도표는 같은 규칙을 경로로 시각화한다.
  • 정적 의미론은 실행 전 의미 제약을 검사하고, 동적 의미론은 실행 시 나타나는 상태·값·조건 변화를 표현한다.
  • 속성문법·기능적·표기적·공리적 의미론은 각각 속성 전달, 상태 전이, 수학적 대응, 조건 보증이라는 다른 질문에 답한다.

프로그램 문장을 분석할 때는 먼저 토큰을 나누고 CFG로 도출 가능한 형태인지 확인한다. 선택과 반복이 복잡하면 BNF를 EBNF나 구문도표로 바꾸어 구조를 읽는다. 그다음 실행 전 타입·속성 제약은 정적 의미론으로, 실행 중 상태 변화·수학적 값·조건 보증은 각각 기능적·표기적·공리적 의미론으로 살핀다. 이 네 관문은 다음 강의의 구문 분석에서 문법 규칙이 실제 분석 과정으로 바뀌는 이유를 이해하게 해 준다.

예상문제 10선

1. 구문론과 의미론의 역할을 올바르게 구분한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 실행 결과는 의미론에 속하고, 구문론은 토큰이 이루는 문장 구조를 다룬다.
  • ② 오답: 타입 검사는 정적 의미의 대표 사례이며 문장 길이는 구문론의 정의가 아니다.
  • ③ 정답: 표면적 구조와 내용적 효과라는 두 층을 정확히 분리한다.
  • ④ 오답: 의미론은 문법 기호를 넘어 타입 제약과 실행 동작을 기술한다.

2. 프로그램 구조에서 최소한의 의미를 갖는 문자의 나열은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 식별자, 숫자, 연산자처럼 문자를 묶어 만든 어휘 단위를 토큰이라 한다.
  • ② 오답: 시작 비단말기호는 문법 도출을 시작하는 기호이지 문자로 만든 최소 어휘가 아니다.
  • ③ 오답: 의미함수는 구문요소를 수학적 의미에 대응시키는 함수다.
  • ④ 오답: 사후조건은 프로그램 실행 뒤 보장하려는 논리 조건이다.

3. 문맥 자유 문법의 네 구성요소를 모두 포함한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 타입과 메모리, 의미함수는 의미 분석에 쓰일 수 있지만 CFG의 구성 집합이 아니다.
  • ② 오답: 프로그램 구조의 층과 의미 분류를 섞었으며 생성규칙이 빠졌다.
  • ③ 오답: 이는 공리적 의미론에서 사용하는 요소다.
  • ④ 정답: 정의 대상, 실제 기호, 바꾸어 쓰는 규칙, 도출의 출발점을 모두 포함한다.

4. BNF 규칙 <문장> ::= <대입문> | <if문>에서 |의 의미는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 순차 결합이라면 두 비단말기호를 나란히 쓰며 택일 기호를 사용하지 않는다.
  • ② 정답: 세로줄은 같은 왼쪽 기호를 정의하는 여러 대안 중 하나를 선택하게 한다.
  • ③ 오답: 생략 가능은 EBNF에서 대괄호로 표현한다.
  • ④ 오답: 꺾쇠괄호로 묶인 문장은 여전히 비단말기호다.

5. EBNF 규칙 [ else <문장> ]이 뜻하는 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 반복은 중괄호로 표현하며 대괄호는 최대 한 번만 허용한다.
  • ② 오답: 대괄호 안의 두 요소는 함께 선택되며 서로 택일하는 관계가 아니다.
  • ③ 오답: 대괄호는 생략할 수 있으므로 0번도 허용한다.
  • ④ 정답: 대괄호가 묶은 전체가 선택 사항이므로 else 없는 if문과 있는 if문을 모두 나타낸다.

6. <unsigned integer> ::= <digit> { <digit> }에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 중괄호 밖 첫 숫자는 필수이고 안쪽 숫자는 0번 이상 추가되어 전체 길이가 1 이상이다.
  • ② 오답: 중괄호는 고정 횟수 두 번이 아니라 0번 이상의 반복이다.
  • ③ 오답: 추가 숫자는 한 번도 반복하지 않을 수 있어 한 자리 정수도 허용한다.
  • ④ 오답:<digit>은 대괄호나 중괄호 밖에 있어 생략할 수 없다.

7. 강의의 구문도표 표기에서 타원과 사각형이 나타내는 대상을 순서대로 고르면?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 강의자료의 도형 대응을 반대로 배치했다.
  • ② 오답: 생성규칙은 도형을 잇는 화살표 경로 전체로 표현된다.
  • ③ 정답: 실제로 나타나는 if·then 같은 단말은 타원, 계속 정의될 논리식·문장은 사각형이다.
  • ④ 오답: 사전·사후조건은 공리적 의미론의 논리식이며 구문도표 도형 구분이 아니다.

8. 정적 의미론과 동적 의미론을 올바르게 구분한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 실행 결과는 동적 의미의 대상이고 토큰 구조는 구문론의 대상이다.
  • ② 정답: 타입 검사처럼 실행 전에 확인할 내용과 실제 수행 중 나타날 효과를 구분한다.
  • ③ 오답: BNF와 EBNF는 구문 표현법이며 정적·동적 의미 구분 기준이 아니다.
  • ④ 오답: 두 의미론은 형태 생성보다 프로그램이 뜻하는 제약과 효과를 다룬다.

9. 의미함수 Bin⟦B1⟧=2×Bin⟦B⟧+1을 이용할 때 Bin⟦101⟧의 값은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: Bin⟦10⟧=2이고 마지막 1을 붙이면 2×2+1=5다.
  • ② 오답: 마지막 비트가 0일 때의 2×Bin⟦B⟧만 적용하고 1을 더하지 않았다.
  • ③ 오답: 앞부분 값과 마지막 비트의 가중치를 잘못 계산했다.
  • ④ 오답: 구문 문자열을 십진 숫자 그대로 읽은 값이며 의미함수를 적용하지 않았다.

10. 프로그램 실행 뒤 특정 사후조건이 보장되는지 확인하려 할 때 가장 알맞은 표현법은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 구문도표는 허용된 문장 경로를 보여 주며 실행 뒤 조건을 증명하지 않는다.
  • ② 오답: 속성문법은 타입 같은 정적 속성을 구문 트리에 전달하는 데 적합하다.
  • ③ 오답: 기능적 의미론은 상태 전이를 추적하는 데 유용하지만 사전·사후조건 보증이 중심은 아니다.
  • ④ 정답: {P} S {Q} 형식으로 사전조건에서 프로그램을 거쳐 사후조건이 성립하는지 판단한다.

참고 자료와 작성 기준

이 글은 해당 차시 강의자료를 바탕으로 학습 목적에 맞게 재구성한 비공식 학습자료입니다. 문법 변환, 의미 계산과 문제 해설은 학습자의 이해를 돕도록 구성하고 검토했습니다.

  • 작성·편집: 올에이클래스 학습연구팀
  • 주요 근거: 한국방송통신대학교 컴퓨터과학과 프로그래밍언어론 제4강 「구문론과 의미론」 강의자료(2025)
  • 보충 자료: 별도의 외부 자료를 사용하지 않음
  • 편집 원칙: 올에이클래스 편집 정책
  • 최종 내용 검토: 2026-08-29

댓글