From e16426b82f0dda94ab9aa92ba6e3af8d769f3fed Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 19 Apr 2020 20:40:32 +0100 Subject: [PATCH] feat(parse): add withID() xform, add doc strings --- packages/parse/src/xform/collect.ts | 6 ++++++ packages/parse/src/xform/hoist.ts | 11 +++++++++++ packages/parse/src/xform/join.ts | 6 ++++++ packages/parse/src/xform/number.ts | 12 ++++++++++++ packages/parse/src/xform/print.ts | 21 +++++++++++++++++++++ packages/parse/src/xform/with-id.ts | 15 +++++++++++++++ 6 files changed, 71 insertions(+) create mode 100644 packages/parse/src/xform/with-id.ts diff --git a/packages/parse/src/xform/collect.ts b/packages/parse/src/xform/collect.ts index 8edf01622f..ddbdc16277 100644 --- a/packages/parse/src/xform/collect.ts +++ b/packages/parse/src/xform/collect.ts @@ -1,6 +1,12 @@ import { Parser, ScopeTransform } from "../api"; import { xform } from "../combinators/xform"; +/** + * Collects results of all direct children into an array, then discards + * children. Also see {@link collect}. + * + * @param scope + */ export const xfCollect: ScopeTransform = (scope) => { scope!.result = scope!.children!.map((c) => c.result); scope!.children = null; diff --git a/packages/parse/src/xform/hoist.ts b/packages/parse/src/xform/hoist.ts index a4e8b532b2..f05d01af06 100644 --- a/packages/parse/src/xform/hoist.ts +++ b/packages/parse/src/xform/hoist.ts @@ -1,10 +1,21 @@ import { Parser, ScopeTransform } from "../api"; import { xform } from "../combinators/xform"; +/** + * Moves the result of first child node to this node, then discards all + * children. Also see {@link hoist}. + * + * @param scope + */ export const xfHoist: ScopeTransform = (scope) => { scope!.result = scope!.children![0].result; scope!.children = null; return scope; }; +/** + * Syntax sugar for `xform(parser, xfHoist)`. + * + * @param parser + */ export const hoist = (parser: Parser) => xform(parser, xfHoist); diff --git a/packages/parse/src/xform/join.ts b/packages/parse/src/xform/join.ts index bdaa19b0f6..c5eaf961ad 100644 --- a/packages/parse/src/xform/join.ts +++ b/packages/parse/src/xform/join.ts @@ -2,6 +2,12 @@ import type { Nullable } from "@thi.ng/api"; import type { Parser, ParseScope } from "../api"; import { xform } from "../combinators/xform"; +/** + * Recursively joins non-null results of all children into a single + * string, then discards children. Also see {@link join}. + * + * @param scope + */ export const xfJoin = (scope: Nullable>) => { if (!scope || !scope.children) return null; const res = []; diff --git a/packages/parse/src/xform/number.ts b/packages/parse/src/xform/number.ts index 7e1361c2c8..bc081f97d2 100644 --- a/packages/parse/src/xform/number.ts +++ b/packages/parse/src/xform/number.ts @@ -1,11 +1,23 @@ import { ScopeTransform } from "../api"; import { xfJoin } from "./join"; +/** + * Higher order transform. First joins all children via {@link xfJoin}, + * then parses resulting string into an integer with given `radix`. + * + * @param radix + */ export const xfInt = (radix = 10): ScopeTransform => (scope) => { scope!.result = parseInt(xfJoin(scope)!.result, radix); return scope; }; +/** + * First joins all children via {@link xfJoin}, then parses resulting + * string into a floating point value. + * + * @param scope + */ export const xfFloat: ScopeTransform = (scope) => { scope!.result = parseFloat(xfJoin(scope)!.result); return scope; diff --git a/packages/parse/src/xform/print.ts b/packages/parse/src/xform/print.ts index 7e85f5ece4..c13c67a90e 100644 --- a/packages/parse/src/xform/print.ts +++ b/packages/parse/src/xform/print.ts @@ -2,6 +2,15 @@ import { Parser, ScopeTransform } from "../api"; import { xform } from "../combinators/xform"; import { indent } from "../utils"; +/** + * Side effect only. Traverses current AST node and all children and + * prints each node's ID, result and reader state (if available). Also + * see {@link print}. + * + * @param scope + * @param ctx + * @param level + */ export const xfPrint: ScopeTransform = (scope, _, level = 0) => { if (!scope) return; const prefix = indent(level); @@ -19,6 +28,18 @@ export const xfPrint: ScopeTransform = (scope, _, level = 0) => { /** * Syntax sugar for `xform(parser, xfPrint)`. * + * @example + * ```ts + * print(seq([lit("["), oneOrMore(ALPHA), lit("]")]))(defContext("[abc]")) + * // seq: null + * // lit: "[" + * // repeat1: null + * // lit: "a" + * // lit: "b" + * // lit: "c" + * // lit: "]" + * ``` + * * @param parser */ export const print = (parser: Parser) => xform(parser, xfPrint); diff --git a/packages/parse/src/xform/with-id.ts b/packages/parse/src/xform/with-id.ts new file mode 100644 index 0000000000..991ed11ab2 --- /dev/null +++ b/packages/parse/src/xform/with-id.ts @@ -0,0 +1,15 @@ +import { ScopeTransform, Parser } from "../api"; +import { xform } from "../combinators/xform"; + +/** + * Assigns given `id` to AST node. E.g. used for re-labeling parser + * results defined by {@link defGrammar}. + * + * @param id + */ +export const xfID = (id: string): ScopeTransform => (scope) => ( + (scope!.id = id), scope +); + +export const withID = (id: string, parser: Parser) => + xform(parser, xfID(id));