import type { Combinator } from '../types.ts'; export type RepeatOptions = { /** * Minimum number of ITEMS. Default `0`. * * `min >= 1` is not a validation nicety — it is what makes the combinator * NON-NULLABLE. A nullable arm matches at every position, which disables its * `choice`'s first-char dispatch by parseman's own first-set rule; a `min >= 1` * repeat keeps the item's first-set, so an arm led by it still gates. */ min?: number; /** Maximum number of ITEMS. Default: unbounded. Never affects nullability. */ max?: number; }; /** * Repetition: `item*` by default, bounded by `{ min, max }` (both count ITEMS). * * many(g.Decl) // zero or more — NULLABLE * many(g.Decl, { min: 1 }) // one or more — same as oneOrMore(g.Decl) * many(g.HexDigit, { min: 3, max: 8 }) * * `oneOrMore(x)` is kept as the sugar for the common `{ min: 1 }` case. */ export declare function many(combinator: Combinator, opts?: RepeatOptions): Combinator; /** * Sugar for the commonest bound: `many(combinator, { min: 1 })` — the identical * combinator, not merely an equivalent one. */ export declare function oneOrMore(combinator: Combinator, opts?: RepeatOptions): Combinator; export declare function optional(combinator: Combinator): Combinator; /** * Non-empty separated list — `oneOrMore`'s relationship to `many`, for separated * lists. `oneOrMoreSep(item, sep)` is exactly `sepBy(item, sep, { min: 1 })`. * * oneOrMoreSep(g.Selector, literal(',')) // a selector list is never empty * * REACH FOR THIS, NOT `sepBy`, for any list that cannot actually be empty — * selector lists, value lists, media-query preludes, keyframe selectors. `sepBy`'s * min-0 default matches the EMPTY STRING, which makes it nullable, and a nullable * arm disables its `choice`'s first-char dispatch by parseman's own first-set * rule. This form is non-nullable and keeps the item's first-set, so an arm led by * it still gates. */ export declare function oneOrMoreSep(combinator: Combinator, separator: Combinator | KeptSeparator, opts?: SepByOptions): Combinator; /** How a separator with NO item after it is treated. */ export type TrailingSeparator = /** * DEFAULT, and what `sepBy` has always done: the trailing separator is NOT * consumed — the list ends before it and the enclosing grammar sees it. (It is * not an error here; "forbid" means the list refuses to own it.) */ 'forbid' /** Consume a trailing separator when present (`a, b,` → 2 items, comma eaten). */ | 'allow'; export type SepByOptions = RepeatOptions & { /** What to do with a separator that has no item after it. Default `'forbid'`. */ trailing?: TrailingSeparator; }; /** A separator the author asked to keep in `children`. Produced by `keepSeparator`. */ export type KeptSeparator = { readonly _keepSeparator: Combinator; }; /** * Keep this list's separators in `children`, interleaved with the items. * * A list contributes its ITEMS and nothing else — that is the default and it is * not negotiable, because a `children` array whose arity depends on a detail of * the separator is the thing that made this defect invisible. But a combinator * may collapse only what its CONSTRUCTION makes recoverable, and that is exactly * the line this helper draws: * * sepBy(g.Value, literal(',')) // ',' is fixed here — recoverable, drop it * sepBy(g.Track, keepSeparator(SLASH_OR_COMMA)) // could be '/' OR ',' — NOT recoverable, keep it * * Wrap the separator when it could have matched more than one thing: a `choice`, * a regex with alternation or a quantifier, a rule reference. In CSS the * separator carries meaning — `grid-area: 1 / 2` and `font: 12px/1.5` do not mean * what `1, 2` means — and dropping it destroys information that exists nowhere * else in the tree. * * The wrap is read at CONSTRUCTION, not per parse, and it is deliberately applied * to the separator rather than passed as an option: the call site then STATES its * own children arity, which is the failure being fixed. `keepSeparator` in the * source is the only documentation that reaches an author who never reads docs. */ export declare function keepSeparator(separator: Combinator): KeptSeparator; /** * Separated list: `(item (sep item)*)?` by default — note that it MATCHES THE * EMPTY STRING, which makes it nullable and therefore un-gateable as a choice arm. * For a list that cannot be empty reach for `oneOrMoreSep`, or pass `{ min: 1 }`. * * sepBy(g.Value, literal(',')) // may be empty — NULLABLE * oneOrMoreSep(g.Selector, literal(',')) // non-empty — gates as a choice arm * sepBy(g.Decl, literal(';'), { trailing: 'allow' }) * * `min`/`max` count ITEMS, not separators. */ export declare function sepBy(combinator: Combinator, separatorArg: Combinator | KeptSeparator, opts?: SepByOptions): Combinator; //# sourceMappingURL=repeat.d.ts.map