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; }
/** 버퍼로부터 C 연산자를 획득합니다. @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; } } |
논리가 같다고 해도 변하는 부분이 없는 것은 아니므로 다른 부분을 확인하면서 이전 절에서 다룬 내용을 모두 이해하기 바란다.