{"id":13415797,"url":"https://github.com/blancas/kern","last_synced_at":"2025-10-21T23:07:21.560Z","repository":{"id":6318872,"uuid":"7553918","full_name":"blancas/kern","owner":"blancas","description":"A Parser Combinators Library for Clojure","archived":false,"fork":false,"pushed_at":"2021-05-08T10:17:38.000Z","size":253,"stargazers_count":241,"open_issues_count":7,"forks_count":16,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-10-21T23:02:40.620Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"okfn/timeliner","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blancas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-01-11T04:20:07.000Z","updated_at":"2025-10-10T03:05:43.000Z","dependencies_parsed_at":"2022-08-26T07:11:40.367Z","dependency_job_id":null,"html_url":"https://github.com/blancas/kern","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/blancas/kern","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blancas%2Fkern","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blancas%2Fkern/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blancas%2Fkern/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blancas%2Fkern/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blancas","download_url":"https://codeload.github.com/blancas/kern/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blancas%2Fkern/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280348066,"owners_count":26315368,"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","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-07-30T21:00:52.184Z","updated_at":"2025-10-21T23:07:21.530Z","avatar_url":"https://github.com/blancas.png","language":"Clojure","funding_links":[],"categories":["Parsing","Clojure"],"sub_categories":[],"readme":"# Kern\n\nKern is a library of parser combinators for Clojure. It is useful for \nimplementing recursive-descent parsers based on predictive LL(1) grammars \nwith on-demand, unlimited look-ahead. The inspiration for Kern comes from \nParsec, a Haskell library written by Daan Leijen,  and from work by Graham \nHutton, Erik Meijer, and William Burge.\n\n## Features\n\n* Purely functional implementation based on a custom state monad.\n* Lexer support for various language styles: C, Java, Haskell, Shell.\n* Support for parsing and evaluating expressions.\n* Ability to produce accurate and detailed error messages.\n* A simple, dynamic i18n scheme for error messages.\n* Access to the parser's internal state from client code.\n* Sample parsers in `src/main/resources`.\n\nThe library is intended for parsing text of all kinds. In addition, there\nis support for parsing programming languages and data formats with language-like\nnotations like JSON and EDN. The lexer combinators may be configured\nfor various language features like handling of whitespace, block and line comments,\ncase sensitivity, and patterns for identifiers, among others.\n\n\n## Parser Combinators\n\nA parser is a high-order function whose job is to match an input string against \na specific pattern. A combinator is a parsing function whose \npattern is determined by parsers or by other combinators for the purposes \nof providing repetition, choice, filtering, or to enforce a certain order in the input.\nWe also use the term *parser* in its more general sense, as a logical module of \nparsing functions for a particular task.\n\nThe key feature of this technique is the ability to devise a composition and\nsequencing of combinators for parsing a grammar, and to do so in such a way\nthat the resulting code resembles the structure of said grammar. Furthermore,\nthe resulting parser may itsef be composed, like any other, custom or predefined,\n to form more elaborate combinators.\n\nThus parser combinators offer means of abstraction and composition\nthat result in a powerful and pleasant way to code parsing modules. Kern provides\na rich set of parsers for higher productivity and not having to start from scratch.\nThe next section illustrates the above by defining a custom parser for JSON data. \n\n## Sample Usage\n\nParsing JSON data.\n\n    pair    ::=  string ':' json\n    array   ::=  '[' (json (',' json)*)* ']'\n    object  ::=  '{' (pair (',' pair)*)* '}'\n    json    ::=  string | number | object | array | true | false | null\n\n```clojure\n(use 'blancas.kern.core\n     'blancas.kern.lexer.basic)\n\n(declare json)\n\n(def pair (bind [f string-lit _ colon v json]\n            (return [f v])))\n\n(def array (brackets (comma-sep (fwd json))))\n\n(def object (braces\n              (bind [fields (comma-sep pair)]\n                (return (apply hash-map (reduce concat [] fields))))))\n\n(def json (\u003c|\u003e string-lit dec-lit float-lit object array bool-lit nil-lit))\n```\n\nEvaluate the `json` parser:\n\n```clojure\n(run json \"{\\\"fst\\\": \\\"Joe\\\", \\\"lst\\\": \\\"Hacks\\\",\\\"id\\\":1122}\")\n;; {\"fst\" \"Joe\", \"lst\" \"Hacks\", \"id\" 1122}\n(run json \"{\\\"id\\\":1122,\\\"scores\\\":[400,125,999],\\\"top\\\":true}\")\n;; {\"scores\" [400 125 999], \"top\" true, \"id\" 1122}\n```\n\n## Performance\n\nKern's design isn't well-suited for achieving very high performance. It is based\non pure functions and the systematic composition of its core parsers. My main\ngoals are high productivity and usability. I'll make, however, every effort\nto improve the efficiency of the library.\n\nJust to give a ballpark figure for performance at the REPL, on my MacBook Pro, \nwithout any JVM warm up, Kern will parse 350K worth of JSON data per second \nusing the above definitions, with variations of some 10% either way. In contrast, \n[data.json](https://github.com/clojure/data.json) will parse 4MB in a quarter\nof a second. (I realize times can vary a lot, but after a few runs they\nconverge somewhat; YMMV.)\n\nI've written Kern as my preferred way of working on domain-specific languages,\nstand-alone and for program extensions. For these jobs I've found its performance\nquite satisfactory, with the big pay-off being the boost in productivity.\n\n## Setup\n\nLeiningen:\n\n```clojure\n[org.blancas/kern \"1.1.0\"]\n```\n\nMaven:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.blancas\u003c/groupId\u003e\n  \u003cartifactId\u003ekern\u003c/artifactId\u003e\n  \u003cversion\u003e1.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Changes for release 1.1.0:\n\n* Fixed issue #13: times failed to parse once.\n* Fixed \u003c+\u003e when using a single parser.\n* Reduced the arity of \u003c*\u003e to 1 allowing for 1+ parsers to be applied, adding this missing flexibility.\n\n## Documentation\n\nBrowse the whole [change log](https://github.com/blancas/kern/wiki/Change-Log).\n\nKern is documented in the [Wiki](https://github.com/blancas/kern/wiki).\n\nBrowse the Codox [Kern v1.1.0 API](http://blancas.github.com/kern).\n\n## YourKit\n\nYourKit is kindly supporting open source projects with its full-featured Java\nProfiler.\n\nYourKit, LLC is the creator of innovative and intelligent tools for profiling\nJava and .NET applications. Take a look at YourKit's leading software products:\n\n* \u003ca href=\"http://www.yourkit.com/java/profiler/index.jsp\"\u003eYourKit Java Profiler\u003c/a\u003e and\n* \u003ca href=\"http://www.yourkit.com/.net/profiler/index.jsp\"\u003eYourKit .NET Profiler\u003c/a\u003e.\n\n## License\n\nCopyright © 2013 Armando Blancas.\n\nLicensed under the [Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblancas%2Fkern","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblancas%2Fkern","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblancas%2Fkern/lists"}