{"id":18351644,"url":"https://github.com/lys-lang/node-ebnf","last_synced_at":"2025-04-06T11:32:34.943Z","repository":{"id":11491154,"uuid":"69812961","full_name":"lys-lang/node-ebnf","owner":"lys-lang","description":"Create AST PEG Parsers from formal grammars in JavaScript","archived":false,"fork":false,"pushed_at":"2023-06-08T22:19:59.000Z","size":482,"stargazers_count":107,"open_issues_count":19,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-02T05:44:51.421Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://menduz.github.io/ebnf-highlighter/","language":"TypeScript","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/lys-lang.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":"2016-10-02T18:05:22.000Z","updated_at":"2025-03-25T23:51:55.000Z","dependencies_parsed_at":"2024-06-18T14:07:03.779Z","dependency_job_id":null,"html_url":"https://github.com/lys-lang/node-ebnf","commit_stats":null,"previous_names":["menduz/node-ebnf"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lys-lang%2Fnode-ebnf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lys-lang%2Fnode-ebnf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lys-lang%2Fnode-ebnf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lys-lang%2Fnode-ebnf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lys-lang","download_url":"https://codeload.github.com/lys-lang/node-ebnf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247478151,"owners_count":20945257,"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":[],"created_at":"2024-11-05T21:32:09.070Z","updated_at":"2025-04-06T11:32:34.669Z","avatar_url":"https://github.com/lys-lang.png","language":"TypeScript","readme":"[![Coverage Status](https://coveralls.io/repos/github/menduz/node-ebnf/badge.svg?branch=master)](https://coveralls.io/github/menduz/node-ebnf?branch=master)\n[![Build Status](https://travis-ci.org/lys-lang/node-ebnf.svg?branch=master)](https://travis-ci.org/lys-lang/node-ebnf)\n\n# What is this?\n\nIt parses a formal grammar and returns a parser instance. That parser returns ASTs based on your grammar. [**SEE IT IN ACTION HERE**](http://menduz.com/ebnf-highlighter/) [GitHub source](https://github.com/menduz/ebnf-highlighter)\n\n# Install\n\n`npm i --save ebnf` (It's compatible with WebPack, and Browserify)\n\n# Usage\n\nBy the moment we only accept two grammars. [BNF](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form) and [W3C EBNF](http://www.w3.org/TR/xquery/#EBNFNotation) (compatible with [Railroad Diagram Generator](http://www.bottlecaps.de/rr/ui))\n\n## Create a parser\n\n```typescript\nimport { Grammars } from 'ebnf';\n\nlet bnfParser = new Grammars.BNF.Parser(bnfGrammar);\nlet w3cParser = new Grammars.W3C.Parser(railRoadGeneratorGrammar);\n```\n\n[**Check out the test folder for more examples**](https://github.com/menduz/node-ebnf/tree/master/test)\n\n## BNF Equation example\n\nIn this example we use plain BNF to create a simple integer formula parser\n\nGrammar:\n\n```ebnf\n\u003cEquation\u003e         ::= \u003cBinaryOperation\u003e | \u003cTerm\u003e\n\u003cTerm\u003e             ::= \"(\" \u003cRULE_WHITESPACE\u003e \u003cEquation\u003e \u003cRULE_WHITESPACE\u003e \")\" | \"(\" \u003cRULE_WHITESPACE\u003e \u003cNumber\u003e \u003cRULE_WHITESPACE\u003e \")\" | \u003cRULE_WHITESPACE\u003e \u003cNumber\u003e \u003cRULE_WHITESPACE\u003e\n\u003cBinaryOperation\u003e  ::= \u003cTerm\u003e \u003cRULE_WHITESPACE\u003e \u003cOperator\u003e \u003cRULE_WHITESPACE\u003e \u003cTerm\u003e\n\n\u003cNumber\u003e           ::= \u003cRULE_NEGATIVE\u003e \u003cRULE_NON_ZERO\u003e \u003cRULE_NUMBER_LIST\u003e | \u003cRULE_NON_ZERO\u003e \u003cRULE_NUMBER_LIST\u003e | \u003cRULE_DIGIT\u003e\n\u003cOperator\u003e         ::= \"+\" | \"-\" | \"*\" | \"/\" | \"^\"\n\n\u003cRULE_NUMBER_LIST\u003e ::= \u003cRULE_DIGIT\u003e \u003cRULE_NUMBER_LIST\u003e | \u003cRULE_DIGIT\u003e\n\u003cRULE_NEGATIVE\u003e    ::= \"-\"\n\u003cRULE_NON_ZERO\u003e    ::= \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\"\n\u003cRULE_DIGIT\u003e       ::= \"0\" | \u003cRULE_NON_ZERO\u003e\n\u003cRULE_WHITESPACE\u003e  ::= \u003cRULE_WS\u003e | \"\"\n\u003cRULE_WS\u003e          ::= \" \" \u003cRULE_WHITESPACE\u003e | \u003cEOL\u003e \u003cRULE_WHITESPACE\u003e | \" \" | \u003cEOL\u003e\n```\n\n```typescript\nimport { Grammars } from 'ebnf';\nlet parser = new Grammars.BNF.Parser(grammar);\n\nparser.getAST('-122 + 2');\n/*             -122 + 2 Equation\n               -122 + 2 BinaryOperation\n               -122     Term\n               -122     Number\n                    +   Operator\n                      2 Term\n                      2 Number\n*/\nparser.getAST( '(2 + (2 * -123)) * 5332');\n/*              (2 + (2 * -123)) * 5332 Equation\n                (2 + (2 * -123)) * 5332 BinaryOperation\n                (2 + (2 * -123))        Term\n                 2 + (2 * -123)         Equation\n                 2 + (2 * -123)         BinaryOperation\n                 2                      Term\n                 2                      Number\n                   +                    Operator\n                     (2 * -123)         Term\n                      2 * -123          Equation\n                      2 * -123          BinaryOperation\n                      2                 Term\n                      2                 Number\n                        *               Operator\n                          -123          Term\n                          -123          Number\n                                 *      Operator\n                                   5332 Term\n                                   5332 Number\n*/\n```\n\n## JSON example\n\n```wbnf\n/* https://www.ietf.org/rfc/rfc4627.txt */\nvalue                ::= false | null | true | object | array | number | string\nBEGIN_ARRAY          ::= WS* #x5B WS*  /* [ left square bracket */\nBEGIN_OBJECT         ::= WS* #x7B WS*  /* { left curly bracket */\nEND_ARRAY            ::= WS* #x5D WS*  /* ] right square bracket */\nEND_OBJECT           ::= WS* #x7D WS*  /* } right curly bracket */\nNAME_SEPARATOR       ::= WS* #x3A WS*  /* : colon */\nVALUE_SEPARATOR      ::= WS* #x2C WS*  /* , comma */\nWS                   ::= [#x20#x09#x0A#x0D]+   /* Space | Tab | \\n | \\r */\nfalse                ::= \"false\"\nnull                 ::= \"null\"\ntrue                 ::= \"true\"\nobject               ::= BEGIN_OBJECT (member (VALUE_SEPARATOR member)*)? END_OBJECT\nmember               ::= string NAME_SEPARATOR value\narray                ::= BEGIN_ARRAY (value (VALUE_SEPARATOR value)*)? END_ARRAY\n\nnumber                ::= \"-\"? (\"0\" | [1-9] [0-9]*) (\".\" [0-9]+)? ((\"e\" | \"E\") ( \"-\" | \"+\" )? (\"0\" | [1-9] [0-9]*))?\n\n/* STRINGS */\n\nstring                ::= '\"' (([#x20-#x21] | [#x23-#x5B] | [#x5D-#xFFFF]) | #x5C (#x22 | #x5C | #x2F | #x62 | #x66 | #x6E | #x72 | #x74 | #x75 HEXDIG HEXDIG HEXDIG HEXDIG))* '\"'\nHEXDIG                ::= [a-fA-F0-9]\n```\n\n```typescript\nimport { Grammars } from 'ebnf';\nlet parser = new Grammars.W3C.Parser(grammar);\n\nparser.getAST( '{\"a\":false,\"b\":\"asd\\\\n      asd \",\"list\":[1,2,3,true]}');\n/*              {\"a\":false,\"b\":\"asd\\n      asd \",\"list\":[1,2,3,true]} value\n                {\"a\":false,\"b\":\"asd\\n      asd \",\"list\":[1,2,3,true]} object\n                 \"a\":false                                            member\n                 \"a\"                                                  string\n                     false                                            value\n                     false                                            false\n                           \"b\":\"asd\\n      asd \"                      member\n                           \"b\"                                        string\n                               \"asd\\n      asd \"                      value\n                               \"asd\\n      asd \"                      string\n                                                 \"list\":[1,2,3,true]  member\n                                                 \"list\"               string\n                                                        [1,2,3,true]  value\n                                                        [1,2,3,true]  array\n                                                         1            value\n                                                         1            number\n                                                           2          value\n                                                           2          number\n                                                             3        value\n                                                             3        number\n                                                               true   value\n                                                               true   true\n*/\n```\n\n## AST\n\nEvery ast node has the following interface\n\n```typescript\ninterface IToken {\n  type: string;         // Rule name\n  text: string;         // Inner text\n  children: IToken[];   // Children nodes\n  start: number;        // Start position of the input string\n  end: number;          // End position\n  errors: TokenError[]; // List of Errors\n}\n```\n\n## Conventions\n\nWe try to keep this tool as much unopinionated and free of conventions as possible. However, we have some conventions:\n- All `UPPER_AND_SNAKE_CASE` rules are not emmited on the AST. This option can be deactivated setting the flag `keepUpperRules: true`.\n","funding_links":[],"categories":["Packages"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flys-lang%2Fnode-ebnf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flys-lang%2Fnode-ebnf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flys-lang%2Fnode-ebnf/lists"}