import type { Combinator } from '../types.ts'; import type { HostMode } from '../cst/host-mode.ts'; import { NODE_TAG, NODE_TYPE, type GrammarWithReflection } from '../cst/reflection.ts'; /** * Non-enumerable key on a `rules()` result holding the factory's declaration * order (the returned object's key order), which differs from the result's own * reference-creation key order. Read by `parseman/spec` for source-order output. */ export declare const RULE_ORDER = "__parsemanRuleOrder"; /** * Define named grammar rules without forward declarations. * * Pass a factory that receives all rule names as references (via a Proxy) * and returns a record of combinators. rules() handles creating ref() * placeholders and wiring them up — the user never sees ref() at all. * * const { value } = rules(g => ({ * value: choice(g.object, g.array, str, num, bool, nil), * object: transform(sequence('{', sepBy(g.pair, ','), '}'), Object.fromEntries), * array: transform(sequence('[', sepBy(g.value, ','), ']'), ([, items]) => items), * pair: transform(sequence(g.key, literal(':'), g.value), ([k,, v]) => [k, v]), * })) * * Not every name in the factory must appear in the returned object — local helpers * (like `comma`, `key`) can be plain const inside the factory and composed normally. * Only names that OTHER rules reference via `g.xxx` need to be in the returned record. * * TypeScript: use an explicit type parameter for full type safety on `g`: * rules<{ value: Combinator; array: Combinator }>(g => ({ ... })) * Without it, `g.*` accesses are typed as `any` but the return is still inferred. */ /** * Grammar-level options for `rules()`. Parity with `parser({...})`, but declared * ONCE for the whole grammar instead of wrapped around a scope. `trivia` becomes * the ambient trivia for every rule (installed at the parse entry, inherited * everywhere, incremental parse included); `parser({trivia})` / `noTrivia` still * override it locally for a sub-region. */ export type RulesOptions = { /** Ambient trivia for the whole grammar. See `parser({ trivia })` for the shape * (`null` clears it — equivalent to omitting it at the grammar level). */ trivia?: Combinator | null; /** * Ambient scan-skip for the whole grammar: opaque non-trivia units (strings, * balanced brackets, …) that a `scanTo`/`balanced` with no explicit `skip` * consults so a sentinel hidden inside one is never matched. Declared ONCE here * and inherited everywhere, mirroring `trivia`. `null`/absent = none. */ scanSkip?: Combinator[] | null; /** * Compile-time host mode for this grammar, same meaning as `compile(g, { hostMode })` * and `compose(items, { hostMode })`: `'ast'` (default) emits each direct builder's * own result and NO positioned-CST branch; `'cst'` builds every node through the * `ctx.build` host and captures unconditionally. * * Declaring it HERE is what lets ONE grammar source serve both consumers under the * macro, which cannot take a compile option any other way: * * ```ts * const factory = (g: any) => ({ … }) * export const grammar = rules({ trivia: rw }, factory) * export const cstGrammar = rules({ trivia: rw, hostMode: 'cst' }, factory) * ``` * * Two call sites over one factory, so the macro emits two independent top-level * artifacts and each bundle tree-shakes away the one it does not import. Neither * pays the other's cost — which is the whole reason host mode is a compile-time * decision rather than a per-node runtime read. * * The INTERPRETER routes dynamically off the host and does not need this; it is * still recorded, so `run()` can refuse a mismatched host once per parse instead of * quietly producing the wrong tree shape. */ hostMode?: HostMode; /** * Compile-time line tracking for this grammar. Under the macro this emits a * separate line-aware artifact from the same factory; the default artifact * remains free of line-tracking helpers and branches. */ trackLines?: boolean; }; type RuleNodeType = C extends { readonly [NODE_TYPE]?: infer T extends string; } ? [T] extends [never] ? K : T : K; type RuleNodeTag = C extends { readonly [NODE_TAG]?: infer Tag extends string; } ? Tag : never; type RuleMapNodeType>> = { [K in keyof T & string]: RuleNodeType; }[keyof T & string]; type RuleMapNodeTag>> = { [K in keyof T & string]: RuleNodeTag; }[keyof T & string]; type RulesResult>> = T & GrammarWithReflection, RuleMapNodeTag>; export declare function rules>>(factory: (self: any) => T): RulesResult; export declare function rules>>(options: RulesOptions, factory: (self: any) => T): RulesResult; export {}; //# sourceMappingURL=parser.d.ts.map