CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-peggy

Parser generator for JavaScript that produces fast parsers with excellent error reporting capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

cli.mddocs/

Command Line Interface

Command-line tools for generating parsers, testing grammars, and working with Peggy from the terminal. The Peggy CLI provides comprehensive functionality for parser development workflows.

Capabilities

CLI Interface

Main command-line interface class that handles argument parsing and command execution.

class PeggyCLI extends Command {
  /**
   * Create CLI instance with optional custom stdio streams
   * @param stdio - Custom streams for testing (optional)
   */
  constructor(stdio?: Stdio);
  
  /**
   * Parse command line arguments asynchronously
   * @returns Promise resolving to configured CLI instance
   * @throws {CommanderError} If command line arguments are invalid
   */
  parseAsync(): Promise<PeggyCLI>;
  
  /**
   * Execute the main CLI functionality
   * @returns Promise resolving to exit code (0 for success, 1 for error)
   */
  main(): Promise<number>;
  
  /** Parser options for generation */
  parserOptions: SourceOptionsBase<"ast">;
  /** Program options for execution */
  progOptions: ProgOptions;
  /** Standard input/output streams */
  std: Stdio;
}

/**
 * Standard I/O interface for CLI
 */
interface Stdio {
  in: Readable;
  out: Writable;
  err: Writable;
}

/**
 * Command-line parsing error
 */
class CommanderError extends Error {
  code: string;
  exitCode: number;
}

/**
 * Invalid argument error
 */
class InvalidArgumentError extends CommanderError {
  argument: string;
  value: any;
  reason: string;
}

Basic CLI Usage:

# Generate parser from grammar file
peggy grammar.peggy

# Generate parser with specific output file
peggy grammar.peggy -o parser.js

# Generate CommonJS module
peggy grammar.peggy --format commonjs

# Generate with allowed start rules
peggy grammar.peggy --allowed-start-rules rule1,rule2,rule3

# Enable caching for better performance
peggy grammar.peggy --cache

# Generate with tracing enabled
peggy grammar.peggy --trace

Command Line Options

The Peggy CLI supports extensive options for configuring parser generation:

# Input and Output
peggy [options] [input_file...]     # Grammar files to read (default: stdin)
peggy [options] <grammar_file> -o <output_file>

# Format Options
--format <format>                   # Output format: amd, bare, commonjs, es, globals, umd (default: commonjs)
-e, --export-var <variable>         # Global variable name (for globals/umd formats)

# Parser Options
--allowed-start-rules <rules>       # Comma-separated list of allowed start rules (use '*' for all)
--cache                            # Enable result caching for better performance
--trace                            # Enable parser tracing for debugging

# Module Dependencies  
-d, --dependency <dependency>       # Module dependency (format: variable:module)
-D, --dependencies <json>           # Dependencies as JSON object

# Output Control
-o, --output <file>                # Output file (default: auto-generated from input)
--ast                              # Output grammar AST instead of parser code
--dts                              # Create TypeScript declaration file

# Source Maps
-m, --source-map [mapfile]         # Generate source map file or inline

# Testing and Development  
-t, --test <text>                  # Test parser with given text
-T, --test-file <filename>         # Test parser with file contents
-S, --start-rule <rule>            # Start rule for testing
-w, --watch                        # Watch input files and regenerate on changes

# Advanced Options
--plugin <module>                  # Load plugin modules
--extra-options <options>          # Additional JSON options for generate()
-c, --extra-options-file <file>    # Load additional options from file
--return-types <typeInfo>          # Type information for rules (JSON)
--verbose                          # Enable verbose logging

# Help and Information
-h, --help                         # Display help information
-v, --version                      # Display version number

Advanced CLI Examples:

# Generate ES module with dependencies
peggy grammar.peggy \
  --format es \
  --dependency "fs:fs" \
  --dependency "path:path" \
  -o parser.mjs

# Generate UMD module with global variable
peggy grammar.peggy \
  --format umd \
  --export-var MyParser \
  -o parser.umd.js

# Generate with multiple start rules and caching
peggy grammar.peggy \
  --allowed-start-rules "expression,statement,program" \
  --cache \
  --trace \
  -o parser.js

# Generate source with inline source map
peggy grammar.peggy \
  --output-format source-with-inline-map \
  -o parser.js

CLI Error Handling

The CLI provides detailed error reporting for both command-line and grammar errors:

# Grammar syntax errors
$ peggy invalid.peggy
Error: Expected "!", "$", "&", "(", ".", "@", character class, comment, end of line, identifier, literal, or whitespace but "#" found.
 --> invalid.peggy:3:9
  |
3 | start = # 'a';
  |         ^

# Grammar semantic errors  
$ peggy undefined-rule.peggy
Error: Rule "undefined_rule" is not defined
 --> undefined-rule.peggy:1:9
  |
1 | start = undefined_rule
  |         ^^^^^^^^^^^^^

# Command line errors
$ peggy --format invalid grammar.peggy
Error: Invalid format: invalid
Valid formats: amd, bare, commonjs, es, globals, umd

$ peggy --allowed-start-rules nonexistent grammar.peggy
Error: Unknown start rule "nonexistent"

Programmatic CLI Usage

Using the CLI classes programmatically for custom build tools and integrations:

import { PeggyCLI, CommanderError, InvalidArgumentError } from "peggy/bin/peggy.js";

async function generateParser(args: string[]): Promise<number> {
  try {
    // Create CLI instance with custom arguments
    process.argv = ["node", "peggy", ...args];
    
    const cli = new PeggyCLI();
    await cli.parseAsync();
    
    // Execute CLI functionality
    const exitCode = await cli.main();
    return exitCode;
    
  } catch (error) {
    if (error instanceof CommanderError) {
      console.error("CLI Error:", error.message);
      return error.exitCode;
    } else if (error instanceof InvalidArgumentError) {
      console.error(`Invalid argument ${error.argument}: ${error.reason}`);
      return 1;
    } else {
      console.error("Unexpected error:", error);
      return 1;
    }
  }
}

Programmatic Usage Example:

import { PeggyCLI } from "peggy/bin/peggy.js";

async function buildParser() {
  // Simulate command line arguments
  const args = [
    "my-grammar.peggy",
    "--format", "commonjs",
    "--cache",
    "--allowed-start-rules", "expression,statement",
    "-o", "dist/parser.js"
  ];
  
  const exitCode = await generateParser(args);
  
  if (exitCode === 0) {
    console.log("Parser generated successfully");
  } else {
    console.error("Parser generation failed");
  }
}

Integration with Build Tools

Examples of integrating Peggy CLI with common build tools:

npm scripts (package.json):

{
  "scripts": {
    "build:parser": "peggy src/grammar.peggy -o lib/parser.js --format commonjs --cache",
    "build:parser:es": "peggy src/grammar.peggy -o dist/parser.mjs --format es",
    "build:parsers": "npm run build:parser && npm run build:parser:es",
    "watch:parser": "nodemon --watch src/grammar.peggy --exec 'npm run build:parser'"
  },
  "devDependencies": {
    "peggy": "^5.0.6",
    "nodemon": "^3.0.0"
  }
}

Makefile:

# Parser generation targets
lib/parser.js: src/grammar.peggy
	peggy $< -o $@ --format commonjs --cache

dist/parser.mjs: src/grammar.peggy  
	peggy $< -o $@ --format es

dist/parser.umd.js: src/grammar.peggy
	peggy $< -o $@ --format umd --export-var MyParser

# Build all parser variants
parsers: lib/parser.js dist/parser.mjs dist/parser.umd.js

# Clean generated files
clean:
	rm -f lib/parser.js dist/parser.mjs dist/parser.umd.js

.PHONY: parsers clean

Gulp task:

const { spawn } = require('child_process');
const gulp = require('gulp');

function buildParser() {
  return new Promise((resolve, reject) => {
    const peggy = spawn('peggy', [
      'src/grammar.peggy',
      '-o', 'lib/parser.js',
      '--format', 'commonjs',
      '--cache'
    ]);
    
    peggy.on('close', (code) => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(`Peggy exited with code ${code}`));
      }
    });
  });
}

gulp.task('parser', buildParser);

gulp.task('watch:parser', () => {
  gulp.watch('src/grammar.peggy', gulp.series('parser'));
});

CLI Configuration Files

While Peggy CLI doesn't support configuration files directly, you can create wrapper scripts for complex configurations:

peggy-config.js:

#!/usr/bin/env node
const { PeggyCLI } = require('peggy/bin/peggy.js');

const configurations = {
  development: [
    'src/grammar.peggy',
    '--format', 'commonjs',
    '--trace',
    '--cache',
    '-o', 'lib/parser.dev.js'
  ],
  
  production: [
    'src/grammar.peggy', 
    '--format', 'es',
    '--cache',
    '-o', 'dist/parser.js'
  ],
  
  browser: [
    'src/grammar.peggy',
    '--format', 'umd',
    '--export-var', 'MyParser',
    '-o', 'dist/parser.umd.js'
  ]
};

async function build(env = 'development') {
  const config = configurations[env];
  if (!config) {
    console.error(`Unknown environment: ${env}`);
    process.exit(1);
  }
  
  process.argv = ['node', 'peggy', ...config];
  
  try {
    const cli = new PeggyCLI();
    await cli.parseAsync();
    const exitCode = await cli.main();
    process.exit(exitCode);
  } catch (error) {
    console.error('Build failed:', error.message);
    process.exit(1);
  }
}

// Usage: node peggy-config.js [development|production|browser]
const env = process.argv[2] || 'development';
build(env);

Usage:

# Use configuration script
node peggy-config.js development
node peggy-config.js production  
node peggy-config.js browser

# Or add to package.json scripts
npm run build:dev    # node peggy-config.js development
npm run build:prod   # node peggy-config.js production
npm run build:browser # node peggy-config.js browser

Install with Tessl CLI

npx tessl i tessl/npm-peggy

docs

ast-compilation.md

cli.md

generated-parsers.md

grammar-parsing.md

index.md

parser-generation.md

tile.json