9.3.3 토큰 구현

이번에는 수식 파서 트리(Numeric Parser Tree)를 이용한 계산기에서 사용할 토큰을 구현합시다.

먼저 토큰 클래스를 정의합시다.

수식 파서 트리를 만들 때 사용할 우선 순위를 멤버 필드로 선언하세요.

토큰 정보를 보여주는 부분은 피연산자와 연산자에 따라 다르므로 순수 가상 메서드(추상 메서드)예요.

파서 트리에서 토큰을 매달 때 우선 순위를 비교하는 메서드를 제공합시다.

파생 클래스에서 자신의 우선 순위를 결정할 수 있게 설정자를 추가하세요.

이제 토큰 소스 파일을 구현합시다. 여기에서는 토큰을 벡터에 보관할 거예요.

Token *형식이 템플릿 인자인 vector를 Tokens 형식으로 지정합시다.

토큰 컬렉션에 보관한 토큰들을 순회할 수 있는 반복자도 타입 재지정하세요.

토큰의 우선 순위를 비교한 결과를 반환하는 메서드를 정의하세요.

우선 순위 설정자도 정의하세요.

 

이번에는 연산자 토큰을 Operator 이름의 클래스로 정의합시다.

연산 기호를 기억하고 있어야겠죠.

생성할 때 연산 기호를 입력 인자로 받습니다.

자신의 정보를 출력하는 View 메서드를 재정의(override) 해야죠.

두 개의 피연산자의 값을 받아 연산하는 메서드를 추가하세요.

정적 메서드로 특정 문자가 연산자가 맞는지 판별하는 메서드를 제공하세요.

토큰이 Operator인지 판별하는 메서드를 제공하세요.

Operator 소스 코드를 구현합시다. 먼저 생성자를 구현하세요.

입력 인자로 받은 연산 기호를 멤버 필드에 설정하세요.

여기에서는 더하기와 빼기는 우선 순위를 1로 곱하기와 나누기는 2로 설정하기로 해요.

정보를 출력하는 메서드에서는 연산 기호를 출력합니다.

계산하는 메서드를 구현합시다.

연산 기호에 따라 알맞은 연산을 수행한 결과를 반환하세요.

나누기 연산에서는 오른쪽 피연산자 값이 0이 아닐 때만 나눈 값을 반환하세요.

오른쪽 피연산자가 0이면 나누기 제로 오류가 있음을 출력하세요.

만약 다른 연산 기호라면 프로그램에 버그가 있는 것입니다.

문자가 사칙 연산 기호인지 판별하는 메서드를 구현하세요. 여기에서는 사칙 연산만 연산자로 제공할 거예요.

토큰이 연산자인지 판별하는 메서드를 구현하세요. 전달받은 token이 Operator 형식인지 판별하세요. dynamic_cast 결과가 0이 아니면 연산자입니다.

 

피연산자 토큰은 Operand 이름의 클래스로 정의합시다.

피연산자 값을 멤버 필드로 선언하세요.

생성자에서는 피연산자의 값을 입력 인자로 받습니다.

자신의 정보를 출력하는 View 메서드를 재정의해 주어야 합니다.

피연산자 값의 접근자 메서드를 제공하세요.

문자가 숫자 문자인지 판별하는 정적 메서드를 제공하세요.

문자열을 정수로 변환하는 정적 메서드를 제공하세요. 변환후 에 다음 토큰의 위치를 판단하기 위해 인덱스를 참조 형식으로 받습니다.

토큰이 피연산자인지 판별하는 정적 메서드를 제공하세요.

Operand 소스 코드를 작성합시다. 먼저 생성자를 정의하기로 해요.

입력 인자로 전달받은 피연산자 값을 멤버 필드 value에 설정하세요.

우선 순위는 제일 높은 3으로 설정하세요.

자신의 정보를 출력하는 메서드를 구현하세요.

피연산자 값의 접근자 메서드를 구현하세요.

문자가 정수 문자인지 판별하는 메서드를 구현하세요. 정수 문자는 ‘0’보다 값이 크거나 같고 ‘9’보다 작거나 같습니다. C언어 표준 라이브러리 함수 isdigit을 사용할 수도 있겠죠.

문자열을 정수로 변환하는 메서드를 구현하세요. C언어 표준 라이브러리 함수 atoi를 사용할 수도 있어요.

초기 값을 0으로 설정합니다.

정수 문자가 아닌 문자가 나올 때까지 반복합니다.

현재 값에 10을 곱한 후에 문자 – ‘0’을 하세요. str[i]가 ‘8’일 때 str[i] – ‘0’은 8입니다.

인덱스를 1 증가하세요.

변환한 값을 반환하세요.

토큰이 피연산자인지 판별하는 메서드를 구현하세요. 전달받은 token이 Operand 형식인지 판별하세요. dynamic_cast 결과가 0이 아니면 연산자입니다.

여기에서는 정수 문자인지 판별하거나 문자열을 정수로 변환하는 메서드를 직접 구현하였습니다. 물론 표준 라이브러리 함수를 사용할 수도 있겠죠.