     self.tokens = tokens
   }
 
-  func peekType() -> TokenType {
-    return tokens[index].type
+  func peek() -> TokenMatch {
+    return tokens[index]
+  }
+
+  func advance() -> TokenMatch {
+    let r = tokens[index]
+    index += 1
+    return r
   }
 
   func parse() -> Yaml {
-    while index < tokens.endIndex {
-      let nextType = peekType()
-      let match = tokens[index].match
-
-      switch nextType {
-
-      case .Comment, .Space:
-        index += 1
-        continue
-
-      case .Null:
-        return .Null
-
-      case .True:
-        return .Bool(true)
-
-      case .False:
-        return .Bool(false)
-
-      case .Int:
-        return .Int((match as NSString).integerValue)
-
-      case .IntOct:
-        return .Int(parseInt(match.substringFromIndex(advance(match.startIndex, 2)), radix: 8))
-
-      case .IntHex:
-        return .Int(parseInt(match.substringFromIndex(advance(match.startIndex, 2)), radix: 16))
-
-      case .PositiveInfinity:
-        return .Float(Float.infinity)
-
-      case .NegativeInfinity:
-        return .Float(-Float.infinity)
-
-      case .NaN:
-        return .Float(Float.NaN)
-
-      case .Float:
-        return .Float((match as NSString).floatValue)
-      }
-    }
-    return .Null
+    switch peek().type {
+
+    case .Comment, .Space:
+      advance()
+      return parse()
+
+    case .Null:
+      advance()
+      return .Null
+
+    case .True:
+      advance()
+      return .Bool(true)
+
+    case .False:
+      advance()
+      return .Bool(false)
+
+    case .Int:
+      let m = advance().match as NSString
+      return .Int(m.integerValue) // what about overflow?
+
+    case .IntOct:
+      let m = advance().match.stringByReplacingOccurrencesOfString("0o", withString: "")
+      return .Int(parseInt(m, radix: 8))
+
+    case .IntHex:
+      let m = advance().match.stringByReplacingOccurrencesOfString("0x", withString: "")
+      return .Int(parseInt(m, radix: 16))
+
+    case .InfinityP:
+      advance()
+      return .Float(Float.infinity)
+
+    case .InfinityN:
+      advance()
+      return .Float(-Float.infinity)
+
+    case .NaN:
+      advance()
+      return .Float(Float.NaN)
+
+    case .Float:
+      let m = advance().match as NSString
+      return .Float(m.floatValue)
+
+    case .End:
+      return .Null
+
+    }
   }
 }
 

  case Null = "null"
  case True = "true"
  case False = "false"
  case PositiveInfinity = "+infinity"
  case NegativeInfinity = "-infinity"
  case NaN = "nan"
  case Float = "float"
  case Int = "int"
  case IntOct = "int-oct"
  case IntHex = "int-hex"

  var description: String {
    return self.toRaw()

  (.Null, "^(null|Null|NULL|~)\(finish)"),
  (.True, "^(true|True|TRUE)\(finish)"),
  (.False, "^(false|False|FALSE)\(finish)"),
  (.InfinityP, "^\\+?\\.(inf|Inf|INF)\(finish)"),
  (.InfinityN, "^-\\.(inf|Inf|INF)\(finish)"),
  (.NaN, "^\\.(nan|NaN|NAN)\(finish)"),
  (.Int, "^[-+]?[0-9]+\(finish)"),
  (.IntOct, "^0o[0-7]+\(finish)"),
