JSCC: JavaScript로 개발하는 C Compiler

코스 전체목록

닫기

dcl: C의 선언 분석 프로그램 (2)

03_dcl_main.cpp

void dirdcl(StringBuffer &bin) { // 직접 선언자를 분석하고 결과 출력

char ch = bin.peekc();

if (is_fnamch(ch)) { // direct-declarator: 이름 (2)

std::string identifier = "";

while (bin.is_empty() == false) {

ch = bin.getc();

if (is_namch(ch) == false) {

bin.ungetc();

break;

}

identifier += ch;

}

if (identifier.empty()) // 식별자에 추가된 문자가 없다면 예외

throw Exception("올바른 식별자 이름이 아닙니다.");

std::cout << identifier.c_str() << ": ";

}

else if (ch == '(') { // direct-declarator: (declarator) (3)

bin.getc(); // ( 문자를 해석해서 진입했으므로 다음으로 넘긴다

dcl(bin);

if (bin.peekc() != ')') // 닫는 괄호가 없으면 예외

throw Exception("닫는 괄호가 없습니다.");

bin.getc(); // ) 괄호 검사를 진행했으므로 다음으로 넘긴다

}

// direct-declarator: direct-declarator() (4)

// direct-declarator: direct-declarator[] (5)

while (bin.is_empty() == false) {

ch = bin.peekc();

if (ch == '(') { // 함수 기호 획득

bin.getc(); // ( 괄호를 해석해서 진입했으므로 넘긴다

if (bin.peekc() != ')') // 닫는 괄호가 없으면 예외

throw Exception("잘못된 함수 기호입니다.");

bin.getc(); // ) 괄호를 해석했으므로 다음으로 넘긴다

std::cout << "function returning ";

}

else if (ch == '[') { // 배열 기호 획득

bin.getc(); // [ 괄호를 해석해서 진입했으므로 넘긴다

if (bin.peekc() != ']') // 닫는 괄호가 없으면 예외

throw Exception("잘못된 배열 기호입니다.");

bin.getc(); // ] 괄호를 해석했으므로 다음으로 넘긴다

std::cout << "array of ";

}

else { // 이외의 경우 반복문을 탈출한다

break;

}

}

}

이 함수는 크게 direct-declarator의 4, 5번 정의를 기준으로 구분할 수 있다위는 이름과 괄호아래는 함수 기호와 배열 기호에 관한 구문이다이제 dcl 프로그램의 모든 구현을 보았으니 다른 선언의 해석이 어떻게 진행되는지를 관찰할 수 있다. arrptr을 예제로 고르자편의를 위해 ap라고 하겠다.

코드

버퍼 상태

출력

dcl1 호출

(*ap)[];

 

while (ch == '*') ...

(*ap)[];

 

dirdcl1 호출

(*ap)[];

 

if (ch == '(') 진입

(*ap)[];

 

bin.getc()

*ap)[];

 

dcl2 호출

*ap)[];

 

while (ch == '*') ...

ap)[];

 

dirdcl2 호출

ap)[];

 

if (is_fnamch(ch)) 진입

ap)[];

 

while (is_namch(ch)) ...

)[];

ap:

dirdcl2 종료

)[];

ap:

dcl2) while (pc > 0) ...

)[];

ap: pointer to

dcl2 종료

)[];

ap: pointer to

if (ch != ')') ...

)[];

ap: pointer to

bin.getc()

[];

ap: pointer to

while ("()" || "[]") ...

;

ap: pointer to array of

dirdcl1 종료

;

ap: pointer to array of

dcl1) while (pc > 0) ...

;

ap: pointer to array of

dcl1 종료

;

ap: pointer to array of

코드가 재귀적으로 호출되기 때문에 혼란스러울 수 있으니 주의 깊게 보기 바란다다른 모든 예제도 이 방법을 이용하여 출력을 예상할 수 있다그러나 원서에도 나와 있지만이 프로그램은 완전하지 않다. const와 같은 키워드를 처리할 수 없고공백을 잘못 입력했을 때 오작동할 수도 있으며함수의 인자에 대해 어떤 것도 하지 않았다.재귀적인 사고에 약한 사람이라면 이 예제를 분석하고 개선하면서 재귀적인 능력이 비약적으로 상승할 것이다또 후에 기회가 된다면 K&R의 dcl 구현을 반드시 살펴보라이 코드보다 아주 간단명료해서이해하는 데 도움이 많이 될 것이다.

이와 같이 C의 선언을 분석하는 프로그램을 만들고 테스트해볼 수 있었다.

댓글

댓글 본문
graphittie 자세히 보기