UNPKG

clarity-pattern-parser

Version:

Parsing Library for Typescript and Javascript.

158 lines (122 loc) 5.32 kB
import { Context } from "../patterns/Context"; import { Expression } from "../patterns/Expression"; import { Literal } from "../patterns/Literal"; import { Pattern } from "../patterns/Pattern"; import { Regex } from "../patterns/Regex"; import { Repeat } from "../patterns/Repeat"; import { IGenerator } from "./igenerator"; import { IVisitor } from "./ivisitor"; export class TypescriptVisitor implements IVisitor { private _generator: IGenerator | null = null; get generator() { if (this._generator == null) { throw new Error("No Generator Found"); } return this._generator; } begin(generator: IGenerator) { this._generator = generator; } end() { } header(): string { return ""; } footer(): string { return ""; } context(pattern: Pattern, depth: number): string { const name = pattern.name; const context = pattern as Context; const contextPatterns = context.getPatternsWithinContext(); this.generator.setDepth(depth); const contextPatternString = this.generator.generate(context.children[0]); const contextPatternsString = this._indent(Object.values(contextPatterns).map(p => { this.generator.setDepth(depth + 2); return this.generator.generate(p); }), depth + 2); return `new Context("${name}",${this._generateTabs(depth + 1)}${contextPatternString}, [${contextPatternsString.join(", ")}${this._generateTabs(depth + 1)}])`; } expression(pattern: Pattern, depth: number): string { const name = pattern.name; const expression = pattern as Expression; const patterns = expression.originalPatterns; const patternsString = this._indent(patterns.map(p => { this.generator.setDepth(depth + 2); return this.generator.generate(p); }), depth + 2); return `new Expression("${name}", [${patternsString.join(", ")}${this._generateTabs(depth)}])`; } literal(pattern: Pattern): string { const name = pattern.name; const literal = pattern as Literal; return `new Literal("${name}", "${this._escapeString(literal.token)}")`; } not(pattern: Pattern, args: string[], depth: number): string { args = this._indent(args, depth + 1); const name = pattern.name; return `new Not("${name}", ${args.join("")})`; } optional(pattern: Pattern, args: string[], depth: number): string { args = this._indent(args, depth + 1); const name = pattern.name; return `new Optional("${name}", ${args.join("")})`; } options(pattern: Pattern, args: string[], depth: number): string { args = this._indent(args, depth + 1); const name = pattern.name; return `new Options("${name}", [${args.join(", ")}${this._generateTabs(depth)}])`; } reference(pattern: Pattern): string { const name = pattern.name; return `new Reference("${name}")`; } regex(pattern: Pattern): string { const name = pattern.name; const regex = pattern as Regex; return `new Literal("${name}", "${this._escapeString(regex.regex)}")`; } infiniteRepeat(pattern: Pattern, depth: number): string { const name = pattern.name; const repeat = pattern as Repeat; this.generator.setDepth(depth); const repeatPattern = repeat.pattern; const options = repeat.options; const repeatPatternString = this.generator.generate(repeatPattern); let dividerString = "null"; if (options.divider != null) { dividerString = this.generator.generate(options.divider); } return `new Repeat("${name}", ${this._generateTabs(depth + 1)}${repeatPatternString}, {min: ${repeat.min}, divider: ${dividerString}})`; } finiteRepeat(pattern: Pattern, depth: number): string { const name = pattern.name; const repeat = pattern as Repeat; this.generator.setDepth(depth); const repeatPattern = repeat.pattern; const options = repeat.options; const repeatPatternString = this.generator.generate(repeatPattern); let dividerString = "null"; if (options.divider != null) { dividerString = this.generator.generate(options.divider); } return `new Repeat("${name}", ${this._generateTabs(depth + 1)}${repeatPatternString}, {min: ${repeat.min}, max: ${repeat.max} divider: ${dividerString}})`; } rightAssociated(_: Pattern, args: string[], depth: number) { args = this._indent(args, depth + 1); return `new RightAssociation(${args.join("")})`; } sequence(pattern: Pattern, args: string[], depth: number): string { args = this._indent(args, depth + 1); const name = pattern.name; return `new Sequence("${name}", [${args.join(", ")}${this._generateTabs(depth)}])`; } private _escapeString(value: string) { return value.replaceAll('"', '\\"'); } private _generateTabs(depth: number) { return "\n" + new Array(depth).fill(" ").join(""); } private _indent(args: string[], depth: number) { return args.map(s => this._generateTabs(depth) + s); } }