Peggy Parser Generator
Peggy is a robust, open-source parser generator for JavaScript that serves as the successor to the popular PEG.js project. It enables developers to define grammars using a simple and expressive syntax based on parsing expression grammar (PEG) formalism, which is more powerful than traditional LL(k) and LR(k) parsers. Peggy integrates both lexical and syntactical analysis and produces fast parsers with excellent error reporting capabilities. The current stable version is 5.1.0, with regular patch and minor releases, and major versions released less frequently. Key differentiators include its superior error reporting, integration of lexical and syntactical analysis, and being usable across various environments: browsers (via an online tool), command line, and as a JavaScript API. It also provides source map support and ships with TypeScript definitions, making it well-suited for modern JavaScript and TypeScript development workflows. It requires Node.js version 20 or higher.
Common errors
-
Error: Cannot find module 'pegjs'
cause You have migrated from PEG.js but have not updated all `require` or `import` statements to reference `peggy` instead.fixGlobally replace `pegjs` with `peggy` in your project's source code and configuration files. -
ReferenceError: require is not defined
cause You are attempting to use CommonJS `require()` syntax for Peggy imports within an ES Module (ESM) context in Node.js, or your generated parser code (pre-v5) is being run in an ESM context without proper transpilation.fixFor Peggy imports, use `import ... from 'peggy';`. For generated parsers in v5+, ensure your project is configured for ESM or transpile the output if targeting an older CJS environment or browser. -
SyntaxError: 'SyntaxError' constructor should not have a return type.
cause This specific TypeScript error indicates an incompatibility with older `peggy.d.ts` definitions (e.g., from v5.0.1 or v5.0.2) when using TypeScript to compile code that imports `SyntaxError` from 'peggy'.fixUpdate Peggy to the latest `5.x.x` patch version (e.g., 5.1.0) to get the corrected TypeScript definitions. -
TypeError: Cannot read properties of undefined (reading 'text')
cause This often occurs within semantic actions (`{ return text(); }`) in your grammar when `text()` is called outside a rule that has matched any input or if the `text()` function isn't available in the current scope for some reason.fixEnsure `text()` is called within a rule's action block and that the rule has successfully matched some input. Verify that the `text()` function is correctly defined and accessible in the context of your generated parser's actions.
Warnings
- breaking Peggy v5.0.0 and later no longer supports ES5 for generated parser code. Generated code now requires ES2020 features (e.g., `const`, `let`). If you need to support earlier runtimes, you must use a transpiler like Babel.
- gotcha When migrating from PEG.js, all `require('pegjs')` or `import ... from 'pegjs'` statements must be updated to `require('peggy')` or `import ... from 'peggy'`. Similarly, any command-line usage of `pegjs` should be replaced with `peggy`.
- breaking As of v5.0.6, Peggy switched from `tsc` and `rollup` to `tsup` for its own code generation. This change might be user-visible as `tsup` injects different polyfills, potentially affecting the runtime behavior of Peggy itself if you rely on specific polyfills in a custom build pipeline.
- gotcha Peggy requires Node.js version 20 or higher. Running Peggy with older Node.js versions will result in errors.
- gotcha Previous versions (e.g., 5.0.1, 5.0.2) had TypeScript definition issues related to `SyntaxError` constructor and return types. While fixed in later patches, if you're stuck on an older 5.x patch, you might encounter type-checking problems.
Install
-
npm install peggy -
yarn add peggy -
pnpm add peggy
Imports
- generate
const generate = require('peggy').generate;import { generate } from 'peggy'; - SyntaxError
import { PeggySyntaxError } from 'peggy';import { SyntaxError } from 'peggy'; - cli
import { cli } from 'peggy';
Quickstart
import { generate } from 'peggy';
const grammar = `
start = expression
expression = term (('+' / '-') term)*
term = factor (('*' / '/') factor)*
factor = number / '(' expression ')'
number 'number' = [0-9]+ { return parseInt(text()); }
`;
try {
const parser = generate(grammar, { output: 'parser', format: 'es' });
const result = parser.parse('1 + 2 * (3 - 4)');
console.log('Parse successful:', result);
// Example of a syntax error
parser.parse('1 +');
} catch (e: any) {
if (e.name === 'SyntaxError') {
console.error(`Syntax Error at line ${e.location.start.line}, column ${e.location.start.column}: ${e.message}`);
} else {
console.error('An unexpected error occurred:', e);
}
}