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,598 @@
1
+ """
2
+ AST.ASTConstructor.py
3
+ =====================
4
+
5
+ Description
6
+ -----------
7
+ Node Creator.
8
+ """
9
+
10
+ from antlr4.tree.Tree import TerminalNodeImpl
11
+
12
+ from vtlengine.AST import (
13
+ Argument,
14
+ Assignment,
15
+ DefIdentifier,
16
+ DPRule,
17
+ DPRuleset,
18
+ HRBinOp,
19
+ HRule,
20
+ HRuleset,
21
+ HRUnOp,
22
+ Operator,
23
+ PersistentAssignment,
24
+ Start,
25
+ )
26
+ from vtlengine.AST.ASTConstructorModules import extract_token_info
27
+ from vtlengine.AST.ASTConstructorModules.Expr import Expr
28
+ from vtlengine.AST.ASTConstructorModules.ExprComponents import ExprComp
29
+ from vtlengine.AST.ASTConstructorModules.Terminals import Terminals
30
+ from vtlengine.AST.ASTDataExchange import de_ruleset_elements
31
+ from vtlengine.AST.Grammar.parser import Parser
32
+ from vtlengine.AST.VtlVisitor import VtlVisitor
33
+ from vtlengine.Exceptions import SemanticError
34
+ from vtlengine.Model import Component, Dataset, Scalar
35
+
36
+ # pylint: disable=unreachable,expression-not-assigned
37
+ # pylint: disable=assignment-from-no-return
38
+
39
+
40
+ class ASTVisitor(VtlVisitor):
41
+ """
42
+ This class walks the parse tree (CTS) and transform the structure
43
+ to an AST which nodes are defined at AST.AST.py
44
+ """
45
+
46
+ """______________________________________________________________________________________
47
+
48
+
49
+ Start Definition.
50
+
51
+ _______________________________________________________________________________________"""
52
+
53
+ def visitStart(self, ctx: Parser.StartContext):
54
+ """
55
+ start:
56
+ (statement EOL)* EOF
57
+ """
58
+ ctx_list = list(ctx.getChildren())
59
+
60
+ statements_nodes = []
61
+ statements = [
62
+ statement for statement in ctx_list if isinstance(statement, Parser.StatementContext)
63
+ ]
64
+ if len(statements) != 0:
65
+ for statement in statements:
66
+ statements_nodes.append(self.visitStatement(statement))
67
+
68
+ token_info = extract_token_info(ctx)
69
+
70
+ start_node = Start(children=statements_nodes, **token_info)
71
+
72
+ return start_node
73
+
74
+ def visitStatement(self, ctx: Parser.StatementContext):
75
+ """
76
+ statement:
77
+ varID ASSIGN expr # temporaryAssignment
78
+ | varID PUT_SYMBOL expr # persistAssignment
79
+ | defOperators # defineExpression
80
+ ;
81
+ """
82
+ ctx_list = list(ctx.getChildren())
83
+ c = ctx_list[0]
84
+
85
+ if isinstance(ctx, Parser.TemporaryAssignmentContext):
86
+ return self.visitTemporaryAssignment(ctx)
87
+
88
+ elif isinstance(ctx, Parser.PersistAssignmentContext):
89
+ return self.visitPersistAssignment(ctx)
90
+
91
+ elif isinstance(ctx, Parser.DefineExpressionContext):
92
+ return self.visitDefineExpression(c)
93
+ else:
94
+ raise NotImplementedError
95
+
96
+ # varID ASSIGN expr # temporaryAssignment
97
+ def visitTemporaryAssignment(self, ctx: Parser.TemporaryAssignmentContext):
98
+ ctx_list = list(ctx.getChildren())
99
+
100
+ left_node = Terminals().visitVarID(ctx_list[0])
101
+ op_node = ctx_list[1].getSymbol().text
102
+
103
+ right_node = Expr().visitExpr(ctx_list[2])
104
+
105
+ token_info = extract_token_info(ctx)
106
+ assignment_node = Assignment(left=left_node, op=op_node, right=right_node, **token_info)
107
+ return assignment_node
108
+
109
+ # | varID PUT_SYMBOL expr # persistAssignment
110
+ def visitPersistAssignment(self, ctx: Parser.PersistAssignmentContext):
111
+ """
112
+ persistentAssignment: varID PUT_SYMBOL expr;
113
+ """
114
+ ctx_list = list(ctx.getChildren())
115
+
116
+ left_node = Terminals().visitVarID(ctx_list[0])
117
+ op_node = ctx_list[1].getSymbol().text
118
+
119
+ right_node = Expr().visitExpr(ctx_list[2])
120
+
121
+ token_info = extract_token_info(ctx)
122
+ persistent_assignment_node = PersistentAssignment(
123
+ left=left_node, op=op_node, right=right_node, **token_info
124
+ )
125
+ return persistent_assignment_node
126
+
127
+ """______________________________________________________________________________________
128
+
129
+
130
+ Artefacts Definition.
131
+
132
+ _______________________________________________________________________________________"""
133
+
134
+ def visitDefineExpression(self, ctx: Parser.DefineExpressionContext):
135
+ """
136
+ defExpr: defOperator
137
+ | defDatapoint
138
+ | defHierarchical
139
+ ;
140
+ """
141
+ if isinstance(ctx, Parser.DefOperatorContext):
142
+ return self.visitDefOperator(ctx)
143
+
144
+ elif isinstance(ctx, Parser.DefDatapointRulesetContext):
145
+ return self.visitDefDatapointRuleset(ctx)
146
+
147
+ elif isinstance(ctx, Parser.DefHierarchicalContext):
148
+ return self.visitDefHierarchical(ctx)
149
+
150
+ def visitDefOperator(self, ctx: Parser.DefOperatorContext):
151
+ """
152
+ DEFINE OPERATOR operatorID LPAREN (parameterItem (COMMA parameterItem)*)? RPAREN
153
+ (RETURNS outputParameterType)? IS (expr) END OPERATOR # defOperator"""
154
+ ctx_list = list(ctx.getChildren())
155
+
156
+ operator = Terminals().visitOperatorID(ctx_list[2])
157
+ parameters = [
158
+ self.visitParameterItem(parameter)
159
+ for parameter in ctx_list
160
+ if isinstance(parameter, Parser.ParameterItemContext)
161
+ ]
162
+ return_ = [
163
+ Terminals().visitOutputParameterType(datatype)
164
+ for datatype in ctx_list
165
+ if isinstance(datatype, Parser.OutputParameterTypeContext)
166
+ ]
167
+ # Here should be modified if we want to include more than one expr per function.
168
+ expr = [
169
+ Expr().visitExpr(expr) for expr in ctx_list if isinstance(expr, Parser.ExprContext)
170
+ ][0]
171
+
172
+ if len(return_) == 0:
173
+ raise SemanticError("1-3-2-2", op=operator)
174
+ else:
175
+ return_node = return_[0]
176
+
177
+ token_info = extract_token_info(ctx)
178
+
179
+ return Operator(
180
+ op=operator,
181
+ parameters=parameters,
182
+ output_type=return_node,
183
+ expression=expr,
184
+ **token_info,
185
+ )
186
+
187
+ """
188
+ -----------------------------------
189
+ Define Datapoint
190
+ -----------------------------------
191
+ """
192
+
193
+ def visitDefDatapointRuleset(self, ctx: Parser.DefDatapointRulesetContext):
194
+ """
195
+ DEFINE DATAPOINT RULESET rulesetID LPAREN rulesetSignature RPAREN IS ruleClauseDatapoint
196
+ END DATAPOINT RULESET # defDatapointRuleset
197
+ """
198
+
199
+ ctx_list = list(ctx.getChildren())
200
+
201
+ ruleset_name = Terminals().visitRulesetID(ctx_list[3])
202
+ signature_type, ruleset_elements = self.visitRulesetSignature(ctx_list[5])
203
+ ruleset_rules = self.visitRuleClauseDatapoint(ctx_list[8])
204
+
205
+ token_info = extract_token_info(ctx)
206
+
207
+ return DPRuleset(
208
+ name=ruleset_name,
209
+ params=ruleset_elements,
210
+ rules=ruleset_rules,
211
+ signature_type=signature_type,
212
+ **token_info,
213
+ )
214
+
215
+ def visitRulesetSignature(self, ctx: Parser.RulesetSignatureContext):
216
+ """
217
+ rulesetSignature: (VALUE_DOMAIN|VARIABLE) varSignature (',' varSignature)* ;
218
+ """
219
+ ctx_list = list(ctx.getChildren())
220
+ signature_type = ctx_list[0].getSymbol().text
221
+
222
+ value_domains = [
223
+ value_domain
224
+ for value_domain in ctx_list
225
+ if isinstance(value_domain, TerminalNodeImpl)
226
+ and value_domain.getSymbol().type == Parser.VALUE_DOMAIN
227
+ ]
228
+ kind = ""
229
+ if len(value_domains) != 0:
230
+ kind = "ValuedomainID"
231
+
232
+ variables = [
233
+ variable
234
+ for variable in ctx_list
235
+ if isinstance(variable, TerminalNodeImpl)
236
+ and variable.getSymbol().type == Parser.VARIABLE
237
+ ]
238
+ if len(variables) != 0:
239
+ kind = "ComponentID"
240
+
241
+ component_nodes = [
242
+ Terminals().visitSignature(component, kind)
243
+ for component in ctx_list
244
+ if isinstance(component, Parser.SignatureContext)
245
+ ]
246
+
247
+ return signature_type, component_nodes
248
+
249
+ def visitRuleClauseDatapoint(self, ctx: Parser.RuleClauseDatapointContext):
250
+ """
251
+ ruleClauseDatapoint: ruleItemDatapoint (';' ruleItemDatapoint)* ;
252
+ """
253
+ ctx_list = list(ctx.getChildren())
254
+
255
+ ruleset_rules = [
256
+ self.visitRuleItemDatapoint(ruleId)
257
+ for ruleId in ctx_list
258
+ if isinstance(ruleId, Parser.RuleItemDatapointContext)
259
+ ]
260
+ return ruleset_rules
261
+
262
+ def visitRuleItemDatapoint(self, ctx: Parser.RuleItemDatapointContext):
263
+ """
264
+ ruleItemDatapoint: (IDENTIFIER ':')? ( WHEN expr THEN )? expr (erCode)? (erLevel)? ;
265
+ """
266
+ ctx_list = list(ctx.getChildren())
267
+
268
+ when = [
269
+ whens
270
+ for whens in ctx_list
271
+ if isinstance(whens, TerminalNodeImpl) and whens.getSymbol().type == Parser.WHEN
272
+ ]
273
+ rule_name = [
274
+ (
275
+ rule_name.getSymbol().text
276
+ if isinstance(rule_name, TerminalNodeImpl)
277
+ and rule_name.getSymbol().type == Parser.IDENTIFIER
278
+ else None
279
+ )
280
+ for rule_name in ctx_list
281
+ ][0]
282
+ expr_node = [
283
+ ExprComp().visitExprComponent(rule_node)
284
+ for rule_node in ctx_list
285
+ if isinstance(rule_node, Parser.ExprComponentContext)
286
+ ]
287
+
288
+ if len(when) != 0:
289
+ token_info = extract_token_info(when[0].getSymbol())
290
+ rule_node = HRBinOp(
291
+ left=expr_node[0], op=when[0].getSymbol().text, right=expr_node[1], **token_info
292
+ )
293
+
294
+ else:
295
+ rule_node = expr_node[0]
296
+
297
+ er_code = [
298
+ Terminals().visitErCode(erCode_name)
299
+ for erCode_name in ctx_list
300
+ if isinstance(erCode_name, Parser.ErCodeContext)
301
+ ]
302
+ er_code = None if len(er_code) == 0 else er_code[0]
303
+ er_level = [
304
+ Terminals().visitErLevel(erLevel_name)
305
+ for erLevel_name in ctx_list
306
+ if isinstance(erLevel_name, Parser.ErLevelContext)
307
+ ]
308
+ er_level = None if len(er_level) == 0 else er_level[0]
309
+
310
+ token_info = extract_token_info(ctx)
311
+ return DPRule(
312
+ name=rule_name, rule=rule_node, erCode=er_code, erLevel=er_level, **token_info
313
+ )
314
+
315
+ def visitParameterItem(self, ctx: Parser.ParameterItemContext):
316
+ """
317
+ parameterItem: varID dataType (DEFAULT constant)? ;
318
+ """
319
+ ctx_list = list(ctx.getChildren())
320
+
321
+ argument_name = [
322
+ Terminals().visitVarID(element)
323
+ for element in ctx_list
324
+ if isinstance(element, Parser.VarIDContext)
325
+ ][0]
326
+ argument_type = [
327
+ Terminals().visitInputParameterType(element)
328
+ for element in ctx_list
329
+ if isinstance(element, Parser.InputParameterTypeContext)
330
+ ][0]
331
+ argument_default = [
332
+ Terminals().visitScalarItem(element)
333
+ for element in ctx_list
334
+ if isinstance(element, Parser.ScalarItemContext)
335
+ ]
336
+ argument_default = None if len(argument_default) == 0 else argument_default[0]
337
+
338
+ if isinstance(argument_type, (Dataset, Component, Scalar)):
339
+ argument_type.name = argument_name.value
340
+ token_info = extract_token_info(ctx)
341
+ return Argument(
342
+ name=argument_name.value, type_=argument_type, default=argument_default, **token_info
343
+ )
344
+
345
+ """
346
+ -----------------------------------
347
+ Define Hierarchical
348
+ -----------------------------------
349
+ """
350
+
351
+ def visitDefHierarchical(self, ctx: Parser.DefHierarchicalContext):
352
+ """
353
+ DEFINE DATAPOINT RULESET rulesetID LPAREN rulesetSignature RPAREN IS ruleClauseDatapoint
354
+ END DATAPOINT RULESET # defDatapointRuleset
355
+ """
356
+
357
+ ctx_list = list(ctx.getChildren())
358
+
359
+ ruleset_name = Terminals().visitRulesetID(ctx_list[3])
360
+ signature_type, ruleset_elements = self.visitHierRuleSignature(ctx_list[5])
361
+ if signature_type == "variable" and isinstance(ruleset_elements, list):
362
+ unique_id_names = list(set([elto.value for elto in ruleset_elements]))
363
+ if len(ruleset_elements) > 2 or len(unique_id_names) < 1:
364
+ raise SemanticError("1-1-10-9", ruleset=ruleset_name)
365
+ ruleset_rules = self.visitRuleClauseHierarchical(ctx_list[8])
366
+ # Keep k,v for the hierarchical rulesets
367
+ de_ruleset_elements[ruleset_name] = ruleset_elements
368
+ if len(ruleset_rules) == 0:
369
+ raise Exception(f"No rules found for the ruleset {ruleset_name}")
370
+
371
+ token_info = extract_token_info(ctx)
372
+
373
+ return HRuleset(
374
+ signature_type=signature_type,
375
+ name=ruleset_name,
376
+ element=ruleset_elements,
377
+ rules=ruleset_rules,
378
+ **token_info,
379
+ )
380
+
381
+ # TODO Add support for value Domains.
382
+ def visitHierRuleSignature(self, ctx: Parser.HierRuleSignatureContext):
383
+ """
384
+ hierRuleSignature: (VALUE_DOMAIN|VARIABLE) valueDomainSignature? RULE IDENTIFIER ;
385
+ """
386
+ ctx_list = list(ctx.getChildren())
387
+
388
+ signature_type = ctx_list[0].getSymbol().text
389
+
390
+ value_domain = [
391
+ valueDomain
392
+ for valueDomain in ctx_list
393
+ if isinstance(valueDomain, TerminalNodeImpl)
394
+ and valueDomain.getSymbol().type == Parser.VALUE_DOMAIN
395
+ ]
396
+ kind = "ValuedomainID" if len(value_domain) != 0 else "DatasetID"
397
+
398
+ conditions = [
399
+ self.visitValueDomainSignature(vtlsig)
400
+ for vtlsig in ctx_list
401
+ if isinstance(vtlsig, Parser.ValueDomainSignatureContext)
402
+ ]
403
+
404
+ dataset = [
405
+ identifier
406
+ for identifier in ctx_list
407
+ if isinstance(identifier, TerminalNodeImpl)
408
+ and identifier.getSymbol().type == Parser.IDENTIFIER
409
+ ][0]
410
+
411
+ token_info = extract_token_info(ctx)
412
+ if conditions:
413
+ identifiers_list = [
414
+ DefIdentifier(
415
+ value=elto.alias if getattr(elto, "alias", None) else elto.value,
416
+ kind=kind,
417
+ **token_info,
418
+ )
419
+ for elto in conditions[0]
420
+ ]
421
+ identifiers_list.append(
422
+ DefIdentifier(value=dataset.getSymbol().text, kind=kind, **token_info)
423
+ )
424
+ return signature_type, identifiers_list
425
+ else:
426
+ return signature_type, DefIdentifier(
427
+ value=dataset.getSymbol().text, kind=kind, **token_info
428
+ )
429
+
430
+ # TODO Support for valueDomainSignature.
431
+ def visitValueDomainSignature(self, ctx: Parser.ValueDomainSignatureContext):
432
+ """
433
+ valueDomainSignature: CONDITION IDENTIFIER (AS IDENTIFIER)? (',' IDENTIFIER (AS IDENTIFIER)?)* ;
434
+ """ # noqa E501
435
+ # AST_ASTCONSTRUCTOR.7
436
+ ctx_list = list(ctx.getChildren())
437
+ component_nodes = [
438
+ Terminals().visitSignature(component)
439
+ for component in ctx_list
440
+ if isinstance(component, Parser.SignatureContext)
441
+ ]
442
+ return component_nodes
443
+
444
+ def visitRuleClauseHierarchical(self, ctx: Parser.RuleClauseHierarchicalContext):
445
+ """
446
+ ruleClauseHierarchical: ruleItemHierarchical (';' ruleItemHierarchical)* ;
447
+ """
448
+ ctx_list = list(ctx.getChildren())
449
+
450
+ rules_nodes = [
451
+ self.visitRuleItemHierarchical(rule)
452
+ for rule in ctx_list
453
+ if isinstance(rule, Parser.RuleItemHierarchicalContext)
454
+ ]
455
+ return rules_nodes
456
+
457
+ def visitRuleItemHierarchical(self, ctx: Parser.RuleItemHierarchicalContext):
458
+ """
459
+ ruleItemHierarchical: (ruleName=IDENTIFIER COLON )? codeItemRelation (erCode)? (erLevel)? ;
460
+ """
461
+ ctx_list = list(ctx.getChildren())
462
+
463
+ rule_name = [
464
+ (
465
+ rule_name.getSymbol().text
466
+ if isinstance(rule_name, TerminalNodeImpl)
467
+ and rule_name.getSymbol().type == Parser.IDENTIFIER
468
+ else None
469
+ )
470
+ for rule_name in ctx_list
471
+ ][0]
472
+ rule_node = [
473
+ self.visitCodeItemRelation(rule_node)
474
+ for rule_node in ctx_list
475
+ if isinstance(rule_node, Parser.CodeItemRelationContext)
476
+ ][0]
477
+
478
+ er_code = [
479
+ Terminals().visitErCode(erCode_name)
480
+ for erCode_name in ctx_list
481
+ if isinstance(erCode_name, Parser.ErCodeContext)
482
+ ]
483
+ er_code = None if len(er_code) == 0 else er_code[0]
484
+ er_level = [
485
+ Terminals().visitErLevel(erLevel_name)
486
+ for erLevel_name in ctx_list
487
+ if isinstance(erLevel_name, Parser.ErLevelContext)
488
+ ]
489
+ er_level = None if len(er_level) == 0 else er_level[0]
490
+
491
+ token_info = extract_token_info(ctx)
492
+
493
+ return HRule(name=rule_name, rule=rule_node, erCode=er_code, erLevel=er_level, **token_info)
494
+
495
+ def visitCodeItemRelation(self, ctx: Parser.CodeItemRelationContext):
496
+ """
497
+ codeItemRelation: ( WHEN expr THEN )? codeItemRef codeItemRelationClause (codeItemRelationClause)* ;
498
+ ( WHEN exprComponent THEN )? codetemRef=valueDomainValue comparisonOperand? codeItemRelationClause (codeItemRelationClause)*
499
+
500
+ """ # noqa E501
501
+
502
+ ctx_list = list(ctx.getChildren())
503
+
504
+ when = None
505
+
506
+ if isinstance(ctx_list[0], TerminalNodeImpl):
507
+ when = ctx_list[0].getSymbol().text
508
+ vd_value = Terminals().visitValueDomainValue(ctx_list[3])
509
+ op = Terminals().visitComparisonOperand(ctx_list[4])
510
+ token_info_value = extract_token_info(ctx_list[3])
511
+ token_info_op = extract_token_info(ctx_list[4])
512
+ else:
513
+ vd_value = Terminals().visitValueDomainValue(ctx_list[0])
514
+ op = Terminals().visitComparisonOperand(ctx_list[1])
515
+ token_info_value = extract_token_info(ctx_list[0])
516
+ token_info_op = extract_token_info(ctx_list[1])
517
+
518
+ rule_node = HRBinOp(
519
+ left=DefIdentifier(value=vd_value, kind="CodeItemID", **token_info_value),
520
+ op=op,
521
+ right=None,
522
+ **token_info_op,
523
+ )
524
+ items = [
525
+ item for item in ctx_list if isinstance(item, Parser.CodeItemRelationClauseContext)
526
+ ]
527
+ token_info = extract_token_info(items[0])
528
+ # Means that no concatenations of operations is needed for that rule.
529
+ if len(items) == 1:
530
+ cir_node = self.visitCodeItemRelationClause(items[0])
531
+ if isinstance(cir_node, HRBinOp):
532
+ rule_node.right = HRUnOp(op=cir_node.op, operand=cir_node.right, **token_info)
533
+
534
+ elif isinstance(cir_node, DefIdentifier):
535
+ rule_node.right = cir_node
536
+
537
+ # Concatenate all the the elements except the last one.
538
+ else:
539
+ previous_node = self.visitCodeItemRelationClause(items[0])
540
+ if isinstance(previous_node, HRBinOp):
541
+ previous_node = HRUnOp(
542
+ op=previous_node.op, operand=previous_node.right, **token_info
543
+ )
544
+
545
+ for item in items[1:]:
546
+ item_node = self.visitCodeItemRelationClause(item)
547
+ item_node.left = previous_node
548
+
549
+ previous_node = item_node
550
+
551
+ rule_node.right = previous_node
552
+
553
+ if when is not None:
554
+ expr_node = ExprComp().visitExprComponent(ctx_list[1])
555
+ token_when_info = extract_token_info(ctx_list[1])
556
+ rule_node = HRBinOp(left=expr_node, op=when, right=rule_node, **token_when_info)
557
+
558
+ return rule_node
559
+
560
+ def visitCodeItemRelationClause(self, ctx: Parser.CodeItemRelationClauseContext):
561
+ """
562
+ (opAdd=( PLUS | MINUS ))? rightCodeItem=valueDomainValue ( QLPAREN rightCondition=exprComponent QRPAREN )?
563
+ """ # noqa E501
564
+ ctx_list = list(ctx.getChildren())
565
+
566
+ expr = [expr for expr in ctx_list if isinstance(expr, Parser.ExprContext)]
567
+ if len(expr) != 0:
568
+ # AST_ASTCONSTRUCTOR.8
569
+ raise NotImplementedError
570
+
571
+ right_condition = [
572
+ ExprComp().visitExprComponent(right_condition)
573
+ for right_condition in ctx_list
574
+ if isinstance(right_condition, Parser.ComparisonExprCompContext)
575
+ ]
576
+
577
+ if isinstance(ctx_list[0], TerminalNodeImpl):
578
+ op = ctx_list[0].getSymbol().text
579
+ value = Terminals().visitValueDomainValue(ctx_list[1])
580
+
581
+ code_item = DefIdentifier(
582
+ value=value, kind="CodeItemID", **extract_token_info(ctx_list[1])
583
+ )
584
+ if right_condition:
585
+ code_item._right_condition = right_condition[0]
586
+
587
+ return HRBinOp(
588
+ left=None, op=op, right=code_item, **extract_token_info(ctx_list[0].getSymbol())
589
+ )
590
+ else:
591
+ value = Terminals().visitValueDomainValue(ctx_list[0])
592
+ code_item = DefIdentifier(
593
+ value=value, kind="CodeItemID", **extract_token_info(ctx_list[0])
594
+ )
595
+ if right_condition:
596
+ code_item._right_condition = right_condition[0]
597
+
598
+ return code_item