CLI Reference — rdp-gen
rdp-gen is the code generator bundled with @configuredthings/rdp.js. The same functionality is available programmatically via the generateParser function in the @configuredthings/rdp.js/generator module.
It reads a grammar file (EBNF or ABNF) and emits a strictly-typed TypeScript
parser class that extends RDParser or ObservableRDParser, together with
exported discriminated-union types for every node in the parse tree.
The generated output compiles cleanly under strict: true and
noUncheckedIndexedAccess: true with no type errors.
Installation
Install the package globally to get rdp-gen on your PATH:
npm install -g @configuredthings/rdp.jsOr use it locally via npx:
npx rdp-gen grammar.ebnf --parser-name MyParserrdp-gen <grammar> — generate a parser
rdp-gen <grammar> [options]
| Option | Default | Description |
|---|---|---|
<grammar> | (required) | Path to a .ebnf or .abnf grammar file |
-o, --outdir <dir> | stdout | Write output files to a directory; each artifact gets a derived filename |
--format <fmt> | inferred from extension | Force ebnf or abnf |
--parser-name <name> | GeneratedParser | Class name for the generated parser |
--tree-name <name> | ParseTree | Type name for the generated parse tree |
--observable | off | Extend ObservableRDParser; adds notifyEnter/notifyExit calls |
--lexer <strategy> | scannerless | Lexer strategy: scannerless (default) or span (emits a span-tokeniser scaffold) |
--traversal <strategy> | — | Emit a traversal scaffold: interpreter or tree-walker (see below) |
--transformer [json] | — | Emit a transformer scaffold; pass json for the two-way JSON variant |
--facade | off | Wrap the scaffold in a module-as-facade (requires --traversal) |
--pipeline | off | Add parse / validate / transform stages (requires --traversal tree-walker) |
--ast-only | off | Emit the grammar AST as JSON (used by the playground) |
--abnf-case-sensitive-strings | off | Match ABNF quoted string literals case-sensitively |
Examples
Generate a parser to a directory (writes src/JsonParser.ts):
rdp-gen grammar.ebnf --parser-name JsonParser --outdir src/Generate with tracing support:
rdp-gen grammar.ebnf --parser-name MyParser --observable --outdir src/Parse an ABNF grammar and write to stdout:
rdp-gen protocol.abnf --format abnf --parser-name FrameParserTraversal stubs (--traversal)
When used alone (without --facade, --pipeline, or --transformer), --traversal
adds evaluation scaffolding directly to the generated parser file — the output is
still a parser, not a separate scaffold. Because the stubs follow the grammar
mechanically, the file can be regenerated as the grammar evolves.
| Flags | What it adds to the parser |
|---|---|
--traversal interpreter | Parser class implements InterpreterMixin<ParseTree, unknown> — one eval{Rule}(node): unknown stub per rule and a static evaluate() entry point |
--traversal tree-walker | Exports a walk(root, fn) function alongside the existing childNodes() helper; includes a commented-out Visitor template covering every rule |
# Generate (or regenerate) a parser with interpreter stubs baked in (writes src/DateParser.ts)
rdp-gen date.ebnf --parser-name DateParser --traversal interpreter --outdir src/When --traversal is combined with --facade, --pipeline, or --transformer, the
traversal strategy moves inside the scaffold — see Scaffolding below.
Scaffolding
When any of --transformer, --facade, --pipeline, or --lexer span is
present, rdp-gen emits a scaffold rather than a parser. A scaffold is a
one-time starter file — unlike the generated parser it is not designed to be
regenerated. It imports the parser by a relative path, wires up the chosen pattern,
and leaves stubs for you to fill in. See also the
generateScaffold programmatic API
and the arithmetic worked example for patterns applied to
a real grammar.
| Flags | What it emits |
|---|---|
--traversal interpreter --facade | Module-as-facade: parse{Base}(), {Base}Result class with from(), private eval functions |
--traversal tree-walker --facade | Module-as-facade: parse{Base}(), {Base}Result class, private walk utility and visitor stubs |
--traversal tree-walker --pipeline | Exported parse/validate/transform + load{Base}() combinator; tree-walker inside transform |
--traversal tree-walker --pipeline --facade | Module-as-facade wrapping a pipeline with a tree walker inside #transform |
--transformer | Exported Transformer<ParseTree, unknown> object with a stub per rule + entry function |
--transformer json | Two-way stubs: {Base}ToJSON: Transformer<ParseTree, JSONAST> and jsonTo{Base}: Transformer<JSONAST, string> plus round-trip helpers |
--lexer span | Span tokeniser + classifier + {Base}TokenParser stubs (see Tokenising for performance) |
Flag compatibility
The scaffold flags are designed to compose. The table below shows which combinations are valid (✓), invalid (✗), or not applicable (—). The one constraint is that --traversal interpreter cannot be combined with --pipeline — the interpreter evaluates directly during traversal, leaving no intermediate tree for the validate stage.
--facade | --pipeline | --transformer [json] | |
|---|---|---|---|
--traversal interpreter | ✓ | ✗ | — |
--traversal tree-walker | ✓ | ✓ | — |
--pipeline | ✓ | — | — |
--facade | — | ✓ | ✓ |
--transformer [json] | ✓ | — |