Terminal Expression
터미널 기호와 관련된 작업을 구현합니다.
문장의 모든 터미널 기호에 인스턴스가 필요합니다.
여기서 말하는 터미널 기호라고 함은 어떤 문장에서 의미있는 최소의 단위입니다.
ex. 연산식의 숫자(피 연산자)
Nonterminal Expression
하나의 클래스는 문법이 가진 모든 규칙을 필요로합니다. (규칙은 R1... Rn으로 표현합니다.)
R1... Rn Symbol 각각에 대한 AbstractExpression 타입의 인스턴스 변수를 유지합니다.
Grammar에서 Nonterminal Symbol에 대한 해석 연산을 구현합니다. Interpret는 R1... Rn까지의 규칙을 나타내는 변수를 통해 재귀적 방식으로 해석합니다.
ex. 연산식의 연산기호
Context
Interpreter가 해석할 문장
Client
문법이 정의하는 언어의 특정 문장을 나타내는 Abstract Syntax Tree를 정의합니다. Abstract Syntax Tree는 Nonterminal Expression, Terminal Expression의 인스턴스로 구성됩니다.
Interpret 작업을 호출
import Foundation
protocol Expression {
func evaluate() -> Int
}
class Number: Expression { //Terminal Experssion
private let number: Int
init(number: Int) {
self.number = number
}
func evaluate() -> Int {
return number
}
}
class Addition: Expression { //NonTerminal Experssion
private let leftOperand: Expression
private let rightOperand: Expression
init(leftOperand: Expression, rightOperand: Expression) {
self.leftOperand = leftOperand
self.rightOperand = rightOperand
}
func evaluate() -> Int {
return leftOperand.evaluate() + rightOperand.evaluate()
}
}
class Interpreter {
func evaluate(problem: String) -> Int {
var tokens: [Expression] = []
let tokenList = problem.components(separatedBy: " ")
for token in tokenList {
if token == "+" {
let lo = tokens.removeFirst()
let ro = tokens.removeFirst()
let op = Addition(leftOperand: lo, rightOperand: ro)
let result = op.evaluate()
tokens.insert(Number(number: result), at: 0)
} else {
let num = Number(number: Int(token)!)
tokens.insert(num, at: 0)
}
}
let result = tokens.remove(at: 0)
return result.evaluate()
}
}
let calcaulator = Interpreter()
let result = calcaulator.evaluate(problem: "4 4 + 5 10 + +")
// "4 4 + 5 10 + +" : context
print(result)
// 8 15 +
// 23