{"id":15561237,"url":"https://github.com/benchr267/parsel","last_synced_at":"2025-04-23T22:23:56.580Z","repository":{"id":62450503,"uuid":"100178499","full_name":"BenchR267/Parsel","owner":"BenchR267","description":"Create complex parsers by combining simple ones with Parsel!","archived":false,"fork":false,"pushed_at":"2018-12-19T08:28:32.000Z","size":3006,"stargazers_count":22,"open_issues_count":2,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-24T16:07:40.165Z","etag":null,"topics":["cocoapods","grammer","parser-combinators","spm","swift"],"latest_commit_sha":null,"homepage":"https://benchr267.github.io/Parsel/","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/BenchR267.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-13T13:28:49.000Z","updated_at":"2021-06-17T14:49:16.000Z","dependencies_parsed_at":"2022-11-01T23:31:40.786Z","dependency_job_id":null,"html_url":"https://github.com/BenchR267/Parsel","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenchR267%2FParsel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenchR267%2FParsel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenchR267%2FParsel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenchR267%2FParsel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BenchR267","download_url":"https://codeload.github.com/BenchR267/Parsel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242254173,"owners_count":20097531,"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":["cocoapods","grammer","parser-combinators","spm","swift"],"created_at":"2024-10-02T16:06:40.845Z","updated_at":"2025-03-06T17:31:48.354Z","avatar_url":"https://github.com/BenchR267.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Parsel \n![Swift](https://img.shields.io/badge/Swift-4.0-orange.svg) [![Build Status](https://travis-ci.org/BenchR267/Parsel.svg?branch=master)](https://travis-ci.org/BenchR267/Parsel) [![Codecov branch](https://img.shields.io/codecov/c/github/BenchR267/Parsel/master.svg)](https://codecov.io/github/BenchR267/Parsel) [![CocoaPods](https://img.shields.io/cocoapods/v/Parsel.svg)]() [![License](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](http://mit-license.org) [![](https://img.shields.io/badge/documentation-available-brightgreen.svg)](https://benchr267.github.io/Parsel/)\n\nParsel is a parser combinator library that makes it easy to write parsers. Parser combinators lets you create simple parses that can be combined together to very complex ones. Take for example a parser that parses a digit from a given String: _(You can use the pre-defined lexical parser for digit: `L.digit`)_\n\n```Swift\nlet digit = Parser\u003cString, Int\u003e { input in\n    guard let first = input.first, let number = Int(String(first)) else {\n        return .fail(/* some pre-defined error */)\n    }\n    return .success(result: number, rest: String(input.dropFirst()))\n}\n```\n\nWe can now simply extend this to create a parser that parses an addition of two digits from a string:\n\n```Swift\nlet addition = (digit ~ L.plus ~ digit).map { a, _, b in a + b } // `L.plus` is a predefined parser that parses the `+` sign\n\nlet result = addition.parse(\"2+4\")\ntry! result.unwrap() // Int: 6\n```\n\n# Why should I use this?\n\nParsing is a very common task, it does not always mean to parse source code or JSON strings. Parsing means to transform an unstructured input to a structured output. In case of source code this means to parse a raw string to an AST (abstract syntax tree), in case of an addition it means to parse the result of adding two numbers out of a string.\nParsing can always fail, if the input does not match the needed grammer. If the input string in the above example would have been `1+`, it would have been failed because the second number is missing.\nThe advantage of parser combinators is that you start with a very basic parser. In the above example `digit` parses only one digit. But it is not hard, to add a parser that parses more than one digit. A number is a repetition of mulitple digits. For repetition, we can use `rep`, which tries to apply the parser until it fails and collects the result as an array.\nParsing an integer addition is as easy as\n\n```Swift\nfunc intFromDigits(_ digits: [Int]) -\u003e Int {\n    return digits.reduce(0) { res, e in    \n        return res * 10 + e\n    }\n}\n\nlet number = digit.rep.map(intFromDigits)\nlet addition = number ~ L.plus ~ number ^^ { a, _, b in // ^^ is convenience for map\n    return a + b\n}\n\nlet result = addition.parse(\"123+456\")\ntry! result.unwrap() // Int: 579\n```\n\n_(There is also a pre-defined lexical parser for numbers `L.number` that is able to parse a number in different formats [binary, octal, hexadecimal, decimal])_\n\n# What are the disadvantages?\n\nSince parser combinators are very high level, they abstract the whole process of parsing a lot. That means it is easier to use but it also means that the performance is not as good as an optimized, handwritten parser.\n\n# Installation\n\nParsel is currently available via Swift Package Manager and Cocoapods. Support for Carthage will come later.\n\n## Swift Package Manager\n\nTo use Parsel in your project, just add it as a dependency in your `Package.swift` file and run `swift package update`.\n\n```Swift\nimport PackageDescription\n\nlet package = Package(\n  name: \"MyAwesomeApp\",\n  dependencies: [\n    .package(url: \"https://github.com/BenchR267/Parsel\", from: \"3.0.2\")\n  ]\n)\n```\n\n## Cocoapods\n\nTo use Parsel with Cocoapods, just add this entry to your Podfile and run `pod install`:\n\n```Ruby\ntarget 'MyAwesomeApp' do\n  use_frameworks!\n\n  pod 'Parsel'\nend\n```\n\n# Requirements\n\n* Swift 4.0\n    * Parsel is written in Swift 4.0 development snapshots and will be available when Swift 4.0 is released\n\n# Example\n\n[Calculator](https://github.com/BenchR267/Calculator) is a small example I wrote with Parsel.\n\n![Calculator_GIF](https://github.com/BenchR267/Calculator/raw/master/doc/img/Calculator.gif)\n\n# Documentation\n\nCheck out the documentation on the [Github page](https://benchr267.github.io/Parsel/).\n\n# Author\n\n* [@benchr](https://twitter.com/benchr), mail@benchr.de\n\n# Contributing\n\nTo start contributing to Parsel please clone the project and configure it initially:\n\n```Bash\n$ git clone git@github.com:BenchR267/Parsel.git\n$ cd Parsel\n$ make initial\n```\n\nPlease make sure that all tests are green before you submit a pull request by running `make test`.\n\nIf you experience a bug or have an idea for a feature request but you don't know where to get started: feel free to open an [issue](https://github.com/BenchR267/Parsel/issues/new) with a self-explaining description text.\n\nIf you have an idea for a better (more readable and/or faster) implementation for an existing function: feel free to change the code and submit a pull request.\nI will be more than happy to review the changes to make Parsel the best project it can be!\n\n# License\n\nParsel is under MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenchr267%2Fparsel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenchr267%2Fparsel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenchr267%2Fparsel/lists"}