UNPKG

dotlr

Version:

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

166 lines (165 loc) 4.92 kB
import { Grammar as _Grammar, Parser as _Parser, } from "./pkg/dotlr"; import { Err, Ok } from "ts-results-es"; export class Grammar { constructor(grammar) { this.cache = { symbols: null, constant_tokens: null, start_symbol: null, regex_tokens: null, productions: null, stringify: null, }; this.grammar = grammar; } static parse(grammar) { try { const res = _Grammar.parse_wasm(grammar); return Ok(new Grammar(res)); } catch (e) { return Err(e); } } getSymbols() { var _a; return ((_a = this.cache).symbols ?? (_a.symbols = this.grammar.symbols_wasm())); } getConstantTokens() { var _a; return ((_a = this.cache).constant_tokens ?? (_a.constant_tokens = this.grammar.constant_tokens_wasm())); } getStartSymbol() { var _a; return ((_a = this.cache).start_symbol ?? (_a.start_symbol = this.grammar.start_symbol_wasm())); } getProductions() { var _a; return ((_a = this.cache).productions ?? (_a.productions = this.grammar.rules_wasm())); } getRegexTokens() { var _a; return ((_a = this.cache).regex_tokens ?? (_a.regex_tokens = this.grammar.regular_expressions_wasm())); } stringify() { var _a; return ((_a = this.cache).stringify ?? (_a.stringify = this.grammar.to_string_wasm())); } clone() { return new Grammar(this.grammar.clone_wasm()); } } export class Parser { constructor(parser) { this.cache = { action_table: null, goto_table: null, parsing_tables: null, automaton: null, first_table: null, follow_table: null, }; this.parser = parser; } parse(input) { try { return Ok(this.parser.parse_wasm(input)); } catch (e) { return Err(e); } } getActionTable() { var _a; return ((_a = this.cache).action_table ?? (_a.action_table = this.parser.action_table_wasm())); } getGotoTable() { var _a; return ((_a = this.cache).goto_table ?? (_a.goto_table = this.parser.goto_table_wasm())); } getParseTables() { var _a; return ((_a = this.cache).parsing_tables ?? (_a.parsing_tables = this.parser.parsing_tables_wasm())); } getAutomaton() { var _a; return ((_a = this.cache).automaton ?? (_a.automaton = this.parser.automaton_wasm())); } getFirstTable() { var _a; return ((_a = this.cache).first_table ?? (_a.first_table = this.parser.first_table_wasm())); } getFollowTable() { var _a; return ((_a = this.cache).follow_table ?? (_a.follow_table = this.parser.follow_table_wasm())); } tokenize(input) { try { const tokens = this.parser.tokenize_wasm(input); return Ok(tokens.map(([token, slice]) => ({ token, slice, }))); } catch (e) { return Err(e); } } trace(input) { try { const [trace, tree] = this.parser.trace_wasm(input); return Ok({ trace, tree, }); } catch (e) { return Err(e); } } } // this function tries to recover the serialized parser into the actual parser function mapParserError(error, kind) { const serialized = error.serialize(); if (serialized.type === "Conflict") { serialized.value.parser = kind === "lalr1" ? // @ts-expect-error private constructor new LALR1Parser(error.into_conflict_parser()) : // @ts-expect-error private constructor new LR1Parser(error.into_conflict_parser()); } return serialized; } export class LR1Parser extends Parser { constructor(parser) { super(parser); } /** * Consumes a grammar and returns a parser, the grammar is consumed and the ownership is transferred to the parser */ static fromGrammar(grammar) { try { return Ok(new LR1Parser(_Parser.new_wasm(grammar.grammar))); } catch (e) { return Err(mapParserError(e, "lr1")); } } } export class LALR1Parser extends Parser { constructor(parser) { super(parser); } /** * Consumes a grammar and returns a parser, the grammar is consumed and the ownership is transferred to the parser */ static fromGrammar(grammar) { try { return Ok(new LALR1Parser(_Parser.new_wasm(grammar.grammar))); } catch (e) { return Err(mapParserError(e, "lalr1")); } } }