or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-compilation.mdcli.mdgenerated-parsers.mdgrammar-parsing.mdindex.mdparser-generation.md

cli.mddocs/

0

# Command Line Interface

1

2

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.

3

4

## Capabilities

5

6

### CLI Interface

7

8

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

9

10

```typescript { .api }

11

class PeggyCLI extends Command {

12

/**

13

* Create CLI instance with optional custom stdio streams

14

* @param stdio - Custom streams for testing (optional)

15

*/

16

constructor(stdio?: Stdio);

17

18

/**

19

* Parse command line arguments asynchronously

20

* @returns Promise resolving to configured CLI instance

21

* @throws {CommanderError} If command line arguments are invalid

22

*/

23

parseAsync(): Promise<PeggyCLI>;

24

25

/**

26

* Execute the main CLI functionality

27

* @returns Promise resolving to exit code (0 for success, 1 for error)

28

*/

29

main(): Promise<number>;

30

31

/** Parser options for generation */

32

parserOptions: SourceOptionsBase<"ast">;

33

/** Program options for execution */

34

progOptions: ProgOptions;

35

/** Standard input/output streams */

36

std: Stdio;

37

}

38

39

/**

40

* Standard I/O interface for CLI

41

*/

42

interface Stdio {

43

in: Readable;

44

out: Writable;

45

err: Writable;

46

}

47

48

/**

49

* Command-line parsing error

50

*/

51

class CommanderError extends Error {

52

code: string;

53

exitCode: number;

54

}

55

56

/**

57

* Invalid argument error

58

*/

59

class InvalidArgumentError extends CommanderError {

60

argument: string;

61

value: any;

62

reason: string;

63

}

64

```

65

66

**Basic CLI Usage:**

67

68

```bash

69

# Generate parser from grammar file

70

peggy grammar.peggy

71

72

# Generate parser with specific output file

73

peggy grammar.peggy -o parser.js

74

75

# Generate CommonJS module

76

peggy grammar.peggy --format commonjs

77

78

# Generate with allowed start rules

79

peggy grammar.peggy --allowed-start-rules rule1,rule2,rule3

80

81

# Enable caching for better performance

82

peggy grammar.peggy --cache

83

84

# Generate with tracing enabled

85

peggy grammar.peggy --trace

86

```

87

88

### Command Line Options

89

90

The Peggy CLI supports extensive options for configuring parser generation:

91

92

```bash

93

# Input and Output

94

peggy [options] [input_file...] # Grammar files to read (default: stdin)

95

peggy [options] <grammar_file> -o <output_file>

96

97

# Format Options

98

--format <format> # Output format: amd, bare, commonjs, es, globals, umd (default: commonjs)

99

-e, --export-var <variable> # Global variable name (for globals/umd formats)

100

101

# Parser Options

102

--allowed-start-rules <rules> # Comma-separated list of allowed start rules (use '*' for all)

103

--cache # Enable result caching for better performance

104

--trace # Enable parser tracing for debugging

105

106

# Module Dependencies

107

-d, --dependency <dependency> # Module dependency (format: variable:module)

108

-D, --dependencies <json> # Dependencies as JSON object

109

110

# Output Control

111

-o, --output <file> # Output file (default: auto-generated from input)

112

--ast # Output grammar AST instead of parser code

113

--dts # Create TypeScript declaration file

114

115

# Source Maps

116

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

117

118

# Testing and Development

119

-t, --test <text> # Test parser with given text

120

-T, --test-file <filename> # Test parser with file contents

121

-S, --start-rule <rule> # Start rule for testing

122

-w, --watch # Watch input files and regenerate on changes

123

124

# Advanced Options

125

--plugin <module> # Load plugin modules

126

--extra-options <options> # Additional JSON options for generate()

127

-c, --extra-options-file <file> # Load additional options from file

128

--return-types <typeInfo> # Type information for rules (JSON)

129

--verbose # Enable verbose logging

130

131

# Help and Information

132

-h, --help # Display help information

133

-v, --version # Display version number

134

```

135

136

**Advanced CLI Examples:**

137

138

```bash

139

# Generate ES module with dependencies

140

peggy grammar.peggy \

141

--format es \

142

--dependency "fs:fs" \

143

--dependency "path:path" \

144

-o parser.mjs

145

146

# Generate UMD module with global variable

147

peggy grammar.peggy \

148

--format umd \

149

--export-var MyParser \

150

-o parser.umd.js

151

152

# Generate with multiple start rules and caching

153

peggy grammar.peggy \

154

--allowed-start-rules "expression,statement,program" \

155

--cache \

156

--trace \

157

-o parser.js

158

159

# Generate source with inline source map

160

peggy grammar.peggy \

161

--output-format source-with-inline-map \

162

-o parser.js

163

```

164

165

### CLI Error Handling

166

167

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

168

169

```bash

170

# Grammar syntax errors

171

$ peggy invalid.peggy

172

Error: Expected "!", "$", "&", "(", ".", "@", character class, comment, end of line, identifier, literal, or whitespace but "#" found.

173

--> invalid.peggy:3:9

174

|

175

3 | start = # 'a';

176

| ^

177

178

# Grammar semantic errors

179

$ peggy undefined-rule.peggy

180

Error: Rule "undefined_rule" is not defined

181

--> undefined-rule.peggy:1:9

182

|

183

1 | start = undefined_rule

184

| ^^^^^^^^^^^^^

185

186

# Command line errors

187

$ peggy --format invalid grammar.peggy

188

Error: Invalid format: invalid

189

Valid formats: amd, bare, commonjs, es, globals, umd

190

191

$ peggy --allowed-start-rules nonexistent grammar.peggy

192

Error: Unknown start rule "nonexistent"

193

```

194

195

### Programmatic CLI Usage

196

197

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

198

199

```typescript { .api }

200

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

201

202

async function generateParser(args: string[]): Promise<number> {

203

try {

204

// Create CLI instance with custom arguments

205

process.argv = ["node", "peggy", ...args];

206

207

const cli = new PeggyCLI();

208

await cli.parseAsync();

209

210

// Execute CLI functionality

211

const exitCode = await cli.main();

212

return exitCode;

213

214

} catch (error) {

215

if (error instanceof CommanderError) {

216

console.error("CLI Error:", error.message);

217

return error.exitCode;

218

} else if (error instanceof InvalidArgumentError) {

219

console.error(`Invalid argument ${error.argument}: ${error.reason}`);

220

return 1;

221

} else {

222

console.error("Unexpected error:", error);

223

return 1;

224

}

225

}

226

}

227

```

228

229

**Programmatic Usage Example:**

230

231

```typescript

232

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

233

234

async function buildParser() {

235

// Simulate command line arguments

236

const args = [

237

"my-grammar.peggy",

238

"--format", "commonjs",

239

"--cache",

240

"--allowed-start-rules", "expression,statement",

241

"-o", "dist/parser.js"

242

];

243

244

const exitCode = await generateParser(args);

245

246

if (exitCode === 0) {

247

console.log("Parser generated successfully");

248

} else {

249

console.error("Parser generation failed");

250

}

251

}

252

```

253

254

### Integration with Build Tools

255

256

Examples of integrating Peggy CLI with common build tools:

257

258

**npm scripts (package.json):**

259

260

```json

261

{

262

"scripts": {

263

"build:parser": "peggy src/grammar.peggy -o lib/parser.js --format commonjs --cache",

264

"build:parser:es": "peggy src/grammar.peggy -o dist/parser.mjs --format es",

265

"build:parsers": "npm run build:parser && npm run build:parser:es",

266

"watch:parser": "nodemon --watch src/grammar.peggy --exec 'npm run build:parser'"

267

},

268

"devDependencies": {

269

"peggy": "^5.0.6",

270

"nodemon": "^3.0.0"

271

}

272

}

273

```

274

275

**Makefile:**

276

277

```makefile

278

# Parser generation targets

279

lib/parser.js: src/grammar.peggy

280

peggy $< -o $@ --format commonjs --cache

281

282

dist/parser.mjs: src/grammar.peggy

283

peggy $< -o $@ --format es

284

285

dist/parser.umd.js: src/grammar.peggy

286

peggy $< -o $@ --format umd --export-var MyParser

287

288

# Build all parser variants

289

parsers: lib/parser.js dist/parser.mjs dist/parser.umd.js

290

291

# Clean generated files

292

clean:

293

rm -f lib/parser.js dist/parser.mjs dist/parser.umd.js

294

295

.PHONY: parsers clean

296

```

297

298

**Gulp task:**

299

300

```javascript

301

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

302

const gulp = require('gulp');

303

304

function buildParser() {

305

return new Promise((resolve, reject) => {

306

const peggy = spawn('peggy', [

307

'src/grammar.peggy',

308

'-o', 'lib/parser.js',

309

'--format', 'commonjs',

310

'--cache'

311

]);

312

313

peggy.on('close', (code) => {

314

if (code === 0) {

315

resolve();

316

} else {

317

reject(new Error(`Peggy exited with code ${code}`));

318

}

319

});

320

});

321

}

322

323

gulp.task('parser', buildParser);

324

325

gulp.task('watch:parser', () => {

326

gulp.watch('src/grammar.peggy', gulp.series('parser'));

327

});

328

```

329

330

### CLI Configuration Files

331

332

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

333

334

**peggy-config.js:**

335

336

```javascript

337

#!/usr/bin/env node

338

const { PeggyCLI } = require('peggy/bin/peggy.js');

339

340

const configurations = {

341

development: [

342

'src/grammar.peggy',

343

'--format', 'commonjs',

344

'--trace',

345

'--cache',

346

'-o', 'lib/parser.dev.js'

347

],

348

349

production: [

350

'src/grammar.peggy',

351

'--format', 'es',

352

'--cache',

353

'-o', 'dist/parser.js'

354

],

355

356

browser: [

357

'src/grammar.peggy',

358

'--format', 'umd',

359

'--export-var', 'MyParser',

360

'-o', 'dist/parser.umd.js'

361

]

362

};

363

364

async function build(env = 'development') {

365

const config = configurations[env];

366

if (!config) {

367

console.error(`Unknown environment: ${env}`);

368

process.exit(1);

369

}

370

371

process.argv = ['node', 'peggy', ...config];

372

373

try {

374

const cli = new PeggyCLI();

375

await cli.parseAsync();

376

const exitCode = await cli.main();

377

process.exit(exitCode);

378

} catch (error) {

379

console.error('Build failed:', error.message);

380

process.exit(1);

381

}

382

}

383

384

// Usage: node peggy-config.js [development|production|browser]

385

const env = process.argv[2] || 'development';

386

build(env);

387

```

388

389

**Usage:**

390

391

```bash

392

# Use configuration script

393

node peggy-config.js development

394

node peggy-config.js production

395

node peggy-config.js browser

396

397

# Or add to package.json scripts

398

npm run build:dev # node peggy-config.js development

399

npm run build:prod # node peggy-config.js production

400

npm run build:browser # node peggy-config.js browser

401

```