Parser generator for JavaScript that produces fast parsers with excellent error reporting capabilities
npx @tessl/cli install tessl/npm-peggy@5.0.0Peggy is a simple parser generator for JavaScript that produces fast parsers with excellent error reporting. You can use it to process complex data or computer languages and build transformers, interpreters, compilers and other tools easily. Peggy uses parsing expression grammar (PEG) formalism, which is more powerful than traditional LL(k) and LR(k) parsers, integrating both lexical and syntactical analysis in a single step.
npm install peggynpm install source-map-generator (optional, for source map functionality)import { generate, VERSION, RESERVED_WORDS, GrammarError, GrammarLocation, parser, compiler } from "peggy";For CommonJS:
const { generate, VERSION, RESERVED_WORDS, GrammarError, GrammarLocation, parser, compiler } = require("peggy");For source map functionality:
import { SourceNode } from "source-map-generator";For AST types and visitor system:
import type { ast } from "peggy";import { generate } from "peggy";
// Define a simple arithmetic grammar
const grammar = `
Expression
= Term (("+" / "-") Term)*
Term
= Factor (("*" / "/") Factor)*
Factor
= "(" Expression ")"
/ Number
Number
= [0-9]+
`;
// Generate a parser from the grammar
const parser = generate(grammar);
// Use the generated parser
try {
const result = parser.parse("2 + 3 * 4");
console.log(result); // Parse result
} catch (error) {
console.error("Parse error:", error.message);
}Peggy is built around several key components:
Core functionality for generating parsers from PEG grammars. The main entry point for all parser generation operations.
function generate(grammar: GrammarInput, options?: ParserBuildOptions): Parser;
function generate(grammar: GrammarInput, options: SourceBuildOptions<"source">): string;
function generate(grammar: GrammarInput, options: SourceBuildOptions<"source-and-map">): SourceNode;
function generate(grammar: GrammarInput, options: SourceBuildOptions<"source-with-inline-map">): string;
function generate(grammar: GrammarInput, options: SourceOptionsBase<"ast">): ast.Grammar;
type GrammarInput = SourceText[] | string;
interface SourceText {
source: any;
text: string;
}Low-level grammar parsing functionality for converting PEG grammar strings into Abstract Syntax Trees.
namespace parser {
function parse(grammar: string, options?: Options): ast.Grammar;
interface Options {
grammarSource?: any;
reservedWords: string[];
startRule?: "Grammar";
}
}Advanced compilation system with multiple passes for transforming, validating, and optimizing grammar ASTs.
namespace compiler {
function compile(ast: ast.Grammar, stages: Stages, options?: ParserBuildOptions): Parser;
interface Stages {
prepare: Pass[];
check: Pass[];
transform: Pass[];
generate: Pass[];
}
}Interface and capabilities of parsers generated by Peggy, including parsing options and error handling.
interface Parser {
StartRules: string[];
SyntaxError: typeof parser.SyntaxError;
parse(input: string, options?: ParserOptions): any;
}
interface ParserOptions {
grammarSource?: any;
startRule?: string;
tracer?: ParserTracer;
}Command-line tools for generating parsers, testing grammars, and working with Peggy from the terminal.
class PeggyCLI {
parseAsync(): Promise<PeggyCLI>;
main(): Promise<number>;
}/** Current Peggy version in semver format */
const VERSION: string;
/** Default list of reserved words. Contains list of JavaScript reserved words */
const RESERVED_WORDS: string[];
/** Thrown if the grammar contains a semantic error */
class GrammarError extends SyntaxError {
location?: LocationRange;
diagnostics: DiagnosticNote[];
stage: Stage | null;
problems: Problem[];
format(sources: SourceText[]): string;
}
/** Location tracking for grammars in larger files */
class GrammarLocation {
source: any;
start: Location;
constructor(source: unknown, start: Location);
static offsetStart(range: LocationRange): Location;
static offsetEnd(range: LocationRange): Location;
offset(loc: Location): Location;
}
/** Position information */
interface Location {
line: number;
column: number;
offset: number;
}
/** Range information */
interface LocationRange {
source: any;
start: Location;
end: Location;
}
/** Source text entry for error formatting */
interface SourceText {
source: any;
text: string;
}
/** Grammar input type */
type GrammarInput = SourceText[] | string;interface ParserBuildOptions extends BuildOptionsBase {
output?: "parser";
}
interface SourceBuildOptions<Output extends SourceOutputs = "source"> extends BuildOptionsBase {
output: Output;
format?: "amd" | "bare" | "commonjs" | "es" | "globals" | "umd";
dependencies?: Dependencies;
exportVar?: string;
}
interface BuildOptionsBase {
allowedStartRules?: string[];
cache?: boolean;
grammarSource?: any;
plugins?: Plugin[];
trace?: boolean;
error?: DiagnosticCallback;
warning?: DiagnosticCallback;
info?: DiagnosticCallback;
reservedWords?: string[];
}
/** Parser dependencies mapping */
interface Dependencies {
[variable: string]: string;
}
/** Plugin interface */
interface Plugin {
use(config: Config, options: ParserBuildOptions): void;
}
/** Plugin configuration */
interface Config {
parser: Parser;
passes: Stages;
reservedWords: string[];
}