@mfissehaye/string-to-drizzle-orm-filters
Version:
155 lines • 5.41 kB
JavaScript
"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