Skip to content

inamiy/TryParsec

This branch is up to date with tryswift/TryParsec:swift/2.0.

Folders and files

NameName
Last commit message
Last commit date
Mar 10, 2016
Feb 28, 2016
Feb 28, 2016
Mar 12, 2016
Mar 12, 2016
Feb 28, 2016
Mar 10, 2016
Mar 10, 2016
Feb 28, 2016
Mar 12, 2016
Mar 10, 2016
Feb 28, 2016
Feb 28, 2016
Mar 10, 2016
Feb 28, 2016
Mar 6, 2016
Feb 28, 2016
Feb 28, 2016
Feb 28, 2016
Feb 28, 2016
Feb 28, 2016
Mar 12, 2016
Feb 28, 2016

Repository files navigation

TryParsec

Monadic Parser Combinator for try! Swift.

  • Inspired by Haskell Attoparsec & Aeson, Swift Argo.
  • Supports CSV, XML, JSON (+ mapping)
  • Doesn't try, but please try :)

NOTE: This library is still in early development. Please see TODO & FIXME.

Quick Play

Open Examples/TryParsecPlayground.playground.

$ sudo gem install fastlane
$ fastlane play   # prepares Xcode Playground

How to use

// Simple Arithmetic
let ans = parseArithmetic(" ( 12 + 3 )         * 4+5").value
expect(ans) == 65

// CSV
let csv = parseCSV("foo,bar,baz\r\n1,22,333\r\n").value
expect(csv) == [["foo", "bar", "baz"], ["1", "22", "333"]]

// XML
let xmlString = "<p class=\"welcome\"><a href=\"underground.html\" target=\"_blank\">Hello</a><?php echo ' Cruel'; ?> World<!-- πŸ’€ --><![CDATA[πŸ’£->πŸ˜‡]]></p>"
let xml = parseXML(xmlString).value
expect(xml) == [.Element("p", [XML.Attribute("class", "welcome")], [.Element("a", [XML.Attribute("href", "underground.html"), XML.Attribute("target", "_blank")], [.Text("Hello")]), .ProcessingInstruction("php echo ' Cruel'; "), .Text(" World"), .Comment(" πŸ’€ "), .Text("πŸ’£->πŸ˜‡")])]

// JSON
let jsonString = "{ \"string\" : \"hello\", \"array\" : [1, \"two\", [true, null]] }"
let json = parseJSON(jsonString).value
expect(json) == JSON.Object([
    "string" : .String("hello"),
    "array" : .Array([.Number(1), .String("two"), .Array([.Bool(true), .Null])])
])

JSON Decoding & Encoding

import Curry

struct Model: FromJSON, ToJSON
{
    let string: String
    let array: [Any]?

    static func fromJSON(json: JSON) -> Result<Model, JSON.ParseError>
    {
        return curry(self.init)
            <^> json !! "string"
            <*> json !? "array"
    }

    static func toJSON(model: Model) -> JSON
    {
        return toJSONObject([
            "string" ~ model.string,
            "array" ~ model.array
        ])
    }
}

let jsonString = "{ \"string\" : \"hello\", \"array\" : [1, \"two\", [true, null]] }"

// JSON String -> Model
let decoded: Result<Model, JSON.ParseError> = decode(jsonString)

// Model -> JSON String
let encoded: String = encode(decoded.value!)

For currying, see thoughtbot/Curry for more information.

Supported functions

  • Basic Operators: >>-, <^>, <*>, *>, <*, <|>, <?>
  • Combinators: zeroOrOne, many, many1, manyTill, skipMany, skipMany1, sepBy, sepBy1, sepEndBy, sepEndBy1, count, chainl, chainl1, chainr, chainr1
  • Text (UnicodeScalarView): peek, endOfInput, satisfy, skip, skipWhile, take, takeWhile, any, char, not, string, asciiCI, oneOf, noneOf, digit, hexDigit, lowerAlphabet, upperAlphabet, alphabet, alphaNum, space, skipSpaces, endOfLine, number

TODO & FIXME

  • Improve overall performance
    • Current JSON parsing is 70x~ slower than NSJSONSerialization (even with whole-module-optimization)
  • Improve error reporting
  • Support indent parser (e.g. YAML)
  • Once apple/swift supports Higher Kinded Types...
    • Support incremental input
    • Remove workarounds e.g. reflection-based JSON encoding

Acknowledgement

This library is heavily inspired by following developers & libraries:

References

Licence

MIT

About

Monadic Parser Combinator for try! Swift http://www.tryswiftconf.com/

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 94.8%
  • Ruby 5.0%
  • Objective-C 0.2%