vtlengine 1.1rc1__py3-none-any.whl → 1.1.1__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.
Potentially problematic release.
This version of vtlengine might be problematic. Click here for more details.
- vtlengine/API/_InternalApi.py +231 -6
- vtlengine/API/__init__.py +258 -69
- vtlengine/AST/ASTComment.py +56 -0
- vtlengine/AST/ASTConstructor.py +71 -18
- vtlengine/AST/ASTConstructorModules/Expr.py +191 -72
- vtlengine/AST/ASTConstructorModules/ExprComponents.py +81 -38
- vtlengine/AST/ASTConstructorModules/Terminals.py +76 -31
- vtlengine/AST/ASTConstructorModules/__init__.py +50 -0
- vtlengine/AST/ASTEncoders.py +4 -0
- vtlengine/AST/ASTString.py +622 -0
- vtlengine/AST/ASTTemplate.py +28 -2
- vtlengine/AST/DAG/__init__.py +10 -1
- vtlengine/AST/__init__.py +127 -14
- vtlengine/Exceptions/messages.py +9 -0
- vtlengine/Interpreter/__init__.py +53 -8
- vtlengine/Model/__init__.py +9 -4
- vtlengine/Operators/Aggregation.py +7 -5
- vtlengine/Operators/Analytic.py +16 -11
- vtlengine/Operators/Conditional.py +20 -5
- vtlengine/Operators/Time.py +11 -10
- vtlengine/Utils/__init__.py +49 -0
- vtlengine/__init__.py +4 -2
- vtlengine/files/parser/__init__.py +16 -26
- vtlengine/files/parser/_rfc_dialect.py +1 -1
- vtlengine/py.typed +0 -0
- vtlengine-1.1.1.dist-info/METADATA +92 -0
- {vtlengine-1.1rc1.dist-info → vtlengine-1.1.1.dist-info}/RECORD +29 -26
- {vtlengine-1.1rc1.dist-info → vtlengine-1.1.1.dist-info}/WHEEL +1 -1
- vtlengine-1.1rc1.dist-info/METADATA +0 -248
- {vtlengine-1.1rc1.dist-info → vtlengine-1.1.1.dist-info}/LICENSE.md +0 -0
|
@@ -14,11 +14,13 @@ from vtlengine.AST import (
|
|
|
14
14
|
MulOp,
|
|
15
15
|
ParamConstant,
|
|
16
16
|
ParamOp,
|
|
17
|
+
ParFunction,
|
|
17
18
|
TimeAggregation,
|
|
18
19
|
UDOCall,
|
|
19
20
|
UnaryOp,
|
|
20
21
|
VarID,
|
|
21
22
|
)
|
|
23
|
+
from vtlengine.AST.ASTConstructorModules import extract_token_info
|
|
22
24
|
from vtlengine.AST.ASTConstructorModules.Terminals import Terminals
|
|
23
25
|
from vtlengine.AST.Grammar.parser import Parser
|
|
24
26
|
from vtlengine.AST.VtlVisitor import VtlVisitor
|
|
@@ -108,7 +110,7 @@ class ExprComp(VtlVisitor):
|
|
|
108
110
|
has_scaped_char = token.text.find("'") != -1
|
|
109
111
|
if has_scaped_char:
|
|
110
112
|
token.text = str(token.text.replace("'", ""))
|
|
111
|
-
var_id_node = VarID(token.text)
|
|
113
|
+
var_id_node = VarID(value=token.text, **extract_token_info(ctx))
|
|
112
114
|
return var_id_node
|
|
113
115
|
|
|
114
116
|
else:
|
|
@@ -124,7 +126,7 @@ class ExprComp(VtlVisitor):
|
|
|
124
126
|
op = ctx_list[1].getSymbol().text
|
|
125
127
|
right_node = self.visitExprComponent(ctx_list[2])
|
|
126
128
|
|
|
127
|
-
bin_op_node = BinOp(left_node, op, right_node)
|
|
129
|
+
bin_op_node = BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
|
|
128
130
|
|
|
129
131
|
return bin_op_node
|
|
130
132
|
|
|
@@ -148,7 +150,7 @@ class ExprComp(VtlVisitor):
|
|
|
148
150
|
right_node = Terminals().visitValueDomainID(ctx_list[2])
|
|
149
151
|
else:
|
|
150
152
|
raise NotImplementedError
|
|
151
|
-
bin_op_node = BinOp(left_node, op, right_node)
|
|
153
|
+
bin_op_node = BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
|
|
152
154
|
|
|
153
155
|
return bin_op_node
|
|
154
156
|
|
|
@@ -156,14 +158,15 @@ class ExprComp(VtlVisitor):
|
|
|
156
158
|
return self.bin_op_creator_comp(ctx)
|
|
157
159
|
|
|
158
160
|
def visitParenthesisExprComp(self, ctx: Parser.ParenthesisExprContext):
|
|
159
|
-
|
|
161
|
+
operand = self.visitExprComponent(list(ctx.getChildren())[1])
|
|
162
|
+
return ParFunction(operand=operand, **extract_token_info(ctx))
|
|
160
163
|
|
|
161
164
|
def visitUnaryExprComp(self, ctx: Parser.UnaryExprContext):
|
|
162
165
|
c_list = list(ctx.getChildren())
|
|
163
166
|
op = c_list[0].getSymbol().text
|
|
164
167
|
right = self.visitExprComponent(c_list[1])
|
|
165
168
|
|
|
166
|
-
return UnaryOp(op, right)
|
|
169
|
+
return UnaryOp(op=op, operand=right, **extract_token_info(ctx))
|
|
167
170
|
|
|
168
171
|
def visitIfExprComp(self, ctx: Parser.IfExprCompContext):
|
|
169
172
|
ctx_list = list(ctx.getChildren())
|
|
@@ -172,7 +175,12 @@ class ExprComp(VtlVisitor):
|
|
|
172
175
|
then_op_node = self.visitExprComponent(ctx_list[3])
|
|
173
176
|
else_op_node = self.visitExprComponent(ctx_list[5])
|
|
174
177
|
|
|
175
|
-
if_node = If(
|
|
178
|
+
if_node = If(
|
|
179
|
+
condition=condition_node,
|
|
180
|
+
thenOp=then_op_node,
|
|
181
|
+
elseOp=else_op_node,
|
|
182
|
+
**extract_token_info(ctx),
|
|
183
|
+
)
|
|
176
184
|
|
|
177
185
|
return if_node
|
|
178
186
|
|
|
@@ -189,10 +197,12 @@ class ExprComp(VtlVisitor):
|
|
|
189
197
|
for i in range(0, len(ctx_list), 4):
|
|
190
198
|
condition = self.visitExprComponent(ctx_list[i + 1])
|
|
191
199
|
thenOp = self.visitExprComponent(ctx_list[i + 3])
|
|
192
|
-
case_obj = CaseObj(
|
|
200
|
+
case_obj = CaseObj(
|
|
201
|
+
condition=condition, thenOp=thenOp, **extract_token_info(ctx_list[i + 1])
|
|
202
|
+
)
|
|
193
203
|
cases.append(case_obj)
|
|
194
204
|
|
|
195
|
-
case_node = Case(cases, else_node)
|
|
205
|
+
case_node = Case(cases=cases, elseOp=else_node, **extract_token_info(ctx))
|
|
196
206
|
|
|
197
207
|
return case_node
|
|
198
208
|
|
|
@@ -210,7 +220,7 @@ class ExprComp(VtlVisitor):
|
|
|
210
220
|
elif isinstance(c, TerminalNodeImpl):
|
|
211
221
|
token = c.getSymbol()
|
|
212
222
|
opt = token.text
|
|
213
|
-
return ID("OPTIONAL", opt)
|
|
223
|
+
return ID(type_="OPTIONAL", value=opt, **extract_token_info(ctx))
|
|
214
224
|
|
|
215
225
|
"""____________________________________________________________________________________
|
|
216
226
|
|
|
@@ -292,7 +302,7 @@ class ExprComp(VtlVisitor):
|
|
|
292
302
|
if isinstance(element, Parser.ParameterComponentContext)
|
|
293
303
|
]
|
|
294
304
|
|
|
295
|
-
return UDOCall(op=op, params=param_nodes)
|
|
305
|
+
return UDOCall(op=op, params=param_nodes, **extract_token_info(ctx))
|
|
296
306
|
|
|
297
307
|
def visitEvalAtomComponent(self, ctx: Parser.EvalAtomComponentContext):
|
|
298
308
|
"""
|
|
@@ -343,6 +353,7 @@ class ExprComp(VtlVisitor):
|
|
|
343
353
|
operands=children_nodes[0],
|
|
344
354
|
output=output_node[0],
|
|
345
355
|
language=language_name[0].getSymbol().text,
|
|
356
|
+
**extract_token_info(ctx),
|
|
346
357
|
)
|
|
347
358
|
|
|
348
359
|
def visitCastExprComponent(self, ctx: Parser.CastExprComponentContext):
|
|
@@ -374,7 +385,11 @@ class ExprComp(VtlVisitor):
|
|
|
374
385
|
|
|
375
386
|
if len(ctx_list) > 6:
|
|
376
387
|
param_node = [
|
|
377
|
-
ParamConstant(
|
|
388
|
+
ParamConstant(
|
|
389
|
+
type_="PARAM_CAST",
|
|
390
|
+
value=str_.symbol.text.strip('"'),
|
|
391
|
+
**extract_token_info(str_.getSymbol()),
|
|
392
|
+
)
|
|
378
393
|
for str_ in ctx_list
|
|
379
394
|
if isinstance(str_, TerminalNodeImpl)
|
|
380
395
|
and str_.getSymbol().type == Parser.STRING_CONSTANT
|
|
@@ -385,7 +400,9 @@ class ExprComp(VtlVisitor):
|
|
|
385
400
|
if len(basic_scalar_type) == 1:
|
|
386
401
|
children_nodes = expr_node + basic_scalar_type
|
|
387
402
|
|
|
388
|
-
return ParamOp(
|
|
403
|
+
return ParamOp(
|
|
404
|
+
op=op, children=children_nodes, params=param_node, **extract_token_info(ctx)
|
|
405
|
+
)
|
|
389
406
|
|
|
390
407
|
else:
|
|
391
408
|
# AST_ASTCONSTRUCTOR.14
|
|
@@ -398,7 +415,7 @@ class ExprComp(VtlVisitor):
|
|
|
398
415
|
if isinstance(c, Parser.ExprComponentContext):
|
|
399
416
|
return self.visitExprComponent(c)
|
|
400
417
|
elif isinstance(c, TerminalNodeImpl):
|
|
401
|
-
return ID("OPTIONAL", c.getSymbol().text)
|
|
418
|
+
return ID(type_="OPTIONAL", value=c.getSymbol().text, **extract_token_info(ctx))
|
|
402
419
|
else:
|
|
403
420
|
raise NotImplementedError
|
|
404
421
|
|
|
@@ -427,7 +444,7 @@ class ExprComp(VtlVisitor):
|
|
|
427
444
|
token = c.getSymbol()
|
|
428
445
|
op_node = token.text
|
|
429
446
|
operand_node = self.visitExprComponent(ctx_list[2])
|
|
430
|
-
return UnaryOp(op_node, operand_node)
|
|
447
|
+
return UnaryOp(op=op_node, operand=operand_node, **extract_token_info(ctx))
|
|
431
448
|
|
|
432
449
|
def visitSubstrAtomComponent(self, ctx: Parser.SubstrAtomComponentContext):
|
|
433
450
|
ctx_list = list(ctx.getChildren())
|
|
@@ -450,7 +467,9 @@ class ExprComp(VtlVisitor):
|
|
|
450
467
|
for param in params:
|
|
451
468
|
params_nodes.append(self.visitOptionalExprComponent(param))
|
|
452
469
|
|
|
453
|
-
return ParamOp(
|
|
470
|
+
return ParamOp(
|
|
471
|
+
op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
|
|
472
|
+
)
|
|
454
473
|
|
|
455
474
|
def visitReplaceAtomComponent(self, ctx: Parser.ReplaceAtomComponentContext):
|
|
456
475
|
ctx_list = list(ctx.getChildren())
|
|
@@ -473,7 +492,9 @@ class ExprComp(VtlVisitor):
|
|
|
473
492
|
children_nodes = [expressions[0]]
|
|
474
493
|
params_nodes = [expressions[1]] + params
|
|
475
494
|
|
|
476
|
-
return ParamOp(
|
|
495
|
+
return ParamOp(
|
|
496
|
+
op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
|
|
497
|
+
)
|
|
477
498
|
|
|
478
499
|
def visitInstrAtomComponent(self, ctx: Parser.InstrAtomComponentContext):
|
|
479
500
|
ctx_list = list(ctx.getChildren())
|
|
@@ -496,7 +517,9 @@ class ExprComp(VtlVisitor):
|
|
|
496
517
|
children_nodes = [expressions[0]]
|
|
497
518
|
params_nodes = [expressions[1]] + params
|
|
498
519
|
|
|
499
|
-
return ParamOp(
|
|
520
|
+
return ParamOp(
|
|
521
|
+
op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
|
|
522
|
+
)
|
|
500
523
|
|
|
501
524
|
"""
|
|
502
525
|
-----------------------------------
|
|
@@ -521,7 +544,7 @@ class ExprComp(VtlVisitor):
|
|
|
521
544
|
token = c.getSymbol()
|
|
522
545
|
op_node = token.text
|
|
523
546
|
operand_node = self.visitExprComponent(ctx_list[2])
|
|
524
|
-
return UnaryOp(op_node, operand_node)
|
|
547
|
+
return UnaryOp(op=op_node, operand=operand_node, **extract_token_info(ctx))
|
|
525
548
|
|
|
526
549
|
def visitUnaryWithOptionalNumericComponent(
|
|
527
550
|
self, ctx: Parser.UnaryWithOptionalNumericComponentContext
|
|
@@ -546,7 +569,9 @@ class ExprComp(VtlVisitor):
|
|
|
546
569
|
for param in params:
|
|
547
570
|
params_nodes.append(self.visitOptionalExprComponent(param))
|
|
548
571
|
|
|
549
|
-
return ParamOp(
|
|
572
|
+
return ParamOp(
|
|
573
|
+
op=op_node, children=children_nodes, params=params_nodes, **extract_token_info(ctx)
|
|
574
|
+
)
|
|
550
575
|
|
|
551
576
|
def visitBinaryNumericComponent(self, ctx: Parser.BinaryNumericComponentContext):
|
|
552
577
|
ctx_list = list(ctx.getChildren())
|
|
@@ -557,7 +582,7 @@ class ExprComp(VtlVisitor):
|
|
|
557
582
|
left_node = self.visitExprComponent(ctx_list[2])
|
|
558
583
|
op_node = token.text
|
|
559
584
|
right_node = self.visitExprComponent(ctx_list[4])
|
|
560
|
-
return BinOp(left_node, op_node, right_node)
|
|
585
|
+
return BinOp(left=left_node, op=op_node, right=right_node, **extract_token_info(ctx))
|
|
561
586
|
|
|
562
587
|
"""
|
|
563
588
|
-----------------------------------
|
|
@@ -617,7 +642,7 @@ class ExprComp(VtlVisitor):
|
|
|
617
642
|
# AST_ASTCONSTRUCTOR.15
|
|
618
643
|
raise NotImplementedError
|
|
619
644
|
|
|
620
|
-
return UnaryOp(op=op, operand=operand_node[0])
|
|
645
|
+
return UnaryOp(op=op, operand=operand_node[0], **extract_token_info(ctx))
|
|
621
646
|
|
|
622
647
|
def visitTimeShiftAtomComponent(self, ctx: Parser.TimeShiftAtomComponentContext):
|
|
623
648
|
"""
|
|
@@ -628,9 +653,13 @@ class ExprComp(VtlVisitor):
|
|
|
628
653
|
|
|
629
654
|
op = c.getSymbol().text
|
|
630
655
|
left_node = self.visitExprComponent(ctx_list[2])
|
|
631
|
-
right_node = Constant(
|
|
656
|
+
right_node = Constant(
|
|
657
|
+
type_="INTEGER_CONSTANT",
|
|
658
|
+
value=int(ctx_list[4].getSymbol().text),
|
|
659
|
+
**extract_token_info(ctx),
|
|
660
|
+
)
|
|
632
661
|
|
|
633
|
-
return BinOp(left=left_node, op=op, right=right_node)
|
|
662
|
+
return BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
|
|
634
663
|
|
|
635
664
|
def visitFillTimeAtomComponent(self, ctx: Parser.FillTimeAtomComponentContext):
|
|
636
665
|
"""
|
|
@@ -643,11 +672,19 @@ class ExprComp(VtlVisitor):
|
|
|
643
672
|
children_node = [self.visitExprComponent(ctx_list[2])]
|
|
644
673
|
|
|
645
674
|
if len(ctx_list) > 4:
|
|
646
|
-
param_constant_node = [
|
|
675
|
+
param_constant_node = [
|
|
676
|
+
ParamConstant(
|
|
677
|
+
type_="PARAM_TIMESERIES",
|
|
678
|
+
value=ctx_list[4].getSymbol().text,
|
|
679
|
+
**extract_token_info(ctx),
|
|
680
|
+
)
|
|
681
|
+
]
|
|
647
682
|
else:
|
|
648
683
|
param_constant_node = []
|
|
649
684
|
|
|
650
|
-
return ParamOp(
|
|
685
|
+
return ParamOp(
|
|
686
|
+
op=op, children=children_node, params=param_constant_node, **extract_token_info(ctx)
|
|
687
|
+
)
|
|
651
688
|
|
|
652
689
|
def visitTimeAggAtomComponent(self, ctx: Parser.TimeAggAtomComponentContext):
|
|
653
690
|
"""
|
|
@@ -679,24 +716,24 @@ class ExprComp(VtlVisitor):
|
|
|
679
716
|
if isinstance(operand_node, ID):
|
|
680
717
|
operand_node = None
|
|
681
718
|
elif isinstance(operand_node, Identifier):
|
|
682
|
-
operand_node = VarID(
|
|
719
|
+
operand_node = VarID(
|
|
720
|
+
value=operand_node.value, **extract_token_info(ctx.op)
|
|
721
|
+
) # Converting Identifier to VarID
|
|
683
722
|
else:
|
|
684
723
|
operand_node = None
|
|
685
724
|
|
|
686
|
-
if operand_node is None:
|
|
687
|
-
# AST_ASTCONSTRUCTOR.17
|
|
688
|
-
raise SemanticError("1-4-2-2")
|
|
689
725
|
return TimeAggregation(
|
|
690
726
|
op=op,
|
|
691
727
|
operand=operand_node,
|
|
692
728
|
period_to=period_to,
|
|
693
729
|
period_from=period_from,
|
|
694
730
|
conf=conf,
|
|
731
|
+
**extract_token_info(ctx),
|
|
695
732
|
)
|
|
696
733
|
|
|
697
734
|
def visitCurrentDateAtomComponent(self, ctx: Parser.CurrentDateAtomComponentContext):
|
|
698
735
|
c = list(ctx.getChildren())[0]
|
|
699
|
-
return MulOp(op=c.getSymbol().text, children=[])
|
|
736
|
+
return MulOp(op=c.getSymbol().text, children=[], **extract_token_info(ctx))
|
|
700
737
|
|
|
701
738
|
def visitDateDiffAtomComponent(self, ctx: Parser.TimeShiftAtomComponentContext):
|
|
702
739
|
""" """
|
|
@@ -707,7 +744,7 @@ class ExprComp(VtlVisitor):
|
|
|
707
744
|
left_node = self.visitExprComponent(ctx_list[2])
|
|
708
745
|
right_node = self.visitExprComponent(ctx_list[4])
|
|
709
746
|
|
|
710
|
-
return BinOp(left=left_node, op=op, right=right_node)
|
|
747
|
+
return BinOp(left=left_node, op=op, right=right_node, **extract_token_info(ctx))
|
|
711
748
|
|
|
712
749
|
def visitDateAddAtomComponentContext(self, ctx: Parser.DateAddAtomComponentContext):
|
|
713
750
|
""" """
|
|
@@ -724,7 +761,9 @@ class ExprComp(VtlVisitor):
|
|
|
724
761
|
if len(ctx_list) > 6:
|
|
725
762
|
param_constant_node.append(self.visitExprComponent(ctx_list[6]))
|
|
726
763
|
|
|
727
|
-
return ParamOp(
|
|
764
|
+
return ParamOp(
|
|
765
|
+
op=op, children=children_node, params=param_constant_node, **extract_token_info(ctx)
|
|
766
|
+
)
|
|
728
767
|
|
|
729
768
|
"""
|
|
730
769
|
-----------------------------------
|
|
@@ -749,7 +788,7 @@ class ExprComp(VtlVisitor):
|
|
|
749
788
|
left_node = self.visitExprComponent(ctx_list[2])
|
|
750
789
|
op_node = token.text
|
|
751
790
|
right_node = self.visitExprComponent(ctx_list[4])
|
|
752
|
-
return BinOp(left_node, op_node, right_node)
|
|
791
|
+
return BinOp(left=left_node, op=op_node, right=right_node, **extract_token_info(ctx))
|
|
753
792
|
|
|
754
793
|
"""
|
|
755
794
|
-----------------------------------
|
|
@@ -780,7 +819,7 @@ class ExprComp(VtlVisitor):
|
|
|
780
819
|
for children in childrens:
|
|
781
820
|
children_nodes.append(self.visitExprComponent(children))
|
|
782
821
|
|
|
783
|
-
return MulOp(op_node, children_nodes)
|
|
822
|
+
return MulOp(op=op_node, children=children_nodes, **extract_token_info(ctx))
|
|
784
823
|
|
|
785
824
|
def visitCharsetMatchAtomComponent(self, ctx: Parser.CharsetMatchAtomComponentContext):
|
|
786
825
|
ctx_list = list(ctx.getChildren())
|
|
@@ -790,7 +829,7 @@ class ExprComp(VtlVisitor):
|
|
|
790
829
|
left_node = self.visitExprComponent(ctx_list[2])
|
|
791
830
|
op_node = token.text
|
|
792
831
|
right_node = self.visitExprComponent(ctx_list[4])
|
|
793
|
-
return BinOp(left_node, op_node, right_node)
|
|
832
|
+
return BinOp(left=left_node, op=op_node, right=right_node, **extract_token_info(ctx))
|
|
794
833
|
|
|
795
834
|
def visitIsNullAtomComponent(self, ctx: Parser.IsNullAtomComponentContext):
|
|
796
835
|
ctx_list = list(ctx.getChildren())
|
|
@@ -798,7 +837,7 @@ class ExprComp(VtlVisitor):
|
|
|
798
837
|
token = c.getSymbol()
|
|
799
838
|
op_node = token.text
|
|
800
839
|
operand_node = self.visitExprComponent(ctx_list[2])
|
|
801
|
-
return UnaryOp(op_node, operand_node)
|
|
840
|
+
return UnaryOp(op=op_node, operand=operand_node, **extract_token_info(ctx))
|
|
802
841
|
|
|
803
842
|
"""
|
|
804
843
|
-----------------------------------
|
|
@@ -818,12 +857,12 @@ class ExprComp(VtlVisitor):
|
|
|
818
857
|
ctx_list = list(ctx.getChildren())
|
|
819
858
|
op_node = ctx_list[0].getSymbol().text
|
|
820
859
|
operand_node = self.visitExprComponent(ctx_list[2])
|
|
821
|
-
return Aggregation(op_node, operand_node)
|
|
860
|
+
return Aggregation(op=op_node, operand=operand_node, **extract_token_info(ctx))
|
|
822
861
|
|
|
823
862
|
def visitCountAggrComp(self, ctx: Parser.CountAggrCompContext):
|
|
824
863
|
ctx_list = list(ctx.getChildren())
|
|
825
864
|
op_node = ctx_list[0].getSymbol().text
|
|
826
|
-
return Aggregation(op_node)
|
|
865
|
+
return Aggregation(op=op_node, **extract_token_info(ctx))
|
|
827
866
|
|
|
828
867
|
"""
|
|
829
868
|
-----------------------------------
|
|
@@ -872,6 +911,7 @@ class ExprComp(VtlVisitor):
|
|
|
872
911
|
partition_by=partition_by,
|
|
873
912
|
order_by=order_by,
|
|
874
913
|
window=params,
|
|
914
|
+
**extract_token_info(ctx),
|
|
875
915
|
)
|
|
876
916
|
|
|
877
917
|
def visitLagOrLeadAnComponent(self, ctx: Parser.LagOrLeadAnComponentContext):
|
|
@@ -906,6 +946,7 @@ class ExprComp(VtlVisitor):
|
|
|
906
946
|
partition_by=partition_by,
|
|
907
947
|
order_by=order_by,
|
|
908
948
|
params=params,
|
|
949
|
+
**extract_token_info(ctx),
|
|
909
950
|
)
|
|
910
951
|
|
|
911
952
|
def visitRankAnComponent(self, ctx: Parser.RankAnComponentContext):
|
|
@@ -930,6 +971,7 @@ class ExprComp(VtlVisitor):
|
|
|
930
971
|
partition_by=partition_by,
|
|
931
972
|
order_by=order_by,
|
|
932
973
|
window=None,
|
|
974
|
+
**extract_token_info(ctx),
|
|
933
975
|
)
|
|
934
976
|
|
|
935
977
|
def visitRatioToReportAnComponent(self, ctx: Parser.RatioToReportAnComponentContext):
|
|
@@ -949,4 +991,5 @@ class ExprComp(VtlVisitor):
|
|
|
949
991
|
partition_by=partition_by,
|
|
950
992
|
order_by=order_by,
|
|
951
993
|
window=params,
|
|
994
|
+
**extract_token_info(ctx),
|
|
952
995
|
)
|
|
@@ -12,6 +12,7 @@ from vtlengine.AST import (
|
|
|
12
12
|
VarID,
|
|
13
13
|
Windowing,
|
|
14
14
|
)
|
|
15
|
+
from vtlengine.AST.ASTConstructorModules import extract_token_info
|
|
15
16
|
from vtlengine.AST.Grammar.parser import Parser
|
|
16
17
|
from vtlengine.AST.VtlVisitor import VtlVisitor
|
|
17
18
|
from vtlengine.DataTypes import (
|
|
@@ -37,26 +38,27 @@ def _remove_scaped_characters(text):
|
|
|
37
38
|
class Terminals(VtlVisitor):
|
|
38
39
|
def visitConstant(self, ctx: Parser.ConstantContext):
|
|
39
40
|
token = ctx.children[0].getSymbol()
|
|
41
|
+
token_info = extract_token_info(token)
|
|
40
42
|
|
|
41
43
|
if token.type == Parser.INTEGER_CONSTANT:
|
|
42
|
-
constant_node = Constant("INTEGER_CONSTANT", int(token.text))
|
|
44
|
+
constant_node = Constant(type_="INTEGER_CONSTANT", value=int(token.text), **token_info)
|
|
43
45
|
|
|
44
46
|
elif token.type == Parser.NUMBER_CONSTANT:
|
|
45
|
-
constant_node = Constant("FLOAT_CONSTANT", float(token.text))
|
|
47
|
+
constant_node = Constant(type_="FLOAT_CONSTANT", value=float(token.text), **token_info)
|
|
46
48
|
|
|
47
49
|
elif token.type == Parser.BOOLEAN_CONSTANT:
|
|
48
50
|
if token.text == "true":
|
|
49
|
-
constant_node = Constant("BOOLEAN_CONSTANT", True)
|
|
51
|
+
constant_node = Constant(type_="BOOLEAN_CONSTANT", value=True, **token_info)
|
|
50
52
|
elif token.text == "false":
|
|
51
|
-
constant_node = Constant("BOOLEAN_CONSTANT", False)
|
|
53
|
+
constant_node = Constant(type_="BOOLEAN_CONSTANT", value=False, **token_info)
|
|
52
54
|
else:
|
|
53
55
|
raise NotImplementedError
|
|
54
56
|
|
|
55
57
|
elif token.type == Parser.STRING_CONSTANT:
|
|
56
|
-
constant_node = Constant("STRING_CONSTANT", token.text[1:-1])
|
|
58
|
+
constant_node = Constant(type_="STRING_CONSTANT", value=token.text[1:-1], **token_info)
|
|
57
59
|
|
|
58
60
|
elif token.type == Parser.NULL_CONSTANT:
|
|
59
|
-
constant_node = Constant("NULL_CONSTANT", None)
|
|
61
|
+
constant_node = Constant(type_="NULL_CONSTANT", value=None, **token_info)
|
|
60
62
|
|
|
61
63
|
else:
|
|
62
64
|
raise NotImplementedError
|
|
@@ -66,7 +68,8 @@ class Terminals(VtlVisitor):
|
|
|
66
68
|
def visitVarID(self, ctx: Parser.VarIDContext):
|
|
67
69
|
token = ctx.children[0].getSymbol()
|
|
68
70
|
token.text = _remove_scaped_characters(token.text)
|
|
69
|
-
|
|
71
|
+
token_info = extract_token_info(token)
|
|
72
|
+
var_id_node = VarID(value=token.text, **token_info)
|
|
70
73
|
return var_id_node
|
|
71
74
|
|
|
72
75
|
def visitVarIdExpr(self, ctx: Parser.VarIdExprContext):
|
|
@@ -76,7 +79,8 @@ class Terminals(VtlVisitor):
|
|
|
76
79
|
token = ctx.children[0].getSymbol()
|
|
77
80
|
# check token text
|
|
78
81
|
token.text = _remove_scaped_characters(token.text)
|
|
79
|
-
|
|
82
|
+
token_info = extract_token_info(token)
|
|
83
|
+
var_id_node = VarID(value=token.text, **token_info)
|
|
80
84
|
return var_id_node
|
|
81
85
|
|
|
82
86
|
def visitSimpleComponentId(self, ctx: Parser.SimpleComponentIdContext):
|
|
@@ -87,7 +91,7 @@ class Terminals(VtlVisitor):
|
|
|
87
91
|
# check token text
|
|
88
92
|
token.text = _remove_scaped_characters(token.text)
|
|
89
93
|
|
|
90
|
-
return Identifier(token.text, "ComponentID")
|
|
94
|
+
return Identifier(value=token.text, kind="ComponentID", **extract_token_info(ctx))
|
|
91
95
|
|
|
92
96
|
def visitComponentID(self, ctx: Parser.ComponentIDContext):
|
|
93
97
|
ctx_list = list(ctx.getChildren())
|
|
@@ -98,7 +102,11 @@ class Terminals(VtlVisitor):
|
|
|
98
102
|
"'"
|
|
99
103
|
): # The component could be imbalance, errorcode or errorlevel
|
|
100
104
|
component_name = component_name[1:-1]
|
|
101
|
-
return Identifier(
|
|
105
|
+
return Identifier(
|
|
106
|
+
value=component_name,
|
|
107
|
+
kind="ComponentID",
|
|
108
|
+
**extract_token_info(ctx_list[0].getSymbol()),
|
|
109
|
+
)
|
|
102
110
|
else:
|
|
103
111
|
component_name = ctx_list[2].getSymbol().text
|
|
104
112
|
if component_name.startswith("'") and component_name.endswith(
|
|
@@ -107,9 +115,18 @@ class Terminals(VtlVisitor):
|
|
|
107
115
|
component_name = component_name[1:-1]
|
|
108
116
|
op_node = ctx_list[1].getSymbol().text
|
|
109
117
|
return BinOp(
|
|
110
|
-
left=Identifier(
|
|
118
|
+
left=Identifier(
|
|
119
|
+
value=ctx_list[0].getSymbol().text,
|
|
120
|
+
kind="DatasetID",
|
|
121
|
+
**extract_token_info(ctx_list[0].getSymbol()),
|
|
122
|
+
),
|
|
111
123
|
op=op_node,
|
|
112
|
-
right=Identifier(
|
|
124
|
+
right=Identifier(
|
|
125
|
+
value=component_name,
|
|
126
|
+
kind="ComponentID",
|
|
127
|
+
**extract_token_info(ctx_list[1].getSymbol()),
|
|
128
|
+
),
|
|
129
|
+
**extract_token_info(ctx),
|
|
113
130
|
)
|
|
114
131
|
|
|
115
132
|
def visitOperatorID(self, ctx: Parser.OperatorIDContext):
|
|
@@ -130,6 +147,7 @@ class Terminals(VtlVisitor):
|
|
|
130
147
|
children=[],
|
|
131
148
|
kind="ValueDomain",
|
|
132
149
|
type="",
|
|
150
|
+
**extract_token_info(ctx),
|
|
133
151
|
)
|
|
134
152
|
|
|
135
153
|
def visitRulesetID(self, ctx: Parser.RulesetIDContext):
|
|
@@ -254,7 +272,9 @@ class Terminals(VtlVisitor):
|
|
|
254
272
|
for scalar_with_cast in scalars_with_cast:
|
|
255
273
|
scalar_nodes.append(self.visitScalarWithCast(scalar_with_cast))
|
|
256
274
|
|
|
257
|
-
return Collection(
|
|
275
|
+
return Collection(
|
|
276
|
+
name="List", type="Lists", children=scalar_nodes, **extract_token_info(ctx)
|
|
277
|
+
)
|
|
258
278
|
|
|
259
279
|
def visitMultModifier(self, ctx: Parser.MultModifierContext):
|
|
260
280
|
"""
|
|
@@ -508,12 +528,22 @@ class Terminals(VtlVisitor):
|
|
|
508
528
|
const_node = self.visitConstant(ctx_list[2])
|
|
509
529
|
basic_scalar_type = [self.visitBasicScalarType(ctx_list[4])]
|
|
510
530
|
|
|
511
|
-
param_node =
|
|
531
|
+
param_node = (
|
|
532
|
+
[
|
|
533
|
+
ParamConstant(
|
|
534
|
+
type_="PARAM_CAST", value=ctx_list[6], **extract_token_info(ctx_list[6])
|
|
535
|
+
)
|
|
536
|
+
]
|
|
537
|
+
if len(ctx_list) > 6
|
|
538
|
+
else []
|
|
539
|
+
)
|
|
512
540
|
|
|
513
541
|
if len(basic_scalar_type) == 1:
|
|
514
542
|
children_nodes = [const_node, basic_scalar_type[0]]
|
|
515
543
|
|
|
516
|
-
return ParamOp(
|
|
544
|
+
return ParamOp(
|
|
545
|
+
op=op, children=children_nodes, params=param_node, **extract_token_info(ctx)
|
|
546
|
+
)
|
|
517
547
|
|
|
518
548
|
else:
|
|
519
549
|
# AST_ASTCONSTRUCTOR.14
|
|
@@ -536,14 +566,20 @@ class Terminals(VtlVisitor):
|
|
|
536
566
|
|
|
537
567
|
if token.type == Parser.BOOLEAN_CONSTANT:
|
|
538
568
|
if token.text == "true":
|
|
539
|
-
param_constant_node = Constant(
|
|
569
|
+
param_constant_node = Constant(
|
|
570
|
+
type_="BOOLEAN_CONSTANT", value=True, **extract_token_info(token)
|
|
571
|
+
)
|
|
540
572
|
elif token.text == "false":
|
|
541
|
-
param_constant_node = Constant(
|
|
573
|
+
param_constant_node = Constant(
|
|
574
|
+
type_="BOOLEAN_CONSTANT", value=False, **extract_token_info(token)
|
|
575
|
+
)
|
|
542
576
|
else:
|
|
543
577
|
raise NotImplementedError
|
|
544
578
|
|
|
545
579
|
elif token.type == Parser.ALL:
|
|
546
|
-
param_constant_node = ParamConstant(
|
|
580
|
+
param_constant_node = ParamConstant(
|
|
581
|
+
type_="PARAM_CONSTANT", value=token.text, **extract_token_info(token)
|
|
582
|
+
)
|
|
547
583
|
|
|
548
584
|
else:
|
|
549
585
|
raise NotImplementedError
|
|
@@ -565,7 +601,7 @@ class Terminals(VtlVisitor):
|
|
|
565
601
|
return ctx.children[0].getSymbol().text
|
|
566
602
|
|
|
567
603
|
def visitSignedInteger(self, ctx: Parser.SignedIntegerContext):
|
|
568
|
-
return ctx.children[0].getSymbol().text
|
|
604
|
+
return int(ctx.children[0].getSymbol().text)
|
|
569
605
|
|
|
570
606
|
def visitComparisonOperand(self, ctx: Parser.ComparisonOperandContext):
|
|
571
607
|
return ctx.children[0].getSymbol().text
|
|
@@ -596,6 +632,7 @@ class Terminals(VtlVisitor):
|
|
|
596
632
|
"""
|
|
597
633
|
VarID (AS alias)?
|
|
598
634
|
"""
|
|
635
|
+
token_info = extract_token_info(ctx)
|
|
599
636
|
|
|
600
637
|
ctx_list = list(ctx.getChildren())
|
|
601
638
|
c = ctx_list[0]
|
|
@@ -605,10 +642,10 @@ class Terminals(VtlVisitor):
|
|
|
605
642
|
alias_name = None
|
|
606
643
|
|
|
607
644
|
if len(ctx_list) == 1:
|
|
608
|
-
return DPRIdentifier(value=node_name, kind=kind, alias=alias_name)
|
|
645
|
+
return DPRIdentifier(value=node_name, kind=kind, alias=alias_name, **token_info)
|
|
609
646
|
|
|
610
647
|
alias_name = self.visitAlias(ctx_list[2])
|
|
611
|
-
return DPRIdentifier(value=node_name, kind=kind, alias=alias_name)
|
|
648
|
+
return DPRIdentifier(value=node_name, kind=kind, alias=alias_name, **token_info)
|
|
612
649
|
|
|
613
650
|
"""
|
|
614
651
|
From Hierarchical
|
|
@@ -663,6 +700,8 @@ class Terminals(VtlVisitor):
|
|
|
663
700
|
|
|
664
701
|
win_mode = ctx_list[0].getSymbol().text # Windowing mode (data points | range )
|
|
665
702
|
|
|
703
|
+
token_info = extract_token_info(ctx)
|
|
704
|
+
|
|
666
705
|
if win_mode == "data":
|
|
667
706
|
num_rows_1, mode_1 = self.visitLimitClauseItem(ctx_list[3])
|
|
668
707
|
num_rows_2, mode_2 = self.visitLimitClauseItem(ctx_list[5])
|
|
@@ -694,31 +733,36 @@ class Terminals(VtlVisitor):
|
|
|
694
733
|
|
|
695
734
|
if mode_1 == mode_2:
|
|
696
735
|
if mode_1 == "preceding" and first != -1 and second > first: # 3 and 1: must be [-3:-1]
|
|
697
|
-
return create_windowing(win_mode, [second, first], [mode_2, mode_1])
|
|
736
|
+
return create_windowing(win_mode, [second, first], [mode_2, mode_1], token_info)
|
|
698
737
|
if mode_1 == "preceding" and second == -1:
|
|
699
|
-
return create_windowing(win_mode, [second, first], [mode_2, mode_1])
|
|
738
|
+
return create_windowing(win_mode, [second, first], [mode_2, mode_1], token_info)
|
|
700
739
|
if mode_1 == "following" and second != -1 and second < first: # 3 and 1: must be [1:3]
|
|
701
|
-
return create_windowing(win_mode, [second, first], [mode_2, mode_1])
|
|
740
|
+
return create_windowing(win_mode, [second, first], [mode_2, mode_1], token_info)
|
|
702
741
|
if mode_1 == "following" and first == -1:
|
|
703
|
-
return create_windowing(win_mode, [second, first], [mode_2, mode_1])
|
|
742
|
+
return create_windowing(win_mode, [second, first], [mode_2, mode_1], token_info)
|
|
704
743
|
|
|
705
|
-
return create_windowing(win_mode, [first, second], [mode_1, mode_2])
|
|
744
|
+
return create_windowing(win_mode, [first, second], [mode_1, mode_2], token_info)
|
|
706
745
|
|
|
707
746
|
def visitOrderByItem(self, ctx: Parser.OrderByItemContext):
|
|
708
747
|
ctx_list = list(ctx.getChildren())
|
|
709
748
|
|
|
749
|
+
token_info = extract_token_info(ctx)
|
|
750
|
+
|
|
710
751
|
if len(ctx_list) == 1:
|
|
711
|
-
return OrderBy(
|
|
752
|
+
return OrderBy(
|
|
753
|
+
component=self.visitComponentID(ctx_list[0]).value, order="asc", **token_info
|
|
754
|
+
)
|
|
712
755
|
|
|
713
756
|
return OrderBy(
|
|
714
757
|
component=self.visitComponentID(ctx_list[0]).value,
|
|
715
758
|
order=ctx_list[1].getSymbol().text,
|
|
759
|
+
**token_info,
|
|
716
760
|
)
|
|
717
761
|
|
|
718
762
|
def visitLimitClauseItem(self, ctx: Parser.LimitClauseItemContext):
|
|
719
763
|
ctx_list = list(ctx.getChildren())
|
|
720
764
|
c = ctx_list[0]
|
|
721
|
-
if c.getSymbol().text == "unbounded":
|
|
765
|
+
if c.getSymbol().text.lower() == "unbounded":
|
|
722
766
|
result = -1
|
|
723
767
|
elif c.getSymbol().text == "current":
|
|
724
768
|
result = 0
|
|
@@ -733,12 +777,12 @@ class Terminals(VtlVisitor):
|
|
|
733
777
|
return result, ctx_list[1].getSymbol().text
|
|
734
778
|
|
|
735
779
|
|
|
736
|
-
def create_windowing(win_mode, values, modes):
|
|
780
|
+
def create_windowing(win_mode, values, modes, token_info):
|
|
737
781
|
for e in range(0, 2):
|
|
738
782
|
if values[e] == -1:
|
|
739
|
-
values[e] = "
|
|
783
|
+
values[e] = "unbounded"
|
|
740
784
|
elif values[e] == 0:
|
|
741
|
-
values[e] = "
|
|
785
|
+
values[e] = "current row"
|
|
742
786
|
|
|
743
787
|
return Windowing(
|
|
744
788
|
type_=win_mode,
|
|
@@ -746,4 +790,5 @@ def create_windowing(win_mode, values, modes):
|
|
|
746
790
|
stop=values[1],
|
|
747
791
|
start_mode=modes[0],
|
|
748
792
|
stop_mode=modes[1],
|
|
793
|
+
**token_info,
|
|
749
794
|
)
|