03장 어휘 및 구문분석
Download
Report
Transcript 03장 어휘 및 구문분석
프로그래밍언어론
Chapter 3
어휘 및 구문 분석
Syntactic sugar causes cancer of the semicolon.
구문설탕은 세미콜론 암을 일으킨다
A. Perlis
Copyright © 2006 The McGraw-Hill Companies, Inc.
목차 Contents
3.1 촘스키 분류 Chomsky Hierarchy
3.2 어휘 분석 Lexical Analysis
3.3 구문 분석 Syntactic Analysis
Copyright © 2006 The McGraw-Hill Companies, Inc.
3.1 촘스키 분류
• 정규 문법 Regular grammar -- least powerful
• 문맥자유 문법 Context-free grammar (BNF)
• 문맥민감 문법 Context-sensitive grammar
• 무제한 문법 Unrestricted grammar
Copyright © 2006 The McGraw-Hill Companies, Inc.
정규 문법 Regular Grammar
• 가장 간단하고 가장 표현력이 약하다
• 다음과 동일한 표현력을 가진다:
– 정규식 Regular expression
– 유한상태 오토마타 Finite-state automaton
• 오른쪽 정규 문법 Right regular grammar:
(여기서 T*, B N)
A→B
A→
Copyright © 2006 The McGraw-Hill Companies, Inc.
예제
•
Integer → 0 Integer | 1 Integer | ... | 9 Integer
| 0 | 1 | ... | 9
Copyright © 2006 The McGraw-Hill Companies, Inc.
정규 문법 Regular Grammars
• 왼쪽 정규 문법 : 오른쪽과 동일
• 토큰 생성기를 구현할 때 사용한다.
• 문맥자유 문법보다 표현력이 약하다.
• 다음은 정규언어가 아니다:
{ aⁿ bⁿ | n ≥ 1 }
쌍을 이루는 구조를 표현할 수 없다: ( ), { }, begin end
Copyright © 2006 The McGraw-Hill Companies, Inc.
문맥자유 문법 Context-free Grammars
• BNF 표기법 : CFG를 표기하는 방법
• 푸쉬다운 오토마타의 표현력과 동일
• 모호성이 없는 많은 CFG에 대하여
– 테이블 구동 방식의 파서를
– 선형 시간 복잡도로 구현 가능
Copyright © 2006 The McGraw-Hill Companies, Inc.
문맥민감 문법 Context-Sensitive Grammars
• 생성규칙:
–
α→β
|α| ≤ |β|
–
α, β (N T)*
• 좌변이 터미널과 넌터미널들의 기호열로 구성
Copyright © 2006 The McGraw-Hill Companies, Inc.
문맥민감 문법의 결정불가능 성질
• 스트링 와 문법 G 가 주어졌을때:
• L(G) ?
• L(G) is non-empty ?
• 결정불가능(Undecidable)
주어진 문제와 임의의 입력에 대하여 해답을 가
지고 멈추는 프로그램을 작성할 수 없음
Copyright © 2006 The McGraw-Hill Companies, Inc.
무제한 문법 Unrestricted Grammar
• 동일한 능력(표현력, 계산능력)을 가는 것:
– Turing machine
– von Neumann machine
– C++, Java
• 모든 계산가능 함수를 계산할 수 있다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
프로그래밍언어론
Chapter 3
어휘 및 구문 분석
Syntactic sugar causes cancer of the semicolon.
A. Perlis
Copyright © 2006 The McGraw-Hill Companies, Inc.
목차
3.1 Chomsky Hierarchy
3.2 Lexical Analysis
3.3 Syntactic Analysis
Copyright © 2006 The McGraw-Hill Companies, Inc.
어휘 분석
• 목적: 프로그램 표현 형태를 변환한다.
• 입력: 출력가능한 Ascii 문자열
• 출력: 토큰열
• 무시되는 것: 여백, 주석
• 토큰(token)
하나의 기호를 나타내기 위해 논리적으로 묶인
문자열
Copyright © 2006 The McGraw-Hill Companies, Inc.
토큰 예
• 식별자 – 명칭이라고도 함
• 리터럴 : 123, 5.67, 'x', true
• 키워드 : bool char ...
• 연산자 : + - * / ...
• 구두문자 : ; , ( ) { }
Copyright © 2006 The McGraw-Hill Companies, Inc.
다른 문자열
• 여백: 공백, 탭 문자
• 주석
// any-char* end-of-line
• 줄끝 표시자 End-of-line
• 파일끝 표시자 End-of-file
Copyright © 2006 The McGraw-Hill Companies, Inc.
어휘 분석이 왜 독립된 단계를 이루는가?
• 파서보다 더 간단하고 빠른 모델이 가능
• 컴파일 시간의 75%를 차지 (최적화없을때)
• 서로 다른 문자집합 (ACSII, EBCDIC, Unicode)
• 서로 다른 줄끝 표시자
Copyright © 2006 The McGraw-Hill Companies, Inc.
정규식 Regular Expressions
Copyright © 2006 The McGraw-Hill Companies, Inc.
Clite 어휘 구문
부류
정규식 정의
• anyChar
[ -~]
• Letter
[a-zA-Z]
• Digit
[0-9]
• Whitespace
[ \t]
• Eol
\n
• Eof
\004
Copyright © 2006 The McGraw-Hill Companies, Inc.
Clite 어휘 구문
부류
• Keyword
정규식 정의
bool | char | else | false | float |
if | int | main | true | while
• Identifier
{Letter}({Letter} | {Digit})*
• integerLit
{Digit}+
• floatLit
{Digit}+\.{Digit}+
• charLit
‘{anyChar}’
Copyright © 2006 The McGraw-Hill Companies, Inc.
Clite 어휘 구문
부류
• Operator
정규식 정의
=
|
|
>=
• Separator
:
|
• Comment
//
||
|
&&
+
|
-
.
|
{
|
|
|
==
*
|
}
|
| != |
/
(
<
|
<=
|
>
|
|! | [ | ]
|
)
({anyChar} | {Whitespace})* {eol}
Copyright © 2006 The McGraw-Hill Companies, Inc.
어휘분석기 생성기
• 입력: 정규식
• 출력: 테이블(배열), 코드
• C/C++: Lex, Flex
• Java: JLex
Copyright © 2006 The McGraw-Hill Companies, Inc.
유한상태 오토마타 Finite State Automata
• 상태 집합: 그래프 노드로 표현
• 입력 알파벳 + 특수 기호(입력의 끝을 나타냄)
• 상태 전이 함수
그래프에서 알파벳 기호가 붙은 아크
• 시작 상태(특별히 지정됨)
• 최종 상태 집합
Copyright © 2006 The McGraw-Hill Companies, Inc.
결정 유한상태 오토마타
• 정의: 유한상태 오토마타에서 각 상태와 입력
기호에 대하여 그 입력 기호가 붙고 그 상태에
서 나가는 아크가 많아야 하나 밖에 없을 때 이
유한상태 오토마타는 결정적(deterministic)이
라고 한다.
• 식별자를 위한 유한상태 오토마타
Copyright © 2006 The McGraw-Hill Companies, Inc.
구성상태와 전이
• 오토마타의 구성 상태(configuration)는 하나의
상태와 나머지 입력(입력끝 표시자로 끝난다)
으로 이루어진다.
• 하나의 전이(move)는 맨 왼쪽 입력 기호에 대
응하면서 현재 상태로부터 진출하는 아크를 따
라가는 것으로 입력 기호 하나를 처리한다.
– 현재 상태와 입력 기호에 대한 전이가 정의되지 않
으면 오토마톤은 오류로서 멈추게 되고 따라서 입력
은 거절된다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
입력의 수락
• 시작 상태에서 시작하여 오토마톤이 모든 입력
기호를 처리한 후에 최종 상태에서 멈추게 될
때 입력은 수락된다(accepted).
Copyright © 2006 The McGraw-Hill Companies, Inc.
예제
• (S, a2i$) ├ (I, 2i$)
├ (I, i$)
├ (I, $)
├ (F, )
따라서 (S, a2i$) ├* (F, )
Copyright © 2006 The McGraw-Hill Companies, Inc.
몇가지 유의점
• 입력끝 표시자($)는 각 토큰마다 나타나지 않고
전체 프로그램에 대해서만 나타남.
• 레이블이 없는 아크는 다른 모든 입력 기호를 나
타냄.
• 토큰의 인식은 최종상태에서 종결됨.
• 토큰이 아닌 입력에 대한 인식(여백, 주석)은 시
작상태로 돌아가는 아크를 가짐.
Copyright © 2006 The McGraw-Hill Companies, Inc.
몇가지 유의점
• 파일끝의 인식은 소스 프로그램의 끝을 나타내
고 종료상태에서 종결됨.
• 오토마타는 결정적이어야 함.
– 키워드 인식을 따로 포함하지 않음.
– 앞부분이 같은 토큰들은 모두 함께 고려해야 함.
Copyright © 2006 The McGraw-Hill Companies, Inc.
Copyright © 2006 The McGraw-Hill Companies, Inc.
렉서 코드
• 파서는 새로운 토큰 하나를 얻기 위해서 렉서를
호출한다.
• 렉서는 입력 문자열을 어디까지 읽었는지를 기
억해야 한다.
• 무조건 한 문자씩 읽어가는 방식은 토큰 인식 과
정에서 한 문자를 더 읽어서 잃어버리게 된다.
– 엿보기 함수(peek function)
– 되돌림 함수(pushback function)
– 시작상태에서는 입력문자 처리를 하지않음.
Copyright © 2006 The McGraw-Hill Companies, Inc.
설계에서 구현으로
private char ch = ‘ ‘;
public Token next ( ) {
do {
switch (ch) {
...
}
} while (true);
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
유의점
• 루프는 토큰이 인식될 때만 종료된다.
• 루프는 return문을 통해 종료된다.
• 변수 ch 는 전역변수이어야 하고
공백으로 초기화되어야 한다.
• 토큰의 실제 표현(문자열이거나 정수이거나)은
설계와 무관하다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
전이 규칙
• A에서 B로 아크를 따라서 이동:
– 아크가 x로 레이블되면 ch == x 이지 검사한다.
– 아크가 레이블이 없으면 if/switch문의 else/default
선택절에 해당된다.
– 아크가 유일한 아크라면 검사는 불필요하다.
– A가 시작상태가 아니면 다음 문자를 읽어온다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
전이 규칙
• 자기자신으로 가는 아크를 가진 노드는
do-while 루프에 해당한다.
– 반복조건은 아크의 레이블에 대응한다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
전이 규칙
• 그 외의 전이는 if/switch문으로 변환된다.
– 각 아크는 각 선택절에 대응함.
– 레이블이 없는 아크는 기본값 선택절(default).
• 연속된 전이는 변환된 문장의 연속으로 표현된
다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
전이 규칙
• 복잡한 하위 다이어그램을 박스로 묶어서 변환
한다.
– 각 박스를 바깥에서 안쪽으로 들어가면서 변환함.
Copyright © 2006 The McGraw-Hill Companies, Inc.
보조함수 isLetter
private boolean isLetter(char c) {
return ch >= ‘a’ && ch <= ‘z’ ||
ch >= ‘A’ && ch <= ‘Z’;
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
보조함수 concat
private String concat(String set) {
StringBuffer r = new StringBuffer(“”);
do {
r.append(ch);
ch = nextChar( );
} while (set.indexOf(ch) >= 0);
return r.toString( );
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
렉서의 토큰 생성
public Token next( ) {
do { if (isLetter(ch) { // ident or keyword
String spelling = concat(letters+digits);
return Token.keyword(spelling);
} else if (isDigit(ch)) { // int or float literal
String number = concat(digits);
if (ch != ‘.’)
return Token.mkIntLiteral(number);
number += concat(digits);
return Token.mkFloatLiteral(number);
Copyright © 2006 The McGraw-Hill Companies, Inc.
렉서의 토큰 생성
} else switch (ch) {
case ‘ ‘: case ‘\t’: case ‘\r’: case eolnCh:
ch = nextCh( ); break;
case eofCh: return Token.eofTok;
case ‘+’: ch = nextChar( );
return Token.plusTok;
…
case ‘&’: check(‘&’); return Token.andTok;
case ‘=‘: return chkOpt(‘=‘, Token.assignTok,
Token.eqeqTok);
Copyright © 2006 The McGraw-Hill Companies, Inc.
소스 프로그램
// a first program
// with 2 comments
int main ( ) {
char c;
int i;
c = 'h';
i = c + 3;
} // main
토큰
int
main
(
)
{
char
Identifier
;
Copyright © 2006 The McGraw-Hill Companies, Inc.
c
목차
3.1 Chomsky Hierarchy
3.2 Lexical Analysis
3.3 Syntactic Analysis
Copyright © 2006 The McGraw-Hill Companies, Inc.
구문 분석
• 파싱(파서)라고도 함.
• 목적: 원시 프로그램의 구조를 파악하는 것
• 입력: 토큰
• 출력: 파스 트리 또는 추상구문트리
• 재귀하향 파서는 문법의 각 넌터미널에 해당하
는 함수들로 구현되는데, 그 함수는 주어진 입력
이 해당 넌터미널로부터 생성가능한 지를 인식
한다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
프로그램 구성
• 수식: x + 2 * y
• 저장문: z = x + 2 * y
• 반복문: while (i < n) a[i++] = 0;
• 함수 정의
• 선언문: int i;
Copyright © 2006 The McGraw-Hill Companies, Inc.
저장문 문법
• Assignment → Identifier = Expression
• Expression → Term { AddOp Term }
• AddOp
→ + | -
• Term
→ Factor { MulOp Factor }
• MulOp
→ * | /
• Factor
→ [ UnaryOp ] Primary
• UnaryOp → - | !
• Primary → Identifier | Literal | ( Expression )
Copyright © 2006 The McGraw-Hill Companies, Inc.
First 집합
• 확장 문법: S – 시작기호
S' → S $
• First(X)는 X로부터 유도가능한 문장형태의 맨
왼쪽 단말자 집합이다.
First(X) = { a T | X →* a w, w (N T)* }
• 단말자 기호에 대한 생성규칙은 없기 때문에,
First(a) = { a }
(a T)
Copyright © 2006 The McGraw-Hill Companies, Inc.
First 집합
• 단말자와 비단말자로 된 임의의 스트링
= X1 ... Xn V 에 대하여
w
First(w) = First(X1) ... First(Xn) First(V)
여기서 X1, ..., Xn은 널이 될 수 있고 V 는 널이 될 수 없다.
• 널이 될 수 있다(nullable)는 것은 빈 스트링을 유
도할 수 있음을 의미한다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
Nullable Algorithm
•
Set nullable = new Set( );
•
do { oldSize = nullable.size( );
•
for (Production p : grammar.productions( ))
•
•
•
•
•
if (p.length( ) == 0)
nullable.add(p.nonterminal( ));
else
<< check righthand side >>
} while (nullable.size( ) > oldSize);
Copyright © 2006 The McGraw-Hill Companies, Inc.
널이 될 수 있는 비단말자 집합 구하기
Copyright © 2006 The McGraw-Hill Companies, Inc.
문법 변환 규칙
• 확장 문법으로 수정
• 비단말자 이름을 간략화
• 메타 구문을 비단말자로 대체
Copyright © 2006 The McGraw-Hill Companies, Inc.
변환된 문법(그림 3.8)
S → A$
A → i=E;
E → T E'
E' → | AO T E'
AO → + | T → F T'
T' → MO F T'
MO → * | /
F → F' P
F' → | UO
UO → - | !
P → i | l | (E)
Copyright © 2006 The McGraw-Hill Companies, Inc.
널이 될 수 있는 비단말자 집합(그림 3.8에 대하여)
Pass
Nullable
1
E' T' F'
2
E' T' F'
Copyright © 2006 The McGraw-Hill Companies, Inc.
왼쪽 종속 그래프(Left Dependency Graph)
• 각 생성규칙 A → V1 ... Vn X w에 대하여
– V1, ... Vn이 널이 될 수 있으면 A에서 X로 가는 아크를
그린다.
– A 에서 V1, ..., A 에서 Vn 으로의 아크도 생성됨
Copyright © 2006 The McGraw-Hill Companies, Inc.
Copyright © 2006 The McGraw-Hill Companies, Inc.
비단말자
First
비단말자
First
A
i
UO
!-
E
!-il(
P
il(
E’
+-
AO
+-
T
!-il(
T’
*/
MO
*/
F
!-il(
F’
!Copyright © 2006 The McGraw-Hill Companies, Inc.
재귀하향 파싱
• 각 비단말자에 대응하는 메소드/함수를 구현
• 비단말자로부터 유도가능한 가장 긴 토큰열을
인식
• 생성규칙을 코드로 변환하는 알고리즘이 필요
• EBNF을 기반
Copyright © 2006 The McGraw-Hill Companies, Inc.
변환 알고리즘 T(EBNF) = Code
(생성규칙 A → w 에 대하여)
1. w가 비단말자이면 이를 호출하라.
2. w가 단말자이면, 주어진 토큰과 매치한다.
3. w가 { w' }이면 다음 코드으로 변환:
while (First(w')에 토큰이 있으면)
{ T(w‘); }
Copyright © 2006 The McGraw-Hill Companies, Inc.
변환 알고리즘 T(EBNF) = Code
(생성규칙 A → w 에 대하여)
4. w 가 w1 | ... | wn 이면 다음 코드로 변환,
switch (token) {
case First(w1): T(w1); break;
...
case First(wn): T(wn); break;
default: error(token);
}
(wi가 빈 것이 있으면 default: break;)
5. w 가 [ w' ] 이면 ( | w' )로 고치고 규칙 4를 적용.
6. w = X1 ... Xn 이면, T(w) = T(X1); ... T(Xn); 를 적용
Copyright © 2006 The McGraw-Hill Companies, Inc.
확장 생성규칙의 변환
• 첫번째 토큰을 구한다.
• 본래의 시작기호에 해당하는 메소드를 호출한다.
• 마지막 토큰이 파일끝 토큰인지 검사한다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
메소드 match
private void match (int t) {
if (token.type() == t)
token = lexer.next();
else
error(t);
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
메소드 error
private void error(int tok) {
System.err.println(
“Syntax error: expecting”
+ tok + “; saw: ” + token);
System.exit(1);
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
배정문 파서
private void assignment( ) {
// Assignment → Identifier = Expression ;
match(Token.Identifier);
match(Token.Assign);
expression( );
match(Token.Semicolon);
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
수식 파서
private void expression( ) {
// Expression → Term { AddOp Term }
term( );
while (isAddOp()) {
token = lexer.next( );
term( );
}
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
구문구조와 의미구조의 연결
• 파스트리는 비효율적
• 우선순위 단계마다 하나의 비단말자가 존재
• 파스트리의 모양이 중요
Copyright © 2006 The McGraw-Hill Companies, Inc.
파스트리 간단히 하기(추상구문 만들기)
• 분리자/구두기호 제거
• 불필요한 루트 비단말자 제거
• 남은 비단말자를 단말자로 대체
Copyright © 2006 The McGraw-Hill Companies, Inc.
추상구문
Assignment = Variable target; Expression source
Expression = Variable | Value | Binary | Unary
Binary = Operator op; Expression term1, term2
Unary = Operator op; Expression term
Variable = String id
Value = Integer value
Operator = + | - | * | / | !
Copyright © 2006 The McGraw-Hill Companies, Inc.
abstract class Expression { }
class Binary extends Expression {
Operator op;
Expression term1, term2;
}
class Unary extends Expression {
Operator op; Expression term;
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
AST를 출력하는 수정판 T
(생성규칙 A → w 에 대하여)
1. 함수 이름을 A라고 하고 A에 대응하는 추상구
문 넌터미널을 이 함수의 반환타입으로 한다.
2. w 가 비단말자이면 반환된 값을 저장.
3. w 가 구두기호가 아닌 즉, 추상구문에도 나오
는 단말자이면 그 값을 저장.
4. 적절한 추상구문트리를 생성하도록 객체를 생
성하여 반환하는 문장을 포함시킨다.
Copyright © 2006 The McGraw-Hill Companies, Inc.
private Assignment assignment( ) {
// Assignment → Identifier = Expression ;
Variable target = match(Token.Identifier);
match(Token.Assign);
Expression source = expression( );
match(Token.Semicolon);
return new Assignment(target, source);
}
Copyright © 2006 The McGraw-Hill Companies, Inc.
private String match (int t) {
String value = Token.value( );
if (token.type( ) == t)
token = lexer.next( );
else
error(t);
return value;
}
Copyright © 2006 The McGraw-Hill Companies, Inc.