flowquery 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +30 -0
- package/.github/workflows/release.yml +84 -0
- package/CODE_OF_CONDUCT.md +10 -0
- package/FlowQueryLogoIcon.png +0 -0
- package/LICENSE +21 -0
- package/README.md +113 -0
- package/SECURITY.md +14 -0
- package/SUPPORT.md +13 -0
- package/docs/flowquery.min.js +1 -0
- package/docs/index.html +105 -0
- package/flowquery-vscode/.vscode-test.mjs +5 -0
- package/flowquery-vscode/.vscodeignore +13 -0
- package/flowquery-vscode/LICENSE +21 -0
- package/flowquery-vscode/README.md +11 -0
- package/flowquery-vscode/demo/FlowQueryVSCodeDemo.gif +0 -0
- package/flowquery-vscode/eslint.config.mjs +25 -0
- package/flowquery-vscode/extension.js +508 -0
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -0
- package/flowquery-vscode/flowquery-worker.js +66 -0
- package/flowquery-vscode/images/FlowQueryLogoIcon.png +0 -0
- package/flowquery-vscode/jsconfig.json +13 -0
- package/flowquery-vscode/libs/page.css +53 -0
- package/flowquery-vscode/libs/table.css +13 -0
- package/flowquery-vscode/libs/tabs.css +66 -0
- package/flowquery-vscode/package-lock.json +2917 -0
- package/flowquery-vscode/package.json +51 -0
- package/flowquery-vscode/test/extension.test.js +196 -0
- package/flowquery-vscode/test/worker.test.js +25 -0
- package/flowquery-vscode/vsc-extension-quickstart.md +42 -0
- package/jest.config.js +11 -0
- package/package.json +28 -0
- package/queries/analyze_catfacts.cql +75 -0
- package/queries/azure_openai_completions.cql +13 -0
- package/queries/azure_openai_models.cql +9 -0
- package/queries/mock_pipeline.cql +84 -0
- package/queries/openai_completions.cql +15 -0
- package/queries/openai_models.cql +13 -0
- package/queries/test.cql +6 -0
- package/queries/tool_inference.cql +24 -0
- package/queries/wisdom.cql +6 -0
- package/queries/wisdom_letter_histogram.cql +8 -0
- package/src/compute/runner.ts +65 -0
- package/src/index.browser.ts +11 -0
- package/src/index.ts +12 -0
- package/src/io/command_line.ts +74 -0
- package/src/parsing/alias.ts +23 -0
- package/src/parsing/alias_option.ts +5 -0
- package/src/parsing/ast_node.ts +153 -0
- package/src/parsing/base_parser.ts +92 -0
- package/src/parsing/components/csv.ts +9 -0
- package/src/parsing/components/from.ts +12 -0
- package/src/parsing/components/headers.ts +12 -0
- package/src/parsing/components/json.ts +9 -0
- package/src/parsing/components/null.ts +9 -0
- package/src/parsing/components/post.ts +9 -0
- package/src/parsing/components/text.ts +9 -0
- package/src/parsing/context.ts +48 -0
- package/src/parsing/data_structures/associative_array.ts +43 -0
- package/src/parsing/data_structures/json_array.ts +31 -0
- package/src/parsing/data_structures/key_value_pair.ts +37 -0
- package/src/parsing/data_structures/lookup.ts +40 -0
- package/src/parsing/data_structures/range_lookup.ts +36 -0
- package/src/parsing/expressions/expression.ts +142 -0
- package/src/parsing/expressions/f_string.ts +26 -0
- package/src/parsing/expressions/identifier.ts +22 -0
- package/src/parsing/expressions/number.ts +40 -0
- package/src/parsing/expressions/operator.ts +179 -0
- package/src/parsing/expressions/reference.ts +42 -0
- package/src/parsing/expressions/string.ts +34 -0
- package/src/parsing/functions/aggregate_function.ts +58 -0
- package/src/parsing/functions/avg.ts +37 -0
- package/src/parsing/functions/collect.ts +44 -0
- package/src/parsing/functions/function.ts +60 -0
- package/src/parsing/functions/function_factory.ts +66 -0
- package/src/parsing/functions/join.ts +26 -0
- package/src/parsing/functions/predicate_function.ts +44 -0
- package/src/parsing/functions/predicate_function_factory.ts +15 -0
- package/src/parsing/functions/predicate_sum.ts +29 -0
- package/src/parsing/functions/rand.ts +13 -0
- package/src/parsing/functions/range.ts +18 -0
- package/src/parsing/functions/reducer_element.ts +10 -0
- package/src/parsing/functions/replace.ts +19 -0
- package/src/parsing/functions/round.ts +17 -0
- package/src/parsing/functions/size.ts +17 -0
- package/src/parsing/functions/split.ts +26 -0
- package/src/parsing/functions/stringify.ts +26 -0
- package/src/parsing/functions/sum.ts +31 -0
- package/src/parsing/functions/to_json.ts +17 -0
- package/src/parsing/functions/value_holder.ts +13 -0
- package/src/parsing/logic/case.ts +26 -0
- package/src/parsing/logic/else.ts +12 -0
- package/src/parsing/logic/end.ts +9 -0
- package/src/parsing/logic/then.ts +12 -0
- package/src/parsing/logic/when.ts +12 -0
- package/src/parsing/operations/aggregated_return.ts +18 -0
- package/src/parsing/operations/aggregated_with.ts +18 -0
- package/src/parsing/operations/group_by.ts +124 -0
- package/src/parsing/operations/limit.ts +22 -0
- package/src/parsing/operations/load.ts +92 -0
- package/src/parsing/operations/operation.ts +65 -0
- package/src/parsing/operations/projection.ts +18 -0
- package/src/parsing/operations/return.ts +43 -0
- package/src/parsing/operations/unwind.ts +32 -0
- package/src/parsing/operations/where.ts +38 -0
- package/src/parsing/operations/with.ts +20 -0
- package/src/parsing/parser.ts +762 -0
- package/src/parsing/token_to_node.ts +91 -0
- package/src/tokenization/keyword.ts +43 -0
- package/src/tokenization/operator.ts +25 -0
- package/src/tokenization/string_walker.ts +194 -0
- package/src/tokenization/symbol.ts +15 -0
- package/src/tokenization/token.ts +633 -0
- package/src/tokenization/token_mapper.ts +53 -0
- package/src/tokenization/token_type.ts +15 -0
- package/src/tokenization/tokenizer.ts +229 -0
- package/src/tokenization/trie.ts +117 -0
- package/src/utils/object_utils.ts +17 -0
- package/src/utils/string_utils.ts +114 -0
- package/tests/compute/runner.test.ts +498 -0
- package/tests/parsing/context.test.ts +27 -0
- package/tests/parsing/expression.test.ts +40 -0
- package/tests/parsing/parser.test.ts +434 -0
- package/tests/tokenization/token_mapper.test.ts +47 -0
- package/tests/tokenization/tokenizer.test.ts +67 -0
- package/tests/tokenization/trie.test.ts +20 -0
- package/tsconfig.json +15 -0
- package/typedoc.json +16 -0
- package/webpack.config.js +26 -0
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
import TokenType from "./token_type";
|
|
2
|
+
import Keyword from "./keyword";
|
|
3
|
+
import Symbol from "./symbol";
|
|
4
|
+
import Operator from "./operator";
|
|
5
|
+
import TokenToNode from "../parsing/token_to_node";
|
|
6
|
+
import ASTNode from "../parsing/ast_node";
|
|
7
|
+
import StringUtils from "../utils/string_utils";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents a single token in the FlowQuery language.
|
|
11
|
+
*
|
|
12
|
+
* Tokens are the atomic units of lexical analysis, produced by the tokenizer
|
|
13
|
+
* and consumed by the parser. Each token has a type (keyword, operator, identifier, etc.)
|
|
14
|
+
* and an optional value.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const withToken = Token.WITH;
|
|
19
|
+
* const identToken = Token.IDENTIFIER("myVar");
|
|
20
|
+
* const numToken = Token.NUMBER("42");
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
class Token {
|
|
24
|
+
private _position: number = -1;
|
|
25
|
+
private _type: TokenType;
|
|
26
|
+
private _value: string | null;
|
|
27
|
+
private _case_sensitive_value: string | null = null;
|
|
28
|
+
private _can_be_identifier: boolean = false;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new Token instance.
|
|
32
|
+
*
|
|
33
|
+
* @param type - The type of the token
|
|
34
|
+
* @param value - The optional value associated with the token
|
|
35
|
+
*/
|
|
36
|
+
constructor(type: TokenType, value: string | null = null) {
|
|
37
|
+
this._type = type;
|
|
38
|
+
this._value = value;
|
|
39
|
+
this._can_be_identifier = StringUtils.can_be_identifier(value || '');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Checks if this token equals another token.
|
|
44
|
+
*
|
|
45
|
+
* @param other - The token to compare against
|
|
46
|
+
* @returns True if tokens are equal, false otherwise
|
|
47
|
+
*/
|
|
48
|
+
public equals(other: Token): boolean {
|
|
49
|
+
if(this._type === TokenType.IDENTIFIER && other.type === TokenType.IDENTIFIER) {
|
|
50
|
+
return true; // Identifier values are not compared
|
|
51
|
+
}
|
|
52
|
+
return this._type === other.type && this._value === other.value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public set position(position: number) {
|
|
56
|
+
this._position = position;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public get position(): number {
|
|
60
|
+
return this._position;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public get type(): TokenType {
|
|
64
|
+
return this._type;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public get value(): string | null {
|
|
68
|
+
return this._case_sensitive_value || this._value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public set case_sensitive_value(value: string) {
|
|
72
|
+
this._case_sensitive_value = value;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public get can_be_identifier(): boolean {
|
|
76
|
+
return this._can_be_identifier;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public get node(): ASTNode {
|
|
80
|
+
return TokenToNode.convert(this);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public toString(): string {
|
|
84
|
+
return `${this._type} ${this._value}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Comment tokens
|
|
88
|
+
|
|
89
|
+
public static COMMENT(comment: string): Token {
|
|
90
|
+
return new Token(TokenType.COMMENT, comment);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public isComment(): boolean {
|
|
94
|
+
return this._type === TokenType.COMMENT;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Identifier token
|
|
98
|
+
|
|
99
|
+
public static IDENTIFIER(value: string): Token {
|
|
100
|
+
return new Token(TokenType.IDENTIFIER, value);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public isIdentifier(): boolean {
|
|
104
|
+
return this._type === TokenType.IDENTIFIER || this._type === TokenType.BACKTICK_STRING;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// String token
|
|
108
|
+
|
|
109
|
+
public static STRING(value: string, quoteChar: string = '"'): Token {
|
|
110
|
+
const unquoted = StringUtils.unquote(value);
|
|
111
|
+
const unescaped = StringUtils.removeEscapedQuotes(unquoted, quoteChar);
|
|
112
|
+
return new Token(TokenType.STRING, unescaped);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public isString(): boolean {
|
|
116
|
+
return this._type === TokenType.STRING || this._type === TokenType.BACKTICK_STRING;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public static BACKTICK_STRING(value: string, quoteChar: string = '"'): Token {
|
|
120
|
+
const unquoted = StringUtils.unquote(value);
|
|
121
|
+
const unescaped = StringUtils.removeEscapedQuotes(unquoted, quoteChar);
|
|
122
|
+
return new Token(TokenType.BACKTICK_STRING, unescaped);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public static F_STRING(value: string, quoteChar: string = '"'): Token {
|
|
126
|
+
const unquoted = StringUtils.unquote(value);
|
|
127
|
+
const unescaped = StringUtils.removeEscapedQuotes(unquoted, quoteChar);
|
|
128
|
+
const fstring = StringUtils.removeEscapedBraces(unescaped);
|
|
129
|
+
return new Token(TokenType.F_STRING, fstring);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public isFString(): boolean {
|
|
133
|
+
return this._type === TokenType.F_STRING;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Number token
|
|
137
|
+
|
|
138
|
+
public static NUMBER(value: string): Token {
|
|
139
|
+
return new Token(TokenType.NUMBER, value);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public isNumber(): boolean {
|
|
143
|
+
return this._type === TokenType.NUMBER;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Symbol tokens
|
|
147
|
+
|
|
148
|
+
public static get LEFT_PARENTHESIS(): Token {
|
|
149
|
+
return new Token(TokenType.SYMBOL, Symbol.LEFT_PARENTHESIS);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public isLeftParenthesis(): boolean {
|
|
153
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.LEFT_PARENTHESIS;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public static get RIGHT_PARENTHESIS(): Token {
|
|
157
|
+
return new Token(TokenType.SYMBOL, Symbol.RIGHT_PARENTHESIS);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public isRightParenthesis(): boolean {
|
|
161
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.RIGHT_PARENTHESIS;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public static get COMMA(): Token {
|
|
165
|
+
return new Token(TokenType.SYMBOL, Symbol.COMMA);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public isComma(): boolean {
|
|
169
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.COMMA;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public static get DOT(): Token {
|
|
173
|
+
return new Token(TokenType.SYMBOL, Symbol.DOT);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public isDot(): boolean {
|
|
177
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.DOT;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public static get COLON(): Token {
|
|
181
|
+
return new Token(TokenType.SYMBOL, Symbol.COLON);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public isColon(): boolean {
|
|
185
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.COLON;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
public static get OPENING_BRACE(): Token {
|
|
189
|
+
return new Token(TokenType.SYMBOL, Symbol.OPENING_BRACE);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
public isOpeningBrace(): boolean {
|
|
193
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.OPENING_BRACE;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
public static get CLOSING_BRACE(): Token {
|
|
197
|
+
return new Token(TokenType.SYMBOL, Symbol.CLOSING_BRACE);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public isClosingBrace(): boolean {
|
|
201
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.CLOSING_BRACE;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public static get OPENING_BRACKET(): Token {
|
|
205
|
+
return new Token(TokenType.SYMBOL, Symbol.OPENING_BRACKET);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
public isOpeningBracket(): boolean {
|
|
209
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.OPENING_BRACKET;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public static get CLOSING_BRACKET(): Token {
|
|
213
|
+
return new Token(TokenType.SYMBOL, Symbol.CLOSING_BRACKET);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
public isClosingBracket(): boolean {
|
|
217
|
+
return this._type === TokenType.SYMBOL && this._value === Symbol.CLOSING_BRACKET;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Whitespace token
|
|
221
|
+
|
|
222
|
+
public static get WHITESPACE(): Token {
|
|
223
|
+
return new Token(TokenType.WHITESPACE);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
public isWhitespace(): boolean {
|
|
227
|
+
return this._type === TokenType.WHITESPACE;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Operator tokens
|
|
231
|
+
|
|
232
|
+
public isOperator(): boolean {
|
|
233
|
+
return this._type === TokenType.OPERATOR;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public isUnaryOperator(): boolean {
|
|
237
|
+
return this._type === TokenType.UNARY_OPERATOR;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
public static get ADD(): Token {
|
|
241
|
+
return new Token(TokenType.OPERATOR, Operator.ADD);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
public isAdd(): boolean {
|
|
245
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.ADD;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
public static get SUBTRACT(): Token {
|
|
249
|
+
return new Token(TokenType.OPERATOR, Operator.SUBTRACT);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
public isSubtract(): boolean {
|
|
253
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.SUBTRACT;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
public isNegation(): boolean {
|
|
257
|
+
return this.isSubtract();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public static get MULTIPLY(): Token {
|
|
261
|
+
return new Token(TokenType.OPERATOR, Operator.MULTIPLY);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
public isMultiply(): boolean {
|
|
265
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.MULTIPLY;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
public static get DIVIDE(): Token {
|
|
269
|
+
return new Token(TokenType.OPERATOR, Operator.DIVIDE);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
public isDivide(): boolean {
|
|
273
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.DIVIDE;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
public static get EXPONENT(): Token {
|
|
277
|
+
return new Token(TokenType.OPERATOR, Operator.EXPONENT);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
public isExponent(): boolean {
|
|
281
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.EXPONENT;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
public static get MODULO(): Token {
|
|
285
|
+
return new Token(TokenType.OPERATOR, Operator.MODULO);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
public isModulo(): boolean {
|
|
289
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.MODULO;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public static get EQUALS(): Token {
|
|
293
|
+
return new Token(TokenType.OPERATOR, Operator.EQUALS);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
public isEquals(): boolean {
|
|
297
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.EQUALS;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public static get NOT_EQUALS(): Token {
|
|
301
|
+
return new Token(TokenType.OPERATOR, Operator.NOT_EQUALS);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
public isNotEquals(): boolean {
|
|
305
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.NOT_EQUALS;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
public static get LESS_THAN(): Token {
|
|
309
|
+
return new Token(TokenType.OPERATOR, Operator.LESS_THAN);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
public isLessThan(): boolean {
|
|
313
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.LESS_THAN;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
public static get LESS_THAN_OR_EQUAL(): Token {
|
|
317
|
+
return new Token(TokenType.OPERATOR, Operator.LESS_THAN_OR_EQUAL);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
public isLessThanOrEqual(): boolean {
|
|
321
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.LESS_THAN_OR_EQUAL;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
public static get GREATER_THAN(): Token {
|
|
325
|
+
return new Token(TokenType.OPERATOR, Operator.GREATER_THAN);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
public isGreaterThan(): boolean {
|
|
329
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.GREATER_THAN;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
public static get GREATER_THAN_OR_EQUAL(): Token {
|
|
333
|
+
return new Token(TokenType.OPERATOR, Operator.GREATER_THAN_OR_EQUAL);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
public isGreaterThanOrEqual(): boolean {
|
|
337
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.GREATER_THAN_OR_EQUAL;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
public static get AND(): Token {
|
|
341
|
+
return new Token(TokenType.OPERATOR, Operator.AND);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
public isAnd(): boolean {
|
|
345
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.AND;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
public static get OR(): Token {
|
|
349
|
+
return new Token(TokenType.OPERATOR, Operator.OR);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
public isOr(): boolean {
|
|
353
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.OR;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
public static get NOT(): Token {
|
|
357
|
+
return new Token(TokenType.UNARY_OPERATOR, Operator.NOT);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
public isNot(): boolean {
|
|
361
|
+
return this._type === TokenType.UNARY_OPERATOR && this._value === Operator.NOT;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
public static get IS(): Token {
|
|
365
|
+
return new Token(TokenType.OPERATOR, Operator.IS);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
public isIs(): boolean {
|
|
369
|
+
return this._type === TokenType.OPERATOR && this._value === Operator.IS;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Keyword tokens
|
|
373
|
+
|
|
374
|
+
public isKeyword(): boolean {
|
|
375
|
+
return this._type === TokenType.KEYWORD;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
public static get WITH(): Token {
|
|
379
|
+
return new Token(TokenType.KEYWORD, Keyword.WITH);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
public isWith(): boolean {
|
|
383
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.WITH;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
public static get RETURN(): Token {
|
|
387
|
+
return new Token(TokenType.KEYWORD, Keyword.RETURN);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
public isReturn(): boolean {
|
|
391
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.RETURN;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
public static get LOAD(): Token {
|
|
395
|
+
return new Token(TokenType.KEYWORD, Keyword.LOAD);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
public isLoad(): boolean {
|
|
399
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.LOAD;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
public static get JSON(): Token {
|
|
403
|
+
return new Token(TokenType.KEYWORD, Keyword.JSON);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
public isJSON(): boolean {
|
|
407
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.JSON;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
public static get CSV(): Token {
|
|
411
|
+
return new Token(TokenType.KEYWORD, Keyword.CSV);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
public isCSV(): boolean {
|
|
415
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.CSV;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
public static get TEXT(): Token {
|
|
419
|
+
return new Token(TokenType.KEYWORD, Keyword.TEXT);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
public isText(): boolean {
|
|
423
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.TEXT;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
public static get FROM(): Token {
|
|
427
|
+
return new Token(TokenType.KEYWORD, Keyword.FROM);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
public isFrom(): boolean {
|
|
431
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.FROM;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
public static get HEADERS(): Token {
|
|
435
|
+
return new Token(TokenType.KEYWORD, Keyword.HEADERS);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
public isHeaders(): boolean {
|
|
439
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.HEADERS;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
public static get POST(): Token {
|
|
443
|
+
return new Token(TokenType.KEYWORD, Keyword.POST);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
public isPost(): boolean {
|
|
447
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.POST;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
public static get UNWIND(): Token {
|
|
451
|
+
return new Token(TokenType.KEYWORD, Keyword.UNWIND);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
public isUnwind(): boolean {
|
|
455
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.UNWIND;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
public static get MATCH(): Token {
|
|
459
|
+
return new Token(TokenType.KEYWORD, Keyword.MATCH);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
public isMatch(): boolean {
|
|
463
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.MATCH;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
public static get AS(): Token {
|
|
467
|
+
return new Token(TokenType.KEYWORD, Keyword.AS);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
public isAs(): boolean {
|
|
471
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.AS;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
public static get WHERE(): Token {
|
|
475
|
+
return new Token(TokenType.KEYWORD, Keyword.WHERE);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
public isWhere(): boolean {
|
|
479
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.WHERE;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
public static get MERGE(): Token {
|
|
483
|
+
return new Token(TokenType.KEYWORD, Keyword.MERGE);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
public isMerge(): boolean {
|
|
487
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.MERGE;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
public static get CREATE(): Token {
|
|
491
|
+
return new Token(TokenType.KEYWORD, Keyword.CREATE);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
public isCreate(): boolean {
|
|
495
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.CREATE;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
public static get DELETE(): Token {
|
|
499
|
+
return new Token(TokenType.KEYWORD, Keyword.DELETE);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
public isDelete(): boolean {
|
|
503
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.DELETE;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
public static get SET(): Token {
|
|
507
|
+
return new Token(TokenType.KEYWORD, Keyword.SET);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
public isSet(): boolean {
|
|
511
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.SET;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
public static get REMOVE(): Token {
|
|
515
|
+
return new Token(TokenType.KEYWORD, Keyword.REMOVE);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
public isRemove(): boolean {
|
|
519
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.REMOVE;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
public static get CASE(): Token {
|
|
523
|
+
return new Token(TokenType.KEYWORD, Keyword.CASE);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
public isCase(): boolean {
|
|
527
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.CASE;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
public static get WHEN(): Token {
|
|
531
|
+
return new Token(TokenType.KEYWORD, Keyword.WHEN);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
public isWhen(): boolean {
|
|
535
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.WHEN;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
public static get THEN(): Token {
|
|
539
|
+
return new Token(TokenType.KEYWORD, Keyword.THEN);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
public isThen(): boolean {
|
|
543
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.THEN;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
public static get ELSE(): Token {
|
|
547
|
+
return new Token(TokenType.KEYWORD, Keyword.ELSE);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
public isElse(): boolean {
|
|
551
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.ELSE;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
public static get END(): Token {
|
|
555
|
+
return new Token(TokenType.KEYWORD, Keyword.END);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
public isEnd(): boolean {
|
|
559
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.END;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
public static get NULL(): Token {
|
|
563
|
+
return new Token(TokenType.KEYWORD, Keyword.NULL);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
public isNull(): boolean {
|
|
567
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.NULL;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
public static get IN(): Token {
|
|
571
|
+
return new Token(TokenType.KEYWORD, Keyword.IN);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
public isIn(): boolean {
|
|
575
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.IN;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
public static get PIPE(): Token {
|
|
579
|
+
return new Token(TokenType.KEYWORD, Operator.PIPE);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
public isPipe(): boolean {
|
|
583
|
+
return this._type === TokenType.KEYWORD && this._value === Operator.PIPE;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
public static get DISTINCT(): Token {
|
|
587
|
+
return new Token(TokenType.KEYWORD, Keyword.DISTINCT);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
public isDistinct(): boolean {
|
|
591
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.DISTINCT;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
public static get LIMIT(): Token {
|
|
595
|
+
return new Token(TokenType.KEYWORD, Keyword.LIMIT);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
public isLimit(): boolean {
|
|
599
|
+
return this._type === TokenType.KEYWORD && this._value === Keyword.LIMIT;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
// End of file token
|
|
604
|
+
|
|
605
|
+
public static get EOF(): Token {
|
|
606
|
+
return new Token(TokenType.EOF);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
public isEOF(): boolean {
|
|
610
|
+
return this._type === TokenType.EOF;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// Other utility methods
|
|
614
|
+
|
|
615
|
+
public isOperand(): boolean {
|
|
616
|
+
return this.isNumber() || this.isString() || this.isNull();
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
public isWhitespaceOrComment(): boolean {
|
|
620
|
+
return this.isWhitespace() || this.isComment();
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
public isSymbol(): boolean {
|
|
624
|
+
return this._type === TokenType.SYMBOL;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Static class method lookup via string
|
|
628
|
+
public static method(name: string): Token | undefined {
|
|
629
|
+
return (Token as any)[name.toUpperCase()] as Token | undefined;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
export default Token;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Token from "../../src/tokenization/token";
|
|
2
|
+
import Trie from "../../src/tokenization/trie";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Maps string values to tokens using a Trie for efficient lookup.
|
|
6
|
+
*
|
|
7
|
+
* Takes an enum of keywords, operators, or symbols and builds a trie
|
|
8
|
+
* for fast token matching during tokenization.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const mapper = new TokenMapper(Keyword);
|
|
13
|
+
* const token = mapper.map("WITH");
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
class TokenMapper {
|
|
17
|
+
private _trie: Trie = new Trie();
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a TokenMapper from an enum of token values.
|
|
21
|
+
*
|
|
22
|
+
* @param _enum - An enum object containing token values
|
|
23
|
+
*/
|
|
24
|
+
constructor(private _enum: { [key: string]: any }) {
|
|
25
|
+
for(const [key, value] of Object.entries(_enum)) {
|
|
26
|
+
const token: Token | undefined = Token.method(key);
|
|
27
|
+
if(token !== undefined && token.value !== null) {
|
|
28
|
+
this._trie.insert(token);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Maps a string value to its corresponding token.
|
|
35
|
+
*
|
|
36
|
+
* @param value - The string value to map
|
|
37
|
+
* @returns The matched token, or undefined if no match found
|
|
38
|
+
*/
|
|
39
|
+
public map(value: string): Token | undefined {
|
|
40
|
+
return this._trie.find(value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Gets the last matched string from the most recent map operation.
|
|
45
|
+
*
|
|
46
|
+
* @returns The last found string, or null if no match
|
|
47
|
+
*/
|
|
48
|
+
public get last_found(): string | null {
|
|
49
|
+
return this._trie.last_found;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default TokenMapper;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
enum TokenType {
|
|
2
|
+
KEYWORD = "KEYWORD",
|
|
3
|
+
OPERATOR = "OPERATOR",
|
|
4
|
+
UNARY_OPERATOR = "UNARY_OPERATOR",
|
|
5
|
+
IDENTIFIER = "IDENTIFIER",
|
|
6
|
+
STRING = "STRING",
|
|
7
|
+
F_STRING = "F-STRING",
|
|
8
|
+
BACKTICK_STRING = "BACKTICK_STRING",
|
|
9
|
+
NUMBER = "NUMBER",
|
|
10
|
+
SYMBOL = "SYMBOL",
|
|
11
|
+
WHITESPACE = "WHITESPACE",
|
|
12
|
+
COMMENT = "COMMENT",
|
|
13
|
+
EOF = "EOF",
|
|
14
|
+
}
|
|
15
|
+
export default TokenType;
|