UNPKG

rawsql-ts

Version:

[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.

97 lines 4.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeywordParser = exports.KeywordMatchResult = void 0; const stringUtils_1 = require("../utils/stringUtils"); var KeywordMatchResult; (function (KeywordMatchResult) { KeywordMatchResult[KeywordMatchResult["NotAKeyword"] = 0] = "NotAKeyword"; KeywordMatchResult[KeywordMatchResult["PartialOnly"] = 1] = "PartialOnly"; KeywordMatchResult[KeywordMatchResult["PartialOrFinal"] = 2] = "PartialOrFinal"; KeywordMatchResult[KeywordMatchResult["Final"] = 3] = "Final"; // "Complete match (no longer keywords after this)" })(KeywordMatchResult || (exports.KeywordMatchResult = KeywordMatchResult = {})); class KeywordParser { constructor(trie) { this.trie = trie; } isEndOfInput(input, position, shift = 0) { return position + shift >= input.length; } canParse(input, position, shift = 0) { return !this.isEndOfInput(input, position, shift); } parse(input, position) { if (this.isEndOfInput(input, position)) { return null; } // reset trie node this.trie.reset(); const result = stringUtils_1.StringUtils.tryReadRegularIdentifier(input, position); if (result === null) { return null; } let matchResult = this.trie.pushLexeme(result.identifier.toLowerCase()); if (matchResult === KeywordMatchResult.NotAKeyword) { return null; } if (matchResult === KeywordMatchResult.Final) { return { keyword: result.identifier, newPosition: result.newPosition }; } // multi-word keyword let lexeme = result.identifier; const commentResult = stringUtils_1.StringUtils.readWhiteSpaceAndComment(input, result.newPosition); position = commentResult.position; const collectedComments = [...commentResult.lines]; // Cache comments during multi-word parsing // end of input if (this.isEndOfInput(input, position)) { if (matchResult === KeywordMatchResult.PartialOrFinal) { // if the last match was partial or final, it means that the keyword is finished return { keyword: lexeme, newPosition: position, comments: collectedComments.length > 0 ? collectedComments : undefined }; } else { return null; } } while (this.canParse(input, position)) { const previousMatchResult = matchResult; const result = stringUtils_1.StringUtils.tryReadRegularIdentifier(input, position); if (result !== null) { matchResult = this.trie.pushLexeme(result.identifier.toLowerCase()); if (matchResult === KeywordMatchResult.NotAKeyword) { if (previousMatchResult === KeywordMatchResult.PartialOrFinal) { break; } else { return null; } } lexeme += ' ' + result.identifier; const nextCommentResult = stringUtils_1.StringUtils.readWhiteSpaceAndComment(input, result.newPosition); position = nextCommentResult.position; collectedComments.push(...nextCommentResult.lines); // Collect comments between multi-word tokens if (matchResult === KeywordMatchResult.Final) { break; } } else if (previousMatchResult === KeywordMatchResult.PartialOrFinal) { break; } else { return null; } } return { keyword: lexeme, newPosition: position, comments: collectedComments.length > 0 ? collectedComments : undefined }; } } exports.KeywordParser = KeywordParser; //# sourceMappingURL=KeywordParser.js.map