Spaces:
Running
Running
| /** | |
| * TGN Parser TypeScript Wrapper | |
| * | |
| * Wraps the jison-generated parser with TypeScript types | |
| * | |
| * Based on lotus project architecture: | |
| * - Use jison npm package for grammar compilation at build time | |
| * - Generate parser to .js file in build phase | |
| * - Use synchronous parsing (no async needed) | |
| * - Works in both browser and Node.js environments | |
| */ | |
| /** | |
| * Parsed move action - represents a single player's action in a round | |
| */ | |
| export interface ParsedMoveAction { | |
| type: "move" | "pass" | "resign"; | |
| position?: string; // ab0yz coordinate notation | |
| } | |
| /** | |
| * Parsed move round - contains both black and white moves | |
| */ | |
| export interface ParsedMoveRound { | |
| round: number; | |
| action_black: ParsedMoveAction; | |
| action_white?: ParsedMoveAction; | |
| } | |
| /** | |
| * Parsed game result | |
| */ | |
| export interface ParsedGameResult { | |
| Result: string; // "black win" | "white win" | "draw" | "unknown" | |
| Conquer?: { | |
| n: number; | |
| unit: string; // "points" | "stones" | |
| }; | |
| } | |
| /** | |
| * Parsed TGN tags (metadata) | |
| */ | |
| export interface ParsedTags { | |
| Event?: string; | |
| Site?: string; | |
| Date?: string; | |
| Round?: string; | |
| Black?: string; | |
| White?: string; | |
| Result?: string; | |
| Board?: number[]; // [x, y, z] or [x, y] | |
| Handicap?: string; | |
| Rules?: string; | |
| TimeControl?: string; | |
| Annotator?: string; | |
| Application?: string; | |
| [key: string]: string | number[] | ParsedGameResult | undefined; | |
| } | |
| /** | |
| * Parser output structure | |
| */ | |
| export interface TGNParseResult { | |
| tags: ParsedTags; | |
| moves: ParsedMoveRound[] | null; | |
| success: boolean; | |
| } | |
| /** | |
| * Parser error with position information | |
| */ | |
| export class TGNParseError extends Error { | |
| constructor( | |
| message: string, | |
| public line?: number, | |
| public column?: number, | |
| public hash?: any | |
| ) { | |
| super(message); | |
| this.name = "TGNParseError"; | |
| } | |
| } | |
| // Will be set by initialization code or build process | |
| let parserModule: any = null; | |
| /** | |
| * Set the parser module (called by initialization code) | |
| * This allows the pre-built parser to be used | |
| */ | |
| export function setParserModule(module: any): void { | |
| parserModule = module; | |
| } | |
| /** | |
| * Get the parser module | |
| * Throws error if parser not loaded | |
| */ | |
| function getParser() { | |
| if (!parserModule) { | |
| throw new Error( | |
| "TGN parser not loaded. Please ensure the parser has been built.\n" + | |
| "Run: npm run build:parsers" | |
| ); | |
| } | |
| return parserModule; | |
| } | |
| /** | |
| * Parse TGN string and return structured data | |
| * Synchronous parsing (no async needed) | |
| * | |
| * @param tgnString - TGN formatted game notation | |
| * @returns Parsed game data with tags and moves | |
| * @throws TGNParseError if parsing fails | |
| */ | |
| export function parseTGN(tgnString: string): TGNParseResult { | |
| const parser = getParser(); | |
| if (!parser.parse) { | |
| throw new Error("TGN parser parse method not available"); | |
| } | |
| try { | |
| const result = parser.parse(tgnString); | |
| return result as TGNParseResult; | |
| } catch (error: any) { | |
| // Wrap jison errors with our custom error type | |
| throw new TGNParseError( | |
| error.message || "Unknown parse error", | |
| error.hash?.line, | |
| error.hash?.loc?.first_column, | |
| error.hash | |
| ); | |
| } | |
| } | |
| /** | |
| * Validate TGN string without fully parsing | |
| * Synchronous validation (no async needed) | |
| * | |
| * @param tgnString - TGN formatted game notation | |
| * @returns Object with valid flag and error message if invalid | |
| */ | |
| export function validateTGN(tgnString: string): { valid: boolean; error?: string } { | |
| try { | |
| parseTGN(tgnString); | |
| return { valid: true }; | |
| } catch (error: any) { | |
| return { | |
| valid: false, | |
| error: error.message || "Unknown validation error" | |
| }; | |
| } | |
| } | |