{"id":16011,"library":"ebnf","title":"EBNF Grammar to AST Parser","description":"The `ebnf` package provides a JavaScript and TypeScript-compatible library for generating Abstract Syntax Tree (AST) parsers from formal grammars defined in either Backus-Naur Form (BNF) or W3C Extended Backus-Naur Form (EBNF). It is currently at version 1.9.1. The library differentiates itself by offering direct AST generation, browser compatibility, and built-in TypeScript type definitions, making it suitable for both Node.js and client-side applications. Releases appear to be driven by bug fixes and minor improvements, without a strict time-based cadence. It's particularly useful for projects requiring custom language parsing or syntax highlighting, such as Domain Specific Languages (DSLs) or code analysis tools.","status":"active","version":"1.9.1","language":"javascript","source_language":"en","source_url":"https://github.com/menduz/node-ebnf","tags":["javascript","EBNF","AST","Parser","Grammar","Lexer","Syntax","typescript"],"install":[{"cmd":"npm install ebnf","lang":"bash","label":"npm"},{"cmd":"yarn add ebnf","lang":"bash","label":"yarn"},{"cmd":"pnpm add ebnf","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While CommonJS `require` might work in some environments (e.g., Webpack), ESM `import` is the idiomatic and recommended way to access `Grammars`.","wrong":"const Grammars = require('ebnf');","symbol":"Grammars","correct":"import { Grammars } from 'ebnf';"},{"note":"The Parser classes are nested under `Grammars.BNF` and `Grammars.W3C` respectively.","wrong":"import { BNF } from 'ebnf'; // Incorrect path, BNF is nested","symbol":"Grammars.BNF.Parser","correct":"import { Grammars } from 'ebnf';\nconst bnfParser = new Grammars.BNF.Parser(bnfGrammar);"},{"note":"Ensure correct capitalization and nesting when accessing the W3C Parser class.","wrong":"import { W3CParser } from 'ebnf';","symbol":"Grammars.W3C.Parser","correct":"import { Grammars } from 'ebnf';\nconst w3cParser = new Grammars.W3C.Parser(w3cGrammar);"}],"quickstart":{"code":"import { Grammars } from 'ebnf';\n\nconst mathGrammar = `\n<Equation>         ::= <BinaryOperation> | <Term>\n<Term>             ::= \"(\" <RULE_WHITESPACE> <Equation> <RULE_WHITESPACE> \")\" | \"(\" <RULE_WHITESPACE> <Number> <RULE_WHITESPACE> \")\" | <RULE_WHITESPACE> <Number> <RULE_WHITESPACE>\n<BinaryOperation>  ::= <Term> <RULE_WHITESPACE> <Operator> <RULE_WHITESPACE> <Term>\n\n<Number>           ::= <RULE_NEGATIVE> <RULE_NON_ZERO> <RULE_NUMBER_LIST> | <RULE_NON_ZERO> <RULE_NUMBER_LIST> | <RULE_DIGIT>\n<Operator>         ::= \"+\" | \"-\" | \"*\" | \"/\" | \"^\"\n\n<RULE_NUMBER_LIST> ::= <RULE_DIGIT> <RULE_NUMBER_LIST> | <RULE_DIGIT>\n<RULE_NEGATIVE>    ::= \"-\"\n<RULE_NON_ZERO>    ::= \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\"\n<RULE_DIGIT>       ::= \"0\" | <RULE_NON_ZERO>\n<RULE_WHITESPACE>  ::= <RULE_WS> | \"\"\n<RULE_WS>          ::= \" \" <RULE_WHITESPACE> | \"\\n\" <RULE_WHITESPACE> | \" \" | \"\\n\"\n`;\n\n// Create a BNF parser instance with the defined grammar\nconst parser = new Grammars.BNF.Parser(mathGrammar);\n\n// Parse an arithmetic expression and get the Abstract Syntax Tree (AST)\nconst ast = parser.getAST('(2 + (2 * -123)) * 5332');\n\nconsole.log(JSON.stringify(ast, null, 2));\n\n/*\nExpected AST structure (simplified representation):\n{\n  \"type\": \"Equation\",\n  \"text\": \"(2 + (2 * -123)) * 5332\",\n  \"children\": [\n    // ... detailed AST nodes for operations and numbers\n  ]\n}\n*/\n","lang":"typescript","description":"This quickstart demonstrates how to define a simple arithmetic grammar using BNF, create a parser instance, and then use it to generate an Abstract Syntax Tree (AST) for a given expression."},"warnings":[{"fix":"Upgrade to version 1.9.1 or later to mitigate potential security implications related to `eval` usage. Ensure all grammar definitions, especially those originating from untrusted sources, are thoroughly validated before being passed to the parser.","message":"Version 1.9.1 included a fix to 'remove eval' from the internal implementation. While not explicitly marked as a breaking change for external API, prior versions might have used `eval` internally, which can carry security risks if not properly sandboxed, especially if user-supplied grammar definitions were possible.","severity":"gotcha","affected_versions":"<1.9.1"},{"fix":"Explicitly choose either `Grammars.BNF.Parser` or `Grammars.W3C.Parser` and ensure your grammar strictly follows the conventions of the chosen format. Consult the respective specifications (BNF, W3C EBNF) for syntax details.","message":"The library differentiates between two EBNF styles: standard BNF and W3C EBNF (compatible with Railroad Diagram Generator). Grammars must adhere strictly to one of these two forms for correct parsing. Mixing notations or using unsupported EBNF extensions will lead to parsing errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If you need `ALL_UPPER_AND_SNAKE_CASE` rules to be present in the AST, you can deactivate this default behavior by setting the `keepUpperRules: true` flag in the parser's options (if supported, verify against latest documentation/source). Otherwise, design your grammar to use different naming conventions for rules intended to be part of the AST.","message":"By default, rules defined with `ALL_UPPER_AND_SNAKE_CASE` in the grammar are not emitted in the resulting AST, simplifying the tree for common use cases like whitespace or comments. This behavior can be surprising if you expect all defined rules to appear in the AST.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Run `npm install ebnf` (or `yarn add ebnf`) to install the package. If using TypeScript, ensure `tsconfig.json` correctly includes `node_modules/@types` or that the package's bundled types are being picked up.","cause":"The `ebnf` package is not installed, or the TypeScript compiler cannot locate its type definitions.","error":"Cannot find module 'ebnf' or its corresponding type declarations."},{"fix":"Verify that `import { Grammars } from 'ebnf';` is used correctly and that the package is installed. If using CommonJS, ensure `const { Grammars } = require('ebnf');` is being used, though ESM imports are preferred.","cause":"This usually occurs when trying to access `Grammars.BNF.Parser` or `Grammars.W3C.Parser` but `Grammars` itself is undefined or incorrectly imported.","error":"TypeError: Cannot read properties of undefined (reading 'Parser')"},{"fix":"Review your EBNF/BNF grammar string and ensure all referenced non-terminal rules are explicitly defined. Check for typos in rule names.","cause":"A non-terminal rule referenced in the grammar (e.g., `<SomeRule>`) does not have a corresponding definition in the provided grammar string.","error":"Error: Invalid grammar, production 'SomeRule' is not defined."},{"fix":"Inspect the input string at the specified line and column. Compare it against your grammar definition to identify which rule is failing to match. This often points to incorrect grammar syntax, missing terminals, or an input string that doesn't conform to the defined language. Consider simplifying the grammar or the input to isolate the issue.","cause":"The parser encountered a token (character or sequence) in the input string that does not match any expected rule at that position according to the grammar.","error":"Error: Line X, column Y: Unexpected token 'Z'."}],"ecosystem":"npm"}