flowquery 1.0.16 → 1.0.17

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.
Files changed (318) hide show
  1. package/.github/workflows/python-publish.yml +97 -0
  2. package/dist/compute/runner.d.ts +3 -2
  3. package/dist/compute/runner.d.ts.map +1 -1
  4. package/dist/compute/runner.js +7 -7
  5. package/dist/compute/runner.js.map +1 -1
  6. package/dist/flowquery.min.js +1 -1
  7. package/dist/graph/data.d.ts +31 -0
  8. package/dist/graph/data.d.ts.map +1 -0
  9. package/dist/graph/data.js +110 -0
  10. package/dist/graph/data.js.map +1 -0
  11. package/dist/graph/database.d.ts +20 -0
  12. package/dist/graph/database.d.ts.map +1 -0
  13. package/dist/graph/database.js +77 -0
  14. package/dist/graph/database.js.map +1 -0
  15. package/dist/graph/hops.d.ts +11 -0
  16. package/dist/graph/hops.d.ts.map +1 -0
  17. package/dist/graph/hops.js +25 -0
  18. package/dist/graph/hops.js.map +1 -0
  19. package/dist/graph/node.d.ts +35 -0
  20. package/dist/graph/node.d.ts.map +1 -0
  21. package/dist/graph/node.js +113 -0
  22. package/dist/graph/node.js.map +1 -0
  23. package/dist/graph/node_data.d.ts +11 -0
  24. package/dist/graph/node_data.d.ts.map +1 -0
  25. package/dist/graph/node_data.js +20 -0
  26. package/dist/graph/node_data.js.map +1 -0
  27. package/dist/graph/node_reference.d.ts +10 -0
  28. package/dist/graph/node_reference.d.ts.map +1 -0
  29. package/dist/graph/node_reference.js +52 -0
  30. package/dist/graph/node_reference.js.map +1 -0
  31. package/dist/graph/pattern.d.ts +18 -0
  32. package/dist/graph/pattern.d.ts.map +1 -0
  33. package/dist/graph/pattern.js +114 -0
  34. package/dist/graph/pattern.js.map +1 -0
  35. package/dist/graph/pattern_expression.d.ts +14 -0
  36. package/dist/graph/pattern_expression.d.ts.map +1 -0
  37. package/dist/graph/pattern_expression.js +58 -0
  38. package/dist/graph/pattern_expression.js.map +1 -0
  39. package/dist/graph/patterns.d.ts +11 -0
  40. package/dist/graph/patterns.d.ts.map +1 -0
  41. package/dist/graph/patterns.js +49 -0
  42. package/dist/graph/patterns.js.map +1 -0
  43. package/dist/graph/physical_node.d.ts +10 -0
  44. package/dist/graph/physical_node.d.ts.map +1 -0
  45. package/dist/graph/physical_node.js +40 -0
  46. package/dist/graph/physical_node.js.map +1 -0
  47. package/dist/graph/physical_relationship.d.ts +10 -0
  48. package/dist/graph/physical_relationship.d.ts.map +1 -0
  49. package/dist/graph/physical_relationship.js +40 -0
  50. package/dist/graph/physical_relationship.js.map +1 -0
  51. package/dist/graph/relationship.d.ts +40 -0
  52. package/dist/graph/relationship.d.ts.map +1 -0
  53. package/dist/graph/relationship.js +124 -0
  54. package/dist/graph/relationship.js.map +1 -0
  55. package/dist/graph/relationship_data.d.ts +12 -0
  56. package/dist/graph/relationship_data.d.ts.map +1 -0
  57. package/dist/graph/relationship_data.js +40 -0
  58. package/dist/graph/relationship_data.js.map +1 -0
  59. package/dist/graph/relationship_match_collector.d.ts +19 -0
  60. package/dist/graph/relationship_match_collector.d.ts.map +1 -0
  61. package/dist/graph/relationship_match_collector.js +55 -0
  62. package/dist/graph/relationship_match_collector.js.map +1 -0
  63. package/dist/graph/relationship_reference.d.ts +8 -0
  64. package/dist/graph/relationship_reference.d.ts.map +1 -0
  65. package/dist/graph/relationship_reference.js +37 -0
  66. package/dist/graph/relationship_reference.js.map +1 -0
  67. package/dist/parsing/base_parser.d.ts +1 -0
  68. package/dist/parsing/base_parser.d.ts.map +1 -1
  69. package/dist/parsing/base_parser.js +4 -1
  70. package/dist/parsing/base_parser.js.map +1 -1
  71. package/dist/parsing/context.d.ts +2 -2
  72. package/dist/parsing/context.js +5 -5
  73. package/dist/parsing/expressions/boolean.d.ts +8 -0
  74. package/dist/parsing/expressions/boolean.d.ts.map +1 -0
  75. package/dist/parsing/expressions/boolean.js +26 -0
  76. package/dist/parsing/expressions/boolean.js.map +1 -0
  77. package/dist/parsing/expressions/expression.d.ts +4 -1
  78. package/dist/parsing/expressions/expression.d.ts.map +1 -1
  79. package/dist/parsing/expressions/expression.js +15 -8
  80. package/dist/parsing/expressions/expression.js.map +1 -1
  81. package/dist/parsing/expressions/operator.d.ts +1 -1
  82. package/dist/parsing/expressions/operator.d.ts.map +1 -1
  83. package/dist/parsing/expressions/operator.js.map +1 -1
  84. package/dist/parsing/functions/function_factory.d.ts +13 -13
  85. package/dist/parsing/functions/function_factory.d.ts.map +1 -1
  86. package/dist/parsing/functions/function_factory.js +20 -18
  87. package/dist/parsing/functions/function_factory.js.map +1 -1
  88. package/dist/parsing/operations/create_node.d.ts +14 -0
  89. package/dist/parsing/operations/create_node.d.ts.map +1 -0
  90. package/dist/parsing/operations/create_node.js +51 -0
  91. package/dist/parsing/operations/create_node.js.map +1 -0
  92. package/dist/parsing/operations/create_relationship.d.ts +14 -0
  93. package/dist/parsing/operations/create_relationship.d.ts.map +1 -0
  94. package/dist/parsing/operations/create_relationship.js +51 -0
  95. package/dist/parsing/operations/create_relationship.js.map +1 -0
  96. package/dist/parsing/operations/match.d.ts +15 -0
  97. package/dist/parsing/operations/match.d.ts.map +1 -0
  98. package/dist/parsing/operations/match.js +45 -0
  99. package/dist/parsing/operations/match.js.map +1 -0
  100. package/dist/parsing/operations/operation.d.ts +1 -0
  101. package/dist/parsing/operations/operation.d.ts.map +1 -1
  102. package/dist/parsing/operations/operation.js +6 -0
  103. package/dist/parsing/operations/operation.js.map +1 -1
  104. package/dist/parsing/operations/return.d.ts +1 -0
  105. package/dist/parsing/operations/return.d.ts.map +1 -1
  106. package/dist/parsing/operations/return.js +7 -1
  107. package/dist/parsing/operations/return.js.map +1 -1
  108. package/dist/parsing/operations/where.d.ts +1 -1
  109. package/dist/parsing/operations/where.d.ts.map +1 -1
  110. package/dist/parsing/operations/where.js +4 -0
  111. package/dist/parsing/operations/where.js.map +1 -1
  112. package/dist/parsing/parser.d.ts +10 -0
  113. package/dist/parsing/parser.d.ts.map +1 -1
  114. package/dist/parsing/parser.js +344 -5
  115. package/dist/parsing/parser.js.map +1 -1
  116. package/dist/parsing/token_to_node.d.ts.map +1 -1
  117. package/dist/parsing/token_to_node.js +7 -0
  118. package/dist/parsing/token_to_node.js.map +1 -1
  119. package/dist/tokenization/keyword.d.ts +1 -0
  120. package/dist/tokenization/keyword.d.ts.map +1 -1
  121. package/dist/tokenization/keyword.js +1 -0
  122. package/dist/tokenization/keyword.js.map +1 -1
  123. package/dist/tokenization/token.d.ts +4 -0
  124. package/dist/tokenization/token.d.ts.map +1 -1
  125. package/dist/tokenization/token.js +14 -1
  126. package/dist/tokenization/token.js.map +1 -1
  127. package/dist/tokenization/token_type.d.ts +1 -0
  128. package/dist/tokenization/token_type.d.ts.map +1 -1
  129. package/dist/tokenization/token_type.js +1 -0
  130. package/dist/tokenization/token_type.js.map +1 -1
  131. package/dist/tokenization/tokenizer.d.ts +2 -1
  132. package/dist/tokenization/tokenizer.d.ts.map +1 -1
  133. package/dist/tokenization/tokenizer.js +25 -12
  134. package/dist/tokenization/tokenizer.js.map +1 -1
  135. package/docs/flowquery.min.js +1 -1
  136. package/flowquery-py/README.md +166 -0
  137. package/flowquery-py/pyproject.toml +75 -0
  138. package/flowquery-py/setup_env.ps1 +92 -0
  139. package/flowquery-py/setup_env.sh +87 -0
  140. package/flowquery-py/src/__init__.py +34 -0
  141. package/flowquery-py/src/__main__.py +10 -0
  142. package/flowquery-py/src/compute/__init__.py +5 -0
  143. package/flowquery-py/src/compute/runner.py +60 -0
  144. package/flowquery-py/src/extensibility.py +52 -0
  145. package/flowquery-py/src/graph/__init__.py +31 -0
  146. package/flowquery-py/src/graph/data.py +118 -0
  147. package/flowquery-py/src/graph/database.py +82 -0
  148. package/flowquery-py/src/graph/hops.py +43 -0
  149. package/flowquery-py/src/graph/node.py +112 -0
  150. package/flowquery-py/src/graph/node_data.py +26 -0
  151. package/flowquery-py/src/graph/node_reference.py +49 -0
  152. package/flowquery-py/src/graph/pattern.py +125 -0
  153. package/flowquery-py/src/graph/pattern_expression.py +62 -0
  154. package/flowquery-py/src/graph/patterns.py +42 -0
  155. package/flowquery-py/src/graph/physical_node.py +40 -0
  156. package/flowquery-py/src/graph/physical_relationship.py +36 -0
  157. package/flowquery-py/src/graph/relationship.py +135 -0
  158. package/flowquery-py/src/graph/relationship_data.py +33 -0
  159. package/flowquery-py/src/graph/relationship_match_collector.py +77 -0
  160. package/flowquery-py/src/graph/relationship_reference.py +21 -0
  161. package/flowquery-py/src/io/__init__.py +5 -0
  162. package/flowquery-py/src/io/command_line.py +67 -0
  163. package/flowquery-py/src/parsing/__init__.py +17 -0
  164. package/flowquery-py/src/parsing/alias.py +20 -0
  165. package/flowquery-py/src/parsing/alias_option.py +11 -0
  166. package/flowquery-py/src/parsing/ast_node.py +146 -0
  167. package/flowquery-py/src/parsing/base_parser.py +84 -0
  168. package/flowquery-py/src/parsing/components/__init__.py +19 -0
  169. package/flowquery-py/src/parsing/components/csv.py +8 -0
  170. package/flowquery-py/src/parsing/components/from_.py +10 -0
  171. package/flowquery-py/src/parsing/components/headers.py +12 -0
  172. package/flowquery-py/src/parsing/components/json.py +8 -0
  173. package/flowquery-py/src/parsing/components/null.py +10 -0
  174. package/flowquery-py/src/parsing/components/post.py +8 -0
  175. package/flowquery-py/src/parsing/components/text.py +8 -0
  176. package/flowquery-py/src/parsing/context.py +50 -0
  177. package/flowquery-py/src/parsing/data_structures/__init__.py +15 -0
  178. package/flowquery-py/src/parsing/data_structures/associative_array.py +41 -0
  179. package/flowquery-py/src/parsing/data_structures/json_array.py +30 -0
  180. package/flowquery-py/src/parsing/data_structures/key_value_pair.py +38 -0
  181. package/flowquery-py/src/parsing/data_structures/lookup.py +49 -0
  182. package/flowquery-py/src/parsing/data_structures/range_lookup.py +42 -0
  183. package/flowquery-py/src/parsing/expressions/__init__.py +57 -0
  184. package/flowquery-py/src/parsing/expressions/boolean.py +20 -0
  185. package/flowquery-py/src/parsing/expressions/expression.py +138 -0
  186. package/flowquery-py/src/parsing/expressions/expression_map.py +26 -0
  187. package/flowquery-py/src/parsing/expressions/f_string.py +27 -0
  188. package/flowquery-py/src/parsing/expressions/identifier.py +20 -0
  189. package/flowquery-py/src/parsing/expressions/number.py +32 -0
  190. package/flowquery-py/src/parsing/expressions/operator.py +169 -0
  191. package/flowquery-py/src/parsing/expressions/reference.py +47 -0
  192. package/flowquery-py/src/parsing/expressions/string.py +27 -0
  193. package/flowquery-py/src/parsing/functions/__init__.py +75 -0
  194. package/flowquery-py/src/parsing/functions/aggregate_function.py +60 -0
  195. package/flowquery-py/src/parsing/functions/async_function.py +62 -0
  196. package/flowquery-py/src/parsing/functions/avg.py +55 -0
  197. package/flowquery-py/src/parsing/functions/collect.py +75 -0
  198. package/flowquery-py/src/parsing/functions/function.py +68 -0
  199. package/flowquery-py/src/parsing/functions/function_factory.py +173 -0
  200. package/flowquery-py/src/parsing/functions/function_metadata.py +149 -0
  201. package/flowquery-py/src/parsing/functions/functions.py +59 -0
  202. package/flowquery-py/src/parsing/functions/join.py +47 -0
  203. package/flowquery-py/src/parsing/functions/keys.py +34 -0
  204. package/flowquery-py/src/parsing/functions/predicate_function.py +46 -0
  205. package/flowquery-py/src/parsing/functions/predicate_sum.py +47 -0
  206. package/flowquery-py/src/parsing/functions/rand.py +28 -0
  207. package/flowquery-py/src/parsing/functions/range_.py +34 -0
  208. package/flowquery-py/src/parsing/functions/reducer_element.py +15 -0
  209. package/flowquery-py/src/parsing/functions/replace.py +37 -0
  210. package/flowquery-py/src/parsing/functions/round_.py +32 -0
  211. package/flowquery-py/src/parsing/functions/size.py +32 -0
  212. package/flowquery-py/src/parsing/functions/split.py +47 -0
  213. package/flowquery-py/src/parsing/functions/stringify.py +47 -0
  214. package/flowquery-py/src/parsing/functions/sum.py +51 -0
  215. package/flowquery-py/src/parsing/functions/to_json.py +33 -0
  216. package/flowquery-py/src/parsing/functions/type_.py +47 -0
  217. package/flowquery-py/src/parsing/functions/value_holder.py +24 -0
  218. package/flowquery-py/src/parsing/logic/__init__.py +15 -0
  219. package/flowquery-py/src/parsing/logic/case.py +29 -0
  220. package/flowquery-py/src/parsing/logic/else_.py +12 -0
  221. package/flowquery-py/src/parsing/logic/end.py +8 -0
  222. package/flowquery-py/src/parsing/logic/then.py +12 -0
  223. package/flowquery-py/src/parsing/logic/when.py +10 -0
  224. package/flowquery-py/src/parsing/operations/__init__.py +35 -0
  225. package/flowquery-py/src/parsing/operations/aggregated_return.py +24 -0
  226. package/flowquery-py/src/parsing/operations/aggregated_with.py +22 -0
  227. package/flowquery-py/src/parsing/operations/call.py +74 -0
  228. package/flowquery-py/src/parsing/operations/create_node.py +34 -0
  229. package/flowquery-py/src/parsing/operations/create_relationship.py +34 -0
  230. package/flowquery-py/src/parsing/operations/group_by.py +130 -0
  231. package/flowquery-py/src/parsing/operations/limit.py +22 -0
  232. package/flowquery-py/src/parsing/operations/load.py +140 -0
  233. package/flowquery-py/src/parsing/operations/match.py +29 -0
  234. package/flowquery-py/src/parsing/operations/operation.py +69 -0
  235. package/flowquery-py/src/parsing/operations/projection.py +21 -0
  236. package/flowquery-py/src/parsing/operations/return_op.py +50 -0
  237. package/flowquery-py/src/parsing/operations/unwind.py +37 -0
  238. package/flowquery-py/src/parsing/operations/where.py +41 -0
  239. package/flowquery-py/src/parsing/operations/with_op.py +18 -0
  240. package/flowquery-py/src/parsing/parser.py +1011 -0
  241. package/flowquery-py/src/parsing/token_to_node.py +109 -0
  242. package/flowquery-py/src/tokenization/__init__.py +23 -0
  243. package/flowquery-py/src/tokenization/keyword.py +48 -0
  244. package/flowquery-py/src/tokenization/operator.py +29 -0
  245. package/flowquery-py/src/tokenization/string_walker.py +158 -0
  246. package/flowquery-py/src/tokenization/symbol.py +19 -0
  247. package/flowquery-py/src/tokenization/token.py +659 -0
  248. package/flowquery-py/src/tokenization/token_mapper.py +52 -0
  249. package/flowquery-py/src/tokenization/token_type.py +21 -0
  250. package/flowquery-py/src/tokenization/tokenizer.py +214 -0
  251. package/flowquery-py/src/tokenization/trie.py +124 -0
  252. package/flowquery-py/src/utils/__init__.py +6 -0
  253. package/flowquery-py/src/utils/object_utils.py +20 -0
  254. package/flowquery-py/src/utils/string_utils.py +113 -0
  255. package/flowquery-py/tests/__init__.py +1 -0
  256. package/flowquery-py/tests/compute/__init__.py +1 -0
  257. package/flowquery-py/tests/compute/test_runner.py +1335 -0
  258. package/flowquery-py/tests/graph/__init__.py +1 -0
  259. package/flowquery-py/tests/graph/test_create.py +56 -0
  260. package/flowquery-py/tests/graph/test_data.py +73 -0
  261. package/flowquery-py/tests/graph/test_match.py +40 -0
  262. package/flowquery-py/tests/parsing/__init__.py +1 -0
  263. package/flowquery-py/tests/parsing/test_context.py +34 -0
  264. package/flowquery-py/tests/parsing/test_expression.py +49 -0
  265. package/flowquery-py/tests/parsing/test_parser.py +674 -0
  266. package/flowquery-py/tests/test_extensibility.py +611 -0
  267. package/flowquery-py/tests/tokenization/__init__.py +1 -0
  268. package/flowquery-py/tests/tokenization/test_token_mapper.py +60 -0
  269. package/flowquery-py/tests/tokenization/test_tokenizer.py +164 -0
  270. package/flowquery-py/tests/tokenization/test_trie.py +30 -0
  271. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  272. package/misc/apps/RAG/package.json +1 -1
  273. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +76 -8
  274. package/misc/apps/RAG/src/components/index.ts +19 -10
  275. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +70 -140
  276. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +12 -0
  277. package/package.json +1 -1
  278. package/src/compute/runner.ts +24 -19
  279. package/src/graph/data.ts +112 -0
  280. package/src/graph/database.ts +63 -0
  281. package/src/graph/hops.ts +22 -0
  282. package/src/graph/node.ts +99 -0
  283. package/src/graph/node_data.ts +18 -0
  284. package/src/graph/node_reference.ts +33 -0
  285. package/src/graph/pattern.ts +101 -0
  286. package/src/graph/pattern_expression.ts +37 -0
  287. package/src/graph/patterns.ts +36 -0
  288. package/src/graph/physical_node.ts +23 -0
  289. package/src/graph/physical_relationship.ts +23 -0
  290. package/src/graph/relationship.ts +116 -0
  291. package/src/graph/relationship_data.ts +27 -0
  292. package/src/graph/relationship_match_collector.ts +58 -0
  293. package/src/graph/relationship_reference.ts +24 -0
  294. package/src/parsing/base_parser.ts +20 -14
  295. package/src/parsing/context.ts +14 -14
  296. package/src/parsing/expressions/boolean.ts +21 -0
  297. package/src/parsing/expressions/expression.ts +34 -26
  298. package/src/parsing/expressions/operator.ts +19 -1
  299. package/src/parsing/functions/function_factory.ts +45 -45
  300. package/src/parsing/operations/create_node.ts +39 -0
  301. package/src/parsing/operations/create_relationship.ts +38 -0
  302. package/src/parsing/operations/match.ts +31 -0
  303. package/src/parsing/operations/operation.ts +3 -0
  304. package/src/parsing/operations/return.ts +11 -7
  305. package/src/parsing/operations/where.ts +10 -6
  306. package/src/parsing/parser.ts +346 -8
  307. package/src/parsing/token_to_node.ts +6 -0
  308. package/src/tokenization/keyword.ts +41 -40
  309. package/src/tokenization/token.ts +21 -1
  310. package/src/tokenization/token_type.ts +2 -1
  311. package/src/tokenization/tokenizer.ts +52 -31
  312. package/tests/compute/runner.test.ts +654 -0
  313. package/tests/extensibility.test.ts +97 -93
  314. package/tests/graph/create.test.ts +36 -0
  315. package/tests/graph/data.test.ts +58 -0
  316. package/tests/graph/match.test.ts +29 -0
  317. package/tests/parsing/parser.test.ts +273 -2
  318. package/tests/tokenization/tokenizer.test.ts +90 -0
@@ -0,0 +1,659 @@
1
+ """Represents a single token in the FlowQuery language."""
2
+
3
+ from __future__ import annotations
4
+ from typing import TYPE_CHECKING, Optional, Any
5
+
6
+ from .token_type import TokenType
7
+ from .keyword import Keyword
8
+ from .operator import Operator
9
+ from .symbol import Symbol
10
+ from ..utils.string_utils import StringUtils
11
+
12
+ if TYPE_CHECKING:
13
+ from ..parsing.ast_node import ASTNode
14
+
15
+
16
+ class Token:
17
+ """Represents a single token in the FlowQuery language.
18
+
19
+ Tokens are the atomic units of lexical analysis, produced by the tokenizer
20
+ and consumed by the parser. Each token has a type (keyword, operator, identifier, etc.)
21
+ and an optional value.
22
+
23
+ Example:
24
+ with_token = Token.WITH
25
+ ident_token = Token.IDENTIFIER("myVar")
26
+ num_token = Token.NUMBER("42")
27
+ """
28
+
29
+ def __init__(self, type_: TokenType, value: Optional[str] = None):
30
+ """Creates a new Token instance.
31
+
32
+ Args:
33
+ type_: The type of the token
34
+ value: The optional value associated with the token
35
+ """
36
+ self._position: int = -1
37
+ self._type = type_
38
+ self._value = value
39
+ self._case_sensitive_value: Optional[str] = None
40
+ self._can_be_identifier = StringUtils.can_be_identifier(value or "")
41
+
42
+ def equals(self, other: Token) -> bool:
43
+ """Checks if this token equals another token.
44
+
45
+ Args:
46
+ other: The token to compare against
47
+
48
+ Returns:
49
+ True if tokens are equal, False otherwise
50
+ """
51
+ if self._type == TokenType.IDENTIFIER and other.type == TokenType.IDENTIFIER:
52
+ return True # Identifier values are not compared
53
+ return self._type == other.type and self._value == other.value
54
+
55
+ @property
56
+ def position(self) -> int:
57
+ return self._position
58
+
59
+ @position.setter
60
+ def position(self, value: int) -> None:
61
+ self._position = value
62
+
63
+ @property
64
+ def type(self) -> TokenType:
65
+ return self._type
66
+
67
+ @property
68
+ def value(self) -> Optional[str]:
69
+ return self._case_sensitive_value or self._value
70
+
71
+ @property
72
+ def case_sensitive_value(self) -> Optional[str]:
73
+ return self._case_sensitive_value
74
+
75
+ @case_sensitive_value.setter
76
+ def case_sensitive_value(self, value: str) -> None:
77
+ self._case_sensitive_value = value
78
+
79
+ @property
80
+ def can_be_identifier(self) -> bool:
81
+ return self._can_be_identifier
82
+
83
+ @property
84
+ def node(self) -> ASTNode:
85
+ from ..parsing.token_to_node import TokenToNode
86
+ return TokenToNode.convert(self)
87
+
88
+ def __str__(self) -> str:
89
+ return f"{self._type.value} {self._value}"
90
+
91
+ # Comment tokens
92
+
93
+ @staticmethod
94
+ def COMMENT(comment: str) -> Token:
95
+ return Token(TokenType.COMMENT, comment)
96
+
97
+ def is_comment(self) -> bool:
98
+ return self._type == TokenType.COMMENT
99
+
100
+ # Identifier token
101
+
102
+ @staticmethod
103
+ def IDENTIFIER(value: str) -> Token:
104
+ return Token(TokenType.IDENTIFIER, value)
105
+
106
+ def is_identifier(self) -> bool:
107
+ return self._type == TokenType.IDENTIFIER or self._type == TokenType.BACKTICK_STRING
108
+
109
+ # String token
110
+
111
+ @staticmethod
112
+ def STRING(value: str, quote_char: str = '"') -> Token:
113
+ unquoted = StringUtils.unquote(value)
114
+ unescaped = StringUtils.remove_escaped_quotes(unquoted, quote_char)
115
+ return Token(TokenType.STRING, unescaped)
116
+
117
+ def is_string(self) -> bool:
118
+ return self._type == TokenType.STRING or self._type == TokenType.BACKTICK_STRING
119
+
120
+ @staticmethod
121
+ def BACKTICK_STRING(value: str, quote_char: str = '"') -> Token:
122
+ unquoted = StringUtils.unquote(value)
123
+ unescaped = StringUtils.remove_escaped_quotes(unquoted, quote_char)
124
+ return Token(TokenType.BACKTICK_STRING, unescaped)
125
+
126
+ @staticmethod
127
+ def F_STRING(value: str, quote_char: str = '"') -> Token:
128
+ unquoted = StringUtils.unquote(value)
129
+ unescaped = StringUtils.remove_escaped_quotes(unquoted, quote_char)
130
+ fstring = StringUtils.remove_escaped_braces(unescaped)
131
+ return Token(TokenType.F_STRING, fstring)
132
+
133
+ def is_f_string(self) -> bool:
134
+ return self._type == TokenType.F_STRING
135
+
136
+ # Number token
137
+
138
+ @staticmethod
139
+ def NUMBER(value: str) -> Token:
140
+ return Token(TokenType.NUMBER, value)
141
+
142
+ def is_number(self) -> bool:
143
+ return self._type == TokenType.NUMBER
144
+
145
+ # Boolean token
146
+
147
+ @staticmethod
148
+ def BOOLEAN(value: str) -> Token:
149
+ return Token(TokenType.BOOLEAN, value)
150
+
151
+ def is_boolean(self) -> bool:
152
+ return self._type == TokenType.BOOLEAN and self._value in ("TRUE", "FALSE")
153
+
154
+ # Symbol tokens
155
+
156
+ @classmethod
157
+ @property
158
+ def LEFT_PARENTHESIS(cls) -> Token:
159
+ return Token(TokenType.SYMBOL, Symbol.LEFT_PARENTHESIS.value)
160
+
161
+ def is_left_parenthesis(self) -> bool:
162
+ return self._type == TokenType.SYMBOL and self._value == Symbol.LEFT_PARENTHESIS.value
163
+
164
+ @classmethod
165
+ @property
166
+ def RIGHT_PARENTHESIS(cls) -> Token:
167
+ return Token(TokenType.SYMBOL, Symbol.RIGHT_PARENTHESIS.value)
168
+
169
+ def is_right_parenthesis(self) -> bool:
170
+ return self._type == TokenType.SYMBOL and self._value == Symbol.RIGHT_PARENTHESIS.value
171
+
172
+ @classmethod
173
+ @property
174
+ def COMMA(cls) -> Token:
175
+ return Token(TokenType.SYMBOL, Symbol.COMMA.value)
176
+
177
+ def is_comma(self) -> bool:
178
+ return self._type == TokenType.SYMBOL and self._value == Symbol.COMMA.value
179
+
180
+ @classmethod
181
+ @property
182
+ def DOT(cls) -> Token:
183
+ return Token(TokenType.SYMBOL, Symbol.DOT.value)
184
+
185
+ def is_dot(self) -> bool:
186
+ return self._type == TokenType.SYMBOL and self._value == Symbol.DOT.value
187
+
188
+ @classmethod
189
+ @property
190
+ def COLON(cls) -> Token:
191
+ return Token(TokenType.SYMBOL, Symbol.COLON.value)
192
+
193
+ def is_colon(self) -> bool:
194
+ return self._type == TokenType.SYMBOL and self._value == Symbol.COLON.value
195
+
196
+ @classmethod
197
+ @property
198
+ def OPENING_BRACE(cls) -> Token:
199
+ return Token(TokenType.SYMBOL, Symbol.OPENING_BRACE.value)
200
+
201
+ def is_opening_brace(self) -> bool:
202
+ return self._type == TokenType.SYMBOL and self._value == Symbol.OPENING_BRACE.value
203
+
204
+ @classmethod
205
+ @property
206
+ def CLOSING_BRACE(cls) -> Token:
207
+ return Token(TokenType.SYMBOL, Symbol.CLOSING_BRACE.value)
208
+
209
+ def is_closing_brace(self) -> bool:
210
+ return self._type == TokenType.SYMBOL and self._value == Symbol.CLOSING_BRACE.value
211
+
212
+ @classmethod
213
+ @property
214
+ def OPENING_BRACKET(cls) -> Token:
215
+ return Token(TokenType.SYMBOL, Symbol.OPENING_BRACKET.value)
216
+
217
+ def is_opening_bracket(self) -> bool:
218
+ return self._type == TokenType.SYMBOL and self._value == Symbol.OPENING_BRACKET.value
219
+
220
+ @classmethod
221
+ @property
222
+ def CLOSING_BRACKET(cls) -> Token:
223
+ return Token(TokenType.SYMBOL, Symbol.CLOSING_BRACKET.value)
224
+
225
+ def is_closing_bracket(self) -> bool:
226
+ return self._type == TokenType.SYMBOL and self._value == Symbol.CLOSING_BRACKET.value
227
+
228
+ # Whitespace token
229
+
230
+ @classmethod
231
+ @property
232
+ def WHITESPACE(cls) -> Token:
233
+ return Token(TokenType.WHITESPACE)
234
+
235
+ def is_whitespace(self) -> bool:
236
+ return self._type == TokenType.WHITESPACE
237
+
238
+ # Operator tokens
239
+
240
+ def is_operator(self) -> bool:
241
+ return self._type == TokenType.OPERATOR
242
+
243
+ def is_unary_operator(self) -> bool:
244
+ return self._type == TokenType.UNARY_OPERATOR
245
+
246
+ @classmethod
247
+ @property
248
+ def ADD(cls) -> Token:
249
+ return Token(TokenType.OPERATOR, Operator.ADD.value)
250
+
251
+ def is_add(self) -> bool:
252
+ return self._type == TokenType.OPERATOR and self._value == Operator.ADD.value
253
+
254
+ @classmethod
255
+ @property
256
+ def SUBTRACT(cls) -> Token:
257
+ return Token(TokenType.OPERATOR, Operator.SUBTRACT.value)
258
+
259
+ def is_subtract(self) -> bool:
260
+ return self._type == TokenType.OPERATOR and self._value == Operator.SUBTRACT.value
261
+
262
+ def is_negation(self) -> bool:
263
+ return self.is_subtract()
264
+
265
+ @classmethod
266
+ @property
267
+ def MULTIPLY(cls) -> Token:
268
+ return Token(TokenType.OPERATOR, Operator.MULTIPLY.value)
269
+
270
+ def is_multiply(self) -> bool:
271
+ return self._type == TokenType.OPERATOR and self._value == Operator.MULTIPLY.value
272
+
273
+ @classmethod
274
+ @property
275
+ def DIVIDE(cls) -> Token:
276
+ return Token(TokenType.OPERATOR, Operator.DIVIDE.value)
277
+
278
+ def is_divide(self) -> bool:
279
+ return self._type == TokenType.OPERATOR and self._value == Operator.DIVIDE.value
280
+
281
+ @classmethod
282
+ @property
283
+ def EXPONENT(cls) -> Token:
284
+ return Token(TokenType.OPERATOR, Operator.EXPONENT.value)
285
+
286
+ def is_exponent(self) -> bool:
287
+ return self._type == TokenType.OPERATOR and self._value == Operator.EXPONENT.value
288
+
289
+ @classmethod
290
+ @property
291
+ def MODULO(cls) -> Token:
292
+ return Token(TokenType.OPERATOR, Operator.MODULO.value)
293
+
294
+ def is_modulo(self) -> bool:
295
+ return self._type == TokenType.OPERATOR and self._value == Operator.MODULO.value
296
+
297
+ @classmethod
298
+ @property
299
+ def EQUALS(cls) -> Token:
300
+ return Token(TokenType.OPERATOR, Operator.EQUALS.value)
301
+
302
+ def is_equals(self) -> bool:
303
+ return self._type == TokenType.OPERATOR and self._value == Operator.EQUALS.value
304
+
305
+ @classmethod
306
+ @property
307
+ def NOT_EQUALS(cls) -> Token:
308
+ return Token(TokenType.OPERATOR, Operator.NOT_EQUALS.value)
309
+
310
+ def is_not_equals(self) -> bool:
311
+ return self._type == TokenType.OPERATOR and self._value == Operator.NOT_EQUALS.value
312
+
313
+ @classmethod
314
+ @property
315
+ def LESS_THAN(cls) -> Token:
316
+ return Token(TokenType.OPERATOR, Operator.LESS_THAN.value)
317
+
318
+ def is_less_than(self) -> bool:
319
+ return self._type == TokenType.OPERATOR and self._value == Operator.LESS_THAN.value
320
+
321
+ @classmethod
322
+ @property
323
+ def LESS_THAN_OR_EQUAL(cls) -> Token:
324
+ return Token(TokenType.OPERATOR, Operator.LESS_THAN_OR_EQUAL.value)
325
+
326
+ def is_less_than_or_equal(self) -> bool:
327
+ return self._type == TokenType.OPERATOR and self._value == Operator.LESS_THAN_OR_EQUAL.value
328
+
329
+ @classmethod
330
+ @property
331
+ def GREATER_THAN(cls) -> Token:
332
+ return Token(TokenType.OPERATOR, Operator.GREATER_THAN.value)
333
+
334
+ def is_greater_than(self) -> bool:
335
+ return self._type == TokenType.OPERATOR and self._value == Operator.GREATER_THAN.value
336
+
337
+ @classmethod
338
+ @property
339
+ def GREATER_THAN_OR_EQUAL(cls) -> Token:
340
+ return Token(TokenType.OPERATOR, Operator.GREATER_THAN_OR_EQUAL.value)
341
+
342
+ def is_greater_than_or_equal(self) -> bool:
343
+ return self._type == TokenType.OPERATOR and self._value == Operator.GREATER_THAN_OR_EQUAL.value
344
+
345
+ @classmethod
346
+ @property
347
+ def AND(cls) -> Token:
348
+ return Token(TokenType.OPERATOR, Operator.AND.value)
349
+
350
+ def is_and(self) -> bool:
351
+ return self._type == TokenType.OPERATOR and self._value == Operator.AND.value
352
+
353
+ @classmethod
354
+ @property
355
+ def OR(cls) -> Token:
356
+ return Token(TokenType.OPERATOR, Operator.OR.value)
357
+
358
+ def is_or(self) -> bool:
359
+ return self._type == TokenType.OPERATOR and self._value == Operator.OR.value
360
+
361
+ @classmethod
362
+ @property
363
+ def NOT(cls) -> Token:
364
+ return Token(TokenType.UNARY_OPERATOR, Operator.NOT.value)
365
+
366
+ def is_not(self) -> bool:
367
+ return self._type == TokenType.UNARY_OPERATOR and self._value == Operator.NOT.value
368
+
369
+ @classmethod
370
+ @property
371
+ def IS(cls) -> Token:
372
+ return Token(TokenType.OPERATOR, Operator.IS.value)
373
+
374
+ def is_is(self) -> bool:
375
+ return self._type == TokenType.OPERATOR and self._value == Operator.IS.value
376
+
377
+ # Keyword tokens
378
+
379
+ def is_keyword(self) -> bool:
380
+ return self._type == TokenType.KEYWORD
381
+
382
+ @classmethod
383
+ @property
384
+ def WITH(cls) -> Token:
385
+ return Token(TokenType.KEYWORD, Keyword.WITH.value)
386
+
387
+ def is_with(self) -> bool:
388
+ return self._type == TokenType.KEYWORD and self._value == Keyword.WITH.value
389
+
390
+ @classmethod
391
+ @property
392
+ def RETURN(cls) -> Token:
393
+ return Token(TokenType.KEYWORD, Keyword.RETURN.value)
394
+
395
+ def is_return(self) -> bool:
396
+ return self._type == TokenType.KEYWORD and self._value == Keyword.RETURN.value
397
+
398
+ @classmethod
399
+ @property
400
+ def LOAD(cls) -> Token:
401
+ return Token(TokenType.KEYWORD, Keyword.LOAD.value)
402
+
403
+ def is_load(self) -> bool:
404
+ return self._type == TokenType.KEYWORD and self._value == Keyword.LOAD.value
405
+
406
+ @classmethod
407
+ @property
408
+ def CALL(cls) -> Token:
409
+ return Token(TokenType.KEYWORD, Keyword.CALL.value)
410
+
411
+ def is_call(self) -> bool:
412
+ return self._type == TokenType.KEYWORD and self._value == Keyword.CALL.value
413
+
414
+ @classmethod
415
+ @property
416
+ def YIELD(cls) -> Token:
417
+ return Token(TokenType.KEYWORD, Keyword.YIELD.value)
418
+
419
+ def is_yield(self) -> bool:
420
+ return self._type == TokenType.KEYWORD and self._value == Keyword.YIELD.value
421
+
422
+ @classmethod
423
+ @property
424
+ def JSON(cls) -> Token:
425
+ return Token(TokenType.KEYWORD, Keyword.JSON.value)
426
+
427
+ def is_json(self) -> bool:
428
+ return self._type == TokenType.KEYWORD and self._value == Keyword.JSON.value
429
+
430
+ @classmethod
431
+ @property
432
+ def CSV(cls) -> Token:
433
+ return Token(TokenType.KEYWORD, Keyword.CSV.value)
434
+
435
+ def is_csv(self) -> bool:
436
+ return self._type == TokenType.KEYWORD and self._value == Keyword.CSV.value
437
+
438
+ @classmethod
439
+ @property
440
+ def TEXT(cls) -> Token:
441
+ return Token(TokenType.KEYWORD, Keyword.TEXT.value)
442
+
443
+ def is_text(self) -> bool:
444
+ return self._type == TokenType.KEYWORD and self._value == Keyword.TEXT.value
445
+
446
+ @classmethod
447
+ @property
448
+ def FROM(cls) -> Token:
449
+ return Token(TokenType.KEYWORD, Keyword.FROM.value)
450
+
451
+ def is_from(self) -> bool:
452
+ return self._type == TokenType.KEYWORD and self._value == Keyword.FROM.value
453
+
454
+ @classmethod
455
+ @property
456
+ def HEADERS(cls) -> Token:
457
+ return Token(TokenType.KEYWORD, Keyword.HEADERS.value)
458
+
459
+ def is_headers(self) -> bool:
460
+ return self._type == TokenType.KEYWORD and self._value == Keyword.HEADERS.value
461
+
462
+ @classmethod
463
+ @property
464
+ def POST(cls) -> Token:
465
+ return Token(TokenType.KEYWORD, Keyword.POST.value)
466
+
467
+ def is_post(self) -> bool:
468
+ return self._type == TokenType.KEYWORD and self._value == Keyword.POST.value
469
+
470
+ @classmethod
471
+ @property
472
+ def UNWIND(cls) -> Token:
473
+ return Token(TokenType.KEYWORD, Keyword.UNWIND.value)
474
+
475
+ def is_unwind(self) -> bool:
476
+ return self._type == TokenType.KEYWORD and self._value == Keyword.UNWIND.value
477
+
478
+ @classmethod
479
+ @property
480
+ def MATCH(cls) -> Token:
481
+ return Token(TokenType.KEYWORD, Keyword.MATCH.value)
482
+
483
+ def is_match(self) -> bool:
484
+ return self._type == TokenType.KEYWORD and self._value == Keyword.MATCH.value
485
+
486
+ @classmethod
487
+ @property
488
+ def AS(cls) -> Token:
489
+ return Token(TokenType.KEYWORD, Keyword.AS.value)
490
+
491
+ def is_as(self) -> bool:
492
+ return self._type == TokenType.KEYWORD and self._value == Keyword.AS.value
493
+
494
+ @classmethod
495
+ @property
496
+ def WHERE(cls) -> Token:
497
+ return Token(TokenType.KEYWORD, Keyword.WHERE.value)
498
+
499
+ def is_where(self) -> bool:
500
+ return self._type == TokenType.KEYWORD and self._value == Keyword.WHERE.value
501
+
502
+ @classmethod
503
+ @property
504
+ def MERGE(cls) -> Token:
505
+ return Token(TokenType.KEYWORD, Keyword.MERGE.value)
506
+
507
+ def is_merge(self) -> bool:
508
+ return self._type == TokenType.KEYWORD and self._value == Keyword.MERGE.value
509
+
510
+ @classmethod
511
+ @property
512
+ def CREATE(cls) -> Token:
513
+ return Token(TokenType.KEYWORD, Keyword.CREATE.value)
514
+
515
+ def is_create(self) -> bool:
516
+ return self._type == TokenType.KEYWORD and self._value == Keyword.CREATE.value
517
+
518
+ @classmethod
519
+ @property
520
+ def VIRTUAL(cls) -> Token:
521
+ return Token(TokenType.KEYWORD, Keyword.VIRTUAL.value)
522
+
523
+ def is_virtual(self) -> bool:
524
+ return self._type == TokenType.KEYWORD and self._value == Keyword.VIRTUAL.value
525
+
526
+ @classmethod
527
+ @property
528
+ def DELETE(cls) -> Token:
529
+ return Token(TokenType.KEYWORD, Keyword.DELETE.value)
530
+
531
+ def is_delete(self) -> bool:
532
+ return self._type == TokenType.KEYWORD and self._value == Keyword.DELETE.value
533
+
534
+ @classmethod
535
+ @property
536
+ def SET(cls) -> Token:
537
+ return Token(TokenType.KEYWORD, Keyword.SET.value)
538
+
539
+ def is_set(self) -> bool:
540
+ return self._type == TokenType.KEYWORD and self._value == Keyword.SET.value
541
+
542
+ @classmethod
543
+ @property
544
+ def REMOVE(cls) -> Token:
545
+ return Token(TokenType.KEYWORD, Keyword.REMOVE.value)
546
+
547
+ def is_remove(self) -> bool:
548
+ return self._type == TokenType.KEYWORD and self._value == Keyword.REMOVE.value
549
+
550
+ @classmethod
551
+ @property
552
+ def CASE(cls) -> Token:
553
+ return Token(TokenType.KEYWORD, Keyword.CASE.value)
554
+
555
+ def is_case(self) -> bool:
556
+ return self._type == TokenType.KEYWORD and self._value == Keyword.CASE.value
557
+
558
+ @classmethod
559
+ @property
560
+ def WHEN(cls) -> Token:
561
+ return Token(TokenType.KEYWORD, Keyword.WHEN.value)
562
+
563
+ def is_when(self) -> bool:
564
+ return self._type == TokenType.KEYWORD and self._value == Keyword.WHEN.value
565
+
566
+ @classmethod
567
+ @property
568
+ def THEN(cls) -> Token:
569
+ return Token(TokenType.KEYWORD, Keyword.THEN.value)
570
+
571
+ def is_then(self) -> bool:
572
+ return self._type == TokenType.KEYWORD and self._value == Keyword.THEN.value
573
+
574
+ @classmethod
575
+ @property
576
+ def ELSE(cls) -> Token:
577
+ return Token(TokenType.KEYWORD, Keyword.ELSE.value)
578
+
579
+ def is_else(self) -> bool:
580
+ return self._type == TokenType.KEYWORD and self._value == Keyword.ELSE.value
581
+
582
+ @classmethod
583
+ @property
584
+ def END(cls) -> Token:
585
+ return Token(TokenType.KEYWORD, Keyword.END.value)
586
+
587
+ def is_end(self) -> bool:
588
+ return self._type == TokenType.KEYWORD and self._value == Keyword.END.value
589
+
590
+ @classmethod
591
+ @property
592
+ def NULL(cls) -> Token:
593
+ return Token(TokenType.KEYWORD, Keyword.NULL.value)
594
+
595
+ def is_null(self) -> bool:
596
+ return self._type == TokenType.KEYWORD and self._value == Keyword.NULL.value
597
+
598
+ @classmethod
599
+ @property
600
+ def IN(cls) -> Token:
601
+ return Token(TokenType.KEYWORD, Keyword.IN.value)
602
+
603
+ def is_in(self) -> bool:
604
+ return self._type == TokenType.KEYWORD and self._value == Keyword.IN.value
605
+
606
+ @classmethod
607
+ @property
608
+ def PIPE(cls) -> Token:
609
+ return Token(TokenType.KEYWORD, Operator.PIPE.value)
610
+
611
+ def is_pipe(self) -> bool:
612
+ return self._type == TokenType.KEYWORD and self._value == Operator.PIPE.value
613
+
614
+ @classmethod
615
+ @property
616
+ def DISTINCT(cls) -> Token:
617
+ return Token(TokenType.KEYWORD, Keyword.DISTINCT.value)
618
+
619
+ def is_distinct(self) -> bool:
620
+ return self._type == TokenType.KEYWORD and self._value == Keyword.DISTINCT.value
621
+
622
+ @classmethod
623
+ @property
624
+ def LIMIT(cls) -> Token:
625
+ return Token(TokenType.KEYWORD, Keyword.LIMIT.value)
626
+
627
+ def is_limit(self) -> bool:
628
+ return self._type == TokenType.KEYWORD and self._value == Keyword.LIMIT.value
629
+
630
+ # End of file token
631
+
632
+ @classmethod
633
+ @property
634
+ def EOF(cls) -> Token:
635
+ return Token(TokenType.EOF)
636
+
637
+ def is_eof(self) -> bool:
638
+ return self._type == TokenType.EOF
639
+
640
+ # Other utility methods
641
+
642
+ def is_operand(self) -> bool:
643
+ return self.is_number() or self.is_boolean() or self.is_string() or self.is_null()
644
+
645
+ def is_whitespace_or_comment(self) -> bool:
646
+ return self.is_whitespace() or self.is_comment()
647
+
648
+ def is_symbol(self) -> bool:
649
+ return self._type == TokenType.SYMBOL
650
+
651
+ # Static class method lookup via string
652
+ @staticmethod
653
+ def method(name: str) -> Optional[Token]:
654
+ name_upper = name.upper()
655
+ if hasattr(Token, name_upper):
656
+ attr = getattr(Token, name_upper)
657
+ if isinstance(attr, Token):
658
+ return attr
659
+ return None
@@ -0,0 +1,52 @@
1
+ """Maps string values to tokens using a Trie for efficient lookup."""
2
+
3
+ from typing import Optional
4
+
5
+ from .token import Token
6
+ from .trie import Trie
7
+
8
+
9
+ class TokenMapper:
10
+ """Maps string values to tokens using a Trie for efficient lookup.
11
+
12
+ Takes an enum of keywords, operators, or symbols and builds a trie
13
+ for fast token matching during tokenization.
14
+
15
+ Example:
16
+ mapper = TokenMapper(Keyword)
17
+ token = mapper.map("WITH")
18
+ """
19
+
20
+ def __init__(self, enum_class):
21
+ """Creates a TokenMapper from an enum of token values.
22
+
23
+ Args:
24
+ enum_class: An enum class containing token values
25
+ """
26
+ self._trie = Trie()
27
+ self._enum = enum_class
28
+
29
+ for member in enum_class:
30
+ token = Token.method(member.name)
31
+ if token is not None and token.value is not None:
32
+ self._trie.insert(token)
33
+
34
+ def map(self, value: str) -> Optional[Token]:
35
+ """Maps a string value to its corresponding token.
36
+
37
+ Args:
38
+ value: The string value to map
39
+
40
+ Returns:
41
+ The matched token, or None if no match found
42
+ """
43
+ return self._trie.find(value)
44
+
45
+ @property
46
+ def last_found(self) -> Optional[str]:
47
+ """Gets the last matched string from the most recent map operation.
48
+
49
+ Returns:
50
+ The last found string, or None if no match
51
+ """
52
+ return self._trie.last_found