JSTQL-JS-Transform/src/parser/wildcardTokenizer.ts
2024-05-28 22:33:51 +02:00

132 lines
3.5 KiB
TypeScript

type TokenKind =
| "BinaryOperator"
| "UnaryOperator"
| "Identifier"
| "OpeningParenthesis"
| "ClosingParenthesis"
| "Pluss"
| "Semicolon";
export interface WildcardToken {
tokenKind: TokenKind;
value: string;
}
export class WildcardTokenizer {
private tokens: WildcardToken[] = [];
private current = -1; // Have to start at -1 because first iteration advances
private source: string[];
constructor(source: string) {
this.source = source.split("");
}
tokenize(): WildcardToken[] {
while (this.current < this.source.length - 1) {
this.scanToken();
}
return this.tokens;
}
private peek(): string | undefined {
return this.source[this.current + 1];
}
private getCurrent() {
return this.source[this.current];
}
private advance() {
this.current += 1;
}
private consumeToken(tokenKind: TokenKind, value: string) {
this.tokens.push({ tokenKind, value });
}
private scanToken() {
this.advance();
let char = this.getCurrent();
switch (char) {
case "(": {
this.consumeToken("OpeningParenthesis", char);
break;
}
case ")": {
this.consumeToken("ClosingParenthesis", char);
break;
}
case "|": {
if (this.peek() === "|") {
this.advance();
this.consumeToken("BinaryOperator", "||");
} else {
throw new Error(
"Invalid token given to tokenizer: " + char
);
}
break;
}
case "!": {
this.consumeToken("UnaryOperator", char);
break;
}
case "&": {
if (this.peek() === "&") {
this.advance();
this.consumeToken("BinaryOperator", "&&");
} else {
throw new Error(
"Invalid token given to tokenizer: " + char
);
}
break;
}
case "+": {
this.consumeToken("Pluss", char);
break;
}
case ":": {
this.consumeToken("Semicolon", char);
break;
}
case " ":
break;
default:
if (this.isAlpha(char)) {
this.consumeAlpha();
break;
} else {
throw new Error("Invalid token given: " + char);
}
}
}
private consumeAlpha() {
let word = "";
while (true) {
word += this.getCurrent();
let next = this.peek();
if (next && this.isAlpha(next)) {
this.advance();
} else {
break;
}
}
this.consumeToken("Identifier", word);
}
private isAlpha(val: string): boolean {
let alphabet = new Set(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_".split("")
);
return alphabet.has(val);
}
}
function testWildcardTokenizer() {
let tokenized = new WildcardTokenizer(
"aiaiai: ((LOL||!Smack)&&SomethingElse)*"
).tokenize();
console.log(tokenized);
}
//testWildcardTokenizer();