parseman 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +510 -0
- package/dist/combinators/choice.d.ts +15 -0
- package/dist/combinators/choice.d.ts.map +1 -0
- package/dist/combinators/first-set.d.ts +8 -0
- package/dist/combinators/first-set.d.ts.map +1 -0
- package/dist/combinators/grammar.d.ts +8 -0
- package/dist/combinators/grammar.d.ts.map +1 -0
- package/dist/combinators/guard.d.ts +15 -0
- package/dist/combinators/guard.d.ts.map +1 -0
- package/dist/combinators/lazy.d.ts +14 -0
- package/dist/combinators/lazy.d.ts.map +1 -0
- package/dist/combinators/literal.d.ts +6 -0
- package/dist/combinators/literal.d.ts.map +1 -0
- package/dist/combinators/map.d.ts +8 -0
- package/dist/combinators/map.d.ts.map +1 -0
- package/dist/combinators/not.d.ts +13 -0
- package/dist/combinators/not.d.ts.map +1 -0
- package/dist/combinators/parser.d.ts +25 -0
- package/dist/combinators/parser.d.ts.map +1 -0
- package/dist/combinators/recover.d.ts +20 -0
- package/dist/combinators/recover.d.ts.map +1 -0
- package/dist/combinators/ref.d.ts +18 -0
- package/dist/combinators/ref.d.ts.map +1 -0
- package/dist/combinators/regex.d.ts +3 -0
- package/dist/combinators/regex.d.ts.map +1 -0
- package/dist/combinators/repeat.d.ts +6 -0
- package/dist/combinators/repeat.d.ts.map +1 -0
- package/dist/combinators/scanTo.d.ts +30 -0
- package/dist/combinators/scanTo.d.ts.map +1 -0
- package/dist/combinators/sequence.d.ts +7 -0
- package/dist/combinators/sequence.d.ts.map +1 -0
- package/dist/combinators/withCtx.d.ts +13 -0
- package/dist/combinators/withCtx.d.ts.map +1 -0
- package/dist/compiler/codegen.d.ts +23 -0
- package/dist/compiler/codegen.d.ts.map +1 -0
- package/dist/compiler/line-index.d.ts +16 -0
- package/dist/compiler/line-index.d.ts.map +1 -0
- package/dist/cst/grammar.d.ts +84 -0
- package/dist/cst/grammar.d.ts.map +1 -0
- package/dist/cst/incremental.d.ts +34 -0
- package/dist/cst/incremental.d.ts.map +1 -0
- package/dist/cst/types.d.ts +74 -0
- package/dist/cst/types.d.ts.map +1 -0
- package/dist/index.cjs +1795 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1762 -0
- package/dist/index.js.map +7 -0
- package/dist/plugin/evaluator.d.ts +15 -0
- package/dist/plugin/evaluator.d.ts.map +1 -0
- package/dist/plugin/index.cjs +1473 -0
- package/dist/plugin/index.cjs.map +7 -0
- package/dist/plugin/index.d.ts +12 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +1442 -0
- package/dist/plugin/index.js.map +7 -0
- package/dist/types.d.ts +201 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Combinator, ParseError } from '../types.ts';
|
|
2
|
+
export type { ParseError };
|
|
3
|
+
/**
|
|
4
|
+
* Error-recovery combinator. Tries `parser`; on success returns normally.
|
|
5
|
+
* On failure, scans forward one character at a time until `sentinel` matches
|
|
6
|
+
* (or EOF), then returns a ParseError node spanning the skipped range.
|
|
7
|
+
* The sentinel is NOT consumed — the caller's grammar continues from there.
|
|
8
|
+
*
|
|
9
|
+
* Intended for IDE/incremental parsers that must produce a result even on
|
|
10
|
+
* broken input. The error path is not optimized; use only where recovery
|
|
11
|
+
* is genuinely needed, not on hot paths.
|
|
12
|
+
*
|
|
13
|
+
* const stmt = choice(
|
|
14
|
+
* ifStmt, whileStmt,
|
|
15
|
+
* recover(exprStmt, literal(';'))
|
|
16
|
+
* )
|
|
17
|
+
*/
|
|
18
|
+
export declare function recover<T>(parser: Combinator<T>, sentinel: Combinator<unknown>): Combinator<T | ParseError>;
|
|
19
|
+
export declare function isParseError(value: unknown): value is ParseError;
|
|
20
|
+
//# sourceMappingURL=recover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../../src/combinators/recover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,UAAU,EAAE,MAAM,aAAa,CAAA;AAEhG,YAAY,EAAE,UAAU,EAAE,CAAA;AAE1B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EACrB,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,GAC5B,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CA4B5B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Combinator } from '../types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Create a forward-declared parser slot for mutually recursive grammars.
|
|
4
|
+
*
|
|
5
|
+
* Because JS evaluates arguments eagerly, you can't reference a variable
|
|
6
|
+
* before it's declared. ref() creates a placeholder you fill in later:
|
|
7
|
+
*
|
|
8
|
+
* const value = ref<JSONValue>()
|
|
9
|
+
* const array = transform(sequence(literal('['), sepBy(value, literal(',')), literal(']')), ...)
|
|
10
|
+
* const object = transform(sequence(literal('{'), sepBy(pair, literal(',')), literal('}')), ...)
|
|
11
|
+
* value.define(choice(object, array, string, number, bool, nullVal))
|
|
12
|
+
*
|
|
13
|
+
* Unlike lazy(() => x), you use the ref directly — no wrapping at each call site.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ref<T>(): Combinator<T> & {
|
|
16
|
+
define(p: Combinator<T>): void;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=ref.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../src/combinators/ref.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAA;AAGpF;;;;;;;;;;;;GAYG;AACH,wBAAgB,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG;IAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;CAAE,CA8B3E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regex.d.ts","sourceRoot":"","sources":["../../src/combinators/regex.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAmD,MAAM,aAAa,CAAA;AA2H9F,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,SAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CA2B9E"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Combinator } from '../types.ts';
|
|
2
|
+
export declare function many<T>(parser: Combinator<T>): Combinator<T[]>;
|
|
3
|
+
export declare function oneOrMore<T>(parser: Combinator<T>): Combinator<T[]>;
|
|
4
|
+
export declare function optional<T>(parser: Combinator<T>): Combinator<T | null>;
|
|
5
|
+
export declare function sepBy<T, S>(parser: Combinator<T>, separator: Combinator<S>): Combinator<T[]>;
|
|
6
|
+
//# sourceMappingURL=repeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repeat.d.ts","sourceRoot":"","sources":["../../src/combinators/repeat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAA;AAEpF,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAwB9D;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CA0BnE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAiBvE;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CA+B5F"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Combinator } from '../types.ts';
|
|
2
|
+
export type ScanToOptions = {
|
|
3
|
+
/** Parsers that match "container" regions to skip over intact (balanced parens, strings, comments…) */
|
|
4
|
+
skip?: Combinator<unknown>[];
|
|
5
|
+
/**
|
|
6
|
+
* If true, reaching EOF without finding the sentinel is a success — returns
|
|
7
|
+
* everything consumed so far. Default false (fail at EOF).
|
|
8
|
+
*/
|
|
9
|
+
orEOF?: boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Consume input up to (but not including) the sentinel, skipping over any
|
|
13
|
+
* "hole" patterns in order so their contents are never mistaken for the sentinel.
|
|
14
|
+
*
|
|
15
|
+
* Returns the consumed text as a string. The sentinel is NOT consumed.
|
|
16
|
+
* Fails if the sentinel is never found (unless orEOF is true).
|
|
17
|
+
*
|
|
18
|
+
* const selector = scanTo(literal('{'), {
|
|
19
|
+
* skip: [cssComment, stringLit, balanced('(', ')'), balanced('[', ']')],
|
|
20
|
+
* })
|
|
21
|
+
*/
|
|
22
|
+
export declare function scanTo(sentinel: Combinator<unknown>, { skip, orEOF }?: ScanToOptions): Combinator<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Match a balanced open/close pair, skipping over any holes inside.
|
|
25
|
+
* Returns the full matched text including delimiters.
|
|
26
|
+
*
|
|
27
|
+
* const parenGroup = balanced('(', ')', { skip: [comment, stringLit] })
|
|
28
|
+
*/
|
|
29
|
+
export declare function balanced(open: string, close: string, options?: ScanToOptions): Combinator<string>;
|
|
30
|
+
//# sourceMappingURL=scanTo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanTo.d.ts","sourceRoot":"","sources":["../../src/combinators/scanTo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAA;AAMpF,MAAM,MAAM,aAAa,GAAG;IAC1B,uGAAuG;IACvG,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAA;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CACpB,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,EAC7B,EAAE,IAAS,EAAE,KAAa,EAAE,GAAE,aAAkB,GAC/C,UAAU,CAAC,MAAM,CAAC,CA6CpB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,UAAU,CAAC,MAAM,CAAC,CAMpB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Combinator } from '../types.ts';
|
|
2
|
+
type UnwrapParsers<T extends Combinator<unknown>[]> = {
|
|
3
|
+
[K in keyof T]: T[K] extends Combinator<infer U> ? U : never;
|
|
4
|
+
};
|
|
5
|
+
export declare function sequence<T extends [Combinator<unknown>, ...Combinator<unknown>[]]>(...parsers: T): Combinator<UnwrapParsers<T>>;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=sequence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../../src/combinators/sequence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAoD,MAAM,aAAa,CAAA;AAG/F,KAAK,aAAa,CAAC,CAAC,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI;KACnD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAC7D,CAAA;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,EAChF,GAAG,OAAO,EAAE,CAAC,GACZ,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAuC9B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Combinator } from '../types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Runs `parser` with `ctx.user` set to `extra` for the duration of the parse.
|
|
4
|
+
* The outer user context is restored on exit (lexical scoping).
|
|
5
|
+
*
|
|
6
|
+
* const functionBody = withCtx({ inFn: true },
|
|
7
|
+
* sequence(literal('{'), many(statement), literal('}'))
|
|
8
|
+
* )
|
|
9
|
+
*
|
|
10
|
+
* Read back with guard() or from within a transform's span argument.
|
|
11
|
+
*/
|
|
12
|
+
export declare function withCtx<U, T>(extra: U, parser: Combinator<T>): Combinator<T>;
|
|
13
|
+
//# sourceMappingURL=withCtx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withCtx.d.ts","sourceRoot":"","sources":["../../src/combinators/withCtx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAA;AAEpF;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAc5E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile a Combinator<T> definition tree into an optimized JavaScript function.
|
|
3
|
+
*
|
|
4
|
+
* Design: every sub-emitter uses early-return on failure. Fallible contexts
|
|
5
|
+
* (many loops, non-disjoint choice arms) wrap inner code in IIFEs so
|
|
6
|
+
* early-return keeps working uniformly throughout.
|
|
7
|
+
*/
|
|
8
|
+
import type { Combinator, ParseResult } from '../types.ts';
|
|
9
|
+
export type CompiledParser<T> = {
|
|
10
|
+
parse(input: string, pos?: number): ParseResult<T>;
|
|
11
|
+
/** The generated source (for inspection / future source maps) */
|
|
12
|
+
source: string;
|
|
13
|
+
/**
|
|
14
|
+
* A self-contained JS expression (IIFE) that evaluates to a parse function.
|
|
15
|
+
* Safe to inline directly into transformed source — no external references
|
|
16
|
+
* except for runtime-fallback parsers embedded via closures.
|
|
17
|
+
* Returns null if the parser cannot be fully inlined (e.g. contains user
|
|
18
|
+
* closures that can't be serialized).
|
|
19
|
+
*/
|
|
20
|
+
inlineExpression: string | null;
|
|
21
|
+
};
|
|
22
|
+
export declare function compile<T>(parser: Combinator<T>): CompiledParser<T>;
|
|
23
|
+
//# sourceMappingURL=codegen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAuB,WAAW,EAAgC,MAAM,aAAa,CAAA;AAowB7G,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAClD,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC,CAAA;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CA0DnE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Span } from '../types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Precomputed index of newline positions for O(log n) offset→line/col lookup.
|
|
4
|
+
* lineStarts[i] is the byte offset of the first character on line i+1.
|
|
5
|
+
*/
|
|
6
|
+
export type LineIndex = {
|
|
7
|
+
lineStarts: number[];
|
|
8
|
+
};
|
|
9
|
+
export declare function buildLineIndex(input: string): LineIndex;
|
|
10
|
+
export declare function offsetToLineCol(index: LineIndex, offset: number): {
|
|
11
|
+
line: number;
|
|
12
|
+
col: number;
|
|
13
|
+
};
|
|
14
|
+
/** Fills startLine/startColumn/endLine/endColumn on a span in-place. */
|
|
15
|
+
export declare function annotateSpan(span: Span, index: LineIndex): Span;
|
|
16
|
+
//# sourceMappingURL=line-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-index.d.ts","sourceRoot":"","sources":["../../src/compiler/line-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEvC;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAEhD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAMvD;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,GACb;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAU/B;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAU/D"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Combinator, Span } from '../types.ts';
|
|
2
|
+
import type { CSTNode, CSTLeaf, CSTError, CSTRawChild, NodeLike } from './types.ts';
|
|
3
|
+
import type { ParseDoc } from './incremental.ts';
|
|
4
|
+
type Capital = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
5
|
+
/** Keys of T whose names start with a capital letter (CST parser). */
|
|
6
|
+
export type RuleKeys<T> = {
|
|
7
|
+
[K in keyof T & string]: K extends `${Capital}${string}` ? K : never;
|
|
8
|
+
}[keyof T & string];
|
|
9
|
+
/**
|
|
10
|
+
* Maps each grammar property to its resolved Combinator type.
|
|
11
|
+
*
|
|
12
|
+
* Use as the parameter type in rule thunks — gives `g.*` the correct
|
|
13
|
+
* Combinator type instead of the raw function type:
|
|
14
|
+
*
|
|
15
|
+
* Expr = (g: Refs<this>) => choice(g.Atom, sequence(g.Expr, literal('+'), g.Atom))
|
|
16
|
+
*/
|
|
17
|
+
export type Refs<T> = {
|
|
18
|
+
[K in keyof T as K extends `_${string}` ? never : T[K] extends Combinator<any> ? K : T[K] extends (g: any) => Combinator<any> ? K : never]: T[K] extends Combinator<infer V> ? Combinator<V> : T[K] extends (g: any) => Combinator<infer V> ? Combinator<V> : never;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Base class for grammars that automatically produce a CST (or a custom AST
|
|
22
|
+
* if you override `buildNode`).
|
|
23
|
+
*
|
|
24
|
+
* Rules are declared as class properties:
|
|
25
|
+
* - Plain Combinator (no cross-references needed):
|
|
26
|
+
* digits = regex(/[0-9]+/)
|
|
27
|
+
* - Thunk (references other parser via `g`):
|
|
28
|
+
* Expr = (g: Refs<this>) => choice(g.Atom, sequence(g.Expr, literal('+')))
|
|
29
|
+
*
|
|
30
|
+
* Convention:
|
|
31
|
+
* Capital letter → CSTNode-producing rule (span + savedContext + children)
|
|
32
|
+
* lowercase → transparent helper (terminals bubble up as CSTLeaf in the
|
|
33
|
+
* nearest enclosing capital rule)
|
|
34
|
+
*
|
|
35
|
+
* Mutual recursion works because thunks are collected first, ref() placeholders
|
|
36
|
+
* installed for each one, then all thunks are called with `g` (a map of refs).
|
|
37
|
+
* Initialization is lazy — triggered on the first call to rule().
|
|
38
|
+
*
|
|
39
|
+
* Grammar inheritance: subclass property initializers naturally override parent
|
|
40
|
+
* ones (they run last in construction order), so extending a grammar means only
|
|
41
|
+
* re-declaring the parser you want to change.
|
|
42
|
+
*
|
|
43
|
+
* class JSONCParser extends JSONParser {
|
|
44
|
+
* ws = jsoncWs // override just this one rule
|
|
45
|
+
* }
|
|
46
|
+
*/
|
|
47
|
+
export declare class Parser<N extends NodeLike = CSTNode> {
|
|
48
|
+
private _built;
|
|
49
|
+
private _build;
|
|
50
|
+
/**
|
|
51
|
+
* Override to produce a custom AST node instead of a plain CSTNode.
|
|
52
|
+
* The returned object must satisfy NodeLike for IncrementalParser to work.
|
|
53
|
+
*
|
|
54
|
+
* `rawChildren` is `children` plus any trivia tokens (whitespace/comments)
|
|
55
|
+
* consumed between terms, in parse order. Use it to inspect trivia when the
|
|
56
|
+
* grammar is whitespace-sensitive (e.g. CSS descendant vs adjacent combinators).
|
|
57
|
+
* The default implementation ignores `rawChildren`.
|
|
58
|
+
*/
|
|
59
|
+
protected buildNode(type: string, span: Span, children: ReadonlyArray<N | CSTLeaf | CSTError>, savedContext: unknown, _rawChildren: ReadonlyArray<CSTRawChild>): N;
|
|
60
|
+
/** Wrap an inner combinator so it produces a CSTNode on each match. */
|
|
61
|
+
private _makeNodeParser;
|
|
62
|
+
/** Reconstruct a node with a new children array (used by IncrementalParser). */
|
|
63
|
+
rebuild(node: N, newChildren: ReadonlyArray<N | CSTLeaf | CSTError>): N;
|
|
64
|
+
/**
|
|
65
|
+
* Parse input starting from a named rule, returning a ParseDoc.
|
|
66
|
+
* The doc carries the tree, any parse errors, and an edit() method
|
|
67
|
+
* for incremental re-parsing on subsequent changes.
|
|
68
|
+
*
|
|
69
|
+
* const doc = css.parse('Stylesheet', src)
|
|
70
|
+
* doc.tree // the CST root, or null on failure
|
|
71
|
+
* doc.errors // ParseFail[], empty on success
|
|
72
|
+
*
|
|
73
|
+
* // In an editor — just keep calling edit():
|
|
74
|
+
* const doc2 = doc.edit(newSrc, changeStart, changeEnd)
|
|
75
|
+
*/
|
|
76
|
+
parse(ruleName: RuleKeys<this>, input: string): ParseDoc<N>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the compiled Combinator for a named rule.
|
|
79
|
+
* Triggers lazy initialization on first call.
|
|
80
|
+
*/
|
|
81
|
+
rule(name: RuleKeys<this>): Combinator<N>;
|
|
82
|
+
}
|
|
83
|
+
export {};
|
|
84
|
+
//# sourceMappingURL=grammar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../src/cst/grammar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,IAAI,EAAE,MAAM,aAAa,CAAA;AAE1F,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAa,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE9F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAMhD,KAAK,OAAO,GAAG,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GACvD,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,GAAC,GAAG,CAAA;AAE9D,sEAAsE;AACtE,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,KAAK;CACrE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAA;AAEnB;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,EAAE,GAAG,KAAK,GAC3C,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,GAChC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,GAC5C,KAAK,GACN,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAChD,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAC5D,KAAK;CACT,CAAA;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,MAAM,CAAC,CAAC,SAAS,QAAQ,GAAG,OAAO;IAC9C,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO,CAAC,MAAM;IA2Cd;;;;;;;;OAQG;IACH,SAAS,CAAC,SAAS,CACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,aAAa,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC,EAC/C,YAAY,EAAE,OAAO,EACrB,YAAY,EAAE,aAAa,CAAC,WAAW,CAAC,GACvC,CAAC,CAEH;IAED,uEAAuE;IACvE,OAAO,CAAC,eAAe;IAoCvB,gFAAgF;IAChF,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAEtE;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAE1D;IAED;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAKxC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ParseFail } from '../types.ts';
|
|
2
|
+
import type { Parser } from './grammar.ts';
|
|
3
|
+
import type { NodeLike } from './types.ts';
|
|
4
|
+
/**
|
|
5
|
+
* The result of Parser.parse() — holds the current tree and supports
|
|
6
|
+
* incremental re-parsing via edit().
|
|
7
|
+
*
|
|
8
|
+
* const doc = css.parse('Stylesheet', src)
|
|
9
|
+
* doc.tree // CSTNode (or your N), null if parse failed
|
|
10
|
+
* doc.errors // ParseFail[], empty on success
|
|
11
|
+
* doc.input // the source string that produced this tree
|
|
12
|
+
*
|
|
13
|
+
* const doc2 = doc.edit(newSrc, changeStart, changeEnd)
|
|
14
|
+
*/
|
|
15
|
+
export interface ParseDoc<N extends NodeLike = NodeLike> {
|
|
16
|
+
readonly tree: N | null;
|
|
17
|
+
readonly errors: ParseFail[];
|
|
18
|
+
readonly input: string;
|
|
19
|
+
/**
|
|
20
|
+
* Incrementally re-parse after a text change.
|
|
21
|
+
*
|
|
22
|
+
* @param changeStart Byte offset where the change begins (same in old and new text).
|
|
23
|
+
* @param oldChangeEnd Byte offset where the replaced region ends in the OLD text (exclusive).
|
|
24
|
+
* @param newText The replacement text (may be empty for a pure deletion).
|
|
25
|
+
*
|
|
26
|
+
* Maps directly to editor change events:
|
|
27
|
+
* VSCode: doc.edit(change.rangeOffset, change.rangeOffset + change.rangeLength, change.text)
|
|
28
|
+
* CodeMirror: doc.edit(change.from, change.to, change.insert)
|
|
29
|
+
* LSP: doc.edit(startByte, endByte, change.text) // after line/col → byte conversion
|
|
30
|
+
*/
|
|
31
|
+
edit(changeStart: number, oldChangeEnd: number, newText: string): ParseDoc<N>;
|
|
32
|
+
}
|
|
33
|
+
export declare function makeParseDoc<N extends NodeLike>(parser: Parser<N>, ruleName: string, input: string): ParseDoc<N>;
|
|
34
|
+
//# sourceMappingURL=incremental.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incremental.d.ts","sourceRoot":"","sources":["../../src/cst/incremental.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAY,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EAAqB,QAAQ,EAAE,MAAM,YAAY,CAAA;AAM7D;;;;;;;;;;GAUG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ;IACrD,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;CAC9E;AA+GD,wBAAgB,YAAY,CAAC,CAAC,SAAS,QAAQ,EAC7C,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,QAAQ,CAAC,CAAC,CAAC,CAOb"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Span } from '../types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal interface a node must satisfy for IncrementalParser to navigate and
|
|
4
|
+
* re-parse the tree. Satisfying this is all that's required for a custom AST
|
|
5
|
+
* produced by overriding GrammarParser.buildNode().
|
|
6
|
+
*
|
|
7
|
+
* `children` only needs to be iterable with items that have `_tag` so the
|
|
8
|
+
* traversal code can distinguish sub-nodes from leaves. For incremental
|
|
9
|
+
* replacement, nodes are reconstructed via object spread — so plain objects
|
|
10
|
+
* work naturally; class instances with non-enumerable properties do not.
|
|
11
|
+
*/
|
|
12
|
+
export type NodeLike = {
|
|
13
|
+
readonly _tag: 'node';
|
|
14
|
+
readonly type: string;
|
|
15
|
+
readonly span: Span;
|
|
16
|
+
readonly savedContext: unknown;
|
|
17
|
+
readonly children: ReadonlyArray<{
|
|
18
|
+
readonly _tag: string;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* A named CST node produced by a capital-letter rule method in GrammarParser.
|
|
23
|
+
* Children are in parse order: CSTNode children from named sub-parser interspersed
|
|
24
|
+
* with CSTLeaf terminals from literal() / regex() calls inside lowercase helpers.
|
|
25
|
+
*/
|
|
26
|
+
export type CSTNode = {
|
|
27
|
+
readonly _tag: 'node';
|
|
28
|
+
/** Rule name — the method name that produced this node. */
|
|
29
|
+
readonly type: string;
|
|
30
|
+
readonly span: Span;
|
|
31
|
+
readonly children: CSTChild[];
|
|
32
|
+
/**
|
|
33
|
+
* Shallow clone of ctx.user at the moment this node's parse began.
|
|
34
|
+
* Used as the re-entry point for incremental re-parsing.
|
|
35
|
+
* Only meaningful when ctx.user is primitives-only (no mutable objects).
|
|
36
|
+
*/
|
|
37
|
+
readonly savedContext: unknown;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A terminal token — the result of a literal() or regex() match inside a CST rule.
|
|
41
|
+
* Lowercase helpers are transparent: their terminals surface as leaves of the
|
|
42
|
+
* nearest enclosing capital-letter rule.
|
|
43
|
+
*/
|
|
44
|
+
export type CSTLeaf = {
|
|
45
|
+
readonly _tag: 'leaf';
|
|
46
|
+
readonly value: string;
|
|
47
|
+
readonly span: Span;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* A record of a failed rule parse — produced when error recovery is active.
|
|
51
|
+
* Carries what was successfully parsed before the failure (partial children)
|
|
52
|
+
* and the expected tokens at the failure point.
|
|
53
|
+
*/
|
|
54
|
+
export type CSTError = {
|
|
55
|
+
readonly _tag: 'error';
|
|
56
|
+
readonly type: string;
|
|
57
|
+
readonly span: Span;
|
|
58
|
+
readonly expected: string[];
|
|
59
|
+
readonly children: CSTChild[];
|
|
60
|
+
readonly savedContext: unknown;
|
|
61
|
+
};
|
|
62
|
+
export type CSTChild = CSTNode | CSTLeaf | CSTError;
|
|
63
|
+
/**
|
|
64
|
+
* A trivia token — whitespace or comment consumed between terms during parsing.
|
|
65
|
+
* Only present in `rawChildren`; never in the structural `children` array.
|
|
66
|
+
*/
|
|
67
|
+
export type CSTTrivia = {
|
|
68
|
+
readonly _tag: 'trivia';
|
|
69
|
+
readonly value: string;
|
|
70
|
+
readonly span: Span;
|
|
71
|
+
};
|
|
72
|
+
/** Full child union including trivia — used in the `rawChildren` arg of `buildNode`. */
|
|
73
|
+
export type CSTRawChild = CSTNode | CSTLeaf | CSTTrivia | CSTError;
|
|
74
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cst/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEvC;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5D,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CACpB,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEnD;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CACpB,CAAA;AAED,wFAAwF;AACxF,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA"}
|