import type { Combinator, ParseContext, ParseError, ParseResult } from '../types.ts'; import { type RootTriviaIndex } from '../cst/trivia-entries.ts'; /** * Run a compiled/interpreted grammar entry against an input and collect the raw * outcome a tool needs to shape a parse result — WITHOUT the consumer having to * hand-build a `ctx`, branch on function-vs-combinator, or scan for leftover * input itself. * * A `compile()`/macro grammar hands you a map of bare parse FUNCTIONS; the * interpreter hands you COMBINATORS. `run()` invokes either, threads the standard * framework ctx (trivia log, recover/expect error sink, the `ctx.build` host, * grammar state), and — given the grammar's trivia parser — reports where * non-trivia input was left unconsumed. The consumer keeps only its own policy: * how to shape the tree and how to turn diagnostics into its error type. */ /** A compiled rule (macro/`compile()` output) OR an interpreter combinator. */ export type Runnable = ((input: string, pos: number, ctx: ParseContext) => ParseResult) | Combinator; export type RunOptions = { /** Optional hooks for a coverage-enabled compiled or macro parser. Ordinary * parses omit this completely, so instrumentation has no normal-path cost. * Table-backed 0.47 artifacts support `_grammarCoverage` but reject * `_grammarTrace` explicitly; interpreted/source-lowered entries may support * both. */ instrumentation?: { _grammarCoverage?: (id: string) => void; _grammarTrace?: { write(event: { id: string; phase: 'enter' | 'attempt' | 'selected' | 'success' | 'failure' | 'backtrack' | 'rollback'; offset: number; end?: number; }): void; }; }; /** `ctx.build` host — makes structural `node()` rules build a CST / AST via the * host instead of their own eval builders. Omit for a grammar's own builders. */ build?: ParseContext['build']; /** Initial grammar state threaded into `ctx.state`. */ state?: unknown; /** * The grammar's trivia rule — an OVERRIDE, no longer a requirement. * * A root rule consumes trivia BETWEEN terms but not after the last one, so * trailing whitespace/comments would otherwise look like unparsed input. `run` * skips that tail before computing `unconsumedFrom` and before reporting * `span`, so only real leftover is reported. * * The trivia used is the ENTRY's own ambient trivia — whatever * `rules({ trivia })` / `parser({ trivia })` declared — resolved automatically * (see `ambientTriviaFromRunnable`). Pass this only to use a DIFFERENT trivia * for the document tail than the grammar parses with; it wins when given. * Passing the grammar's own trivia is now a no-op, and remains supported. * * Either way it encodes dialect differences for free: CSS trivia leaves a * trailing `//` as leftover, Less trivia (which treats `//` as a line comment) * does not. An UNTERMINATED comment (which the trivia rule won't match) * surfaces at its start. */ trivia?: Runnable; /** * Restrict PER-NODE CST trivia capture (the `triviaLog` a node's builder sees) * to these trivia kinds — a bitmask over the grammar's `triviaKindLabels` * indices (build it with `triviaKindMask(labels, ['comment', …])`). Unlisted * kinds (e.g. whitespace) are skipped over but not recorded per node, so a host * that only reads comments doesn't pay to log every whitespace run. Omit to * capture every kind. */ triviaCaptureMask?: number; /** * Opt into sparse root trivia capture. `run()` retains no root trivia unless * this is supplied. Capture records only the named labels, each with the one * complete authored gap that owns it; ordinary whitespace has no root entry. */ rootTrivia?: { readonly select: readonly string[]; }; /** * Activate automatic list recovery. When true, `many`/`sepBy`/`oneOrMore` recover * from a failed element — skip to a sync point (a resume token inferred from the * grammar's structure; the grammar carries no recovery config), emit a * `ParseError` over the skipped span (collected in `errors`), and keep parsing the * rest of the list — instead of stopping at the first bad element. Omit (the * default) for the strict "one clean error and stop" behavior, byte-identical to a * run with no recovery. Recovery is a cold path: on well-formed input nothing * fails, so none of the machinery runs. */ tolerant?: boolean; }; export type RootTriviaCapture = { /** Packed `[gapStart, gapEnd, markerStart, markerEnd, selectedKindIndex]` rows. */ readonly rows: readonly number[]; /** Labels requested by this caller; row kind indices refer to this array. */ readonly select: readonly string[]; /** Lazy lookup over `rows`; no tokens or strings are materialized. */ readonly index: RootTriviaIndex; }; export type RunResult = { ok: boolean; /** The entry's value on success; undefined on failure. */ value: unknown; span: { start: number; end: number; }; /** Expected-token set when the TOP-LEVEL parse failed (empty on success). */ expected: string[]; /** Recovery diagnostics (tolerant lists / `expect()`) collected during the parse (in order). */ errors: ParseError[]; /** * Sparse selected root trivia. This is present only when at least one requested * category was actually retained; omitted means the parse retained no root * trivia at all. */ rootTrivia?: RootTriviaCapture; /** Offset where unparsed input begins — the first non-trivia character the parse * left unconsumed (the document's trailing trivia is always skipped; see * `RunOptions.trivia`), or null if the whole input was consumed. This is how you * detect "the grammar stopped short, there's junk here". Only meaningful on * success — a failed parse reports its own `span`/`expected`. */ unconsumedFrom: number | null; }; export declare function run(entry: Runnable, input: string, options?: RunOptions): RunResult; //# sourceMappingURL=run.d.ts.map