{"id":49891042,"url":"https://github.com/lambdachad/vom","last_synced_at":"2026-05-15T21:13:10.830Z","repository":{"id":45135406,"uuid":"443919879","full_name":"lambdachad/vom","owner":"lambdachad","description":"V parser combinator framework","archived":false,"fork":false,"pushed_at":"2024-05-09T19:21:30.000Z","size":935,"stargazers_count":16,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-04-13T14:30:37.899Z","etag":null,"topics":["grammar","parse","parser","parser-combinators","v","vom"],"latest_commit_sha":null,"homepage":"https://knarkzel.github.io/vom","language":"V","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/lambdachad.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":"2022-01-03T02:30:17.000Z","updated_at":"2025-03-21T07:15:10.000Z","dependencies_parsed_at":"2024-05-09T20:33:51.818Z","dependency_job_id":"f026257f-42c2-4006-bd59-614cb82d0cff","html_url":"https://github.com/lambdachad/vom","commit_stats":null,"previous_names":["svelterust/vom","lambdachad/vom"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lambdachad/vom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdachad%2Fvom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdachad%2Fvom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdachad%2Fvom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdachad%2Fvom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lambdachad","download_url":"https://codeload.github.com/lambdachad/vom/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdachad%2Fvom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33080700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T20:25:35.270Z","status":"ssl_error","status_checked_at":"2026-05-15T20:25:34.732Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["grammar","parse","parser","parser-combinators","v","vom"],"created_at":"2026-05-15T21:13:08.463Z","updated_at":"2026-05-15T21:13:10.822Z","avatar_url":"https://github.com/lambdachad.png","language":"V","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n    \u003ch1\u003evom\u003c/h1\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![GitHub contributors](https://img.shields.io/github/contributors/knarkzel/vom)](https://github.com/knarkzel/vom/graphs/contributors)\n[![GitHub issues](https://img.shields.io/github/issues/knarkzel/vom)](https://github.com/knarkzel/vom/issues)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/knarkzel/vom/pulls)\n[![HitCount](https://views.whatilearened.today/views/github/knarkzel/vom.svg)](https://github.com/knarkzel/vom)\n\n\u003c/div\u003e\n\n`vom` is a rewrite of [nom](https://github.com/Geal/nom \"nom\"), which is a parser combinator library.\nIt is written in V, hence the name.\n\n## Example\n\n[Hexadecimal color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) parser:\n\n```v\nmodule main\n\nimport vom { is_hex_digit, tag, take_while_m_n, tuple }\n\nstruct Color {\n        red   u8\n        green u8\n        blue  u8\n}\n\nfn from_hex(input string) u8 {\n        return '0x${input}'.u8()\n}\n\nfn hex_primary(input string) !(string, string, int) {\n        parser := take_while_m_n(2, 2, is_hex_digit)\n        return parser(input)\n}\n\nfn hex_color(input string) !(string, Color) {\n        discard := tag('#')\n        hex_part, _, _ := discard(input)!\n        parser := tuple([hex_primary, hex_primary, hex_primary])\n        rest, output, _ := parser(hex_part)!\n        red, green, blue := from_hex(output[0]), from_hex(output[1]), from_hex(output[2])\n        return rest, Color{red, green, blue}\n}\n\nfn main() {\n        _, color := hex_color('#2F14DF')!\n        assert color == Color{47, 20, 223}\n        println(color)\n}\n```\n\n## When will it reach 1.0?\n\nThere are some features I both need and want working in V before I will complete this library:\n\n### Generic return type for closures returned from functions\n\n- [Generic return type for closure returned from function doesn't work #13253](https://github.com/vlang/v/issues/13253 \"Generic return type for closure returned from function doesn't work #13253\")\n\nThis is the only feature I absolutely need in order to finish this\nlibrary. Without it, we're stuck with returning `?(string, string)` instead of\n`?(string, T)` from each parser, and thus can't construct an Ast with the\nlibrary alone. That's currently something you need to do manually.\n\n### Generic type aliases\n\n- [Aliases with generic parameters #12702](https://github.com/vlang/v/discussions/12702 \"Aliases with generic parameters #12702 \")\n\nCurrently this isn't implemented yet. Although it's not required in order to\nimplement the features that are missing, it will make the codebase look horrible\nwithout because almost all of the functions depend on following:\n\n```v\ntype Fn = fn (string) ?(string, string)\ntype FnMany = fn (string) ?(string, []string)\n```\n\nAnd I need the last argument to be generic, because parsers could return other\ntypes such as int, token, []token etc. Although I could search and replace each\nentry manually, I'm too lazy to do that.\n\n### Functions that return closure that captures functions from function parameter\n\n- [Closures fail when capturing parameters that are functions #13032](https://github.com/vlang/v/issues/13032 \"Closures fail when capturing parameters that are functions #13032\")\n\nThis is not a necessary issue either, but it would remove lots of\nboilerplate in the current code, for instance from [sequence.v](https://github.com/knarkzel/vom/blob/master/sequence.v \"sequence.v\").\n\nAdding this would turn following:\n\n```v\npub fn minimal(cond fn (int) bool) fn (int) bool {\n\tfunctions := [cond]\n\treturn fn [functions] (input int) bool {\n\t\tcond := functions[0]\n\t\treturn cond(input)\n\t}\n}\n```\n\nInto this:\n\n```v\npub fn minimal(cond fn (int) bool) fn (int) bool {\n\treturn fn [cond] (input int) bool {\n\t\treturn cond(input)\n\t}\n}\n```\n\n### Call closure returned from function immediately \n\n- [Closures created from functions can't be called immediately #13051](https://github.com/vlang/v/issues/13051 \"Closures created from functions can't be called immediately #13051\")\n\nThis is again not a mandatory feature for this library to work, but would be a\nnice addition. Instead of following code:\n\n```v\nfn operator(input string, location Location) ?(string, Token) {\n\tparser := alt([tag('+'), tag('-'), tag('\u003c')])\n\trest, output := parser(input) ?\n\treturn rest, Token{output, location, .operator}\n}\n```\n\nWe could write this instead, which is a very common pattern in `nom`:\n\n```v\nfn operator(input string, location Location) ?(string, Token) {\n\trest, output := alt([tag('+'), tag('-'), tag('\u003c')])(input) ?\n\treturn rest, Token{output, location, .operator}\n}\n```\n\n## Install\n\n```bash\nv install --git https://github.com/knarkzel/vom\n```\n\nThen import in your file like so:\n\n```v\nimport vom\nrest, output := vom.digit1('123hello') ?\nassert output == '123'\nassert rest == 'hello'\n```\n\nThere are examples in the `examples/` folder.\n\n## Why use vom?\n\n- The parsers are small and easy to write\n- The parsers components are easy to reuse\n- The parsers components are easy to test separately\n- The parser combination code looks close to the grammar you would have written\n- You can build partial parsers, specific to the data you need at the moment, and ignore the rest\n\n## Resources\n\n- [nom::recipes](https://docs.rs/nom/7.1.3/nom/recipes/index.html)\n- [nom/examples](https://github.com/Geal/nom/tree/main/examples)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdachad%2Fvom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flambdachad%2Fvom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdachad%2Fvom/lists"}