rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
87 lines • 3.34 kB
JavaScript
import { StringUtils } from "../utils/stringUtils";
export 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 || (KeywordMatchResult = {}));
export 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.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;
position = StringUtils.readWhiteSpaceAndComment(input, result.newPosition).position;
// 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
};
}
else {
return null;
}
}
while (this.canParse(input, position)) {
const previousMatchResult = matchResult;
const result = 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;
position = StringUtils.readWhiteSpaceAndComment(input, result.newPosition).position;
if (matchResult === KeywordMatchResult.Final) {
break;
}
}
else if (previousMatchResult === KeywordMatchResult.PartialOrFinal) {
break;
}
else {
return null;
}
}
return {
keyword: lexeme,
newPosition: position
};
}
}
//# sourceMappingURL=KeywordParser.js.map