{"id":13416053,"url":"https://github.com/tryswift/TryParsec","last_synced_at":"2025-03-14T23:31:16.201Z","repository":{"id":66387397,"uuid":"52714470","full_name":"tryswift/TryParsec","owner":"tryswift","description":"Monadic Parser Combinator for try! Swift http://www.tryswiftconf.com/","archived":false,"fork":false,"pushed_at":"2019-06-08T23:46:44.000Z","size":123,"stargazers_count":279,"open_issues_count":1,"forks_count":23,"subscribers_count":12,"default_branch":"swift/5.0","last_synced_at":"2024-07-31T21:55:12.920Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tryswift.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-02-28T09:46:14.000Z","updated_at":"2024-02-07T12:32:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"f1813bf7-588a-478f-94ab-8b63769cf603","html_url":"https://github.com/tryswift/TryParsec","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tryswift%2FTryParsec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tryswift%2FTryParsec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tryswift%2FTryParsec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tryswift%2FTryParsec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tryswift","download_url":"https://codeload.github.com/tryswift/TryParsec/tar.gz/refs/heads/swift/5.0","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243663478,"owners_count":20327299,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T21:00:53.927Z","updated_at":"2025-03-14T23:31:15.596Z","avatar_url":"https://github.com/tryswift.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# TryParsec\n\nMonadic Parser Combinator for [try! Swift](http://www.tryswiftconf.com/).\n\n- Inspired by Haskell [Attoparsec](https://hackage.haskell.org/package/attoparsec) \u0026 [Aeson](https://hackage.haskell.org/package/aeson), Swift  [Argo](https://github.com/thoughtbot/Argo).\n- Supports CSV, XML, JSON (+ mapping)\n- Doesn't `try`, but please try :)\n\n**NOTE:** This library is still in early development. Please see [TODO \u0026 FIXME](#todo--fixme).\n\n## Quick Play\n\nOpen `Examples/TryParsecPlayground.playground`.\n\n```bash\n$ sudo gem install fastlane\n$ fastlane play   # prepares Xcode Playground\n```\n\n\n## How to use\n\n```swift\n// Simple Arithmetic\nlet ans = parseArithmetic(\" ( 12 + 3 )         * 4+5\").value\nexpect(ans) == 65\n\n// CSV\nlet csv = parseCSV(\"foo,bar,baz\\r\\n1,22,333\\r\\n\").value\nexpect(csv) == [[\"foo\", \"bar\", \"baz\"], [\"1\", \"22\", \"333\"]]\n\n// XML\nlet xmlString = \"\u003cp class=\\\"welcome\\\"\u003e\u003ca href=\\\"underground.html\\\" target=\\\"_blank\\\"\u003eHello\u003c/a\u003e\u003c?php echo ' Cruel'; ?\u003e World\u003c!-- 💀 --\u003e\u003c![CDATA[💣-\u003e😇]]\u003e\u003c/p\u003e\"\nlet xml = parseXML(xmlString).value\nexpect(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(\"💣-\u003e😇\")])]\n\n// JSON\nlet jsonString = \"{ \\\"string\\\" : \\\"hello\\\", \\\"array\\\" : [1, \\\"two\\\", [true, null]] }\"\nlet json = parseJSON(jsonString).value\nexpect(json) == JSON.object([\n    \"string\" : .string(\"hello\"),\n    \"array\" : .array([.number(1), .string(\"two\"), .array([.bool(true), .null])])\n])\n```\n\n### JSON Decoding \u0026 Encoding\n\n```swift\nimport Curry\n\nstruct Model: FromJSON, ToJSON\n{\n    let string: String\n    let array: [Any]?\n\n    static func fromJSON(json: JSON) -\u003e Result\u003cModel, JSON.ParseError\u003e\n    {\n        return curry(self.init)\n            \u003c^\u003e json !! \"string\"\n            \u003c*\u003e json !? \"array\"\n    }\n\n    static func toJSON(model: Model) -\u003e JSON\n    {\n        return toJSONObject([\n            \"string\" ~ model.string,\n            \"array\" ~ model.array\n        ])\n    }\n}\n\nlet jsonString = \"{ \\\"string\\\" : \\\"hello\\\", \\\"array\\\" : [1, \\\"two\\\", [true, null]] }\"\n\n// JSON String -\u003e Model\nlet decoded: Result\u003cModel, JSON.ParseError\u003e = decode(jsonString)\n\n// Model -\u003e JSON String\nlet encoded: String = encode(decoded.value!)\n```\n\nFor `curry`ing, see [thoughtbot/Curry](https://github.com/thoughtbot/Curry) for more information.\n\n\n## Supported functions\n\n- **Basic Operators:** `\u003e\u003e-`, `\u003c^\u003e`, `\u003c*\u003e`, `*\u003e`, `\u003c*`, `\u003c|\u003e`, `\u003c?\u003e`\n- **Combinators:** `zeroOrOne`, `many`, `many1`, `manyTill`, `skipMany`, `skipMany1`, `sepBy`, `sepBy1`, `sepEndBy`, `sepEndBy1`, `count`, `chainl`, `chainl1`, `chainr`, `chainr1`\n- **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`\n\n\n## TODO \u0026 FIXME\n\n- **Improve overall performance**\n  - Current JSON parsing is 70x~ slower than `NSJSONSerialization` (even with whole-module-optimization)\n- Improve error reporting\n- Support indent parser (e.g. YAML)\n- Once [apple/swift](https://github.com/apple/swift) supports [Higher Kinded Types](https://en.wikipedia.org/wiki/Kind_(type_theory))...\n  - Support incremental input\n  - Remove workarounds e.g. reflection-based JSON encoding\n\n\n## Acknowledgement\n\nThis library is heavily inspired by following developers \u0026 libraries:\n\n- Bryan O'Sullivan: Author of [Attoparsec](https://hackage.haskell.org/package/attoparsec) \u0026 [Aeson](https://hackage.haskell.org/package/aeson) (Haskell)\n- Daan Leijen: Author of [Parsec](https://hackage.haskell.org/package/parsec) (Haskell)\n- thoughtbot: Author of [Argo](https://github.com/thoughtbot/Argo) (Swift JSON decoding library)\n\n\n## References\n\n- [Parser Combinators in Swift](https://realm.io/news/tryswift-yasuhiro-inami-parser-combinator/) (video)\n- [Parser Combinator in Swift // Speaker Deck](https://speakerdeck.com/inamiy/parser-combinator-in-swift) (slide)\n\n\n## Licence\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftryswift%2FTryParsec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftryswift%2FTryParsec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftryswift%2FTryParsec/lists"}