{"id":11541,"library":"pegjs-util","title":"Peggy/PEG.js Utility Library","description":"pegjs-util is a utility library for the Peggy parser generator (formerly PEG.js), currently at stable version 2.0.2. It enhances Peggy's core `parse` function by injecting convenient utilities directly into grammar actions. The library provides three main features: Parser Tree Token Unrolling, which simplifies common patterns of extracting tokens from repeated grammar rule matches; Abstract Syntax Tree (AST) Node Generation, which assists in building structured ASTs directly within grammar rules; and improved, \"cooked\" Error Reporting, offering more user-friendly diagnostics than Peggy's default output. Releases appear to follow the development of Peggy itself, with the latest versions published as needed. It differentiates itself by streamlining common parser generator tasks, reducing boilerplate in `.peggy` grammar files, and providing a more robust parsing and error reporting experience.","status":"active","version":"2.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/rse/pegjs-util","tags":["javascript","peggy","pegjs","parser","AST","unroll"],"install":[{"cmd":"npm install pegjs-util","lang":"bash","label":"npm"},{"cmd":"yarn add pegjs-util","lang":"bash","label":"yarn"},{"cmd":"pnpm add pegjs-util","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core parser generator this library extends and integrates with.","package":"peggy","optional":false}],"imports":[{"note":"pegjs-util is currently a CommonJS module (version 2.0.2); direct native ESM imports are not supported. Use CommonJS require syntax.","wrong":"import PEGUtil from 'pegjs-util';","symbol":"PEGUtil","correct":"const PEGUtil = require('pegjs-util');"},{"note":"The `makeUnroll` function is not a direct export. It is provided to the grammar via the `options.util` object when `PEGUtil.parse` is used to run the parser.","wrong":"import { makeUnroll } from 'pegjs-util';","symbol":"makeUnroll","correct":"var unroll = options.util.makeUnroll(location, options);"},{"note":"The `makeAST` function is not a direct export. It is provided to the grammar via the `options.util` object when `PEGUtil.parse` is used, and typically relies on a user-provided `makeAST` callback in the parse options.","wrong":"import { makeAST } from 'pegjs-util';","symbol":"makeAST","correct":"var ast = options.util.makeAST(location, options);"}],"quickstart":{"code":"const fs = require(\"fs\");\nconst ASTY = require(\"asty\"); // Companion library, install separately if needed\nconst PEG = require(\"peggy\");\nconst PEGUtil = require(\"pegjs-util\");\n\nconst pegjsGrammar = `\n{\n    var unroll = options.util.makeUnroll(location, options);\n    var ast    = options.util.makeAST(location, options);\n}\n\nstart\n    = _ seq:id_seq _ {\n          return ast(\"Sample\").add(seq);\n      }\n\nid_seq\n    = id:id ids:(_ \",\" _ id)* {\n          return ast(\"IdentifierSequence\").add(unroll(id, ids, 3));\n      }\n\nid\n    = id:$([a-zA-Z_][a-zA-Z0-9_]*) {\n          return ast(\"Identifier\").set(\"name\", id);\n      }\n\n_ \"blank\"\n    = (co / ws)*\n\nco \"comment\"\n    = \"//\" (![\\r\\n] .)*\n    / \"/*\" (!\"*/\" .)* \"*/\"\n\nws \"whitespaces\"\n    = [ \\t\\r\\n]+\n`;\n\nconst asty = new ASTY();\nconst parser = PEG.generate(pegjsGrammar);\n\n// Simulate input for parsing\nconst sampleInputOk = \"/*  some ok input  */\\nfoo, bar, quux\";\nconst sampleInputBad = \"/*  some bad input  */\\nfoo, bar, quux baz\";\n\nfunction parseInput(inputString, fileName) {\n  console.log(`\\n--- Parsing ${fileName || 'input'} ---`);\n  const result = PEGUtil.parse(parser, inputString, {\n    startRule: \"start\",\n    makeAST: function (line, column, offset, args) {\n      // This callback is what the 'ast' helper in the grammar calls\n      return asty.create.apply(asty, args).pos(line, column, offset);\n    }\n  });\n\n  if (result.error !== null) {\n    console.error(\"ERROR: Parsing Failure:\\n\" +\n      PEGUtil.errorMessage(result.error, true).replace(/^/mg, \"ERROR: \"));\n  } else {\n    console.log(result.ast.dump().replace(/\\n$/, \"\"));\n  }\n}\n\n// To run this code, ensure you have installed:\n// npm install peggy asty pegjs-util\n\nparseInput(sampleInputOk, \"sample-input-ok.txt\");\nparseInput(sampleInputBad, \"sample-input-bad.txt\");","lang":"javascript","description":"Demonstrates how to use `pegjs-util` to parse a simple language, generate an Abstract Syntax Tree (AST) with `asty`, and benefit from enhanced error reporting. It shows the integration of `unroll` and `ast` helpers within a Peggy grammar, enabled by `PEGUtil.parse`."},"warnings":[{"fix":"Use `const PEGUtil = require('pegjs-util');` for importing the library in Node.js environments.","message":"pegjs-util is published as a CommonJS module. It does not officially support native ES module (ESM) imports (e.g., `import PEGUtil from 'pegjs-util'`) in its current version (2.0.2). Users attempting ESM imports may encounter errors.","severity":"gotcha","affected_versions":"<=2.0.2"},{"fix":"Always use `PEGUtil.parse(parser, input, options)` to leverage the utility features within your Peggy grammars.","message":"The `makeUnroll` and `makeAST` utilities are only injected into the grammar's `options.util` object when parsing via `PEGUtil.parse`. If you use Peggy's standard `PEG.parse` method directly, these utilities will be undefined within your grammar rules, leading to runtime errors like `options.util is undefined`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If using the AST generation features as demonstrated, ensure `asty` is installed: `npm install asty`.","message":"While `pegjs-util`'s examples extensively use `asty` for Abstract Syntax Tree (AST) generation, `asty` is not a direct runtime dependency of `pegjs-util`. Users who wish to utilize the AST generation features shown in the examples must explicitly install `asty` (i.e., `npm install asty`) in their project.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure your project uses `peggy` (version 1.x or newer) and update `require('pegjs')` or `import 'pegjs'` statements to `require('peggy')` or `import 'peggy'` respectively. Consult Peggy's migration guide for details.","message":"The underlying parser generator transitioned from 'PEG.js' to 'Peggy'. While `pegjs-util` is compatible with 'Peggy', older projects or grammars specifically tied to 'PEG.js' (pre-1.0 versions) might require updates to `peggy` and potentially slight grammar adjustments.","severity":"breaking","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Examine the error message, specifically the expected tokens and the found character at the indicated line and column, and correct the input string or adjust the grammar definition.","cause":"The input string does not conform to the defined Peggy grammar, leading to a parsing error reported by pegjs-util's enhanced error handling.","error":"ERROR: Parsing Failure:\\nERROR: line X (column Y): ...\\nERROR: ---^\\nERROR: Expected \"Z\" or end of input but \"A\" found."},{"fix":"Ensure that your parser execution uses `PEGUtil.parse(parser, input, options)` instead of Peggy's direct `parser.parse(input, options)`.","cause":"This error occurs within a Peggy grammar action (e.g., when calling `options.util.makeUnroll` or `options.util.makeAST`) if the parser was not invoked using `PEGUtil.parse`. `PEGUtil.parse` is responsible for injecting the `util` object into the options passed to grammar actions.","error":"TypeError: Cannot read properties of undefined (reading 'util')"},{"fix":"Install the `asty` package (`npm install asty`) and ensure it is correctly imported (`const ASTY = require('asty');`) in the file where the `makeAST` callback is defined.","cause":"This error typically occurs in the `makeAST` callback provided to `PEGUtil.parse` if the `asty` library is used within that callback but has not been properly imported or installed.","error":"ReferenceError: asty is not defined"}],"ecosystem":"npm"}