Parsing/Shunting-yard algorithm: Difference between revisions
Improved and adapted to Swift 5.7
(Improved and adapted to Swift 5.7) |
|||
Line 4,705:
struct Stack<T> {
private(set) var elements = [T]()
var isEmpty: Bool { return elements.isEmpty }▼
mutating func push(newElement: T) {▼
elements.
}
}
mutating func
}▼
mutating func pop() -> T? {
self.isEmpty ? nil : elements.removeLast()
}
}
Line 4,722 ⟶ 4,725:
struct Queue<T> {
private(set) var elements = [T]()
var isEmpty: Bool { return elements.isEmpty }▼
▲ mutating func enqueue(newElement: T) {
elements.isEmpty
}
elements.append(newElement)
}
Line 4,733 ⟶ 4,739:
}
enum Associativity {
case Left, Right
}
//
protocol OperatorType: Comparable, Hashable {
var name: String { get }
Line 4,746 ⟶ 4,754:
let precedence: Int
let associativity: Associativity
//
func hash(into hasher: inout Hasher) {
hasher.combine(self.name)
Line 4,757 ⟶ 4,766:
func ==(x: Operator, y: Operator) -> Bool {
// Identified by name
}
func <(x: Operator, y: Operator) -> Bool {
//
}
extension Set where Element: OperatorType {
func contains(
▲ return contains { $0.name == operatorName }
}
subscript (operatorName: String) -> Element? {
get {
}
}
Line 4,785 ⟶ 4,793:
struct ShuntingYard {
enum
case MismatchedParenthesis(parenthesis: String, expression: String)
case UnrecognizedToken(token: String, expression: String)
case ExtraneousToken(token: String, expression: String)
}
Line 4,794 ⟶ 4,803:
var output = Queue<String>()
let tokens = input.components(separatedBy: " ")
for token in tokens {
// Number?
if token.isNumber {
// Add it to the output
output.enqueue(token)
continue
}
// Operator?
// While there is a operator on top of the stack and has lower precedence than current operator (token)
while let top = stack.top
// Pop it off to the output queue
output.enqueue(
}
// Push current operator (token) onto the operator stack
stack.push(
continue
}
else if token == "(" {▼
// Push it onto the stack
continue
}
▲ // If the token is a right parenthesis:
// Right parenthesis?
// Until the token at the top of the stack is a left parenthesis
while
// Pop operators off the stack onto the output queue.
output.enqueue(
}
//
// If the stack runs out, than there is no matching left parenthesis
throw
}
continue
▲ let _ = stack.pop()
▲ }
throw ShuntingYardError.UnrecognizedToken(token)▼
}
// Token not recognized!
}
//
//
while let top = stack.top
//
output.enqueue(
}
// If
// Note: Assume that all operators has been
if
throw (
top == "("
? ParseError.MismatchedParenthesis(parenthesis: "(", expression: input)
: ParseError.ExtraneousToken(token: top, expression: input)
)
}
Line 4,857 ⟶ 4,875:
}
static private func
guard let firstOperator = operators[firstToken],
let secondOperator = operators[secondToken] else {
return
return firstOperator < secondOperator
}
}
|