JSCC: JavaScript로 개발하는 C Compiler

코스 전체목록

닫기

버퍼 확장 메서드: get_number, get_identifier, get_operator, get_token

5.3.3) 버퍼 확장 메서드: get_number, get_identifier, get_operator, get_token

사실 우리는 이전 절에서 기본 메서드를 다루면서 JS에서의 특이 사항을 모두 학습했고, C++에서 작성했던 확장 메서드의 논리가 변하는 것도 아니기 때문에 변하는 부분을 눈으로만 확인하면 된다.

StringBuffer.js (get_number, get_identifier, get_operator)

/**

버퍼로부터 정수를 획득합니다.

@return {string}

*/

StringBuffer.prototype.get_number = function() {

this.trim(); // 공백 제거

if (this.is_empty()) // 버퍼에 남은 문자가 없다면 예외

throw new StringBufferException("Buffer is empty", this);

else if (is_digit(this.str[this.idx]) == false) // 첫 문자가 숫자가 아니면 예외

throw new StringBufferException("invalid number", this);

var value = '';

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

if (is_digit(this.str[this.idx]) == false)

break;

value += this.str[this.idx];

++this.idx;

}

return value;

}

 

/**

버퍼로부터 식별자를 획득합니다.

@return {string}

*/

StringBuffer.prototype.get_identifier = function() {

this.trim(); // 공백 제거

if (this.is_empty()) // 버퍼에 남은 문자가 없다면 예외

throw new StringBufferException("Buffer is empty", this);

else if (is_fnamch(this.str[this.idx]) == false)

throw new StringBufferException("invalid identifier", this);

var identifier = '';

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

if (is_namch(this.str[this.idx]) == false) // 식별자 문자가 아니라면 탈출

break;

identifier += this.str[this.idx];

++this.idx;

}

return identifier;

}

 

/**

버퍼로부터 연산자를 획득합니다.

@return {string}

*/

StringBuffer.prototype.get_operator = function() {

this.trim();

if (this.is_empty())

throw new StringBufferException("Buffer is empty", this);

var ch = this.str[this.idx++]; // 현재 문자를 획득하고 포인터를 이동한다

var op = '';

switch (ch) {

case '+': op = ch; break;

case '-': op = ch; break;

case '*': op = ch; break;

case '/': op = ch; break;

default: throw new StringBufferException("invalid operator", this);

}

return op;

}

 

/**

공백이 아닌 문자가 나올 때까지 포인터를 옮깁니다.

*/

StringBuffer.prototype.trim = function() {

while (this.is_empty() == false) { // 버퍼에 문자가 남아있는 동안

if (is_space(this.str[this.idx]) == false) // 공백이 아닌 문자를 발견하면

break; // 반복문을 탈출한다

++this.idx; // 공백이면 다음 문자로 포인터를 넘긴다

}

}

그리고 이 예제에서 get_token 메서드에 try-catch 구문이 추가된다.

StringBuffer.js (get_token)

/**

현재 위치 다음에 존재하는 토큰을 획득합니다.

토큰 획득에 실패하면 null을 반환합니다.

@return {string}

*/

StringBuffer.prototype.get_token = function() {

try {

this.trim();

if (this.is_empty())

throw new StringBufferException("Buffer is empty", this);

 

var ch = this.str[this.idx];

var ss = ''; // 문자열 스트림 생성

if (is_digit(ch)) { // 정수를 발견했다면 정수 획득

ss += this.get_number(); // cout 출력 스트림처럼 사용하면 된다

}

else if (is_fnamch(ch)) { // 식별자 문자를 발견했다면 식별자 획득

ss += this.get_identifier();

}

else { // 이외의 경우 일단 연산자로 획득

ss += this.get_operator();

}

return ss; // 획득한 문자열을 반환한다

} catch (ex) {

// 토큰 획득에 실패한 경우 null을 반환합니다.

return null;

}

}

논리가 같다고 해도 변하는 부분이 없는 것은 아니므로 다른 부분을 확인하면서 이전 절에서 다룬 내용을 모두 이해하기 바란다.

댓글

댓글 본문
graphittie 자세히 보기