/**
 * Types for defining language grammar using Backus-Naur Form (BNF).
 *
 * Utilities for serializing and deserializing BNF grammar
 * and creating a simple LL(1) parser.
 *
 * See [Backus-Naur form](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form).
 *
 * @module
 *
 * @example
 *
 * ```ts
 * import type { Rule } from './module.f.ts'
 *
 * // Matches 'A-Z', 'a-z', and '0-9'
 * const grammar: Rule = () => [
 *     [[65, 90]],
 *     [[97, 122]],
 *     [[48, 57]],
 * ]
 * ```
 */
import { type CodePoint } from '../../text/utf16/module.f.ts';
/**
 * Represents a terminal range as a pair of Unicode code points.
 * Typically used to define character ranges.
 *
 * @example
 *
 * ```ts
 * const alpha: TerminalRange = [65, 90] // Matches 'A-Z'
 * ```
 */
export type TerminalRange = readonly [CodePoint, CodePoint];
/**
 * Represents a sequence of rules that must match in order.
 *
 * @example
 *
 * ```ts
 * const alpha: TerminalRange = [65, 90] // Matches 'A-Z'
 * const id2: Sequence = [alpha, alpha]  // Matches two uppercase letters
 * ```
 */
export type Sequence = readonly (TerminalRange | Rule)[];
/**
 * Represents a logical "or" operation between multiple sequences.
 * Allows defining alternatives within the grammar.
 *
 * @example
 *
 * ```ts
 * const alpha: TerminalRange = [65, 90] // Matches 'A-Z'
 * const id2: Sequence = [alpha, alpha]  // Matches two uppercase letters
 * const digit: TerminalRange = [48, 57] // Matches '0-9'
 * // Matches two uppercase letters or one digit
 * const id2OrDigit: Or = [
 *     id2,
 *     [digit],
 * ]
 * ```
 */
export type Or = readonly Sequence[];
/**
 * Represents a lazy grammar rule for recursive definitions.
 *
 * @example
 *
 * ```ts
 * const alpha: TerminalRange = [65, 90]  // Matches 'A-Z'
 * // zero or more alpha symbols
 * const alpha0x: Rule = () => [
 *     [],              // Empty
 *     [alpha, alpha0x] // Recursive
 * ]
 * const id: Sequence = [alpha, alpha0x]
 * ```
 */
export type Rule = () => Or;
/**
 * Converts a string to an array of terminal ranges where each character is a separate range.
 *
 * @param s - The input string.
 * @returns An array of terminal ranges representing each character in the string.
 *
 * @example
 *
 * ```ts
 * const ranges = str('abc') // [[97, 97], [98, 98], [99, 99]]
 * ```
 */
export declare const str: (s: string) => readonly TerminalRange[];
/**
 * Converts a single character string to a terminal range.
 *
 * @param a - The input character string.
 * @returns A terminal range representing the character.
 *
 * @example
 * ```ts
 * const range = cp('A'); // [65, 65]
 * ```
 */
export declare const cp: (a: string) => TerminalRange;
/**
 * Converts a two-character string into a terminal range.
 *
 * @param ab - The input string of two characters.
 * @returns A terminal range representing the two characters.
 *
 * @throws {number} Throws an error if the input string does not have exactly two code points.
 *
 * @example
 * ```ts
 * const result = range('AZ'); // [65, 90]
 * ```
 */
export declare const range: (ab: string) => TerminalRange;
type RangeSet = readonly TerminalRange[];
/**
 * A set of terminal ranges compatible with the `Or` rule.
 */
export type OrRangeSet = readonly (readonly [TerminalRange])[];
/**
 * Convert a sequence of character into `OrRangeSet`
 *
 * @param s a set of code points
 * @returns A set compatible with `Or`
 */
export declare const set: (s: string) => OrRangeSet;
/**
 * Removes a terminal range from a set of ranges.
 *
 * @param range the original range.
 * @param removeSet the set of ranges to be removed.
 * @returns The resulting set of ranges after removal.
 *
 * @example
 *
 * ```ts
 * const result = remove([65, 90], [cp('C'), cp('W')]) // [A..Z] w/o C and W
 * ```
 */
export declare const remove: (range: TerminalRange, removeSet: RangeSet) => OrRangeSet;
export declare const repeat0: (rule: Rule) => Rule;
export declare const join0: (rule: Rule, separator: Rule) => Rule;
export {};
