vtlengine 1.4.0rc2__py3-none-any.whl

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 (66) hide show
  1. vtlengine/API/_InternalApi.py +791 -0
  2. vtlengine/API/__init__.py +612 -0
  3. vtlengine/API/data/schema/external_routines_schema.json +34 -0
  4. vtlengine/API/data/schema/json_schema_2.1.json +116 -0
  5. vtlengine/API/data/schema/value_domain_schema.json +97 -0
  6. vtlengine/AST/ASTComment.py +57 -0
  7. vtlengine/AST/ASTConstructor.py +598 -0
  8. vtlengine/AST/ASTConstructorModules/Expr.py +1928 -0
  9. vtlengine/AST/ASTConstructorModules/ExprComponents.py +995 -0
  10. vtlengine/AST/ASTConstructorModules/Terminals.py +790 -0
  11. vtlengine/AST/ASTConstructorModules/__init__.py +50 -0
  12. vtlengine/AST/ASTDataExchange.py +10 -0
  13. vtlengine/AST/ASTEncoders.py +32 -0
  14. vtlengine/AST/ASTString.py +675 -0
  15. vtlengine/AST/ASTTemplate.py +558 -0
  16. vtlengine/AST/ASTVisitor.py +25 -0
  17. vtlengine/AST/DAG/__init__.py +479 -0
  18. vtlengine/AST/DAG/_words.py +10 -0
  19. vtlengine/AST/Grammar/Vtl.g4 +705 -0
  20. vtlengine/AST/Grammar/VtlTokens.g4 +409 -0
  21. vtlengine/AST/Grammar/__init__.py +0 -0
  22. vtlengine/AST/Grammar/lexer.py +2139 -0
  23. vtlengine/AST/Grammar/parser.py +16597 -0
  24. vtlengine/AST/Grammar/tokens.py +169 -0
  25. vtlengine/AST/VtlVisitor.py +824 -0
  26. vtlengine/AST/__init__.py +674 -0
  27. vtlengine/DataTypes/TimeHandling.py +562 -0
  28. vtlengine/DataTypes/__init__.py +863 -0
  29. vtlengine/DataTypes/_time_checking.py +135 -0
  30. vtlengine/Exceptions/__exception_file_generator.py +96 -0
  31. vtlengine/Exceptions/__init__.py +159 -0
  32. vtlengine/Exceptions/messages.py +1004 -0
  33. vtlengine/Interpreter/__init__.py +2048 -0
  34. vtlengine/Model/__init__.py +501 -0
  35. vtlengine/Operators/Aggregation.py +357 -0
  36. vtlengine/Operators/Analytic.py +455 -0
  37. vtlengine/Operators/Assignment.py +23 -0
  38. vtlengine/Operators/Boolean.py +106 -0
  39. vtlengine/Operators/CastOperator.py +451 -0
  40. vtlengine/Operators/Clause.py +366 -0
  41. vtlengine/Operators/Comparison.py +488 -0
  42. vtlengine/Operators/Conditional.py +495 -0
  43. vtlengine/Operators/General.py +191 -0
  44. vtlengine/Operators/HROperators.py +254 -0
  45. vtlengine/Operators/Join.py +447 -0
  46. vtlengine/Operators/Numeric.py +422 -0
  47. vtlengine/Operators/RoleSetter.py +77 -0
  48. vtlengine/Operators/Set.py +176 -0
  49. vtlengine/Operators/String.py +578 -0
  50. vtlengine/Operators/Time.py +1144 -0
  51. vtlengine/Operators/Validation.py +275 -0
  52. vtlengine/Operators/__init__.py +900 -0
  53. vtlengine/Utils/__Virtual_Assets.py +34 -0
  54. vtlengine/Utils/__init__.py +479 -0
  55. vtlengine/__extras_check.py +17 -0
  56. vtlengine/__init__.py +27 -0
  57. vtlengine/files/__init__.py +0 -0
  58. vtlengine/files/output/__init__.py +35 -0
  59. vtlengine/files/output/_time_period_representation.py +55 -0
  60. vtlengine/files/parser/__init__.py +240 -0
  61. vtlengine/files/parser/_rfc_dialect.py +22 -0
  62. vtlengine/py.typed +0 -0
  63. vtlengine-1.4.0rc2.dist-info/METADATA +89 -0
  64. vtlengine-1.4.0rc2.dist-info/RECORD +66 -0
  65. vtlengine-1.4.0rc2.dist-info/WHEEL +4 -0
  66. vtlengine-1.4.0rc2.dist-info/licenses/LICENSE.md +661 -0
@@ -0,0 +1,995 @@
1
+ from antlr4.tree.Tree import TerminalNodeImpl
2
+
3
+ from vtlengine.AST import (
4
+ ID,
5
+ Aggregation,
6
+ Analytic,
7
+ BinOp,
8
+ Case,
9
+ CaseObj,
10
+ Constant,
11
+ EvalOp,
12
+ Identifier,
13
+ If,
14
+ MulOp,
15
+ ParamConstant,
16
+ ParamOp,
17
+ ParFunction,
18
+ TimeAggregation,
19
+ UDOCall,
20
+ UnaryOp,
21
+ VarID,
22
+ )
23
+ from vtlengine.AST.ASTConstructorModules import extract_token_info
24
+ from vtlengine.AST.ASTConstructorModules.Terminals import Terminals
25
+ from vtlengine.AST.Grammar.parser import Parser
26
+ from vtlengine.AST.VtlVisitor import VtlVisitor
27
+ from vtlengine.Exceptions import SemanticError
28
+
29
+
30
+ class ExprComp(VtlVisitor):
31
+ """______________________________________________________________________________________
32
+
33
+
34
+ ExprComponent Definition.
35
+
36
+ _______________________________________________________________________________________
37
+ """
38
+
39
+ def visitExprComponent(self, ctx: Parser.ExprComponentContext):
40
+ """
41
+ exprComponent:
42
+ LPAREN exprComponent RPAREN # parenthesisExprComp
43
+ | functionsComponents # functionsExpressionComp
44
+ | op=(PLUS|MINUS|NOT) right=exprComponent # unaryExprComp
45
+ | left=exprComponent op=(MUL|DIV) right=exprComponent # arithmeticExprComp
46
+ | left=exprComponent op=(PLUS|MINUS|CONCAT) right=exprComponent # arithmeticExprOrConcatComp
47
+ | left=exprComponent comparisonOperand right=exprComponent # comparisonExprComp
48
+ | left=exprComponent op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExprComp
49
+ | left=exprComponent op=AND right=exprComponent # booleanExprComp
50
+ | left=exprComponent op=(OR|XOR) right=exprComponent # booleanExprComp
51
+ | IF conditionalExpr=exprComponent THEN thenExpr=exprComponent ELSE elseExpr=exprComponent # ifExprComp
52
+ | constant # constantExprComp
53
+ | componentID # compId
54
+ ;
55
+ """ # noqa E501
56
+ ctx_list = list(ctx.getChildren())
57
+ c = ctx_list[0]
58
+
59
+ if isinstance(ctx, Parser.ParenthesisExprCompContext):
60
+ return self.visitParenthesisExprComp(ctx)
61
+
62
+ # functions
63
+ elif isinstance(ctx, Parser.FunctionsExpressionCompContext):
64
+ return self.visitFunctionsComponents(c)
65
+
66
+ # op=(PLUS|MINUS|NOT) right=expr # unary expression
67
+ elif isinstance(ctx, Parser.UnaryExprCompContext):
68
+ return self.visitUnaryExprComp(ctx)
69
+
70
+ # | left=expr op=(MUL|DIV) right=expr # arithmeticExpr
71
+ elif isinstance(ctx, Parser.ArithmeticExprCompContext):
72
+ return self.visitArithmeticExprComp(ctx)
73
+
74
+ # | left=expr op=(PLUS|MINUS|CONCAT) right=expr # arithmeticExprOrConcat
75
+ elif isinstance(ctx, Parser.ArithmeticExprOrConcatCompContext):
76
+ return self.visitArithmeticExprOrConcatComp(ctx)
77
+
78
+ # | left=expr op=comparisonOperand right=expr # comparisonExpr
79
+ elif isinstance(ctx, Parser.ComparisonExprCompContext):
80
+ return self.visitComparisonExprComp(ctx)
81
+
82
+ # | left=expr op=(IN|NOT_IN)(lists|valueDomainID) # inNotInExpr
83
+ elif isinstance(ctx, Parser.InNotInExprCompContext):
84
+ return self.visitInNotInExprComp(ctx)
85
+
86
+ # | left=expr op=AND right=expr # booleanExpr
87
+ # | left=expr op=(OR|XOR) right=expr
88
+ elif isinstance(ctx, Parser.BooleanExprCompContext):
89
+ return self.visitBooleanExprComp(ctx)
90
+
91
+ # IF conditionalExpr=expr THEN thenExpr=expr ELSE elseExpr=expr # ifExpr
92
+ elif isinstance(ctx, Parser.IfExprCompContext):
93
+ return self.visitIfExprComp(ctx)
94
+
95
+ # CASE WHEN conditionalExpr=expr THEN thenExpr=expr ELSE elseExpr=expr END # caseExpr
96
+ elif isinstance(ctx, Parser.CaseExprCompContext):
97
+ return self.visitCaseExprComp(ctx)
98
+
99
+ # constant
100
+ elif isinstance(ctx, Parser.ConstantExprCompContext):
101
+ return Terminals().visitConstant(c)
102
+
103
+ # componentID
104
+ # TODO Changed to pass more tests. Original code: return Terminals().visitComponentID(c)
105
+ elif isinstance(ctx, Parser.CompIdContext):
106
+ if len(c.children) > 1:
107
+ return Terminals().visitComponentID(c)
108
+ token = c.children[0].getSymbol()
109
+ # check token text
110
+ has_scaped_char = token.text.find("'") != -1
111
+ if has_scaped_char:
112
+ token.text = str(token.text.replace("'", ""))
113
+ var_id_node = VarID(value=token.text, **extract_token_info(ctx))
114
+ return var_id_node
115
+
116
+ else:
117
+ # AST_ASTCONSTRUCTOR.3
118
+ raise NotImplementedError
119
+
120
+ def bin_op_creator_comp(self, ctx: Parser.ExprComponentContext):
121
+ ctx_list = list(ctx.getChildren())
122
+ left_node = self.visitExprComponent(ctx_list[0])
123
+ if isinstance(ctx_list[1], Parser.ComparisonOperandContext):
124
+ op = list(ctx_list[1].getChildren())[0].getSymbol().text
125
+ else:
126
+ op = ctx_list[1].getSymbol().text
127
+ right_node = self.visitExprComponent(ctx_list[2])
128
+
129
+ bin_op_node = BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
130
+
131
+ return bin_op_node
132
+
133
+ def visitArithmeticExprComp(self, ctx: Parser.ArithmeticExprContext):
134
+ return self.bin_op_creator_comp(ctx)
135
+
136
+ def visitArithmeticExprOrConcatComp(self, ctx: Parser.ArithmeticExprOrConcatContext):
137
+ return self.bin_op_creator_comp(ctx)
138
+
139
+ def visitComparisonExprComp(self, ctx: Parser.ComparisonExprContext):
140
+ return self.bin_op_creator_comp(ctx)
141
+
142
+ def visitInNotInExprComp(self, ctx: Parser.InNotInExprContext):
143
+ ctx_list = list(ctx.getChildren())
144
+ left_node = self.visitExprComponent(ctx_list[0])
145
+ op = ctx_list[1].symbol.text
146
+
147
+ if isinstance(ctx_list[2], Parser.ListsContext):
148
+ right_node = Terminals().visitLists(ctx_list[2])
149
+ elif isinstance(ctx_list[2], Parser.ValueDomainIDContext):
150
+ right_node = Terminals().visitValueDomainID(ctx_list[2])
151
+ else:
152
+ raise NotImplementedError
153
+ bin_op_node = BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
154
+
155
+ return bin_op_node
156
+
157
+ def visitBooleanExprComp(self, ctx: Parser.BooleanExprContext):
158
+ return self.bin_op_creator_comp(ctx)
159
+
160
+ def visitParenthesisExprComp(self, ctx: Parser.ParenthesisExprContext):
161
+ operand = self.visitExprComponent(list(ctx.getChildren())[1])
162
+ return ParFunction(operand=operand, **extract_token_info(ctx))
163
+
164
+ def visitUnaryExprComp(self, ctx: Parser.UnaryExprContext):
165
+ c_list = list(ctx.getChildren())
166
+ op = c_list[0].getSymbol().text
167
+ right = self.visitExprComponent(c_list[1])
168
+
169
+ return UnaryOp(op=op, operand=right, **extract_token_info(ctx))
170
+
171
+ def visitIfExprComp(self, ctx: Parser.IfExprCompContext):
172
+ ctx_list = list(ctx.getChildren())
173
+
174
+ condition_node = self.visitExprComponent(ctx_list[1])
175
+ then_op_node = self.visitExprComponent(ctx_list[3])
176
+ else_op_node = self.visitExprComponent(ctx_list[5])
177
+
178
+ if_node = If(
179
+ condition=condition_node,
180
+ thenOp=then_op_node,
181
+ elseOp=else_op_node,
182
+ **extract_token_info(ctx),
183
+ )
184
+
185
+ return if_node
186
+
187
+ def visitCaseExprComp(self, ctx: Parser.CaseExprCompContext):
188
+ ctx_list = list(ctx.getChildren())
189
+
190
+ if len(ctx_list) % 4 != 3:
191
+ raise ValueError("Syntax error.")
192
+
193
+ else_node = self.visitExprComponent(ctx_list[-1])
194
+ ctx_list = ctx_list[1:-2]
195
+ cases = []
196
+
197
+ for i in range(0, len(ctx_list), 4):
198
+ condition = self.visitExprComponent(ctx_list[i + 1])
199
+ thenOp = self.visitExprComponent(ctx_list[i + 3])
200
+ case_obj = CaseObj(
201
+ condition=condition, thenOp=thenOp, **extract_token_info(ctx_list[i + 1])
202
+ )
203
+ cases.append(case_obj)
204
+
205
+ case_node = Case(cases=cases, elseOp=else_node, **extract_token_info(ctx))
206
+
207
+ return case_node
208
+
209
+ def visitOptionalExprComponent(self, ctx: Parser.OptionalExprComponentContext):
210
+ """
211
+ optionalExpr: expr
212
+ | OPTIONAL ;
213
+ """
214
+ ctx_list = list(ctx.getChildren())
215
+ c = ctx_list[0]
216
+
217
+ if isinstance(c, Parser.ExprComponentContext):
218
+ return self.visitExprComponent(c)
219
+
220
+ elif isinstance(c, TerminalNodeImpl):
221
+ token = c.getSymbol()
222
+ opt = token.text
223
+ return ID(type_="OPTIONAL", value=opt, **extract_token_info(ctx))
224
+
225
+ """____________________________________________________________________________________
226
+
227
+
228
+ FunctionsComponents Definition.
229
+
230
+ _____________________________________________________________________________________"""
231
+
232
+ def visitFunctionsComponents(self, ctx: Parser.FunctionsComponentsContext):
233
+ """
234
+ functionsComponents:
235
+ genericOperatorsComponent # genericFunctionsComponents
236
+ | stringOperatorsComponent # stringFunctionsComponents
237
+ | numericOperatorsComponent # numericFunctionsComponents
238
+ | comparisonOperatorsComponent # comparisonFunctionsComponents
239
+ | timeOperatorsComponent # timeFunctionsComponents
240
+ | conditionalOperatorsComponent # conditionalFunctionsComponents
241
+ | aggrOperators # aggregateFunctionsComponents
242
+ | anFunctionComponent # analyticFunctionsComponents
243
+
244
+ ;
245
+ """
246
+ ctx_list = list(ctx.getChildren())
247
+ c = ctx_list[0]
248
+
249
+ if isinstance(ctx, Parser.GenericFunctionsComponentsContext):
250
+ return self.visitGenericFunctionsComponents(c)
251
+
252
+ elif isinstance(ctx, Parser.StringFunctionsComponentsContext):
253
+ return self.visitStringFunctionsComponents(c)
254
+
255
+ elif isinstance(ctx, Parser.NumericFunctionsComponentsContext):
256
+ return self.visitNumericFunctionsComponents(c)
257
+
258
+ elif isinstance(ctx, Parser.ComparisonFunctionsComponentsContext):
259
+ return self.visitComparisonFunctionsComponents(c)
260
+
261
+ elif isinstance(ctx, Parser.TimeFunctionsComponentsContext):
262
+ return self.visitTimeFunctionsComponents(c)
263
+
264
+ elif isinstance(ctx, Parser.ConditionalFunctionsComponentsContext):
265
+ return self.visitConditionalFunctionsComponents(c)
266
+
267
+ elif isinstance(ctx, Parser.AggregateFunctionsComponentsContext):
268
+ return self.visitAggregateFunctionsComponents(c)
269
+
270
+ elif isinstance(ctx, Parser.AnalyticFunctionsComponentsContext):
271
+ return self.visitAnalyticFunctionsComponents(c)
272
+ else:
273
+ raise NotImplementedError
274
+
275
+ """
276
+ -----------------------------------
277
+ Generic Functions Components
278
+ -----------------------------------
279
+ """
280
+
281
+ def visitGenericFunctionsComponents(self, ctx: Parser.GenericFunctionsComponentsContext):
282
+ if isinstance(ctx, Parser.CallComponentContext):
283
+ return self.visitCallComponent(ctx)
284
+ elif isinstance(ctx, Parser.EvalAtomComponentContext):
285
+ return self.visitEvalAtomComponent(ctx)
286
+ elif isinstance(ctx, Parser.CastExprComponentContext):
287
+ return self.visitCastExprComponent(ctx)
288
+ else:
289
+ raise NotImplementedError
290
+
291
+ def visitCallComponent(self, ctx: Parser.CallComponentContext):
292
+ """
293
+ callFunction: operatorID LPAREN (parameterComponent (COMMA parameterComponent)*)? RPAREN # callComponent
294
+ """ # noqa E501
295
+ ctx_list = list(ctx.getChildren())
296
+ c = ctx_list[0]
297
+
298
+ op = Terminals().visitOperatorID(c)
299
+ param_nodes = [
300
+ self.visitParameterComponent(element)
301
+ for element in ctx_list
302
+ if isinstance(element, Parser.ParameterComponentContext)
303
+ ]
304
+
305
+ return UDOCall(op=op, params=param_nodes, **extract_token_info(ctx))
306
+
307
+ def visitEvalAtomComponent(self, ctx: Parser.EvalAtomComponentContext):
308
+ """
309
+ | EVAL LPAREN routineName LPAREN (componentID|scalarItem)? (COMMA (componentID|scalarItem))* RPAREN (LANGUAGE STRING_CONSTANT)? (RETURNS outputParameterTypeComponent)? RPAREN # evalAtomComponent
310
+ """ # noqa E501
311
+ ctx_list = list(ctx.getChildren())
312
+
313
+ routine_name = Terminals().visitRoutineName(ctx_list[2])
314
+
315
+ # Think of a way to maintain the order, for now its not necessary.
316
+ var_ids_nodes = [
317
+ Terminals().visitVarID(varID)
318
+ for varID in ctx_list
319
+ if isinstance(varID, Parser.VarIDContext)
320
+ ]
321
+ constant_nodes = [
322
+ Terminals().visitScalarItem(scalar)
323
+ for scalar in ctx_list
324
+ if isinstance(scalar, Parser.ScalarItemContext)
325
+ ]
326
+ children_nodes = var_ids_nodes + constant_nodes
327
+
328
+ if len(children_nodes) > 1:
329
+ raise Exception("Only one operand is allowed in Eval")
330
+
331
+ # Reference manual says it is mandatory.
332
+ language_name = [
333
+ language
334
+ for language in ctx_list
335
+ if isinstance(language, TerminalNodeImpl)
336
+ and language.getSymbol().type == Parser.STRING_CONSTANT
337
+ ]
338
+ if len(language_name) == 0:
339
+ # AST_ASTCONSTRUCTOR.12
340
+ raise SemanticError("1-3-2-1", option="language")
341
+ # Reference manual says it is mandatory.
342
+ output_node = [
343
+ Terminals().visitOutputParameterTypeComponent(output)
344
+ for output in ctx_list
345
+ if isinstance(output, Parser.OutputParameterTypeComponentContext)
346
+ ]
347
+ if len(output_node) == 0:
348
+ # AST_ASTCONSTRUCTOR.13
349
+ raise SemanticError("1-3-2-1", option="output")
350
+
351
+ return EvalOp(
352
+ name=routine_name,
353
+ operands=children_nodes[0],
354
+ output=output_node[0],
355
+ language=language_name[0].getSymbol().text,
356
+ **extract_token_info(ctx),
357
+ )
358
+
359
+ def visitCastExprComponent(self, ctx: Parser.CastExprComponentContext):
360
+ """
361
+ | CAST LPAREN exprComponent COMMA (basicScalarType|valueDomainName) (COMMA STRING_CONSTANT)? RPAREN # castExprComponent
362
+ """ # noqa E501
363
+ ctx_list = list(ctx.getChildren())
364
+ c = ctx_list[0]
365
+
366
+ token = c.getSymbol()
367
+
368
+ op = token.text
369
+ expr_node = [
370
+ self.visitExprComponent(expr)
371
+ for expr in ctx_list
372
+ if isinstance(expr, Parser.ExprComponentContext)
373
+ ]
374
+ basic_scalar_type = [
375
+ Terminals().visitBasicScalarType(type_)
376
+ for type_ in ctx_list
377
+ if isinstance(type_, Parser.BasicScalarTypeContext)
378
+ ]
379
+
380
+ [
381
+ Terminals().visitValueDomainName(valueD)
382
+ for valueD in ctx_list
383
+ if isinstance(valueD, Parser.ValueDomainNameContext)
384
+ ]
385
+
386
+ if len(ctx_list) > 6:
387
+ param_node = [
388
+ ParamConstant(
389
+ type_="PARAM_CAST",
390
+ value=str_.symbol.text.strip('"'),
391
+ **extract_token_info(str_.getSymbol()),
392
+ )
393
+ for str_ in ctx_list
394
+ if isinstance(str_, TerminalNodeImpl)
395
+ and str_.getSymbol().type == Parser.STRING_CONSTANT
396
+ ]
397
+ else:
398
+ param_node = []
399
+
400
+ if len(basic_scalar_type) == 1:
401
+ children_nodes = expr_node + basic_scalar_type
402
+
403
+ return ParamOp(
404
+ op=op, children=children_nodes, params=param_node, **extract_token_info(ctx)
405
+ )
406
+
407
+ else:
408
+ # AST_ASTCONSTRUCTOR.14
409
+ raise NotImplementedError
410
+
411
+ def visitParameterComponent(self, ctx: Parser.ParameterComponentContext):
412
+ ctx_list = list(ctx.getChildren())
413
+ c = ctx_list[0]
414
+
415
+ if isinstance(c, Parser.ExprComponentContext):
416
+ return self.visitExprComponent(c)
417
+ elif isinstance(c, TerminalNodeImpl):
418
+ return ID(type_="OPTIONAL", value=c.getSymbol().text, **extract_token_info(ctx))
419
+ else:
420
+ raise NotImplementedError
421
+
422
+ """
423
+ -----------------------------------
424
+ String Functions
425
+ -----------------------------------
426
+ """
427
+
428
+ def visitStringFunctionsComponents(self, ctx: Parser.StringFunctionsComponentsContext):
429
+ if isinstance(ctx, Parser.UnaryStringFunctionComponentContext):
430
+ return self.visitUnaryStringFunctionComponent(ctx)
431
+ elif isinstance(ctx, Parser.SubstrAtomComponentContext):
432
+ return self.visitSubstrAtomComponent(ctx)
433
+ elif isinstance(ctx, Parser.ReplaceAtomComponentContext):
434
+ return self.visitReplaceAtomComponent(ctx)
435
+ elif isinstance(ctx, Parser.InstrAtomComponentContext):
436
+ return self.visitInstrAtomComponent(ctx)
437
+ else:
438
+ raise NotImplementedError
439
+
440
+ def visitUnaryStringFunctionComponent(self, ctx: Parser.UnaryStringFunctionComponentContext):
441
+ ctx_list = list(ctx.getChildren())
442
+ c = ctx_list[0]
443
+
444
+ token = c.getSymbol()
445
+ op_node = token.text
446
+ operand_node = self.visitExprComponent(ctx_list[2])
447
+ return UnaryOp(op=op_node, operand=operand_node, **extract_token_info(ctx))
448
+
449
+ def visitSubstrAtomComponent(self, ctx: Parser.SubstrAtomComponentContext):
450
+ ctx_list = list(ctx.getChildren())
451
+ c = ctx_list[0]
452
+
453
+ params_nodes = []
454
+ children_nodes = []
455
+
456
+ token = c.getSymbol()
457
+ childrens = [expr for expr in ctx_list if isinstance(expr, Parser.ExprComponentContext)]
458
+ params = [
459
+ param for param in ctx_list if isinstance(param, Parser.OptionalExprComponentContext)
460
+ ]
461
+
462
+ op_node = token.text
463
+ for children in childrens:
464
+ children_nodes.append(self.visitExprComponent(children))
465
+
466
+ if len(params) != 0:
467
+ for param in params:
468
+ params_nodes.append(self.visitOptionalExprComponent(param))
469
+
470
+ return ParamOp(
471
+ op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
472
+ )
473
+
474
+ def visitReplaceAtomComponent(self, ctx: Parser.ReplaceAtomComponentContext):
475
+ ctx_list = list(ctx.getChildren())
476
+ c = ctx_list[0]
477
+
478
+ token = c.getSymbol()
479
+ expressions = [
480
+ self.visitExprComponent(expr)
481
+ for expr in ctx_list
482
+ if isinstance(expr, Parser.ExprComponentContext)
483
+ ]
484
+ params = [
485
+ self.visitOptionalExprComponent(param)
486
+ for param in ctx_list
487
+ if isinstance(param, Parser.OptionalExprComponentContext)
488
+ ]
489
+
490
+ op_node = token.text
491
+
492
+ children_nodes = [expressions[0]]
493
+ params_nodes = [expressions[1]] + params
494
+
495
+ return ParamOp(
496
+ op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
497
+ )
498
+
499
+ def visitInstrAtomComponent(self, ctx: Parser.InstrAtomComponentContext):
500
+ ctx_list = list(ctx.getChildren())
501
+ c = ctx_list[0]
502
+
503
+ token = c.getSymbol()
504
+ expressions = [
505
+ self.visitExprComponent(expr)
506
+ for expr in ctx_list
507
+ if isinstance(expr, Parser.ExprComponentContext)
508
+ ]
509
+ params = [
510
+ self.visitOptionalExprComponent(param)
511
+ for param in ctx_list
512
+ if isinstance(param, Parser.OptionalExprComponentContext)
513
+ ]
514
+
515
+ op_node = token.text
516
+
517
+ children_nodes = [expressions[0]]
518
+ params_nodes = [expressions[1]] + params
519
+
520
+ return ParamOp(
521
+ op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
522
+ )
523
+
524
+ """
525
+ -----------------------------------
526
+ Numeric Component Functions
527
+ -----------------------------------
528
+ """
529
+
530
+ def visitNumericFunctionsComponents(self, ctx: Parser.NumericFunctionsComponentsContext):
531
+ if isinstance(ctx, Parser.UnaryNumericComponentContext):
532
+ return self.visitUnaryNumericComponent(ctx)
533
+ elif isinstance(ctx, Parser.UnaryWithOptionalNumericComponentContext):
534
+ return self.visitUnaryWithOptionalNumericComponent(ctx)
535
+ elif isinstance(ctx, Parser.BinaryNumericComponentContext):
536
+ return self.visitBinaryNumericComponent(ctx)
537
+ else:
538
+ raise NotImplementedError
539
+
540
+ def visitUnaryNumericComponent(self, ctx: Parser.UnaryNumericComponentContext):
541
+ ctx_list = list(ctx.getChildren())
542
+ c = ctx_list[0]
543
+
544
+ token = c.getSymbol()
545
+ op_node = token.text
546
+ operand_node = self.visitExprComponent(ctx_list[2])
547
+ return UnaryOp(op=op_node, operand=operand_node, **extract_token_info(ctx))
548
+
549
+ def visitUnaryWithOptionalNumericComponent(
550
+ self, ctx: Parser.UnaryWithOptionalNumericComponentContext
551
+ ):
552
+ ctx_list = list(ctx.getChildren())
553
+ c = ctx_list[0]
554
+
555
+ params_nodes = []
556
+ children_nodes = []
557
+
558
+ token = c.getSymbol()
559
+ childrens = [expr for expr in ctx_list if isinstance(expr, Parser.ExprComponentContext)]
560
+ params = [
561
+ param for param in ctx_list if isinstance(param, Parser.OptionalExprComponentContext)
562
+ ]
563
+
564
+ op_node = token.text
565
+ for children in childrens:
566
+ children_nodes.append(self.visitExprComponent(children))
567
+
568
+ if len(params) != 0:
569
+ for param in params:
570
+ params_nodes.append(self.visitOptionalExprComponent(param))
571
+
572
+ return ParamOp(
573
+ op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
574
+ )
575
+
576
+ def visitBinaryNumericComponent(self, ctx: Parser.BinaryNumericComponentContext):
577
+ ctx_list = list(ctx.getChildren())
578
+ c = ctx_list[0]
579
+
580
+ token = c.getSymbol()
581
+
582
+ left_node = self.visitExprComponent(ctx_list[2])
583
+ op_node = token.text
584
+ right_node = self.visitExprComponent(ctx_list[4])
585
+ return BinOp(left=left_node, op=op_node, right=right_node, **extract_token_info(ctx))
586
+
587
+ """
588
+ -----------------------------------
589
+ Time Functions
590
+ -----------------------------------
591
+ """
592
+
593
+ def visitTimeFunctionsComponents(self, ctx: Parser.TimeFunctionsComponentsContext):
594
+ if isinstance(ctx, Parser.PeriodAtomComponentContext):
595
+ return self.visitTimeUnaryAtomComponent(ctx)
596
+ elif isinstance(ctx, Parser.FillTimeAtomComponentContext):
597
+ return self.visitFillTimeAtomComponent(ctx)
598
+ elif isinstance(ctx, Parser.FlowAtomComponentContext):
599
+ raise SemanticError("1-1-19-7", op=ctx.op.text)
600
+ elif isinstance(ctx, Parser.TimeShiftAtomComponentContext):
601
+ return self.visitTimeShiftAtomComponent(ctx)
602
+ elif isinstance(ctx, Parser.TimeAggAtomComponentContext):
603
+ return self.visitTimeAggAtomComponent(ctx)
604
+ elif isinstance(ctx, Parser.CurrentDateAtomComponentContext):
605
+ return self.visitCurrentDateAtomComponent(ctx)
606
+ elif isinstance(ctx, Parser.DateDiffAtomComponentContext):
607
+ return self.visitDateDiffAtomComponent(ctx)
608
+ elif isinstance(ctx, Parser.DateAddAtomComponentContext):
609
+ return self.visitDateAddAtomComponentContext(ctx)
610
+ elif isinstance(
611
+ ctx,
612
+ (
613
+ Parser.YearAtomComponentContext,
614
+ Parser.MonthAtomComponentContext,
615
+ Parser.DayOfMonthAtomComponentContext,
616
+ Parser.DayOfYearAtomComponentContext,
617
+ Parser.DayToYearAtomComponentContext,
618
+ Parser.DayToMonthAtomComponentContext,
619
+ Parser.YearToDayAtomComponentContext,
620
+ Parser.MonthToDayAtomComponentContext,
621
+ ),
622
+ ):
623
+ return self.visitTimeUnaryAtomComponent(ctx)
624
+ else:
625
+ raise NotImplementedError
626
+
627
+ def visitTimeUnaryAtomComponent(self, ctx: Parser.PeriodAtomComponentContext):
628
+ """
629
+ periodExpr: PERIOD_INDICATOR '(' expr? ')' ;
630
+ """
631
+ ctx_list = list(ctx.getChildren())
632
+ c = ctx_list[0]
633
+
634
+ op = c.getSymbol().text
635
+ operand_node = [
636
+ self.visitExprComponent(operand)
637
+ for operand in ctx_list
638
+ if isinstance(operand, Parser.ExprComponentContext)
639
+ ]
640
+
641
+ if len(operand_node) == 0:
642
+ # AST_ASTCONSTRUCTOR.15
643
+ raise NotImplementedError
644
+
645
+ return UnaryOp(op=op, operand=operand_node[0], **extract_token_info(ctx))
646
+
647
+ def visitTimeShiftAtomComponent(self, ctx: Parser.TimeShiftAtomComponentContext):
648
+ """
649
+ timeShiftExpr: TIMESHIFT '(' expr ',' INTEGER_CONSTANT ')' ;
650
+ """
651
+ ctx_list = list(ctx.getChildren())
652
+ c = ctx_list[0]
653
+
654
+ op = c.getSymbol().text
655
+ left_node = self.visitExprComponent(ctx_list[2])
656
+ right_node = Constant(
657
+ type_="INTEGER_CONSTANT",
658
+ value=int(ctx_list[4].getSymbol().text),
659
+ **extract_token_info(ctx),
660
+ )
661
+
662
+ return BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
663
+
664
+ def visitFillTimeAtomComponent(self, ctx: Parser.FillTimeAtomComponentContext):
665
+ """
666
+ timeSeriesExpr: FILL_TIME_SERIES '(' expr (',' (SINGLE|ALL))? ')' ;
667
+ """
668
+ ctx_list = list(ctx.getChildren())
669
+ c = ctx_list[0]
670
+
671
+ op = c.getSymbol().text
672
+ children_node = [self.visitExprComponent(ctx_list[2])]
673
+
674
+ if len(ctx_list) > 4:
675
+ param_constant_node = [
676
+ ParamConstant(
677
+ type_="PARAM_TIMESERIES",
678
+ value=ctx_list[4].getSymbol().text,
679
+ **extract_token_info(ctx),
680
+ )
681
+ ]
682
+ else:
683
+ param_constant_node = []
684
+
685
+ return ParamOp(
686
+ op=op, children=children_node, params=param_constant_node, **extract_token_info(ctx)
687
+ )
688
+
689
+ def visitTimeAggAtomComponent(self, ctx: Parser.TimeAggAtomComponentContext):
690
+ """
691
+ TIME_AGG LPAREN periodIndTo=STRING_CONSTANT (COMMA periodIndFrom=(STRING_CONSTANT| OPTIONAL ))?
692
+ (COMMA op=optionalExprComponent)? (COMMA (FIRST|LAST))? RPAREN # timeAggAtomComponent;
693
+ """ # noqa E501
694
+ ctx_list = list(ctx.getChildren())
695
+ c = ctx_list[0]
696
+
697
+ op = c.getSymbol().text
698
+ period_to = str(ctx.periodIndTo.text)[1:-1]
699
+ period_from = None
700
+
701
+ if ctx.periodIndFrom is not None and ctx.periodIndFrom.type != Parser.OPTIONAL:
702
+ # raise SemanticError("periodIndFrom is not allowed in Time_agg")
703
+ period_from = str(ctx.periodIndFrom.text)[1:-1]
704
+
705
+ conf = [
706
+ str_.getSymbol().text
707
+ for str_ in ctx_list
708
+ if isinstance(str_, TerminalNodeImpl)
709
+ and str_.getSymbol().type in [Parser.FIRST, Parser.LAST]
710
+ ]
711
+
712
+ conf = None if len(conf) == 0 else conf[0]
713
+
714
+ if ctx.op is not None:
715
+ operand_node = self.visitOptionalExprComponent(ctx.op)
716
+ if isinstance(operand_node, ID):
717
+ operand_node = None
718
+ elif isinstance(operand_node, Identifier):
719
+ operand_node = VarID(
720
+ value=operand_node.value, **extract_token_info(ctx.op)
721
+ ) # Converting Identifier to VarID
722
+ else:
723
+ operand_node = None
724
+
725
+ return TimeAggregation(
726
+ op=op,
727
+ operand=operand_node,
728
+ period_to=period_to,
729
+ period_from=period_from,
730
+ conf=conf,
731
+ **extract_token_info(ctx),
732
+ )
733
+
734
+ def visitCurrentDateAtomComponent(self, ctx: Parser.CurrentDateAtomComponentContext):
735
+ c = list(ctx.getChildren())[0]
736
+ return MulOp(op=c.getSymbol().text, children=[], **extract_token_info(ctx))
737
+
738
+ def visitDateDiffAtomComponent(self, ctx: Parser.TimeShiftAtomComponentContext):
739
+ """ """
740
+ ctx_list = list(ctx.getChildren())
741
+ c = ctx_list[0]
742
+
743
+ op = c.getSymbol().text
744
+ left_node = self.visitExprComponent(ctx_list[2])
745
+ right_node = self.visitExprComponent(ctx_list[4])
746
+
747
+ return BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
748
+
749
+ def visitDateAddAtomComponentContext(self, ctx: Parser.DateAddAtomComponentContext):
750
+ """ """
751
+ ctx_list = list(ctx.getChildren())
752
+ c = ctx_list[0]
753
+
754
+ op = c.getSymbol().text
755
+ children_node = [self.visitExprComponent(ctx_list[2])]
756
+
757
+ param_constant_node = []
758
+
759
+ if len(ctx_list) > 4:
760
+ param_constant_node = [self.visitExprComponent(ctx_list[4])]
761
+ if len(ctx_list) > 6:
762
+ param_constant_node.append(self.visitExprComponent(ctx_list[6]))
763
+
764
+ return ParamOp(
765
+ op=op, children=children_node, params=param_constant_node, **extract_token_info(ctx)
766
+ )
767
+
768
+ """
769
+ -----------------------------------
770
+ Conditional Functions
771
+ -----------------------------------
772
+ """
773
+
774
+ def visitConditionalFunctionsComponents(
775
+ self, ctx: Parser.ConditionalFunctionsComponentsContext
776
+ ):
777
+ if isinstance(ctx, Parser.NvlAtomComponentContext):
778
+ return self.visitNvlAtomComponent(ctx)
779
+ else:
780
+ raise NotImplementedError
781
+
782
+ def visitNvlAtomComponent(self, ctx: Parser.NvlAtomComponentContext):
783
+ ctx_list = list(ctx.getChildren())
784
+ c = ctx_list[0]
785
+
786
+ token = c.getSymbol()
787
+
788
+ left_node = self.visitExprComponent(ctx_list[2])
789
+ op_node = token.text
790
+ right_node = self.visitExprComponent(ctx_list[4])
791
+ return BinOp(left=left_node, op=op_node, right=right_node, **extract_token_info(ctx))
792
+
793
+ """
794
+ -----------------------------------
795
+ Comparison Components Functions
796
+ -----------------------------------
797
+ """
798
+
799
+ def visitComparisonFunctionsComponents(self, ctx: Parser.ComparisonFunctionsComponentsContext):
800
+ if isinstance(ctx, Parser.BetweenAtomComponentContext):
801
+ return self.visitBetweenAtomComponent(ctx)
802
+ elif isinstance(ctx, Parser.CharsetMatchAtomComponentContext):
803
+ return self.visitCharsetMatchAtomComponent(ctx)
804
+ elif isinstance(ctx, Parser.IsNullAtomComponentContext):
805
+ return self.visitIsNullAtomComponent(ctx)
806
+ else:
807
+ raise NotImplementedError
808
+
809
+ def visitBetweenAtomComponent(self, ctx: Parser.BetweenAtomComponentContext):
810
+ ctx_list = list(ctx.getChildren())
811
+ c = ctx_list[0]
812
+
813
+ children_nodes = []
814
+
815
+ token = c.getSymbol()
816
+ childrens = [expr for expr in ctx_list if isinstance(expr, Parser.ExprComponentContext)]
817
+
818
+ op_node = token.text
819
+ for children in childrens:
820
+ children_nodes.append(self.visitExprComponent(children))
821
+
822
+ return MulOp(op=op_node, children=children_nodes, **extract_token_info(ctx))
823
+
824
+ def visitCharsetMatchAtomComponent(self, ctx: Parser.CharsetMatchAtomComponentContext):
825
+ ctx_list = list(ctx.getChildren())
826
+ c = ctx_list[0]
827
+ token = c.getSymbol()
828
+
829
+ left_node = self.visitExprComponent(ctx_list[2])
830
+ op_node = token.text
831
+ right_node = self.visitExprComponent(ctx_list[4])
832
+ return BinOp(left=left_node, op=op_node, right=right_node, **extract_token_info(ctx))
833
+
834
+ def visitIsNullAtomComponent(self, ctx: Parser.IsNullAtomComponentContext):
835
+ ctx_list = list(ctx.getChildren())
836
+ c = ctx_list[0]
837
+ token = c.getSymbol()
838
+ op_node = token.text
839
+ operand_node = self.visitExprComponent(ctx_list[2])
840
+ return UnaryOp(op=op_node, operand=operand_node, **extract_token_info(ctx))
841
+
842
+ """
843
+ -----------------------------------
844
+ Aggregate Components Functions
845
+ -----------------------------------
846
+ """
847
+
848
+ def visitAggregateFunctionsComponents(self, ctx: Parser.AggregateFunctionsComponentsContext):
849
+ if isinstance(ctx, Parser.AggrCompContext):
850
+ return self.visitAggrComp(ctx)
851
+ elif isinstance(ctx, Parser.CountAggrCompContext):
852
+ return self.visitCountAggrComp(ctx)
853
+ else:
854
+ raise NotImplementedError
855
+
856
+ def visitAggrComp(self, ctx: Parser.AggrCompContext):
857
+ ctx_list = list(ctx.getChildren())
858
+ op_node = ctx_list[0].getSymbol().text
859
+ operand_node = self.visitExprComponent(ctx_list[2])
860
+ return Aggregation(op=op_node, operand=operand_node, **extract_token_info(ctx))
861
+
862
+ def visitCountAggrComp(self, ctx: Parser.CountAggrCompContext):
863
+ ctx_list = list(ctx.getChildren())
864
+ op_node = ctx_list[0].getSymbol().text
865
+ return Aggregation(op=op_node, **extract_token_info(ctx))
866
+
867
+ """
868
+ -----------------------------------
869
+ Analytic Components Functions
870
+ -----------------------------------
871
+ """
872
+
873
+ def visitAnalyticFunctionsComponents(self, ctx: Parser.AnalyticFunctionsComponentsContext):
874
+ if isinstance(ctx, Parser.AnSimpleFunctionComponentContext):
875
+ return self.visitAnSimpleFunctionComponent(ctx)
876
+ elif isinstance(ctx, Parser.LagOrLeadAnComponentContext):
877
+ return self.visitLagOrLeadAnComponent(ctx)
878
+ elif isinstance(ctx, Parser.RankAnComponentContext):
879
+ return self.visitRankAnComponent(ctx)
880
+ elif isinstance(ctx, Parser.RatioToReportAnComponentContext):
881
+ return self.visitRatioToReportAnComponent(ctx)
882
+ else:
883
+ raise NotImplementedError
884
+
885
+ def visitAnSimpleFunctionComponent(self, ctx: Parser.AnSimpleFunctionComponentContext):
886
+ ctx_list = list(ctx.getChildren())
887
+
888
+ params = None
889
+ partition_by = None
890
+ order_by = None
891
+
892
+ op_node = ctx_list[0].getSymbol().text
893
+ operand = self.visitExprComponent(ctx_list[2])
894
+
895
+ for c in ctx_list[5:-2]:
896
+ if isinstance(c, Parser.PartitionByClauseContext):
897
+ partition_by = Terminals().visitPartitionByClause(c)
898
+ continue
899
+ elif isinstance(c, Parser.OrderByClauseContext):
900
+ order_by = Terminals().visitOrderByClause(c)
901
+ continue
902
+ elif isinstance(c, Parser.WindowingClauseContext):
903
+ params = Terminals().visitWindowingClause(c)
904
+ continue
905
+ else:
906
+ raise NotImplementedError
907
+
908
+ return Analytic(
909
+ op=op_node,
910
+ operand=operand,
911
+ partition_by=partition_by,
912
+ order_by=order_by,
913
+ window=params,
914
+ **extract_token_info(ctx),
915
+ )
916
+
917
+ def visitLagOrLeadAnComponent(self, ctx: Parser.LagOrLeadAnComponentContext):
918
+ ctx_list = list(ctx.getChildren())
919
+
920
+ params = None
921
+ partition_by = None
922
+ order_by = None
923
+
924
+ op_node = ctx_list[0].getSymbol().text
925
+ operand = self.visitExprComponent(ctx_list[2])
926
+
927
+ for c in ctx_list[4:-2]:
928
+ if isinstance(c, Parser.PartitionByClauseContext):
929
+ partition_by = Terminals().visitPartitionByClause(c)
930
+ continue
931
+ elif isinstance(c, Parser.OrderByClauseContext):
932
+ order_by = Terminals().visitOrderByClause(c)
933
+ continue
934
+ elif isinstance(c, (Parser.SignedIntegerContext, Parser.ScalarItemContext)):
935
+ if params is None:
936
+ params = []
937
+ if isinstance(c, Parser.SignedIntegerContext):
938
+ params.append(Terminals().visitSignedInteger(c))
939
+ else:
940
+ params.append(Terminals().visitScalarItem(c))
941
+ continue
942
+
943
+ return Analytic(
944
+ op=op_node,
945
+ operand=operand,
946
+ partition_by=partition_by,
947
+ order_by=order_by,
948
+ params=params,
949
+ **extract_token_info(ctx),
950
+ )
951
+
952
+ def visitRankAnComponent(self, ctx: Parser.RankAnComponentContext):
953
+ ctx_list = list(ctx.getChildren())
954
+
955
+ partition_by = None
956
+ order_by = None
957
+
958
+ op_node = ctx_list[0].getSymbol().text
959
+
960
+ for c in ctx_list[4:-2]:
961
+ if isinstance(c, Parser.PartitionByClauseContext):
962
+ partition_by = Terminals().visitPartitionByClause(c)
963
+ continue
964
+ elif isinstance(c, Parser.OrderByClauseContext):
965
+ order_by = Terminals().visitOrderByClause(c)
966
+ continue
967
+
968
+ return Analytic(
969
+ op=op_node,
970
+ operand=None,
971
+ partition_by=partition_by,
972
+ order_by=order_by,
973
+ window=None,
974
+ **extract_token_info(ctx),
975
+ )
976
+
977
+ def visitRatioToReportAnComponent(self, ctx: Parser.RatioToReportAnComponentContext):
978
+ ctx_list = list(ctx.getChildren())
979
+
980
+ params = None
981
+ order_by = None
982
+
983
+ op_node = ctx_list[0].getSymbol().text
984
+ operand = self.visitExprComponent(ctx_list[2])
985
+
986
+ partition_by = Terminals().visitPartitionByClause(ctx_list[5])
987
+
988
+ return Analytic(
989
+ op=op_node,
990
+ operand=operand,
991
+ partition_by=partition_by,
992
+ order_by=order_by,
993
+ window=params,
994
+ **extract_token_info(ctx),
995
+ )