{"id":13415837,"url":"https://github.com/bitwalker/combine","last_synced_at":"2025-04-08T12:06:53.499Z","repository":{"id":35285395,"uuid":"39546321","full_name":"bitwalker/combine","owner":"bitwalker","description":"A parser combinator library for Elixir projects","archived":false,"fork":false,"pushed_at":"2023-11-02T19:45:23.000Z","size":249,"stargazers_count":199,"open_issues_count":6,"forks_count":19,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-31T14:59:44.509Z","etag":null,"topics":["elixir","parser-combinators","parsing"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/bitwalker.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-07-23T04:50:29.000Z","updated_at":"2025-03-23T15:50:06.000Z","dependencies_parsed_at":"2024-05-30T01:27:16.650Z","dependency_job_id":"eaf3de2f-4bfe-4b10-98ad-42a405b39632","html_url":"https://github.com/bitwalker/combine","commit_stats":{"total_commits":139,"total_committers":15,"mean_commits":9.266666666666667,"dds":"0.17985611510791366","last_synced_commit":"31fda750ba0f9f330e1ab48908a55b17a5fe4c60"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwalker%2Fcombine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwalker%2Fcombine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwalker%2Fcombine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwalker%2Fcombine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitwalker","download_url":"https://codeload.github.com/bitwalker/combine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247267085,"owners_count":20910921,"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":["elixir","parser-combinators","parsing"],"created_at":"2024-07-30T21:00:52.455Z","updated_at":"2025-04-08T12:06:53.474Z","avatar_url":"https://github.com/bitwalker.png","language":"Elixir","readme":"## Combine\n\nA parser combinator library for Elixir projects.\n\n[![Master](https://travis-ci.org/bitwalker/combine.svg?branch=master)](https://travis-ci.org/bitwalker/combine)\n[![Hex.pm Version](http://img.shields.io/hexpm/v/combine.svg?style=flat)](https://hex.pm/packages/combine)\n\n## How to Use\n\nFirst add it to your dependency list like so:\n\n```elixir\ndef deps do\n  [{:combine, \"~\u003e x.x.x\"}, ...]\nend\n```\n\nDocumentation is [located here](http://hexdocs.pm/combine).\n\nFrom there the API is fairly straightforward, the docs cover what\nparser combinators are available, but here's a quick taste of how you\nuse it:\n\n```elixir\ndefmodule DateTimeParser do\n  use Combine\n\n  def parse(datetime), do: Combine.parse(datetime, parser)\n\n  defp parser, do: date |\u003e ignore(char(\"T\")) |\u003e time\n\n  defp date do\n    label(integer, \"year\")\n    |\u003e ignore(char(\"-\"))\n    |\u003e label(integer, \"month\")\n    |\u003e ignore(char(\"-\"))\n    |\u003e label(integer, \"day\")\n  end\n\n  defp time(previous) do\n    previous\n    |\u003e label(integer, \"hour\")\n    |\u003e ignore(char(\":\"))\n    |\u003e label(integer, \"minute\")\n    |\u003e ignore(char(\":\"))\n    |\u003e label(float, \"seconds\")\n    |\u003e either(\n      map(char(\"Z\"), fn _ -\u003e \"UTC\" end),\n      pipe([either(char(\"-\"), char(\"+\")), word], \u0026(Enum.join(\u00261)))\n    )\n  end\nend\n\n...\u003e datetime = \"2014-07-22T12:30:05.0002Z\"\n...\u003e datetime_zoned = \"2014-07-22T12:30:05.0002+0200\"\n...\u003e DateTimeParser.parse(datetime)\n[2014, 7, 22, 12, 30, 5.0002, \"UTC\"]\n...\u003e DateTimeParser.parse(datetime_zoned)\n[2014, 7, 22, 12, 30, 5.0002, \"+0200\"]\n\n```\n\n## Why Combine vs ExParsec?\n\nCombine is a superset of ExParsec's API for the most part and it's performance is significantly\nbetter in the one benchmark I've run with a very simple parser. Benchfella was used to run the\nbenchmarks, and the benchmarks used for comparison are present in both Combine and ExParsec's\n`bench` directories with the exception of the datetime parsing one, which is easily replicated\nin ExParsec if you wish to double check yourself. For reference, here's what I'm seeing on my machine:\n\n```\n# ExParsec\n\nSettings:\n  duration:      1.0 s\n\n## Bench.ExParsec.Binary\n[19:01:54] 1/2: many bits\n## Bench.ExParsec.Text\n[19:01:56] 2/2: many any_char\n\nFinished in 5.67 seconds\n\n## Bench.ExParsec.Binary\nmany bits            1000   1731.83 µs/op\n\n## Bench.ExParsec.Text\nmany any_char                  5000   616.02 µs/op\nparse ISO 8601 datetime        2000   964.48 µs/op\n\n# Combine\n\nSettings:\n  duration:      1.0 s\n\n## Combine.Bench\n[15:21:21] 1/5: parse ISO 8601 datetime\n[15:21:22] 2/5: many bits\n[15:21:25] 3/5: many any_char\n[15:21:27] 4/5: large set of choices (one_of/word)\n[15:21:30] 5/5: large set of choices (choice/parsers)\n\nFinished in 12.08 seconds\n\n## Combine.Bench\nlarge set of choices (one_of/word)         100000   25.60 µs/op\nmany any_char                               50000   32.98 µs/op\nmany bits                                   50000   43.90 µs/op\nparse ISO 8601 datetime                     10000   139.45 µs/op\nlarge set of choices (choice/parsers)       10000   265.04 µs/op\n```\n\nExParsec also appears to be falling behind on maintenance, even with PRs being submitted,\nso rather than forking I decided to write my own from scratch that met my needs.\n\n## Parsers\n\nYou should look at the docs for usage on each parser combinator, but the following\nlists which ones are available in each module.\n\n### Combine.Parsers.Base\n--------\n```\nbetween         both\nchoice          either\neof             fail\nfatal           ignore\nlabel           many\nmap             none_of\none_of          option\npair_both       pair_left\npair_right      pipe\nsatisfy         sep_by\nsep_by1         sequence\nskip            skip_many\nskip_many1      times\nzero\n```\n\n### Combine.Parsers.Text\n--------\n```\nalphanumeric      bin_digit\nchar              digit\nfloat             fixed_integer\nhex_digit         integer\nletter            lower\nnewline           octal_digit\nspace             spaces\nstring            tab\nupper             word\nword_of\n```\n\n### Combine.Parsers.Binary\n--------\n```\nbits       bytes\nfloat      int\nuint\n```\n\n## Roadmap\n\n- Streaming parsers\n\n## License\n\nMIT\n","funding_links":[],"categories":["Elixir"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwalker%2Fcombine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitwalker%2Fcombine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwalker%2Fcombine/lists"}