UNPKG

@mfissehaye/string-to-drizzle-orm-filters

Version:
155 lines 5.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Lexer = exports.TokenType = void 0; var TokenType; (function (TokenType) { TokenType["Identifier"] = "IDENTIFIER"; TokenType["StringLiteral"] = "STRING_LITERAL"; TokenType["NumberLiteral"] = "NUMBER_LITERAL"; TokenType["LParen"] = "LPAREN"; TokenType["RParen"] = "RPAREN"; TokenType["Comma"] = "COMMA"; TokenType["Whitespace"] = "WHITESPACE"; TokenType["EOF"] = "EOF"; TokenType["Unknown"] = "UNKNOWN"; })(TokenType || (exports.TokenType = TokenType = {})); /** * The Lexer class is responsible for taking an input string and * breaking it down into a sequence of tokens. */ class Lexer { input; currentPosition; constructor(input) { this.input = input; this.currentPosition = 0; } /** * Resets the lexer's position to the beginning of the input */ reset() { this.currentPosition = 0; } nextToken() { this.skipWhitespace(); if (this.currentPosition >= this.input.length) { return this.createToken(TokenType.EOF, '', this.currentPosition); } const char = this.input[this.currentPosition]; switch (char) { case '(': return this.advanceAndCreateToken(TokenType.LParen, char); case ')': return this.advanceAndCreateToken(TokenType.RParen, char); case ',': return this.advanceAndCreateToken(TokenType.Comma, char); case '"': return this.readStringLiteral(); default: if (this.isLetter(char)) { return this.readIdentifier(); } else if (this.isDigit(char)) { // Check for numbers return this.readNumberLiteral(); } // Handle other unknown characters or numbers if needed later return this.advanceAndCreateToken(TokenType.Unknown, char); } } /** * Reads a string literal (e.g., "value") including the quotes. */ readStringLiteral() { const startPos = this.currentPosition; this.currentPosition++; // Consume the opening quote let value = ''; while (this.currentPosition < this.input.length && this.input[this.currentPosition] !== '"') { // Basic escape sequence handling if neede (e.g., '\"') if (this.input[this.currentPosition] === '\\' && this.currentPosition + 1 < this.input.length) { value += this.input[this.currentPosition]; // Add backslash this.currentPosition++; value += this.input[this.currentPosition]; // Add escaped char } else { value += this.input[this.currentPosition]; } this.currentPosition++; } if (this.currentPosition >= this.input.length) { // Unclosed string literal throw new Error(`Unclosed string literal starting at position ${startPos}`); } this.currentPosition++; // Consume the closing quote return this.createToken(TokenType.StringLiteral, value, startPos); } /** * Reads an identifier (e.g., "and", "eq"). */ readIdentifier() { const startPos = this.currentPosition; while (this.currentPosition < this.input.length && this.isLetter(this.input[this.currentPosition])) { this.currentPosition++; } const value = this.input.substring(startPos, this.currentPosition); return this.createToken(TokenType.Identifier, value, startPos); } /** * Reads a number literal (e.g., 123, 3.14). */ readNumberLiteral() { const startPos = this.currentPosition; let value = ''; while (this.currentPosition < this.input.length && (this.isDigit(this.input[this.currentPosition]) || this.input[this.currentPosition] === '.')) { value += this.input[this.currentPosition]; this.currentPosition++; } return this.createToken(TokenType.NumberLiteral, value, startPos); } /** * Skips over whitespace characters */ skipWhitespace() { while (this.currentPosition < this.input.length && this.isWhitespace(this.input[this.currentPosition])) { this.currentPosition++; } } /** * Checks if a character is a letter. */ isLetter(char) { return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z'); } /** * Checks if a character is a digit. */ isDigit(char) { return char >= '0' && char <= '9'; } /** * Checks if a character is whitespace. */ isWhitespace(char) { return /\s/.test(char); } /** * Creates a token and advances the current position. */ advanceAndCreateToken(type, value) { const token = this.createToken(type, value, this.currentPosition); this.currentPosition++; // Move past the current character return token; } /** * Helper to create a token object. */ createToken(type, value, position) { return { type, value, position }; } } exports.Lexer = Lexer; //# sourceMappingURL=lexer.js.map