Created
August 5, 2019 15:53
Revisions
-
zonble created this gist
Aug 5, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,78 @@ enum Token { case num(Int) case op(String) } func tokenize(_ s: String) -> [Token] { let scanner = Scanner(string: s) scanner.charactersToBeSkipped = CharacterSet.whitespaces var tokens = [Token]() while !scanner.isAtEnd { if let c = scanner.scanCharacters(from: CharacterSet(charactersIn: "+-*/")) { tokens.append(.op(String(c))) } else if let int = scanner.scanInt() { tokens.append(.num(int)) } } return tokens } enum MyError : Error { case invalidToken } func calc(_ tokens: [Token]) throws -> Int { if tokens.count == 0 { return 0 } guard case let .num(x) = tokens[0] else { throw MyError.invalidToken } var v = x var currentToken: Token = tokens[0] for token in tokens[1...] { switch token { case .num(let i): switch currentToken { case .num(_): throw MyError.invalidToken case .op(let c): switch c { case "+": v += i case "-": v -= i case "*": v *= i case "/": v /= i default: throw MyError.invalidToken } currentToken = token } case .op(_): switch currentToken { case .op(_): throw MyError.invalidToken case .num(_): currentToken = token } break } } return v } //let t = tokenize("1 / 1 * 2 + 100 - 80") let t = tokenize("1 + 100 * 200") print(t) t do { let result = try calc(t) result } catch { error }