{"id":26905884,"url":"https://github.com/soasme/peppapeg","last_synced_at":"2025-08-02T11:06:33.720Z","repository":{"id":45094546,"uuid":"335486703","full_name":"soasme/PeppaPEG","owner":"soasme","description":"PEG Parser in ANSI C","archived":false,"fork":false,"pushed_at":"2022-01-09T20:02:10.000Z","size":9087,"stargazers_count":57,"open_issues_count":12,"forks_count":8,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-01T10:59:07.925Z","etag":null,"topics":["c","parser","peg","peg-parser"],"latest_commit_sha":null,"homepage":"https://soasme.com/PeppaPEG","language":"C","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/soasme.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.rst","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["soasme"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2021-02-03T02:40:19.000Z","updated_at":"2025-02-19T13:12:23.000Z","dependencies_parsed_at":"2022-09-22T17:01:52.755Z","dependency_job_id":null,"html_url":"https://github.com/soasme/PeppaPEG","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/soasme/PeppaPEG","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasme%2FPeppaPEG","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasme%2FPeppaPEG/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasme%2FPeppaPEG/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasme%2FPeppaPEG/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soasme","download_url":"https://codeload.github.com/soasme/PeppaPEG/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasme%2FPeppaPEG/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268378749,"owners_count":24240896,"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-08-02T02:00:12.353Z","response_time":74,"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":["c","parser","peg","peg-parser"],"created_at":"2025-04-01T10:59:12.737Z","updated_at":"2025-08-02T11:06:33.671Z","avatar_url":"https://github.com/soasme.png","language":"C","funding_links":["https://github.com/sponsors/soasme"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e✨ Peppa PEG 🐷 ✨\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eAn ultra lightweight PEG Parser in ANSI C.\u003c/p\u003e\n\n```\n  ____                          ____  _____ ____\n |  _ \\ ___ _ __  _ __   __ _  |  _ \\| ____/ ___|\n | |_) / _ \\ '_ \\| '_ \\ / _` | | |_) |  _|| |  _\n |  __/  __/ |_) | |_) | (_| | |  __/| |__| |_| |\n |_|   \\___| .__/| .__/ \\__,_| |_|   |_____\\____|\n           |_|   |_|\n```\n\n[![Test | Build Status](https://github.com/soasme/PeppaPEG/actions/workflows/check.yml/badge.svg?branch=main)](https://github.com/soasme/PeppaPEG/actions/workflows/check.yml)\n[![Docs | Build Status](https://github.com/soasme/PeppaPEG/actions/workflows/docs.yml/badge.svg?branch=main)](https://github.com/soasme/PeppaPEG/actions/workflows/docs.yml)\n[![Docs](https://img.shields.io/badge/docs-soasme.com-green)](https://www.soasme.com/PeppaPEG)\n\n# Hello, There!\n\nPeppa PEG is an ultra lightweight [PEG] (parsing expression grammar) parser in ANSI C.\n\nReferences: [GitHub](https://github.com/soasme/PeppaPEG)\n| [Project Home Page](https://soasme.com/PeppaPEG/landing.html)\n| [Project Documentation Pages](https://soasme.com/PeppaPEG/).\n\nCurrently, this repo hosted the grammar specification written in Peppa PEG for the following languages:\n\n[ABNF](configs/abnf.peg) ([RFC 5234](https://tools.ietf.org/html/rfc5234)) |\n[Golang v1.17](configs/golang-v1.17.peg) |\n[HCL 2](configs/hcl2.peg) |\n[JSON](configs/json.peg) ([ECMA-404](https://www.ecma-international.org/publications-and-standards/standards/ecma-404/)) |\n[Lua v5.3](configs/lua-v5.3.peg) |\n[TOML v1.0](configs/toml-v1.0.peg) |\n.\n\n## Installation\n\nAssume your system has `cmake` installed, run\n\n```\n$ cd PeppaPEG/\n$ mkdir build\n$ cd build\n$ cmake ..\n$ make\n$ make install\n```\n\nOnce installed, add include macro and start using the library!\n\n```c\n#include \u003cpeppa.h\u003e\n```\n\nYou can use pkg-config to link the library:\n\n```c\n$ gcc `pkg-config --cflags --libs libpeppa` example.c\n```\n\n## Copy `peppa.h` / `peppa.c`\n\nPeppa PEG has a header file and a C file, so alternatively you can add\nit to your project by copying files \"peppa.h\" and \"peppa.c\".\n\nOnce copied, add include macro and start using the library!\n\n```c\n#include \"peppa.h\"\n```\n\nYou can manually load the library source:\n\n```bash\n$ gcc example.c peppa.c\n```\n\n# Usage\n\n## CLI\n\nPeppa PEG ships with a tiny utility: `peppa` to help develop a PEG grammar.\n\nExample: given files: `json.peg` and `data.json`, run with `peppa` utility:\n\n```bash\n$ cat json.peg\n@lifted entry = \u0026. value !.;\n@lifted value = object / array / string / number / true / false / null;\nobject = \"{\" (item (\",\" item)*)? \"}\";\nitem = string \":\" value;\narray = \"[\" (value (\",\" value)*)? \"]\";\n@tight string = \"\\\"\" ([\\u0020-\\u0021] / [\\u0023-\\u005b] / [\\u005d-\\U0010ffff] / escape )* \"\\\"\";\ntrue = \"true\";\nfalse = \"false\";\nnull = \"null\";\n@tight @squashed number = minus? integral fractional? exponent?;\n@tight @squashed @lifted escape = \"\\\\\" (\"\\\"\" / \"/\" / \"\\\\\" / \"b\" / \"f\" / \"n\" / \"r\" / \"t\" / unicode);\n@tight @squashed unicode = \"u\" ([0-9] / [a-f] / [A-F]){4};\nminus = \"-\";\nplus = \"+\";\n@squashed @tight integral = \"0\" / [1-9] [0-9]*;\n@squashed @tight fractional = \".\" [0-9]+;\n@tight exponent = i\"e\" (plus / minus)? [0-9]+;\n@spaced @lifted whitespace = \" \" / \"\\r\" / \"\\n\" / \"\\t\";\n\n$ cat data.json\n[{\"numbers\": [1,2.0,3e1]},[true,false,null],\"xyz\"]\n\n$ peppa parse -G json.peg -e entry data.json | python3 ./scripts/gendot.py | dot -Tsvg -o/tmp/data.svg\n```\n\n![Example JSON AST](docs/_static/readme-json-ast2.svg)\n\n## C API\n\nIn Peppa PEG, grammar syntax can be loaded from a string. Below is an example of JSON grammar syntax.\n\n```c\nP4_Grammar* grammar = P4_LoadGrammar(\n    \"@lifted\\n\"\n    \"entry = \u0026. value !.;\\n\"\n\n    \"@lifted\\n\"\n    \"value = object / array / string / number / true / false / null;\\n\"\n\n    \"object = \\\"{\\\" (item (\\\",\\\" item)*)? \\\"}\\\";\\n\"\n    \"item = string \\\":\\\" value;\\n\"\n\n    \"array = \\\"[\\\" (value (\\\",\\\" value)*)? \\\"]\\\";\\n\"\n\n    \"@tight\\n\"\n    \"string = \\\"\\\\\\\"\\\" ([\\\\u0020-\\\\u0021] / [\\\\u0023-\\\\u005b] / [\\\\u005d-\\\\U0010ffff] / escape )* \\\"\\\\\\\"\\\";\\n\"\n\n    \"true = \\\"true\\\";\\n\"\n    \"false = \\\"false\\\";\\n\"\n    \"null = \\\"null\\\";\\n\"\n\n    \"@tight @squashed\\n\"\n    \"number = minus? integral fractional? exponent?;\\n\"\n\n    \"@tight @squashed @lifted\\n\"\n    \"escape = \\\"\\\\\\\\\\\" (\\\"\\\\\\\"\\\" / \\\"/\\\" / \\\"\\\\\\\\\\\" / \\\"b\\\" / \\\"f\\\" / \\\"n\\\" / \\\"r\\\" / \\\"t\\\" / unicode);\\n\"\n\n    \"@tight @squashed\"\n    \"unicode = \\\"u\\\" ([0-9] / [a-f] / [A-F]){4};\\n\"\n\n    \"minus = \\\"-\\\";\\n\"\n    \"plus = \\\"+\\\";\\n\"\n\n    \"@squashed @tight\\n\"\n    \"integral = \\\"0\\\" / [1-9] [0-9]*;\\n\"\n\n    \"@squashed @tight\\n\"\n    \"fractional = \\\".\\\" [0-9]+;\\n\"\n\n    \"@tight\"\n    \"exponent = i\\\"e\\\" (plus / minus)? [0-9]+;\\n\"\n\n    \"@spaced @lifted\\n\"\n    \"whitespace = \\\" \\\" / \\\"\\\\r\\\" / \\\"\\\\n\\\" / \\\"\\\\t\\\";\\n\"\n);\n```\n\nThe input can be parsed via `P4_Parse`:\n\n```c\nP4_Source* source = P4_CreateSource(\"[{\\\"numbers\\\": [1,2.0,3e1]},[true,false,null],\\\"xyz\\\"]\", \"entry\");\nP4_Parse(grammar, source);\n```\n\nYou can traverse the parse tree. For example, the below function\noutputs the parse tree into JSON format:\n\n```c\nP4_Node* root = P4_GetSourceAST(source);\nP4_JsonifySourceAst(stdout, root, NULL);\n```\n\n```javascript\n[{\"slice\":[0,50],\"type\":\"array\",\"children\":[\n        {\"slice\":[1,25],\"type\":\"object\",\"children\":[\n            {\"slice\":[2,24],\"type\":\"item\",\"children\":[\n                {\"slice\":[2,11],\"type\":\"string\"},\n                {\"slice\":[13,24],\"type\":\"array\",\"children\":[\n                    {\"slice\":[14,15],\"type\":\"number\"},\n                    {\"slice\":[16,19],\"type\":\"number\"},\n                    {\"slice\":[20,23],\"type\":\"number\"}]}]}]},\n        {\"slice\":[26,43],\"type\":\"array\",\"children\":[\n            {\"slice\":[27,31],\"type\":\"true\"},\n            {\"slice\":[32,37],\"type\":\"false\"},\n            {\"slice\":[38,42],\"type\":\"null\"}]},\n        {\"slice\":[44,49],\"type\":\"string\"}]}]\n```\n\n# Peppy Hacking Peppa PEG!\n\nRead the documentation here: \u003chttps://soasme.com/PeppaPEG/\u003e.\n\n## Test\n\nAssume you have `cmake` and `gcc` installed.\n\n```bash\n(root) $ mkdir -p build\n(root) $ cd build\n(build) $ cmake -DENABLE_CHECK=On ..\n(build) $ make check\n...\n100% tests passed, 0 tests failed\n```\n\nIf valgrind is installed, you can also run the test along with memory leak check.\n\n```bash\n(root) $ mkdir -p build\n(root) $ cd build\n(build) $ cmake -DENABLE_VALGRIND=ON ..\n(build) $ make check\n```\n\nIf you feel having a testing environment is hard, try docker:\n\n```bash\n$ docker run --rm -v `pwd`:/app -it ubuntu:latest bash\n# apt-get install gcc gdb valgrind make cmake python3 python3-venv python3-pip doxygen\n# mkdir -p build \u0026\u0026 cd build \u0026\u0026 cmake .. \u0026\u0026 make check\n```\n\n## Docs\n\nPeppa PEG docs can be built via doxygen:\n\n```bash\n(root) $ cd build\n(build) $ cmake -DENABLE_DOCS=On ..\n(build) $ rm -rf docs \u0026\u0026 make docs\n```\n\nThe outputs are stored on `build/docs`.\n\n## Examples\n\n* Write an INI Parser using Peppa PEG: [ini.h](examples/ini.h), [ini.c](examples/ini.c).\n* Write a Mustache Parser using Peppa PEG: [mustache.h](examples/mustache.h).\n* Write a JSON Parser using Peppa PEG: [json.h](examples/json.h).\n* Write a Calculator Parser using Peppa PEG: [calc.h](examples/calc.h), [calc.c](examples/calc.c).\n* Write a [Dot](https://graphviz.org/doc/info/lang.html) parser using Peppa PEG: [dot.h](examples/dot.h).\n\nMade with ❤️  by [Ju](https://github.com/soasme).\n\n[PEG]: https://en.wikipedia.org/wiki/Parsing_expression_grammar\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoasme%2Fpeppapeg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoasme%2Fpeppapeg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoasme%2Fpeppapeg/lists"}