Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import XCTest
- @testable import Parsimonious
- indirect enum JSON {
- case string(String)
- case number(NSNumber)
- case boolean(Bool)
- case object([String: JSON])
- case array([JSON])
- }
- let escape = "\\"
- let quote = "\""
- let quotation = char(quote) *> manyS(char(all: !escape, !quote) | (char(escape) *> char(any: escape, quote))) <* char(quote)
- let jstring = JSON.string <*> quotation
- func jnumber(_ context: Context<String>) throws -> JSON {
- let digits = many1S("0123456789")
- let num = digits + optionalS(char(".") + digits)
- let formatter = NumberFormatter()
- formatter.numberStyle = .decimal
- let ns = try context <- num
- guard let n = formatter.number(from: ns) else {
- throw ParseError(message: "Expected a number, but got \(ns).", context: context)
- }
- return JSON.number(n)
- }
- let jbool = {s in JSON.boolean(s == "true")} <*> string("true") | string("false") | fail("Expected a boolean value.")
- let ws = manyS(\Character.isWhitespace)
- func jarray(_ context: Context<String>) throws -> JSON {
- return try context <- JSON.array <*> char("[") *> ws *> many(json <* ws, sepBy: ws + char(",") + ws) <* char("]")
- }
- func jpair(_ context: Context<String>) throws -> (key: String, value: JSON) {
- return try context.transact {
- let key = try context <- quotation
- try context <- ws + char(":") + ws
- let value = try context <- json
- return (key, value)
- }
- }
- func jobject(_ context: Context<String>) throws -> JSON {
- return try context.transact {
- try context <- char("{") <* ws
- let pairs = try context <- many(jpair <* ws, sepBy: ws + char(",") + ws)
- try context <- char("}")
- var object: [String: JSON] = [:]
- for pair in pairs {
- object[pair.key] = pair.value
- }
- return JSON.object(object)
- }
- }
- let json = jstring | jnumber | jbool | jarray | jobject
- class ParsimoniousTests: XCTestCase {
- func testParser() {
- let s = """
- {
- "foo": "bar",
- "x": [7, 9, 11.14, {"yes": true}]
- }
- """
- try XCTAssertNoThrow(parse(s, with: ws *> json <* ws))
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement