UNPKG

@flowscripter/mpeg-sdl-parser

Version:

ISO/IEC 14496-34 Syntactic Description Language (MPEG SDL) parser implemented in TypeScript

75 lines (62 loc) 2.21 kB
import { LRParser as LezerParser } from "@lezer/lr"; import { debugEnabled } from "../util/logger.ts"; import { Text } from "@codemirror/state"; import type { Input } from "@lezer/common"; import { SyntacticParseError } from "../ParseError.ts"; // Generated by Lezer from the SDL grammar import { parser } from "./parser.ts"; import { getContextTracker } from "./contextTracker.ts"; let lenientSdlParser: LezerParser | undefined; let strictSdlParser: LezerParser | undefined; /** * Create an in memory lenient Lezer based parser using the SDL grammar and store it as a "singleton". */ export function createLenientSdlParser(): LezerParser { if (!lenientSdlParser) { if (debugEnabled) { lenientSdlParser = parser.configure({ contextTracker: getContextTracker(parser), }); } else { lenientSdlParser = parser; } } return lenientSdlParser; } /** * Create an in memory strict Lezer based parser using the SDL grammar and store it as a "singleton". */ export function createStrictSdlParser(): LezerParser { if (!strictSdlParser) { strictSdlParser = createLenientSdlParser().configure({ strict: true, }); // Wrap the parser's parse method to catch errors and wrap them in ParseError const originalParseFunc = strictSdlParser.parse.bind(strictSdlParser); strictSdlParser.parse = (input: Input | string, ...args) => { try { return originalParseFunc(input, ...args); } catch (err) { // parse position out of error message which takes the form "No parse at 0" const errorMessage = (err as Error).message; const match = errorMessage.match(/No parse at (\d+)/); let position = 0; if (match) { const parsed = parseInt(match[1], 10); position = isNaN(parsed) ? 0 : parsed; } let inputText: string; if (typeof input === "string") { inputText = input; } else { inputText = input.read(0, input.length); } const text = Text.of( inputText.split("\n"), ); throw SyntacticParseError.fromTextAndPosition(text, position); } }; } return strictSdlParser; }