Releases: ConfiguredThings/RDP.js
Releases · ConfiguredThings/RDP.js
v0.7.0
Added
generateScaffoldFiles(source, flags, options): Record<string, string>— new programmatic API that returns a map of filename → content; used by the CLI when--outdiris given (#25)InterpreterMixin<TTree, TResult>andWalkerMixin<TTree>exported from the main package — TypeScript mixin interfaces for interpreter and tree-walker traversal patterns
Fixed
--transformer json --facade --pipelinenow produces three separate scaffold files ({base}-transformer.ts,{base}-pipeline.ts,{base}-facade.ts) so the facade is a genuine module boundary; consumers import only from the facade (#25)
Changed
--output <file>renamed to--outdir <dir>— the flag now accepts a directory; artifact filenames are derived from the parser base name (e.g.date-facade.ts,date-transformer.ts) (#25)--traversalalone now adds mixin stubs directly to the generated parser file (can be re-generated freely) rather than producing a separate scaffold file. Using--traversaltogether with--facade,--pipeline, or--transformerstill produces a scaffold file
v0.6.0
Added
ScannerlessRDParser— concrete character-by-character parser, extracted fromRDParser. Replaces directRDParserextension for scannerless grammars.TokenRDParserandTokenStream— new parser variant that operates over a pre-tokenised token stream rather than raw bytes.withObservable(Base)— mixin function that addsParseObserversupport to anyRDParsersubclass (e.g.withObservable(TokenRDParser)).--scaffoldnow accepts a--lexer spanflag, emitting a span-tokeniser and classifier pipeline scaffold.
Changed
RDParseris now an abstract base class. It no longer contains character-reading methods (peek,advance,matchChar, etc.) — those live onScannerlessRDParser. Existing parsers that extendedRDParserdirectly must switch toScannerlessRDParser.ObservableRDParsernow extendsScannerlessRDParserinstead ofRDParser.ScaffoldFlagstype replaced the previous scaffold option shape with orthogonal flags (traversal,transformer,facade,pipeline,lexer). Invalid combinations (e.g.--traversal interpreter --pipelinewithout--facade) now throw at codegen time.- Generated parser scaffolds reference
ScannerlessRDParserinstead ofRDParser(except--lexer spanscaffolds, which useTokenRDParser).
v0.5.0
Added
Transformer<Union, T>type andtransform()function exported from the main package — likeVisitorbut with required keys, giving a compile-time exhaustiveness guarantee that everykindin the union has a handler.JSONASTdiscriminated union type (string | number | boolean | null | array | object), plustoJSONASTandfromJSONASThelpers, exported from the main package — a typed representation of JSON values for use as aTransformertarget when translating a DSL to JSON.--scaffold transformer— emits an exhaustiveTransformer<ParseTree, T>object with one stub per grammar rule, plus a conveniencetransform<Base>(input)wrapper.--scaffold json-transformer— emits two transformer stubs (<base>ToJSON: Transformer<ParseTree, JSONAST>andjsonTo<Base>: Transformer<JSONAST, string>) and round-trip helpers (<base>ToJSONString/jsonStringTo<Base>) for two-way translation between the grammar's format and JSON.
v0.4.0
Added
--scaffoldnow accepts a composable--inner <strategy>option that specifies the traversal strategy embedded insidefacadeandpipelinewrappers. Eight combinations are now available: two standalone (interpreter,tree-walker) and six composable (facade --inner interpreter,facade --inner tree-walker,facade --inner pipeline:interpreter,facade --inner pipeline:tree-walker,pipeline --inner interpreter,pipeline --inner tree-walker).facadeandpipelinerequire--inner;interpreterandtree-walkerforbid it.ScaffoldInnertype ('interpreter' | 'tree-walker' | 'pipeline:interpreter' | 'pipeline:tree-walker') exported from@configuredthings/rdp.js/generatorfor use with the programmaticgenerateScaffoldAPI.
Changed
childNodeshelper is now always emitted alongside the generated parser; the--walkerflag has been removed. There is no longer any reason to pass a separate flag to get tree-walking support.--scaffold evaluatorrenamed to--scaffold interpreterto align with standard language-implementation terminology.--scaffold walkerrenamed to--scaffold tree-walker;--inner walkerrenamed to--inner tree-walker;--inner pipeline:walkerrenamed to--inner pipeline:tree-walker.
Removed
--walkerflag removed fromrdp-gen <grammar>documentation and generated output.childNodesis unconditionally emitted;--walkeris silently accepted and ignored for backwards compatibility.
v0.3.0
Added
src/grammars/arith.ebnf— canonical arithmetic expression grammar (with whitespace handling, operator precedence, and parenthesised sub-expressions) used throughout worked examples; exported asarithEBNFfrom@configuredthings/rdp.js/grammarssrc/examples/arith/— complete worked example: generatedArithParser(withchildNodeswalker), all four scaffold files (arith-evaluator,arith-facade,arith-pipeline,arith-walker), grammar AST export, and TypeDoc entry point. Documented as theArithExampleAPI modulenpm run generate:examples— regenerates all files insrc/examples/arith/fromarith.ebnfvia the built CLI; follows the same pattern asgenerate:metasrc/__testUtils__/generator-runtime.ts— shared test helpers (transpile,compileAndImport,importScaffold,nav) extracted from duplicate definitions across generator test files- Evaluator scaffold now emits
// node.field: Typeinline comments in each stub function body, showing the exact node shape without requiring users to cross-reference the generated types file - New guide page "Worked Example: Arithmetic Parser" covering the full lifecycle from grammar to generated parser to all four scaffold patterns; linked from README, CLI reference, and Using the Parse Tree
rdp-gen initnow emits a startersrc/<ClassName>.tsalongsidepackage.jsonandtsconfig.json, scaffolding the private-constructor / static-parseboilerplate so a new project compiles immediately (#13)rdp-gen init --observablevariant extendsObservableRDParserinstead ofRDParser; the starter includesnotifyEnter/notifyExitcall sites and accepts an optionalParseObserverparameter instatic parse()rdp-gen generate --scaffold <pattern>emits a one-time starter file for a chosen usage pattern (not regenerated; edit freely). Four patterns are available:evaluator(a typed function per grammar rule),facade(domain error class, public entry point, transform stub),pipeline(parse / validate / transform stage stubs),walker(awalk()utility built onchildNodes) (#17)rdp-gen generate --walkerappends achildNodes(node: ParseTree): ParseTree[]helper to the generated parser file, returning the directParseTreechildren of any node — useful for tree walkers, linters, and formatters (#17)Visitor<Union, T>type andvisit()function exported from the main package — dispatch a parse-tree node to the matching handler in a visitor map without writing explicitswitchstatements; useRequired<Visitor<ParseTree, T>>to enforce exhaustive handling (#17)
Changed
npm run diagramsreplaced bydocs-site/scripts/render-diagrams.sh— auto-discovers all.pumlfiles rather than requiring each to be listed explicitly- Architecture diagram restructured so
grammar.ebnf → Toolchain (build-time) → Your parsersreads left-to-right;skinparam linetype orthoeliminates curved arc arrows throughout cli.mdxEBNF grammar examples andRailroadDiagramcomponent now importarithEBNFfrom@configuredthings/rdp.js/grammarsrather than inlining the grammar text- Internal cross-links added throughout the guide (LL(1) → Concepts,
--observable→ Debugging, TypeDoc API links for key types and functions) - CI:
pr-checks.ymlanddocs.ymlnow verify that committed files insrc/examples/matchnpm run generate:examplesoutput, failing with a diff if they drift
Removed
commanderdependency removed from the CLI — replaced with Node's built-inutil.parseArgs. Turns out "zero dependencies" is easier to maintain when there actually are zero dependencies.
Changed
rdp-gen initsimplifiedpackage.jsonscripts: the scaffolded project now has a singlebuild: tscscript rather than a grammar-generation step, reflecting thatinittargets hand-written parsers- Generated parse-tree node types now use named fields for non-terminal references instead of positional
item0,item1, … names. A field referencing ruleYearis now typed asyear: YearNode; terminals (string literals, char values) keepitemn names. When the same non-terminal appears more than once in a rule body all occurrences are suffixed (year0,year1, …). This is a breaking change for any code that accesses generated node fields by positional name (#15) - Generated parser methods now use per-method, per-hint variable counters instead of a single global counter. Internal variable and label names (
_pos0,found_alt0, …) reset to index 0 at the start of each method, producing cleaner and more readable generated output (#15)
v0.2.0
Added
- Added integration tests that type-check generated parser output using the TypeScript compiler API (
ts.createProgram) understrict: trueandnoUncheckedIndexedAccess, covering terminals, sequences, alternations, optional/repetition constructs, non-terminal references, observable mode, and ABNF grammars. - Dependabot configuration to track npm dependencies (root package only) and GitHub Actions versions
Changed
SECURITY.md— added Scope section clarifying that only library runtime dependencies are in scope; docs-site build-toolchain vulnerabilities are explicitly out of scope
Fixed
rdp-gennow emits(A | B | C)[]instead ofA | B | C[]when a repetition (*,+, orm*n) repeats a mixed-type alternation. The previous output was parsed by TypeScript asA | B | (C[]), causing type errors understrict: true. (#3)
v0.1.0
Added
RDParser— base class for writing recursive descent parsers in TypeScript, with buffer management and position trackingObservableRDParser— extendsRDParserwith opt-in parse tracing via an attachedParseObserverTraceObserverandDebugObserver— built-in observer implementations for collecting and printing parse tracesrdp-genCLI — reads an ISO 14977 EBNF or RFC 5234 ABNF grammar file and emits a fully typed TypeScript parser classGrammarInterpreter— runtime interpreter that executes a grammar directly from its AST without a code-generation stepEBNFParserandABNFParser— parse EBNF and ABNF grammar source into aGrammarASTgenerateParser— programmatic API for generating parser source from a grammar string- Dual ESM/CJS package with full TypeScript declarations
- Bootstrapping meta-grammars: EBNF and ABNF formats each described in both EBNF and ABNF (
src/grammars/) - Left-recursion detection at grammar compilation time