functionalscript
Version:
FunctionalScript is a purely functional subset of JavaScript
149 lines (148 loc) • 3.98 kB
TypeScript
/**
* 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 {};