UNPKG

dotlr

Version:

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

192 lines (174 loc) 3.86 kB
//TODO not sure how to type Symbol import { Grammar, LALR1Parser, LR1Parser, Parser } from "./index"; export type Rule<T extends Token = Token> = { symbol: string; pattern: AtomicPattern<T>[]; }; //TODO not sure how to type Symbol //prettier-ignore export type AtomicPattern<T extends Token = Token> = { type: 'Symbol', value: string } | { type: 'Token', value: T } //prettier-ignore 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>[] } } //prettier-ignore export type Token<C = string, R = string> = { type: 'Constant' value: C } | { type: 'Regex', value: R } | { type: 'Eof' } | { type: 'Empty' } //prettier-ignore 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 } } //prettier-ignore 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> } } //prettier-ignore 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>[]; }; //prettier-ignore 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;