UNPKG

dotlr

Version:

An LR(1) parser generator and visualizer created for educational purposes.

160 lines (159 loc) 3.73 kB
import { Grammar, LALR1Parser, LR1Parser, Parser } from "./index"; export type Rule<T extends Token = Token> = { symbol: string; pattern: AtomicPattern<T>[]; }; export type AtomicPattern<T extends Token = Token> = { type: 'Symbol'; value: string; } | { type: 'Token'; value: T; }; export type Tree<NT extends string = string, T extends Token = Token> = { type: 'Terminal'; value: { token: T; slice: string; span: Span; }; } | { type: 'NonTerminal'; value: { symbol: NT; pattern: Tree<NT, T>[]; }; }; export type Token<C = string, R = string> = { type: 'Constant'; value: C; } | { type: 'Regex'; value: R; } | { type: 'Eof'; } | { type: 'Empty'; }; export type GrammarError = { type: "UnexpectedToken"; value: { line: number; column: number; token: string; expected: string[]; }; } | { type: "UnexpectedEof"; value: { expected: string[]; }; } | { type: "InvalidRegex"; value: { line: number; column: number; regex: string; }; }; export type ParserError<P extends Parser = Parser> = { type: "EmptyGrammar"; } | { type: "UndefinedSymbol"; value: { symbol: string; rule: Rule<TokenOfParser<P>>; }; } | { type: "UndefinedRegexToken"; value: { regex_token: string; rule: Rule<TokenOfParser<P>>; }; } | { type: "Conflict"; value: { parser: P; state: number; token: TokenOfParser<P>; }; }; export type ParsingError<T extends Token = Token> = { type: "UnknownToken"; value: { token: string; span: Span; }; } | { type: "UnexpectedToken"; value: { token: string; span: Span; expected: T[]; }; } | { type: "UnexpectedEof"; value: { span: Span; expected: T[]; }; }; export type Trace<Tr extends Tree = Tree> = { steps: Step<Tr>[]; }; export type Step<Tr extends Tree = Tree> = { state_stack: number[]; tree_stack: Tr[]; remaining_tokens: Tr extends Tree<string, infer T> ? Spanned<T>[] : never; action_taken: Action; }; export type Item<T extends Token = Token> = { rule: Rule<T>; dot: number; lookahead: T[]; }; export type State<T extends Token = Token> = { id: number; items: Item<T>[]; transitions: Map<AtomicPattern<T>, number>; }; export type Automaton<T extends Token = Token> = { states: State<T>[]; }; export type Action = { type: 'Shift'; value: { next_state: number; }; } | { type: 'Reduce'; value: { rule_index: number; }; } | { type: 'Accept'; value: { rule_index: number; }; }; export type Span = { offset: number; length: number; column: number; line: number; }; export type Spanned<T> = { span: Span; object: T; }; export type FirstTable<T extends Token = Token> = Map<string, T[]>; export type FollowTable<T extends Token = Token> = Map<string, T[]>; export type GoToTable<NT extends string = string> = Map<NT, number>[]; export type ActionTable<T extends Token = Token> = Map<T, Action[]>[]; export type ParsingTables<NT extends string = string, T extends Token = Token> = { action_table: ActionTable<T>; goto_table: GoToTable<NT>; }; export type TokenOfParser<P extends Parser> = P extends Parser<infer T> ? Token<T> : never; export type LALR1ParserOfGrammar<G extends Grammar> = G extends Grammar<infer T, infer NT, infer R> ? LALR1Parser<T, NT, R> : never; export type LR1ParserOfGrammar<G extends Grammar> = G extends Grammar<infer T, infer NT, infer R> ? LR1Parser<T, NT, R> : never;